Skip to content

Commit 85693f0

Browse files
committed
feat(hydration): handle consecutive if node
1 parent 5ee1628 commit 85693f0

File tree

3 files changed

+38
-8
lines changed

3 files changed

+38
-8
lines changed

packages/runtime-vapor/__tests__/hydration.spec.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1269,6 +1269,26 @@ describe('Vapor Mode hydration', () => {
12691269
expect(container.innerHTML).toBe(`<!--${anchorLabel}-->`)
12701270
})
12711271

1272+
test('consecutive if node', async () => {
1273+
const data = ref(true)
1274+
const { container } = await testHydration(
1275+
`<template>
1276+
<components.Child v-if="data"/>
1277+
</template>`,
1278+
{ Child: `<template><div v-if="data">foo</div></template>` },
1279+
data,
1280+
)
1281+
expect(container.innerHTML).toBe(`<div>foo</div><!--if--><!--if-->`)
1282+
1283+
data.value = false
1284+
await nextTick()
1285+
expect(container.innerHTML).toBe(`<!--if-->`)
1286+
1287+
data.value = true
1288+
await nextTick()
1289+
expect(container.innerHTML).toBe(`<div>foo</div><!--if--><!--if-->`)
1290+
})
1291+
12721292
test('v-if/else-if/else chain on component - switch branches', async () => {
12731293
const data = ref('a')
12741294
const { container } = await testHydration(

packages/runtime-vapor/src/block.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
import { createComment, createTextNode } from './dom/node'
99
import { EffectScope, setActiveSub } from '@vue/reactivity'
1010
import {
11+
advanceHydrationNode,
1112
currentHydrationNode,
1213
isComment,
1314
isHydrating,
@@ -41,12 +42,13 @@ export class DynamicFragment extends VaporFragment {
4142
current?: BlockFn
4243
fallback?: BlockFn
4344
teardown?: () => void
45+
anchorLabel?: string
4446

4547
constructor(anchorLabel?: string) {
4648
super([])
4749
if (isHydrating) {
50+
this.anchorLabel = anchorLabel
4851
locateHydrationNode()
49-
this.hydrate(anchorLabel!)
5052
} else {
5153
this.anchor =
5254
__DEV__ && anchorLabel ? createComment(anchorLabel) : createTextNode()
@@ -55,12 +57,13 @@ export class DynamicFragment extends VaporFragment {
5557

5658
update(render?: BlockFn, key: any = render): void {
5759
if (key === this.current) {
60+
if (isHydrating) this.hydrate(this.anchorLabel!)
5861
return
5962
}
6063
this.current = key
6164

6265
const prevSub = setActiveSub()
63-
const parent = this.anchor.parentNode
66+
const parent = isHydrating ? null : this.anchor.parentNode
6467

6568
// teardown previous branch
6669
if (this.scope) {
@@ -89,6 +92,8 @@ export class DynamicFragment extends VaporFragment {
8992
}
9093

9194
setActiveSub(prevSub)
95+
96+
if (isHydrating) this.hydrate(this.anchorLabel!)
9297
}
9398

9499
hydrate(label: string): void {
@@ -105,6 +110,7 @@ export class DynamicFragment extends VaporFragment {
105110
throw new Error(`${label} fragment anchor node was not found.`)
106111
}
107112
}
113+
advanceHydrationNode(this.anchor)
108114
}
109115
}
110116

packages/runtime-vapor/src/dom/hydration.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ export function setCurrentHydrationNode(node: Node | null): void {
1919
currentHydrationNode = node
2020
}
2121

22+
export function advanceHydrationNode(node: Node): void {
23+
setCurrentHydrationNode(node.nextSibling || node.parentNode)
24+
}
25+
2226
let isOptimized = false
2327

2428
function performHydration<T>(
@@ -96,7 +100,7 @@ function adoptTemplateImpl(node: Node, template: string): Node | null {
96100
}
97101
}
98102

99-
currentHydrationNode = node.nextSibling
103+
advanceHydrationNode(node)
100104
return node
101105
}
102106

@@ -169,12 +173,12 @@ export function isNonHydrationNode(node: Node): boolean {
169173
export function locateVaporFragmentAnchor(
170174
node: Node,
171175
anchorLabel: string,
172-
): Comment | undefined {
173-
let n = node.nextSibling
174-
while (n) {
175-
if (isComment(n, anchorLabel)) return n
176-
n = n.nextSibling
176+
): Comment | null {
177+
while (node) {
178+
if (isComment(node, anchorLabel)) return node
179+
node = node.nextSibling!
177180
}
181+
return null
178182
}
179183

180184
export function isEmptyTextNode(node: Node): node is Text {

0 commit comments

Comments
 (0)