diff --git a/packages/runtime-vapor/__tests__/hydration.spec.ts b/packages/runtime-vapor/__tests__/hydration.spec.ts
index 67f5c634b..ecb8d8202 100644
--- a/packages/runtime-vapor/__tests__/hydration.spec.ts
+++ b/packages/runtime-vapor/__tests__/hydration.spec.ts
@@ -264,6 +264,48 @@ describe('Vapor Mode hydration', () => {
)
})
+ test('nested components with anchor insertion', async () => {
+ const { container, data } = await testHydration(
+ `
+
+ `,
+ {
+ Parent: `
`,
+ Child: `{{ data }}
`,
+ },
+ )
+ expect(container.innerHTML).toMatchInlineSnapshot(
+ `"
"`,
+ )
+
+ data.value = 'bar'
+ await nextTick()
+ expect(container.innerHTML).toMatchInlineSnapshot(
+ `""`,
+ )
+ })
+
+ test('nested components with multi level anchor insertion', async () => {
+ const { container, data } = await testHydration(
+ `
+
+ `,
+ {
+ Parent: `
`,
+ Child: `{{ data }}
`,
+ },
+ )
+ expect(container.innerHTML).toMatchInlineSnapshot(
+ `""`,
+ )
+
+ data.value = 'bar'
+ await nextTick()
+ expect(container.innerHTML).toMatchInlineSnapshot(
+ `""`,
+ )
+ })
+
test('consecutive components with anchor insertion', async () => {
const { container, data } = await testHydration(
`
@@ -290,6 +332,48 @@ describe('Vapor Mode hydration', () => {
)
})
+ test('nested consecutive components with anchor insertion', async () => {
+ const { container, data } = await testHydration(
+ `
+
+ `,
+ {
+ Parent: `
`,
+ Child: `{{ data }}
`,
+ },
+ )
+ expect(container.innerHTML).toMatchInlineSnapshot(
+ `""`,
+ )
+
+ data.value = 'bar'
+ await nextTick()
+ expect(container.innerHTML).toMatchInlineSnapshot(
+ `""`,
+ )
+ })
+
+ test('nested consecutive components with multi level anchor insertion', async () => {
+ const { container, data } = await testHydration(
+ `
+
+ `,
+ {
+ Parent: `
`,
+ Child: `{{ data }}
`,
+ },
+ )
+ expect(container.innerHTML).toMatchInlineSnapshot(
+ `""`,
+ )
+
+ data.value = 'bar'
+ await nextTick()
+ expect(container.innerHTML).toMatchInlineSnapshot(
+ `""`,
+ )
+ })
+
test('mixed component and element with anchor insertion', async () => {
const { container, data } = await testHydration(
`
@@ -369,6 +453,48 @@ describe('Vapor Mode hydration', () => {
)
})
+ test('nested fragment component with anchor insertion', async () => {
+ const { container, data } = await testHydration(
+ `
+
+ `,
+ {
+ Parent: `
`,
+ Child: `{{ data }}
-{{ data }}-`,
+ },
+ )
+ expect(container.innerHTML).toMatchInlineSnapshot(
+ `""`,
+ )
+
+ data.value = 'bar'
+ await nextTick()
+ expect(container.innerHTML).toMatchInlineSnapshot(
+ `""`,
+ )
+ })
+
+ test('nested fragment component with multi level anchor insertion', async () => {
+ const { container, data } = await testHydration(
+ `
+
+ `,
+ {
+ Parent: `
`,
+ Child: `{{ data }}
-{{ data }}-`,
+ },
+ )
+ expect(container.innerHTML).toMatchInlineSnapshot(
+ `""`,
+ )
+
+ data.value = 'bar'
+ await nextTick()
+ expect(container.innerHTML).toMatchInlineSnapshot(
+ `""`,
+ )
+ })
+
test('consecutive fragment components with anchor insertion', async () => {
const { container, data } = await testHydration(
`
@@ -395,6 +521,69 @@ describe('Vapor Mode hydration', () => {
)
})
+ test('nested consecutive fragment components with anchor insertion', async () => {
+ const { container, data } = await testHydration(
+ `
+
+ `,
+ {
+ Parent: `
`,
+ Child: `{{ data }}
-{{ data }}-`,
+ },
+ )
+ expect(container.innerHTML).toMatchInlineSnapshot(
+ `""`,
+ )
+
+ data.value = 'bar'
+ await nextTick()
+ expect(container.innerHTML).toMatchInlineSnapshot(
+ `""`,
+ )
+ })
+
+ test('nested consecutive fragment components with multi level anchor insertion', async () => {
+ const { container, data } = await testHydration(
+ `
+
+ `,
+ {
+ Parent: `
`,
+ Child: `{{ data }}
-{{ data }}-`,
+ },
+ )
+ expect(container.innerHTML).toMatchInlineSnapshot(
+ `""`,
+ )
+
+ data.value = 'bar'
+ await nextTick()
+ expect(container.innerHTML).toMatchInlineSnapshot(
+ `""`,
+ )
+ })
+
+ test('nested consecutive fragment components with root level anchor insertion', async () => {
+ const { container, data } = await testHydration(
+ `
+
+ `,
+ {
+ Parent: ``,
+ Child: `{{ data }}
-{{ data }}-`,
+ },
+ )
+ expect(container.innerHTML).toMatchInlineSnapshot(
+ `""`,
+ )
+
+ data.value = 'bar'
+ await nextTick()
+ expect(container.innerHTML).toMatchInlineSnapshot(
+ `""`,
+ )
+ })
+
test('mixed fragment component and element with anchor insertion', async () => {
const { container, data } = await testHydration(
`
diff --git a/packages/runtime-vapor/src/dom/node.ts b/packages/runtime-vapor/src/dom/node.ts
index 66f1a42f8..82971e876 100644
--- a/packages/runtime-vapor/src/dom/node.ts
+++ b/packages/runtime-vapor/src/dom/node.ts
@@ -53,8 +53,11 @@ function __next(node: Node): Node {
}
let n = node.nextSibling!
- // skip dynamic anchors and empty text nodes
- while (n && (isDynamicAnchor(n) || isEmptyText(n))) {
+ // skip if:
+ // - dynamic anchors (, )
+ // - fragment end anchor (``)
+ // - empty text nodes
+ while (n && (isDynamicAnchor(n) || isComment(n, ']') || isEmptyText(n))) {
n = n.nextSibling!
}
return n