Skip to content

Commit 9c30fd4

Browse files
committed
wip: save
1 parent e5dd701 commit 9c30fd4

File tree

6 files changed

+107
-69
lines changed

6 files changed

+107
-69
lines changed

packages/compiler-ssr/__tests__/ssrElement.spec.ts

-18
Original file line numberDiff line numberDiff line change
@@ -398,24 +398,6 @@ describe('ssr: element', () => {
398398
})
399399

400400
describe('dynamic child anchor', () => {
401-
test('component with element siblings', () => {
402-
expect(
403-
getCompiledString(`
404-
<div>
405-
<div/>
406-
<Comp1/>
407-
<div/>
408-
</div>
409-
`),
410-
).toMatchInlineSnapshot(`
411-
"\`<div><div></div>\`)
412-
_push("<!--[[-->")
413-
_push(_ssrRenderComponent(_component_Comp1, null, null, _parent))
414-
_push("<!--]]-->")
415-
_push(\`<div></div></div>\`"
416-
`)
417-
})
418-
419401
test('with consecutive components', () => {
420402
expect(
421403
getCompiledString(`

packages/compiler-ssr/src/transforms/ssrTransformComponent.ts

+20-1
Original file line numberDiff line numberDiff line change
@@ -428,5 +428,24 @@ function shouldAddDynamicAnchor(
428428
}
429429
}
430430

431-
return hasStaticPreviousSibling && hasStaticNextSibling
431+
let hasConsecutiveDynamicNodes = false
432+
if (index > 0 && index < len - 1) {
433+
if (index > 0 && !isStaticElement(children[index - 1])) {
434+
hasConsecutiveDynamicNodes = true
435+
}
436+
437+
if (
438+
!hasConsecutiveDynamicNodes &&
439+
index < len - 1 &&
440+
!isStaticElement(children[index + 1])
441+
) {
442+
hasConsecutiveDynamicNodes = true
443+
}
444+
}
445+
446+
return (
447+
hasStaticPreviousSibling &&
448+
hasStaticNextSibling &&
449+
hasConsecutiveDynamicNodes
450+
)
432451
}

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

-14
Original file line numberDiff line numberDiff line change
@@ -1844,20 +1844,6 @@ describe('SSR hydration', () => {
18441844
})
18451845

18461846
describe('dynamic child anchor', () => {
1847-
test('component with element siblings', () => {
1848-
const Comp = {
1849-
render() {
1850-
return createTextVNode('foo')
1851-
},
1852-
}
1853-
const { vnode, container } = mountWithHydration(
1854-
`<div><span></span><!--[[-->foo<!--]]--><span></span></div>`,
1855-
() => h('div', null, [h('span'), h(Comp), h('span')]),
1856-
)
1857-
expect(vnode.el).toBe(container.firstChild)
1858-
expect(`Hydration children mismatch`).not.toHaveBeenWarned()
1859-
})
1860-
18611847
test('with consecutive components', () => {
18621848
const Comp = {
18631849
render() {

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

+53-4
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,7 @@ describe('Vapor Mode hydration', () => {
241241

242242
test('component with anchor insertion', async () => {
243243
const { container, data } = await testHydration(
244-
`
245-
<template>
244+
`<template>
246245
<div>
247246
<span/>
248247
<components.Child/>
@@ -255,13 +254,13 @@ describe('Vapor Mode hydration', () => {
255254
},
256255
)
257256
expect(container.innerHTML).toMatchInlineSnapshot(
258-
`"<div><span></span><!--[[-->foo<!--]]--><span></span></div>"`,
257+
`"<div><span></span>foo<span></span></div>"`,
259258
)
260259

261260
data.value = 'bar'
262261
await nextTick()
263262
expect(container.innerHTML).toMatchInlineSnapshot(
264-
`"<div><span></span><!--[[-->bar<!--]]--><span></span></div>"`,
263+
`"<div><span></span>bar<span></span></div>"`,
265264
)
266265
})
267266

@@ -291,6 +290,56 @@ describe('Vapor Mode hydration', () => {
291290
)
292291
})
293292

293+
test('mixed component and element with anchor insertion', async () => {
294+
const { container, data } = await testHydration(
295+
`<template>
296+
<div>
297+
<span/>
298+
<components.Child/>
299+
<span/>
300+
<components.Child/>
301+
<span/>
302+
</div>
303+
</template>
304+
`,
305+
{
306+
Child: `<template>{{ data }}</template>`,
307+
},
308+
)
309+
expect(container.innerHTML).toMatchInlineSnapshot(
310+
`"<div><span></span>foo<span></span>foo<span></span></div>"`,
311+
)
312+
313+
data.value = 'bar'
314+
await nextTick()
315+
expect(container.innerHTML).toMatchInlineSnapshot(
316+
`"<div><span></span>bar<span></span>bar<span></span></div>"`,
317+
)
318+
})
319+
320+
test.todo('mixed component and text with anchor insertion', async () => {
321+
const { container, data } = await testHydration(
322+
`<template>
323+
<div>
324+
<span/>
325+
<components.Child/>
326+
{{ data }}
327+
<components.Child/>
328+
<span/>
329+
</div>
330+
</template>
331+
`,
332+
{
333+
Child: `<template>{{ data }}</template>`,
334+
},
335+
)
336+
expect(container.innerHTML).toMatchInlineSnapshot(``)
337+
338+
data.value = 'bar'
339+
await nextTick()
340+
expect(container.innerHTML).toMatchInlineSnapshot(``)
341+
})
342+
294343
test.todo('if')
295344

296345
test.todo('for')

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

+33-31
Original file line numberDiff line numberDiff line change
@@ -75,45 +75,47 @@ function locateHydrationNodeImpl() {
7575
// prepend / firstChild
7676
if (insertionAnchor === 0) {
7777
node = child(insertionParent!)
78-
} else {
78+
} else if (insertionParent && insertionAnchor) {
7979
// dynamic child anchor `<!--[[-->`
8080
if (insertionAnchor && isDynamicStart(insertionAnchor)) {
81-
const anchor = (insertionParent!.lds = insertionParent!.lds
81+
const anchor = (insertionParent!.$lds = insertionParent!.$lds
8282
? // continuous dynamic children, the next dynamic start must exist
83-
locateNextDynamicStart(insertionParent!.lds)!
83+
locateNextDynamicStart(insertionParent!.$lds)!
8484
: insertionAnchor)
8585
node = anchor.nextSibling
8686
} else {
8787
node = insertionAnchor
88-
? insertionAnchor.previousSibling
89-
: insertionParent
90-
? insertionParent.lastChild
91-
: currentHydrationNode
92-
if (node && isComment(node, ']')) {
93-
// fragment backward search
94-
if (node.$fs) {
95-
// already cached matching fragment start
96-
node = node.$fs
97-
} else {
98-
let cur: Node | null = node
99-
let curFragEnd = node
100-
let fragDepth = 0
101-
node = null
102-
while (cur) {
103-
cur = cur.previousSibling
104-
if (cur) {
105-
if (isComment(cur, '[')) {
106-
curFragEnd.$fs = cur
107-
if (!fragDepth) {
108-
node = cur
109-
break
110-
} else {
111-
fragDepth--
112-
}
113-
} else if (isComment(cur, ']')) {
114-
curFragEnd = cur
115-
fragDepth++
88+
}
89+
} else {
90+
node = insertionAnchor
91+
? insertionAnchor.previousSibling
92+
: insertionParent
93+
? insertionParent.lastChild
94+
: currentHydrationNode
95+
if (node && isComment(node, ']')) {
96+
// fragment backward search
97+
if (node.$fs) {
98+
// already cached matching fragment start
99+
node = node.$fs
100+
} else {
101+
let cur: Node | null = node
102+
let curFragEnd = node
103+
let fragDepth = 0
104+
node = null
105+
while (cur) {
106+
cur = cur.previousSibling
107+
if (cur) {
108+
if (isComment(cur, '[')) {
109+
curFragEnd.$fs = cur
110+
if (!fragDepth) {
111+
node = cur
112+
break
113+
} else {
114+
fragDepth--
116115
}
116+
} else if (isComment(cur, ']')) {
117+
curFragEnd = cur
118+
fragDepth++
117119
}
118120
}
119121
}

packages/runtime-vapor/src/insertionState.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
export let insertionParent:
22
| (ParentNode & {
33
// cached the last dynamic start anchor
4-
lds?: Anchor
4+
$lds?: Anchor
55
})
66
| undefined
77
export let insertionAnchor: Node | 0 | undefined | null

0 commit comments

Comments
 (0)