mirror of https://github.com/vuejs/core.git
wip: save
This commit is contained in:
parent
e5dd701291
commit
9c30fd4db9
|
@ -398,24 +398,6 @@ describe('ssr: element', () => {
|
|||
})
|
||||
|
||||
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', () => {
|
||||
expect(
|
||||
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', () => {
|
||||
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', () => {
|
||||
const Comp = {
|
||||
render() {
|
||||
|
|
|
@ -241,8 +241,7 @@ describe('Vapor Mode hydration', () => {
|
|||
|
||||
test('component with anchor insertion', async () => {
|
||||
const { container, data } = await testHydration(
|
||||
`
|
||||
<template>
|
||||
`<template>
|
||||
<div>
|
||||
<span/>
|
||||
<components.Child/>
|
||||
|
@ -255,13 +254,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>"`,
|
||||
)
|
||||
})
|
||||
|
||||
|
@ -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('for')
|
||||
|
|
|
@ -75,45 +75,47 @@ function locateHydrationNodeImpl() {
|
|||
// prepend / firstChild
|
||||
if (insertionAnchor === 0) {
|
||||
node = child(insertionParent!)
|
||||
} else {
|
||||
} else if (insertionParent && insertionAnchor) {
|
||||
// dynamic child anchor `<!--[[-->`
|
||||
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
|
||||
locateNextDynamicStart(insertionParent!.lds)!
|
||||
locateNextDynamicStart(insertionParent!.$lds)!
|
||||
: insertionAnchor)
|
||||
node = anchor.nextSibling
|
||||
} else {
|
||||
node = insertionAnchor
|
||||
? insertionAnchor.previousSibling
|
||||
: insertionParent
|
||||
? insertionParent.lastChild
|
||||
: currentHydrationNode
|
||||
if (node && isComment(node, ']')) {
|
||||
// fragment backward search
|
||||
if (node.$fs) {
|
||||
// already cached matching fragment start
|
||||
node = node.$fs
|
||||
} else {
|
||||
let cur: Node | null = node
|
||||
let curFragEnd = node
|
||||
let fragDepth = 0
|
||||
node = null
|
||||
while (cur) {
|
||||
cur = cur.previousSibling
|
||||
if (cur) {
|
||||
if (isComment(cur, '[')) {
|
||||
curFragEnd.$fs = cur
|
||||
if (!fragDepth) {
|
||||
node = cur
|
||||
break
|
||||
} else {
|
||||
fragDepth--
|
||||
}
|
||||
} else if (isComment(cur, ']')) {
|
||||
curFragEnd = cur
|
||||
fragDepth++
|
||||
}
|
||||
} else {
|
||||
node = insertionAnchor
|
||||
? insertionAnchor.previousSibling
|
||||
: insertionParent
|
||||
? insertionParent.lastChild
|
||||
: currentHydrationNode
|
||||
if (node && isComment(node, ']')) {
|
||||
// fragment backward search
|
||||
if (node.$fs) {
|
||||
// already cached matching fragment start
|
||||
node = node.$fs
|
||||
} else {
|
||||
let cur: Node | null = node
|
||||
let curFragEnd = node
|
||||
let fragDepth = 0
|
||||
node = null
|
||||
while (cur) {
|
||||
cur = cur.previousSibling
|
||||
if (cur) {
|
||||
if (isComment(cur, '[')) {
|
||||
curFragEnd.$fs = cur
|
||||
if (!fragDepth) {
|
||||
node = cur
|
||||
break
|
||||
} else {
|
||||
fragDepth--
|
||||
}
|
||||
} else if (isComment(cur, ']')) {
|
||||
curFragEnd = cur
|
||||
fragDepth++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
export let insertionParent:
|
||||
| (ParentNode & {
|
||||
// cached the last dynamic start anchor
|
||||
lds?: Anchor
|
||||
$lds?: Anchor
|
||||
})
|
||||
| undefined
|
||||
export let insertionAnchor: Node | 0 | undefined | null
|
||||
|
|
Loading…
Reference in New Issue