Skip to content

Commit e499d56

Browse files
authored
chore(runtime-vapor): render fallback at the deepest invalid fragment (#14172)
1 parent 2f0676f commit e499d56

File tree

1 file changed

+23
-17
lines changed

1 file changed

+23
-17
lines changed

packages/runtime-vapor/src/fragment.ts

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -151,20 +151,31 @@ export class DynamicFragment extends VaporFragment {
151151
this.render(render, transition, parent, instance)
152152

153153
if (this.fallback) {
154-
// set fallback for nested fragments
155-
const hasNestedFragment = isFragment(this.nodes)
156-
if (hasNestedFragment) {
157-
setFragmentFallback(this.nodes as VaporFragment, this.fallback)
154+
// Find the deepest invalid fragment
155+
let invalidFragment: VaporFragment | null = null
156+
if (isFragment(this.nodes)) {
157+
setFragmentFallback(
158+
this.nodes,
159+
this.fallback,
160+
(frag: VaporFragment) => {
161+
if (!isValidBlock(frag.nodes)) {
162+
invalidFragment = frag
163+
}
164+
},
165+
)
166+
}
167+
168+
// Check self validity (when no nested fragment or nested is valid)
169+
if (!invalidFragment && !isValidBlock(this.nodes)) {
170+
invalidFragment = this
158171
}
159172

160-
const invalidFragment = findInvalidFragment(this)
161173
if (invalidFragment) {
162174
parent && remove(this.nodes, parent)
163175
const scope = this.scope || (this.scope = new EffectScope())
164176
scope.run(() => {
165-
// for nested fragments, render invalid fragment's fallback
166-
if (hasNestedFragment) {
167-
renderFragmentFallback(invalidFragment)
177+
if (invalidFragment !== this) {
178+
renderFragmentFallback(invalidFragment!)
168179
} else {
169180
this.nodes = this.fallback!() || []
170181
}
@@ -297,6 +308,7 @@ export class DynamicFragment extends VaporFragment {
297308
export function setFragmentFallback(
298309
fragment: VaporFragment,
299310
fallback: BlockFn,
311+
onFragment?: (frag: VaporFragment) => void,
300312
): void {
301313
if (fragment.fallback) {
302314
const originalFallback = fragment.fallback
@@ -313,8 +325,10 @@ export function setFragmentFallback(
313325
fragment.fallback = fallback
314326
}
315327

328+
if (onFragment) onFragment(fragment)
329+
316330
if (isFragment(fragment.nodes)) {
317-
setFragmentFallback(fragment.nodes, fragment.fallback)
331+
setFragmentFallback(fragment.nodes, fragment.fallback, onFragment)
318332
}
319333
}
320334

@@ -328,14 +342,6 @@ function renderFragmentFallback(fragment: VaporFragment): void {
328342
}
329343
}
330344

331-
function findInvalidFragment(fragment: VaporFragment): VaporFragment | null {
332-
if (isValidBlock(fragment.nodes)) return null
333-
334-
return isFragment(fragment.nodes)
335-
? findInvalidFragment(fragment.nodes) || fragment
336-
: fragment
337-
}
338-
339345
export function isFragment(val: NonNullable<unknown>): val is VaporFragment {
340346
return val instanceof VaporFragment
341347
}

0 commit comments

Comments
 (0)