Skip to content

Commit 3a52e46

Browse files
committed
fix(runtime-vapor): improve fallback handling for nested fragments
1 parent b8ceb89 commit 3a52e46

File tree

1 file changed

+21
-19
lines changed

1 file changed

+21
-19
lines changed

packages/runtime-vapor/src/block.ts

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -74,18 +74,19 @@ export class DynamicFragment extends VaporFragment {
7474

7575
if (this.fallback) {
7676
// set fallback for nested fragments
77-
const isFrag = isFragment(this.nodes)
78-
if (isFrag) {
77+
const hasNestedFragment = isFragment(this.nodes)
78+
if (hasNestedFragment) {
7979
setFragmentFallback(this.nodes as VaporFragment, this.fallback)
8080
}
8181

82-
if (!isValidBlock(this.nodes)) {
82+
const invalidFragment = findInvalidFragment(this)
83+
if (invalidFragment) {
8384
parent && remove(this.nodes, parent)
8485
const scope = this.scope || (this.scope = new EffectScope())
8586
scope.run(() => {
86-
if (isFrag) {
87-
// render fragment's fallback
88-
renderFragmentFallback(this.nodes as VaporFragment)
87+
// for nested fragments, render invalid fragment's fallback
88+
if (hasNestedFragment) {
89+
renderFragmentFallback(invalidFragment)
8990
} else {
9091
this.nodes = this.fallback!() || []
9192
}
@@ -98,13 +99,11 @@ export class DynamicFragment extends VaporFragment {
9899
}
99100
}
100101

101-
function setFragmentFallback(
102-
fragment: VaporFragment,
103-
fallback: BlockFn | undefined,
104-
): void {
105-
if (!fragment.fallback) {
106-
fragment.fallback = fallback
107-
}
102+
function setFragmentFallback(fragment: VaporFragment, fallback: BlockFn): void {
103+
// stop recursion if fragment has its own fallback
104+
if (fragment.fallback) return
105+
106+
fragment.fallback = fallback
108107
if (isFragment(fragment.nodes)) {
109108
setFragmentFallback(fragment.nodes, fallback)
110109
}
@@ -114,17 +113,20 @@ function renderFragmentFallback(fragment: VaporFragment): void {
114113
if (fragment instanceof ForFragment) {
115114
fragment.nodes[0] = [fragment.fallback!() || []] as Block[]
116115
} else if (fragment instanceof DynamicFragment) {
117-
const nodes = fragment.nodes
118-
if (isFragment(nodes)) {
119-
renderFragmentFallback(nodes)
120-
} else {
121-
fragment.update(fragment.fallback)
122-
}
116+
fragment.update(fragment.fallback)
123117
} else {
124118
// vdom slots
125119
}
126120
}
127121

122+
function findInvalidFragment(fragment: VaporFragment): VaporFragment | null {
123+
if (isValidBlock(fragment.nodes)) return null
124+
125+
return isFragment(fragment.nodes)
126+
? findInvalidFragment(fragment.nodes) || fragment
127+
: fragment
128+
}
129+
128130
export function isFragment(val: NonNullable<unknown>): val is VaporFragment {
129131
return val instanceof VaporFragment
130132
}

0 commit comments

Comments
 (0)