diff --git a/packages/runtime-vapor/src/fragment.ts b/packages/runtime-vapor/src/fragment.ts index f80f0761176..41bfde220b1 100644 --- a/packages/runtime-vapor/src/fragment.ts +++ b/packages/runtime-vapor/src/fragment.ts @@ -151,20 +151,31 @@ export class DynamicFragment extends VaporFragment { this.render(render, transition, parent, instance) if (this.fallback) { - // set fallback for nested fragments - const hasNestedFragment = isFragment(this.nodes) - if (hasNestedFragment) { - setFragmentFallback(this.nodes as VaporFragment, this.fallback) + // Find the deepest invalid fragment + let invalidFragment: VaporFragment | null = null + if (isFragment(this.nodes)) { + setFragmentFallback( + this.nodes, + this.fallback, + (frag: VaporFragment) => { + if (!isValidBlock(frag.nodes)) { + invalidFragment = frag + } + }, + ) + } + + // Check self validity (when no nested fragment or nested is valid) + if (!invalidFragment && !isValidBlock(this.nodes)) { + invalidFragment = this } - const invalidFragment = findInvalidFragment(this) if (invalidFragment) { parent && remove(this.nodes, parent) const scope = this.scope || (this.scope = new EffectScope()) scope.run(() => { - // for nested fragments, render invalid fragment's fallback - if (hasNestedFragment) { - renderFragmentFallback(invalidFragment) + if (invalidFragment !== this) { + renderFragmentFallback(invalidFragment!) } else { this.nodes = this.fallback!() || [] } @@ -297,6 +308,7 @@ export class DynamicFragment extends VaporFragment { export function setFragmentFallback( fragment: VaporFragment, fallback: BlockFn, + onFragment?: (frag: VaporFragment) => void, ): void { if (fragment.fallback) { const originalFallback = fragment.fallback @@ -313,8 +325,10 @@ export function setFragmentFallback( fragment.fallback = fallback } + if (onFragment) onFragment(fragment) + if (isFragment(fragment.nodes)) { - setFragmentFallback(fragment.nodes, fragment.fallback) + setFragmentFallback(fragment.nodes, fragment.fallback, onFragment) } } @@ -328,14 +342,6 @@ function renderFragmentFallback(fragment: VaporFragment): void { } } -function findInvalidFragment(fragment: VaporFragment): VaporFragment | null { - if (isValidBlock(fragment.nodes)) return null - - return isFragment(fragment.nodes) - ? findInvalidFragment(fragment.nodes) || fragment - : fragment -} - export function isFragment(val: NonNullable): val is VaporFragment { return val instanceof VaporFragment }