]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
wip: process component as a single element during hydration
authordaiwei <daiwei521@126.com>
Tue, 5 Aug 2025 07:13:07 +0000 (15:13 +0800)
committerdaiwei <daiwei521@126.com>
Tue, 5 Aug 2025 07:13:07 +0000 (15:13 +0800)
packages/compiler-ssr/__tests__/ssrElement.spec.ts
packages/compiler-ssr/src/ssrCodegenTransform.ts
packages/runtime-core/__tests__/hydration.spec.ts
packages/runtime-vapor/__tests__/hydration.spec.ts
packages/runtime-vapor/src/dom/hydration.ts

index d344405f3ed27d56acecb882c517ec53f53140c5..57e4f022c034b137a391d7f7f70c42e1e823b2ce 100644 (file)
@@ -409,9 +409,9 @@ describe('ssr: element', () => {
         </div>
         `),
       ).toMatchInlineSnapshot(`
-        "\`<div><div></div>\`)
+        "\`<div><div></div><!--[[-->\`)
           _push(_ssrRenderComponent(_component_Comp1, null, null, _parent))
-          _push(\`<!--[[-->\`)
+          _push(\`<!--]]--><!--[[-->\`)
           _push(_ssrRenderComponent(_component_Comp2, null, null, _parent))
           _push(\`<!--]]--><div></div></div>\`"
       `)
@@ -430,15 +430,15 @@ describe('ssr: element', () => {
         </div>
         `),
       ).toMatchInlineSnapshot(`
-        "\`<div><div></div>\`)
+        "\`<div><div></div><!--[[-->\`)
           _push(_ssrRenderComponent(_component_Comp1, null, null, _parent))
-          _push(\`<!--[[-->\`)
+          _push(\`<!--]]--><!--[[-->\`)
           _push(_ssrRenderComponent(_component_Comp2, null, null, _parent))
           _push(\`<!--]]--><!--[[-->\`)
           _push(_ssrRenderComponent(_component_Comp3, null, null, _parent))
-          _push(\`<!--]]-->\`)
+          _push(\`<!--]]--><!--[[-->\`)
           _push(_ssrRenderComponent(_component_Comp4, null, null, _parent))
-          _push(\`<div></div></div>\`"
+          _push(\`<!--]]--><div></div></div>\`"
       `)
     })
   })
index 852e02820cc87cc12dd0b80897dddec27e235dd3..80329aaab787e7333fe6ed9efc7d5508608b74f7 100644 (file)
@@ -197,7 +197,11 @@ export function processChildren(
             ssrProcessElement(child, context)
             break
           case ElementTypes.COMPONENT:
+            if (inElement)
+              context.pushStringPart(`<!--${DYNAMIC_START_ANCHOR_LABEL}-->`)
             ssrProcessComponent(child, context, parent)
+            if (inElement)
+              context.pushStringPart(`<!--${DYNAMIC_END_ANCHOR_LABEL}-->`)
             break
           case ElementTypes.SLOT:
             ssrProcessSlotOutlet(child, context)
index 092df4738a3bd8932889e6faa14cf9bdcdf7d49e..418d37cc8a66df459213342fca6227ef22bf1c8f 100644 (file)
@@ -713,7 +713,7 @@ describe('SSR hydration', () => {
     // server render
     container.innerHTML = await renderToString(h(App))
     expect(container.innerHTML).toBe(
-      '<div><!--teleport start--><!--teleport end--></div>',
+      '<div><!--[[--><!--teleport start--><!--teleport end--><!--]]--></div>',
     )
     expect(teleportContainer1.innerHTML).toBe('')
     expect(teleportContainer2.innerHTML).toBe('')
@@ -721,7 +721,7 @@ describe('SSR hydration', () => {
     // hydrate
     createSSRApp(App).mount(container)
     expect(container.innerHTML).toBe(
-      '<div><!--teleport start--><!--teleport end--></div>',
+      '<div><!--[[--><!--teleport start--><!--teleport end--><!--]]--></div>',
     )
     expect(teleportContainer1.innerHTML).toBe('<span>Teleported</span>')
     expect(teleportContainer2.innerHTML).toBe('')
@@ -1005,7 +1005,7 @@ describe('SSR hydration', () => {
     // server render
     container.innerHTML = await renderToString(h(App))
     expect(container.innerHTML).toMatchInlineSnapshot(
-      `"<div><span>1</span><span>2</span></div>"`,
+      `"<div><!--[[--><span>1</span><!--]]--><!--[[--><span>2</span><!--]]--></div>"`,
     )
     // reset asyncDeps from ssr
     asyncDeps.length = 0
@@ -1923,14 +1923,14 @@ describe('SSR hydration', () => {
     const root = document.createElement('div')
     root.innerHTML = await renderToString(h(App))
     createSSRApp(App).mount(root)
-    expect(root.innerHTML).toBe('<div><div>foo</div></div>')
+    expect(root.innerHTML).toBe('<div><!--[[--><div>foo</div><!--]]--></div>')
 
     reload(id, {
       __hmrId: id,
       template: `<div>bar</div>`,
     })
     await nextTick()
-    expect(root.innerHTML).toBe('<div><div>bar</div></div>')
+    expect(root.innerHTML).toBe('<div><!--[[--><div>bar</div><!--]]--></div>')
   })
 
   test('hmr root reload', async () => {
index 86c110e203983e4d3a7a23ab996c52f88a060962..5ff4cbf51f4ee06346881e1805c8588e059d89ca 100644 (file)
@@ -276,13 +276,13 @@ describe('Vapor Mode hydration', () => {
         { Child: `<template>{{ data }}</template>` },
       )
       expect(container.innerHTML).toMatchInlineSnapshot(
-        `"<div><span></span>foo</div>"`,
+        `"<div><span></span><!--[[-->foo<!--]]--></div>"`,
       )
 
       data.value = 'bar'
       await nextTick()
       expect(container.innerHTML).toMatchInlineSnapshot(
-        `"<div><span></span>bar</div>"`,
+        `"<div><span></span><!--[[-->bar<!--]]--></div>"`,
       )
     })
 
@@ -294,13 +294,13 @@ describe('Vapor Mode hydration', () => {
         { Child: `<template><div>{{ data }}</div>-{{ data }}-</template>` },
       )
       expect(container.innerHTML).toMatchInlineSnapshot(
-        `"<div><span></span><!--[--><div>foo</div>-foo-<!--]--></div>"`,
+        `"<div><span></span><!--[[--><!--[--><div>foo</div>-foo-<!--]--><!--]]--></div>"`,
       )
 
       data.value = 'bar'
       await nextTick()
       expect(container.innerHTML).toMatchInlineSnapshot(
-        `"<div><span></span><!--[--><div>bar</div>-bar-<!--]--></div>"`,
+        `"<div><span></span><!--[[--><!--[--><div>bar</div>-bar-<!--]--><!--]]--></div>"`,
       )
     })
 
@@ -312,13 +312,13 @@ describe('Vapor Mode hydration', () => {
         { Child: `<template><div>{{ data }}</div>-{{ data }}-</template>` },
       )
       expect(container.innerHTML).toMatchInlineSnapshot(
-        `"<div><!--[--><div>foo</div>-foo-<!--]--><span></span></div>"`,
+        `"<div><!--[[--><!--[--><div>foo</div>-foo-<!--]--><!--]]--><span></span></div>"`,
       )
 
       data.value = 'bar'
       await nextTick()
       expect(container.innerHTML).toMatchInlineSnapshot(
-        `"<div><!--[--><div>bar</div>-bar-<!--]--><span></span></div>"`,
+        `"<div><!--[[--><!--[--><div>bar</div>-bar-<!--]--><!--]]--><span></span></div>"`,
       )
     })
 
@@ -334,11 +334,11 @@ describe('Vapor Mode hydration', () => {
       )
       expect(container.innerHTML).toBe(
         `<div>` +
-          `<!--[-->` +
+          `<!--[[--><!--[-->` +
           `<div></div>` +
           `<!--[--><div>foo</div>-foo-<!--]-->` +
           `<div></div>` +
-          `<!--]-->` +
+          `<!--]--><!--]]-->` +
           `<span></span>` +
           `</div>`,
       )
@@ -347,11 +347,11 @@ describe('Vapor Mode hydration', () => {
       await nextTick()
       expect(container.innerHTML).toBe(
         `<div>` +
-          `<!--[-->` +
+          `<!--[[--><!--[-->` +
           `<div></div>` +
           `<!--[--><div>bar</div>-bar-<!--]-->` +
           `<div></div>` +
-          `<!--]-->` +
+          `<!--]--><!--]]-->` +
           `<span></span>` +
           `</div>`,
       )
@@ -372,13 +372,13 @@ describe('Vapor Mode hydration', () => {
         },
       )
       expect(container.innerHTML).toMatchInlineSnapshot(
-        `"<div><span></span>foo<span></span></div>"`,
+        `"<div><span></span><!--[[-->foo<!--]]--><span></span></div>"`,
       )
 
       data.value = 'bar'
       await nextTick()
       expect(container.innerHTML).toMatchInlineSnapshot(
-        `"<div><span></span>bar<span></span></div>"`,
+        `"<div><span></span><!--[[-->bar<!--]]--><span></span></div>"`,
       )
     })
 
@@ -393,13 +393,13 @@ describe('Vapor Mode hydration', () => {
         },
       )
       expect(container.innerHTML).toBe(
-        `<div><span></span><div>foo</div><span></span></div>`,
+        `<div><span></span><!--[[--><div>foo</div><!--]]--><span></span></div>`,
       )
 
       data.value = 'bar'
       await nextTick()
       expect(container.innerHTML).toBe(
-        `<div><span></span><div>bar</div><span></span></div>`,
+        `<div><span></span><!--[[--><div>bar</div><!--]]--><span></span></div>`,
       )
     })
 
@@ -416,11 +416,11 @@ describe('Vapor Mode hydration', () => {
       expect(container.innerHTML).toBe(
         `<div>` +
           `<span></span>` +
-          `<div>` +
+          `<!--[[--><div>` +
           `<span></span>` +
-          `<div>foo</div>` +
+          `<!--[[--><div>foo</div><!--]]-->` +
           `<span></span>` +
-          `</div>` +
+          `</div><!--]]-->` +
           `<span></span>` +
           `</div>`,
       )
@@ -430,11 +430,11 @@ describe('Vapor Mode hydration', () => {
       expect(container.innerHTML).toBe(
         `<div>` +
           `<span></span>` +
-          `<div>` +
+          `<!--[[--><div>` +
           `<span></span>` +
-          `<div>bar</div>` +
+          `<!--[[--><div>bar</div><!--]]-->` +
           `<span></span>` +
-          `</div>` +
+          `</div><!--]]-->` +
           `<span></span>` +
           `</div>`,
       )
@@ -458,7 +458,7 @@ describe('Vapor Mode hydration', () => {
       expect(container.innerHTML).toBe(
         `<div>` +
           `<span></span>` +
-          `foo` +
+          `<!--[[-->foo<!--]]-->` +
           `<!--[[-->foo<!--]]-->` +
           `<span></span>` +
           `</div>`,
@@ -469,7 +469,7 @@ describe('Vapor Mode hydration', () => {
       expect(container.innerHTML).toBe(
         `<div>` +
           `<span></span>` +
-          `bar` +
+          `<!--[[-->bar<!--]]-->` +
           `<!--[[-->bar<!--]]-->` +
           `<span></span>` +
           `</div>`,
@@ -493,14 +493,14 @@ describe('Vapor Mode hydration', () => {
         data,
       )
       expect(container.innerHTML).toBe(
-        `<div><span>foo</span><span>bar</span></div>`,
+        `<div><!--[[--><span>foo</span><!--]]--><!--[[--><span>bar</span><!--]]--></div>`,
       )
 
       data.foo = 'foo1'
       data.bar = 'bar1'
       await nextTick()
       expect(container.innerHTML).toBe(
-        `<div><span>foo1</span><span>bar1</span></div>`,
+        `<div><!--[[--><span>foo1</span><!--]]--><!--[[--><span>bar1</span><!--]]--></div>`,
       )
     })
 
@@ -517,7 +517,7 @@ describe('Vapor Mode hydration', () => {
       expect(container.innerHTML).toBe(
         `<div>` +
           `<span></span>` +
-          `<div>foo</div>` +
+          `<!--[[--><div>foo</div><!--]]-->` +
           `<!--[[--><div>foo</div><!--]]-->` +
           `<span></span>` +
           `</div>`,
@@ -528,7 +528,7 @@ describe('Vapor Mode hydration', () => {
       expect(container.innerHTML).toBe(
         `<div>` +
           `<span></span>` +
-          `<div>bar</div>` +
+          `<!--[[--><div>bar</div><!--]]-->` +
           `<!--[[--><div>bar</div><!--]]-->` +
           `<span></span>` +
           `</div>`,
@@ -548,12 +548,12 @@ describe('Vapor Mode hydration', () => {
       expect(container.innerHTML).toBe(
         `<div>` +
           `<span></span>` +
-          `<div>` +
+          `<!--[[--><div>` +
           `<span></span>` +
-          `<div>foo</div>` +
+          `<!--[[--><div>foo</div><!--]]-->` +
           `<!--[[--><div>foo</div><!--]]-->` +
           `<span></span>` +
-          `</div>` +
+          `</div><!--]]-->` +
           `<span></span>` +
           `</div>`,
       )
@@ -563,12 +563,12 @@ describe('Vapor Mode hydration', () => {
       expect(container.innerHTML).toBe(
         `<div>` +
           `<span></span>` +
-          `<div>` +
+          `<!--[[--><div>` +
           `<span></span>` +
-          `<div>bar</div>` +
+          `<!--[[--><div>bar</div><!--]]-->` +
           `<!--[[--><div>bar</div><!--]]-->` +
           `<span></span>` +
-          `</div>` +
+          `</div><!--]]-->` +
           `<span></span>` +
           `</div>`,
       )
@@ -593,9 +593,9 @@ describe('Vapor Mode hydration', () => {
       expect(container.innerHTML).toBe(
         `<div>` +
           `<span></span>` +
-          `foo` +
+          `<!--[[-->foo<!--]]-->` +
           `<span></span>` +
-          `foo` +
+          `<!--[[-->foo<!--]]-->` +
           `<span></span>` +
           `</div>`,
       )
@@ -605,9 +605,9 @@ describe('Vapor Mode hydration', () => {
       expect(container.innerHTML).toBe(
         `<div>` +
           `<span></span>` +
-          `bar` +
+          `<!--[[-->bar<!--]]-->` +
           `<span></span>` +
-          `bar` +
+          `<!--[[-->bar<!--]]-->` +
           `<span></span>` +
           `</div>`,
       )
@@ -632,9 +632,9 @@ describe('Vapor Mode hydration', () => {
       expect(container.innerHTML).toBe(
         `<div>` +
           `<span></span>` +
-          `foo` +
-          `<!--[[--> foo <!--]]-->` +
-          `foo` +
+          `<!--[[-->foo<!--]]-->` +
+          ` <!--[[--> foo <!--]]--> ` +
+          `<!--[[-->foo<!--]]-->` +
           `<span></span>` +
           `</div>`,
       )
@@ -644,9 +644,9 @@ describe('Vapor Mode hydration', () => {
       expect(container.innerHTML).toBe(
         `<div>` +
           `<span></span>` +
-          `bar` +
-          `<!--[[--> bar <!--]]-->` +
-          `bar` +
+          `<!--[[-->bar<!--]]-->` +
+          ` <!--[[--> bar <!--]]--> ` +
+          `<!--[[-->bar<!--]]-->` +
           `<span></span>` +
           `</div>`,
       )
@@ -669,7 +669,7 @@ describe('Vapor Mode hydration', () => {
       expect(container.innerHTML).toBe(
         `<div>` +
           `<span></span>` +
-          `<!--[--><div>foo</div>-foo<!--]-->` +
+          `<!--[[--><!--[--><div>foo</div>-foo<!--]--><!--]]-->` +
           `<span></span>` +
           `</div>`,
       )
@@ -679,7 +679,7 @@ describe('Vapor Mode hydration', () => {
       expect(container.innerHTML).toBe(
         `<div>` +
           `<span></span>` +
-          `<!--[--><div>bar</div>-bar<!--]-->` +
+          `<!--[[--><!--[--><div>bar</div>-bar<!--]--><!--]]-->` +
           `<span></span>` +
           `</div>`,
       )
@@ -698,7 +698,7 @@ describe('Vapor Mode hydration', () => {
       expect(container.innerHTML).toBe(
         `<div>` +
           `<span></span>` +
-          `<!--[--><div>foo</div>-foo-<!--]-->` +
+          `<!--[[--><!--[--><div>foo</div>-foo-<!--]--><!--]]-->` +
           `<span></span>` +
           `</div>`,
       )
@@ -708,7 +708,7 @@ describe('Vapor Mode hydration', () => {
       expect(container.innerHTML).toBe(
         `<div>` +
           `<span></span>` +
-          `<!--[--><div>bar</div>-bar-<!--]-->` +
+          `<!--[[--><!--[--><div>bar</div>-bar-<!--]--><!--]]-->` +
           `<span></span>` +
           `</div>`,
       )
@@ -727,11 +727,11 @@ describe('Vapor Mode hydration', () => {
       expect(container.innerHTML).toBe(
         `<div>` +
           `<span></span>` +
-          `<div>` +
+          `<!--[[--><div>` +
           `<span></span>` +
-          `<!--[--><div>foo</div>-foo-<!--]-->` +
+          `<!--[[--><!--[--><div>foo</div>-foo-<!--]--><!--]]-->` +
           `<span></span>` +
-          `</div>` +
+          `</div><!--]]-->` +
           `<span></span>` +
           `</div>`,
       )
@@ -741,11 +741,11 @@ describe('Vapor Mode hydration', () => {
       expect(container.innerHTML).toBe(
         `<div>` +
           `<span></span>` +
-          `<div>` +
+          `<!--[[--><div>` +
           `<span></span>` +
-          `<!--[--><div>bar</div>-bar-<!--]-->` +
+          `<!--[[--><!--[--><div>bar</div>-bar-<!--]--><!--]]-->` +
           `<span></span>` +
-          `</div>` +
+          `</div><!--]]-->` +
           `<span></span>` +
           `</div>`,
       )
@@ -769,10 +769,8 @@ describe('Vapor Mode hydration', () => {
       expect(container.innerHTML).toBe(
         `<div>` +
           `<span></span>` +
-          `<!--[--><div>foo</div>-foo<!--]-->` +
-          `<!--[[-->` +
-          `<!--[--><div>foo</div>-foo<!--]-->` +
-          `<!--]]-->` +
+          `<!--[[--><!--[--><div>foo</div>-foo<!--]--><!--]]-->` +
+          `<!--[[--><!--[--><div>foo</div>-foo<!--]--><!--]]-->` +
           `<span></span>` +
           `</div>`,
       )
@@ -782,10 +780,8 @@ describe('Vapor Mode hydration', () => {
       expect(container.innerHTML).toBe(
         `<div>` +
           `<span></span>` +
-          `<!--[--><div>bar</div>-bar<!--]-->` +
-          `<!--[[-->` +
-          `<!--[--><div>bar</div>-bar<!--]-->` +
-          `<!--]]-->` +
+          `<!--[[--><!--[--><div>bar</div>-bar<!--]--><!--]]-->` +
+          `<!--[[--><!--[--><div>bar</div>-bar<!--]--><!--]]-->` +
           `<span></span>` +
           `</div>`,
       )
@@ -804,10 +800,8 @@ describe('Vapor Mode hydration', () => {
       expect(container.innerHTML).toBe(
         `<div>` +
           `<span></span>` +
-          `<!--[--><div>foo</div>-foo-<!--]-->` +
-          `<!--[[-->` +
-          `<!--[--><div>foo</div>-foo-<!--]-->` +
-          `<!--]]-->` +
+          `<!--[[--><!--[--><div>foo</div>-foo-<!--]--><!--]]-->` +
+          `<!--[[--><!--[--><div>foo</div>-foo-<!--]--><!--]]-->` +
           `<span></span>` +
           `</div>`,
       )
@@ -817,10 +811,8 @@ describe('Vapor Mode hydration', () => {
       expect(container.innerHTML).toBe(
         `<div>` +
           `<span></span>` +
-          `<!--[--><div>bar</div>-bar-<!--]-->` +
-          `<!--[[-->` +
-          `<!--[--><div>bar</div>-bar-<!--]-->` +
-          `<!--]]-->` +
+          `<!--[[--><!--[--><div>bar</div>-bar-<!--]--><!--]]-->` +
+          `<!--[[--><!--[--><div>bar</div>-bar-<!--]--><!--]]-->` +
           `<span></span>` +
           `</div>`,
       )
@@ -839,14 +831,12 @@ describe('Vapor Mode hydration', () => {
       expect(container.innerHTML).toBe(
         `<div>` +
           `<span></span>` +
-          `<div>` +
+          `<!--[[--><div>` +
           `<span></span>` +
-          `<!--[--><div>foo</div>-foo-<!--]-->` +
-          `<!--[[-->` +
-          `<!--[--><div>foo</div>-foo-<!--]-->` +
-          `<!--]]-->` +
+          `<!--[[--><!--[--><div>foo</div>-foo-<!--]--><!--]]-->` +
+          `<!--[[--><!--[--><div>foo</div>-foo-<!--]--><!--]]-->` +
           `<span></span>` +
-          `</div>` +
+          `</div><!--]]-->` +
           `<span></span>` +
           `</div>`,
       )
@@ -856,14 +846,12 @@ describe('Vapor Mode hydration', () => {
       expect(container.innerHTML).toBe(
         `<div>` +
           `<span></span>` +
-          `<div>` +
+          `<!--[[--><div>` +
           `<span></span>` +
-          `<!--[--><div>bar</div>-bar-<!--]-->` +
-          `<!--[[-->` +
-          `<!--[--><div>bar</div>-bar-<!--]-->` +
-          `<!--]]-->` +
+          `<!--[[--><!--[--><div>bar</div>-bar-<!--]--><!--]]-->` +
+          `<!--[[--><!--[--><div>bar</div>-bar-<!--]--><!--]]-->` +
           `<span></span>` +
-          `</div>` +
+          `</div><!--]]-->` +
           `<span></span>` +
           `</div>`,
       )
@@ -882,10 +870,10 @@ describe('Vapor Mode hydration', () => {
       expect(container.innerHTML).toBe(
         `<div>` +
           `<span></span>` +
-          `<!--[-->` +
+          `<!--[[--><!--[-->` +
           `<!--[--><div>foo</div>-foo-<!--]-->` +
           `<!--[--><div>foo</div>-foo-<!--]-->` +
-          `<!--]-->` +
+          `<!--]--><!--]]-->` +
           `<span></span>` +
           `</div>`,
       )
@@ -895,10 +883,10 @@ describe('Vapor Mode hydration', () => {
       expect(container.innerHTML).toBe(
         `<div>` +
           `<span></span>` +
-          `<!--[-->` +
+          `<!--[[--><!--[-->` +
           `<!--[--><div>bar</div>-bar-<!--]-->` +
           `<!--[--><div>bar</div>-bar-<!--]-->` +
-          `<!--]-->` +
+          `<!--]--><!--]]-->` +
           `<span></span>` +
           `</div>`,
       )
@@ -923,9 +911,9 @@ describe('Vapor Mode hydration', () => {
       expect(container.innerHTML).toBe(
         `<div>` +
           `<span></span>` +
-          `<!--[--><div>foo</div>-foo<!--]-->` +
+          `<!--[[--><!--[--><div>foo</div>-foo<!--]--><!--]]-->` +
           `<span></span>` +
-          `<!--[--><div>foo</div>-foo<!--]-->` +
+          `<!--[[--><!--[--><div>foo</div>-foo<!--]--><!--]]-->` +
           `<span></span>` +
           `</div>`,
       )
@@ -935,9 +923,9 @@ describe('Vapor Mode hydration', () => {
       expect(container.innerHTML).toBe(
         `<div>` +
           `<span></span>` +
-          `<!--[--><div>bar</div>-bar<!--]-->` +
+          `<!--[[--><!--[--><div>bar</div>-bar<!--]--><!--]]-->` +
           `<span></span>` +
-          `<!--[--><div>bar</div>-bar<!--]-->` +
+          `<!--[[--><!--[--><div>bar</div>-bar<!--]--><!--]]-->` +
           `<span></span>` +
           `</div>`,
       )
@@ -962,9 +950,9 @@ describe('Vapor Mode hydration', () => {
       expect(container.innerHTML).toBe(
         `<div>` +
           `<span></span>` +
-          `<!--[--><div>foo</div>-foo<!--]-->` +
+          `<!--[[--><!--[--><div>foo</div>-foo<!--]--><!--]]-->` +
           ` <!--[[--> foo <!--]]--> ` +
-          `<!--[--><div>foo</div>-foo<!--]-->` +
+          `<!--[[--><!--[--><div>foo</div>-foo<!--]--><!--]]-->` +
           `<span></span>` +
           `</div>`,
       )
@@ -974,9 +962,9 @@ describe('Vapor Mode hydration', () => {
       expect(container.innerHTML).toBe(
         `<div>` +
           `<span></span>` +
-          `<!--[--><div>bar</div>-bar<!--]-->` +
+          `<!--[[--><!--[--><div>bar</div>-bar<!--]--><!--]]-->` +
           ` <!--[[--> bar <!--]]--> ` +
-          `<!--[--><div>bar</div>-bar<!--]-->` +
+          `<!--[[--><!--[--><div>bar</div>-bar<!--]--><!--]]-->` +
           `<span></span>` +
           `</div>`,
       )
@@ -1022,7 +1010,7 @@ describe('Vapor Mode hydration', () => {
       expect(container.innerHTML).toBe(
         `<div>` +
           `<span></span>` +
-          `<div>foo</div><!--${anchorLabel}-->` +
+          `<!--[[--><div>foo</div><!--${anchorLabel}--><!--]]-->` +
           `<span></span>` +
           `</div>`,
       )
@@ -1032,7 +1020,7 @@ describe('Vapor Mode hydration', () => {
       expect(container.innerHTML).toBe(
         `<div>` +
           `<span></span>` +
-          `<div>bar</div><!--${anchorLabel}-->` +
+          `<!--[[--><div>bar</div><!--${anchorLabel}--><!--]]-->` +
           `<span></span>` +
           `</div>`,
       )
@@ -1057,7 +1045,7 @@ describe('Vapor Mode hydration', () => {
       expect(container.innerHTML).toBe(
         `<div>` +
           `<span></span>` +
-          `<div>foo</div><!--${anchorLabel}-->` +
+          `<!--[[--><div>foo</div><!--${anchorLabel}--><!--]]-->` +
           `<!--[[--><div>foo</div><!--${anchorLabel}--><!--]]-->` +
           `<span></span>` +
           `</div>`,
@@ -1068,7 +1056,7 @@ describe('Vapor Mode hydration', () => {
       expect(container.innerHTML).toBe(
         `<div>` +
           `<span></span>` +
-          `<div>bar</div><!--${anchorLabel}-->` +
+          `<!--[[--><div>bar</div><!--${anchorLabel}--><!--]]-->` +
           `<!--[[--><div>bar</div><!--${anchorLabel}--><!--]]-->` +
           `<span></span>` +
           `</div>`,
@@ -1145,7 +1133,9 @@ describe('Vapor Mode hydration', () => {
         { Child: `<template>foo</template>` },
         data,
       )
-      expect(container.innerHTML).toBe(`<div>foo</div><!--${anchorLabel}-->`)
+      expect(container.innerHTML).toBe(
+        `<div><!--[[-->foo<!--]]--></div><!--${anchorLabel}-->`,
+      )
 
       data.value = false
       await nextTick()
@@ -1481,8 +1471,8 @@ describe('Vapor Mode hydration', () => {
       )
       expect(container.innerHTML).toBe(
         `<div>` +
-          `<span>foo</span>` +
-          `<span>bar</span>` +
+          `<!--[[--><span>foo</span><!--]]-->` +
+          `<!--[[--><span>bar</span><!--]]-->` +
           `</div>` +
           `<!--${anchorLabel}-->`,
       )
@@ -2335,9 +2325,9 @@ describe('Vapor Mode hydration', () => {
       )
       expect(container.innerHTML).toBe(
         `<div>` +
-          `<div>bar</div>` +
+          `<!--[[--><div>bar</div><!--]]-->` +
           `<!--[--><span>foo</span><!--]--><!--${slotAnchorLabel}-->` +
-          `<div>bar</div>` +
+          `<!--[[--><div>bar</div><!--]]-->` +
           `</div>`,
       )
 
@@ -2345,9 +2335,9 @@ describe('Vapor Mode hydration', () => {
       await nextTick()
       expect(container.innerHTML).toBe(
         `<div>` +
-          `<div>hello</div>` +
+          `<!--[[--><div>hello</div><!--]]-->` +
           `<!--[--><span>foo</span><!--]--><!--${slotAnchorLabel}-->` +
-          `<div>hello</div>` +
+          `<!--[[--><div>hello</div><!--]]-->` +
           `</div>`,
       )
     })
@@ -2381,9 +2371,9 @@ describe('Vapor Mode hydration', () => {
       )
       expect(container.innerHTML).toBe(
         `<div>` +
-          `<!--[--><div>foo</div> bar<!--]-->` +
+          `<!--[[--><!--[--><div>foo</div> bar<!--]--><!--]]-->` +
           `<!--[--><span>foo</span><!--]--><!--${slotAnchorLabel}-->` +
-          `<!--[--><div>foo</div> bar<!--]-->` +
+          `<!--[[--><!--[--><div>foo</div> bar<!--]--><!--]]-->` +
           `</div>`,
       )
 
@@ -2392,9 +2382,9 @@ describe('Vapor Mode hydration', () => {
       await nextTick()
       expect(container.innerHTML).toBe(
         `<div>` +
-          `<!--[--><div>hello</div> vapor<!--]-->` +
+          `<!--[[--><!--[--><div>hello</div> vapor<!--]--><!--]]-->` +
           `<!--[--><span>hello</span><!--]--><!--${slotAnchorLabel}-->` +
-          `<!--[--><div>hello</div> vapor<!--]-->` +
+          `<!--[[--><!--[--><div>hello</div> vapor<!--]--><!--]]-->` +
           `</div>`,
       )
     })
@@ -2667,14 +2657,14 @@ describe('Vapor Mode hydration', () => {
       )
       expect(container.innerHTML).toBe(
         `<div>` +
-          `<div>` +
-          `<div>` +
+          `<!--[[--><div>` +
+          `<!--[[--><div>` +
           `<!--[-->` +
           `<!--[--><span>foo</span><!--]--><!--slot-->` +
           `<!--]-->` +
           `<!--slot-->` +
-          `</div>` +
-          `</div>` +
+          `</div><!--]]-->` +
+          `</div><!--]]-->` +
           `<div>bar</div>` +
           `</div>`,
       )
@@ -2684,14 +2674,14 @@ describe('Vapor Mode hydration', () => {
       await nextTick()
       expect(container.innerHTML).toBe(
         `<div>` +
-          `<div>` +
-          `<div>` +
+          `<!--[[--><div>` +
+          `<!--[[--><div>` +
           `<!--[-->` +
           `<!--[--><span>foo1</span><!--]--><!--slot-->` +
           `<!--]-->` +
           `<!--slot-->` +
-          `</div>` +
-          `</div>` +
+          `</div><!--]]-->` +
+          `</div><!--]]-->` +
           `<div>bar1</div>` +
           `</div>`,
       )
index 0186300585a2aa8c429565ca8232b00a32b00f62..1f4df1f45408628c8c86571120def4b17725e9fa 100644 (file)
@@ -12,7 +12,7 @@ import {
   disableHydrationNodeLookup,
   enableHydrationNodeLookup,
 } from './node'
-import { isVaporAnchors } from '@vue/shared'
+import { DYNAMIC_END_ANCHOR_LABEL, isVaporAnchors } from '@vue/shared'
 
 export let isHydrating = false
 export let currentHydrationNode: Node | null = null
@@ -23,15 +23,22 @@ export function setCurrentHydrationNode(node: Node | null): void {
 
 function findParentSibling(n: Node): Node | null {
   if (!n.parentNode) return null
-  const next = n.parentNode.nextSibling
+  let next = n.parentNode.nextSibling
+  while (next && isComment(next, DYNAMIC_END_ANCHOR_LABEL)) {
+    next = next.nextElementSibling
+  }
   return next ? next : findParentSibling(n.parentNode)
 }
 
 export function advanceHydrationNode(node: Node & { $ps?: Node | null }): void {
+  let next = node.nextSibling
+  while (next && isComment(next, DYNAMIC_END_ANCHOR_LABEL)) {
+    next = next.nextSibling
+  }
+
   // if no next sibling, find the next node in the parent chain
-  const next =
-    node.nextSibling || node.$ps || (node.$ps = findParentSibling(node))
-  if (next) setCurrentHydrationNode(next)
+  const ret = next || node.$ps || (node.$ps = findParentSibling(node))
+  if (ret) setCurrentHydrationNode(ret)
 }
 
 let isOptimized = false