wip: save
This commit is contained in:
parent
e5dd701291
commit
9c30fd4db9
|
@ -398,24 +398,6 @@ describe('ssr: element', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('dynamic child anchor', () => {
|
describe('dynamic child anchor', () => {
|
||||||
test('component with element siblings', () => {
|
|
||||||
expect(
|
|
||||||
getCompiledString(`
|
|
||||||
<div>
|
|
||||||
<div/>
|
|
||||||
<Comp1/>
|
|
||||||
<div/>
|
|
||||||
</div>
|
|
||||||
`),
|
|
||||||
).toMatchInlineSnapshot(`
|
|
||||||
"\`<div><div></div>\`)
|
|
||||||
_push("<!--[[-->")
|
|
||||||
_push(_ssrRenderComponent(_component_Comp1, null, null, _parent))
|
|
||||||
_push("<!--]]-->")
|
|
||||||
_push(\`<div></div></div>\`"
|
|
||||||
`)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('with consecutive components', () => {
|
test('with consecutive components', () => {
|
||||||
expect(
|
expect(
|
||||||
getCompiledString(`
|
getCompiledString(`
|
||||||
|
|
|
@ -428,5 +428,24 @@ function shouldAddDynamicAnchor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return hasStaticPreviousSibling && hasStaticNextSibling
|
let hasConsecutiveDynamicNodes = false
|
||||||
|
if (index > 0 && index < len - 1) {
|
||||||
|
if (index > 0 && !isStaticElement(children[index - 1])) {
|
||||||
|
hasConsecutiveDynamicNodes = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!hasConsecutiveDynamicNodes &&
|
||||||
|
index < len - 1 &&
|
||||||
|
!isStaticElement(children[index + 1])
|
||||||
|
) {
|
||||||
|
hasConsecutiveDynamicNodes = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
hasStaticPreviousSibling &&
|
||||||
|
hasStaticNextSibling &&
|
||||||
|
hasConsecutiveDynamicNodes
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1844,20 +1844,6 @@ describe('SSR hydration', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('dynamic child anchor', () => {
|
describe('dynamic child anchor', () => {
|
||||||
test('component with element siblings', () => {
|
|
||||||
const Comp = {
|
|
||||||
render() {
|
|
||||||
return createTextVNode('foo')
|
|
||||||
},
|
|
||||||
}
|
|
||||||
const { vnode, container } = mountWithHydration(
|
|
||||||
`<div><span></span><!--[[-->foo<!--]]--><span></span></div>`,
|
|
||||||
() => h('div', null, [h('span'), h(Comp), h('span')]),
|
|
||||||
)
|
|
||||||
expect(vnode.el).toBe(container.firstChild)
|
|
||||||
expect(`Hydration children mismatch`).not.toHaveBeenWarned()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('with consecutive components', () => {
|
test('with consecutive components', () => {
|
||||||
const Comp = {
|
const Comp = {
|
||||||
render() {
|
render() {
|
||||||
|
|
|
@ -241,8 +241,7 @@ describe('Vapor Mode hydration', () => {
|
||||||
|
|
||||||
test('component with anchor insertion', async () => {
|
test('component with anchor insertion', async () => {
|
||||||
const { container, data } = await testHydration(
|
const { container, data } = await testHydration(
|
||||||
`
|
`<template>
|
||||||
<template>
|
|
||||||
<div>
|
<div>
|
||||||
<span/>
|
<span/>
|
||||||
<components.Child/>
|
<components.Child/>
|
||||||
|
@ -255,13 +254,13 @@ describe('Vapor Mode hydration', () => {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
expect(container.innerHTML).toMatchInlineSnapshot(
|
expect(container.innerHTML).toMatchInlineSnapshot(
|
||||||
`"<div><span></span><!--[[-->foo<!--]]--><span></span></div>"`,
|
`"<div><span></span>foo<span></span></div>"`,
|
||||||
)
|
)
|
||||||
|
|
||||||
data.value = 'bar'
|
data.value = 'bar'
|
||||||
await nextTick()
|
await nextTick()
|
||||||
expect(container.innerHTML).toMatchInlineSnapshot(
|
expect(container.innerHTML).toMatchInlineSnapshot(
|
||||||
`"<div><span></span><!--[[-->bar<!--]]--><span></span></div>"`,
|
`"<div><span></span>bar<span></span></div>"`,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -291,6 +290,56 @@ describe('Vapor Mode hydration', () => {
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('mixed component and element with anchor insertion', async () => {
|
||||||
|
const { container, data } = await testHydration(
|
||||||
|
`<template>
|
||||||
|
<div>
|
||||||
|
<span/>
|
||||||
|
<components.Child/>
|
||||||
|
<span/>
|
||||||
|
<components.Child/>
|
||||||
|
<span/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
`,
|
||||||
|
{
|
||||||
|
Child: `<template>{{ data }}</template>`,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
expect(container.innerHTML).toMatchInlineSnapshot(
|
||||||
|
`"<div><span></span>foo<span></span>foo<span></span></div>"`,
|
||||||
|
)
|
||||||
|
|
||||||
|
data.value = 'bar'
|
||||||
|
await nextTick()
|
||||||
|
expect(container.innerHTML).toMatchInlineSnapshot(
|
||||||
|
`"<div><span></span>bar<span></span>bar<span></span></div>"`,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test.todo('mixed component and text with anchor insertion', async () => {
|
||||||
|
const { container, data } = await testHydration(
|
||||||
|
`<template>
|
||||||
|
<div>
|
||||||
|
<span/>
|
||||||
|
<components.Child/>
|
||||||
|
{{ data }}
|
||||||
|
<components.Child/>
|
||||||
|
<span/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
`,
|
||||||
|
{
|
||||||
|
Child: `<template>{{ data }}</template>`,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
expect(container.innerHTML).toMatchInlineSnapshot(``)
|
||||||
|
|
||||||
|
data.value = 'bar'
|
||||||
|
await nextTick()
|
||||||
|
expect(container.innerHTML).toMatchInlineSnapshot(``)
|
||||||
|
})
|
||||||
|
|
||||||
test.todo('if')
|
test.todo('if')
|
||||||
|
|
||||||
test.todo('for')
|
test.todo('for')
|
||||||
|
|
|
@ -75,45 +75,47 @@ function locateHydrationNodeImpl() {
|
||||||
// prepend / firstChild
|
// prepend / firstChild
|
||||||
if (insertionAnchor === 0) {
|
if (insertionAnchor === 0) {
|
||||||
node = child(insertionParent!)
|
node = child(insertionParent!)
|
||||||
} else {
|
} else if (insertionParent && insertionAnchor) {
|
||||||
// dynamic child anchor `<!--[[-->`
|
// dynamic child anchor `<!--[[-->`
|
||||||
if (insertionAnchor && isDynamicStart(insertionAnchor)) {
|
if (insertionAnchor && isDynamicStart(insertionAnchor)) {
|
||||||
const anchor = (insertionParent!.lds = insertionParent!.lds
|
const anchor = (insertionParent!.$lds = insertionParent!.$lds
|
||||||
? // continuous dynamic children, the next dynamic start must exist
|
? // continuous dynamic children, the next dynamic start must exist
|
||||||
locateNextDynamicStart(insertionParent!.lds)!
|
locateNextDynamicStart(insertionParent!.$lds)!
|
||||||
: insertionAnchor)
|
: insertionAnchor)
|
||||||
node = anchor.nextSibling
|
node = anchor.nextSibling
|
||||||
} else {
|
} else {
|
||||||
node = insertionAnchor
|
node = insertionAnchor
|
||||||
? insertionAnchor.previousSibling
|
}
|
||||||
: insertionParent
|
} else {
|
||||||
? insertionParent.lastChild
|
node = insertionAnchor
|
||||||
: currentHydrationNode
|
? insertionAnchor.previousSibling
|
||||||
if (node && isComment(node, ']')) {
|
: insertionParent
|
||||||
// fragment backward search
|
? insertionParent.lastChild
|
||||||
if (node.$fs) {
|
: currentHydrationNode
|
||||||
// already cached matching fragment start
|
if (node && isComment(node, ']')) {
|
||||||
node = node.$fs
|
// fragment backward search
|
||||||
} else {
|
if (node.$fs) {
|
||||||
let cur: Node | null = node
|
// already cached matching fragment start
|
||||||
let curFragEnd = node
|
node = node.$fs
|
||||||
let fragDepth = 0
|
} else {
|
||||||
node = null
|
let cur: Node | null = node
|
||||||
while (cur) {
|
let curFragEnd = node
|
||||||
cur = cur.previousSibling
|
let fragDepth = 0
|
||||||
if (cur) {
|
node = null
|
||||||
if (isComment(cur, '[')) {
|
while (cur) {
|
||||||
curFragEnd.$fs = cur
|
cur = cur.previousSibling
|
||||||
if (!fragDepth) {
|
if (cur) {
|
||||||
node = cur
|
if (isComment(cur, '[')) {
|
||||||
break
|
curFragEnd.$fs = cur
|
||||||
} else {
|
if (!fragDepth) {
|
||||||
fragDepth--
|
node = cur
|
||||||
}
|
break
|
||||||
} else if (isComment(cur, ']')) {
|
} else {
|
||||||
curFragEnd = cur
|
fragDepth--
|
||||||
fragDepth++
|
|
||||||
}
|
}
|
||||||
|
} else if (isComment(cur, ']')) {
|
||||||
|
curFragEnd = cur
|
||||||
|
fragDepth++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
export let insertionParent:
|
export let insertionParent:
|
||||||
| (ParentNode & {
|
| (ParentNode & {
|
||||||
// cached the last dynamic start anchor
|
// cached the last dynamic start anchor
|
||||||
lds?: Anchor
|
$lds?: Anchor
|
||||||
})
|
})
|
||||||
| undefined
|
| undefined
|
||||||
export let insertionAnchor: Node | 0 | undefined | null
|
export let insertionAnchor: Node | 0 | undefined | null
|
||||||
|
|
Loading…
Reference in New Issue