refactor: insertion anchors

This commit is contained in:
daiwei 2025-08-18 21:57:44 +08:00
parent aa9f9ea7e3
commit eccf317a09
9 changed files with 345 additions and 375 deletions

View File

@ -163,7 +163,7 @@ export interface ComponentNode extends BaseElementNode {
| MemoExpression // when cached by v-memo
| undefined
ssrCodegenNode?: CallExpression
anchor?: string
needAnchor?: boolean
}
export interface SlotOutletNode extends BaseElementNode {
@ -173,14 +173,14 @@ export interface SlotOutletNode extends BaseElementNode {
| CacheExpression // when cached by v-once
| undefined
ssrCodegenNode?: CallExpression
anchor?: string
needAnchor?: boolean
}
export interface TemplateNode extends BaseElementNode {
tagType: ElementTypes.TEMPLATE
// TemplateNode is a container type that always gets compiled away
codegenNode: undefined
anchor?: string
needAnchor?: boolean
}
export interface TextNode extends Node {
@ -290,7 +290,7 @@ export interface IfNode extends Node {
type: NodeTypes.IF
branches: IfBranchNode[]
codegenNode?: IfConditionalExpression | CacheExpression // <div v-if v-once>
anchor?: string
needAnchor?: boolean
}
export interface IfBranchNode extends Node {
@ -310,7 +310,7 @@ export interface ForNode extends Node {
parseResult: ForParseResult
children: TemplateChildNode[]
codegenNode?: ForCodegenNode
anchor?: string
needAnchor?: boolean
}
export interface ForParseResult {

View File

@ -1,16 +1,16 @@
import { getCompiledString } from './utils'
describe('insertion anchors', () => {
describe('block anchors', () => {
describe('prepend', () => {
test('prepend anchor with component', () => {
expect(
getCompiledString('<div><Comp/><Comp/><span/></div>', { vapor: true }),
).toMatchInlineSnapshot(`
"\`<div><!--[p-->\`)
"\`<div><!--[[-->\`)
_push(_ssrRenderComponent(_component_Comp, null, null, _parent))
_push(\`<!--p]--><!--[p-->\`)
_push(\`<!--]]--><!--[[-->\`)
_push(_ssrRenderComponent(_component_Comp, null, null, _parent))
_push(\`<!--p]--><span></span></div>\`"
_push(\`<!--]]--><span></span></div>\`"
`)
})
@ -29,20 +29,20 @@ describe('insertion anchors', () => {
_ssrRenderVNode(_push, _createVNode(_resolveDynamicComponent('div'), null, {
default: _withCtx((_, _push, _parent, _scopeId) => {
if (_push) {
_push(\`<div\${_scopeId}><!--[p-->\`)
_push(\`<div\${_scopeId}><!--[[-->\`)
_push(_ssrRenderComponent(_component_Comp, null, null, _parent, _scopeId))
_push(\`<!--p]--><!--[p-->\`)
_push(\`<!--]]--><!--[[-->\`)
_push(_ssrRenderComponent(_component_Comp, null, null, _parent, _scopeId))
_push(\`<!--p]--><span\${_scopeId}></span></div>\`)
_push(\`<!--]]--><span\${_scopeId}></span></div>\`)
} else {
return [
_createVNode("div", null, [
_createCommentVNode("[p"),
_createCommentVNode("[["),
_createVNode(_component_Comp),
_createCommentVNode("p]"),
_createCommentVNode("[p"),
_createCommentVNode("]]"),
_createCommentVNode("[["),
_createVNode(_component_Comp),
_createCommentVNode("p]"),
_createCommentVNode("]]"),
_createVNode("span")
])
]
@ -60,11 +60,11 @@ describe('insertion anchors', () => {
vapor: true,
}),
).toMatchInlineSnapshot(`
"\`<div><!--[p-->\`)
"\`<div><!--[[-->\`)
_ssrRenderSlot(_ctx.$slots, "foo", {}, null, _push, _parent)
_push(\`<!--slot--><!--p]--><!--[p-->\`)
_push(\`<!--slot--><!--]]--><!--[[-->\`)
_ssrRenderSlot(_ctx.$slots, "default", {}, null, _push, _parent)
_push(\`<!--slot--><!--p]--><span></span></div>\`"
_push(\`<!--slot--><!--]]--><span></span></div>\`"
`)
})
@ -85,22 +85,22 @@ describe('insertion anchors', () => {
_ssrRenderVNode(_push, _createVNode(_resolveDynamicComponent('div'), null, {
default: _withCtx((_, _push, _parent, _scopeId) => {
if (_push) {
_push(\`<div\${_scopeId}><!--[p-->\`)
_push(\`<div\${_scopeId}><!--[[-->\`)
_ssrRenderSlot(_ctx.$slots, "foo", {}, null, _push, _parent, _scopeId)
_push(\`<!--slot--><!--p]--><!--[p-->\`)
_push(\`<!--slot--><!--]]--><!--[[-->\`)
_ssrRenderSlot(_ctx.$slots, "default", {}, null, _push, _parent, _scopeId)
_push(\`<!--slot--><!--p]--><span\${_scopeId}></span></div>\`)
_push(\`<!--slot--><!--]]--><span\${_scopeId}></span></div>\`)
} else {
return [
_createVNode("div", null, [
_createCommentVNode("[p"),
_createCommentVNode("[["),
_renderSlot(_ctx.$slots, "foo"),
_createCommentVNode("slot"),
_createCommentVNode("p]"),
_createCommentVNode("[p"),
_createCommentVNode("]]"),
_createCommentVNode("[["),
_renderSlot(_ctx.$slots, "default"),
_createCommentVNode("slot"),
_createCommentVNode("p]"),
_createCommentVNode("]]"),
_createVNode("span")
])
]
@ -126,7 +126,7 @@ describe('insertion anchors', () => {
},
),
).toMatchInlineSnapshot(`
"\`<div><!--[p-->\`)
"\`<div><!--[[-->\`)
if (_ctx.foo) {
_push(\`<span></span>\`)
_push(\`<!--if-->\`)
@ -137,7 +137,7 @@ describe('insertion anchors', () => {
_push(\`<span></span>\`)
_push(\`<!--if--><!--if-->\`)
}
_push(\`<!--p]--><span></span></div>\`"
_push(\`<!--]]--><span></span></div>\`"
`)
})
@ -159,7 +159,7 @@ describe('insertion anchors', () => {
_ssrRenderVNode(_push, _createVNode(_resolveDynamicComponent('div'), null, {
default: _withCtx((_, _push, _parent, _scopeId) => {
if (_push) {
_push(\`<div\${_scopeId}><!--[p-->\`)
_push(\`<div\${_scopeId}><!--[[-->\`)
if (_ctx.foo) {
_push(\`<span\${_scopeId}></span>\`)
_push(\`<!--if-->\`)
@ -170,11 +170,11 @@ describe('insertion anchors', () => {
_push(\`<span\${_scopeId}></span>\`)
_push(\`<!--if--><!--if-->\`)
}
_push(\`<!--p]--><span\${_scopeId}></span></div>\`)
_push(\`<!--]]--><span\${_scopeId}></span></div>\`)
} else {
return [
_createVNode("div", null, [
_createCommentVNode("[p"),
_createCommentVNode("[["),
(_ctx.foo)
? (_openBlock(), _createBlock(_Fragment, { key: 0 }, [
_createVNode("span"),
@ -189,7 +189,7 @@ describe('insertion anchors', () => {
_createVNode("span"),
_createCommentVNode("<!--if--><!--if-->")
], 64 /* STABLE_FRAGMENT */)),
_createCommentVNode("p]"),
_createCommentVNode("]]"),
_createVNode("span")
])
]
@ -224,39 +224,39 @@ describe('insertion anchors', () => {
},
),
).toMatchInlineSnapshot(`
"\`<div><!--[p-->\`)
"\`<div><!--[[-->\`)
if (_ctx.foo) {
_push(\`<span><!--[p-->\`)
_push(\`<span><!--[[-->\`)
if (_ctx.foo1) {
_push(\`<span></span>\`)
_push(\`<!--if-->\`)
} else {
_push(\`<!--if-->\`)
}
_push(\`<!--p]--><span></span></span>\`)
_push(\`<!--]]--><span></span></span>\`)
_push(\`<!--if-->\`)
} else if (_ctx.bar) {
_push(\`<span><!--[p-->\`)
_push(\`<span><!--[[-->\`)
if (_ctx.bar1) {
_push(\`<span></span>\`)
_push(\`<!--if-->\`)
} else {
_push(\`<!--if-->\`)
}
_push(\`<!--p]--><span></span></span>\`)
_push(\`<!--]]--><span></span></span>\`)
_push(\`<!--if--><!--if-->\`)
} else {
_push(\`<span><!--[p-->\`)
_push(\`<span><!--[[-->\`)
if (_ctx.bar2) {
_push(\`<span></span>\`)
_push(\`<!--if-->\`)
} else {
_push(\`<!--if-->\`)
}
_push(\`<!--p]--><span></span></span>\`)
_push(\`<!--]]--><span></span></span>\`)
_push(\`<!--if--><!--if-->\`)
}
_push(\`<!--p]--><span></span></div>\`"
_push(\`<!--]]--><span></span></div>\`"
`)
})
@ -287,52 +287,52 @@ describe('insertion anchors', () => {
_ssrRenderVNode(_push, _createVNode(_resolveDynamicComponent('div'), null, {
default: _withCtx((_, _push, _parent, _scopeId) => {
if (_push) {
_push(\`<div\${_scopeId}><!--[p-->\`)
_push(\`<div\${_scopeId}><!--[[-->\`)
if (_ctx.foo) {
_push(\`<span\${_scopeId}><!--[p-->\`)
_push(\`<span\${_scopeId}><!--[[-->\`)
if (_ctx.foo1) {
_push(\`<span\${_scopeId}></span>\`)
_push(\`<!--if-->\`)
} else {
_push(\`<!--if-->\`)
}
_push(\`<!--p]--><span\${_scopeId}></span></span>\`)
_push(\`<!--]]--><span\${_scopeId}></span></span>\`)
_push(\`<!--if-->\`)
} else if (_ctx.bar) {
_push(\`<span\${_scopeId}><!--[p-->\`)
_push(\`<span\${_scopeId}><!--[[-->\`)
if (_ctx.bar1) {
_push(\`<span\${_scopeId}></span>\`)
_push(\`<!--if-->\`)
} else {
_push(\`<!--if-->\`)
}
_push(\`<!--p]--><span\${_scopeId}></span></span>\`)
_push(\`<!--]]--><span\${_scopeId}></span></span>\`)
_push(\`<!--if--><!--if-->\`)
} else {
_push(\`<span\${_scopeId}><!--[p-->\`)
_push(\`<span\${_scopeId}><!--[[-->\`)
if (_ctx.bar2) {
_push(\`<span\${_scopeId}></span>\`)
_push(\`<!--if-->\`)
} else {
_push(\`<!--if-->\`)
}
_push(\`<!--p]--><span\${_scopeId}></span></span>\`)
_push(\`<!--]]--><span\${_scopeId}></span></span>\`)
_push(\`<!--if--><!--if-->\`)
}
_push(\`<!--p]--><span\${_scopeId}></span></div>\`)
_push(\`<!--]]--><span\${_scopeId}></span></div>\`)
} else {
return [
_createVNode("div", null, [
_createCommentVNode("[p"),
_createCommentVNode("[["),
(_ctx.foo)
? (_openBlock(), _createBlock(_Fragment, { key: 0 }, [
_createVNode("span", null, [
_createCommentVNode("[p"),
_createCommentVNode("[["),
(_ctx.foo1)
? (_openBlock(), _createBlock("span", { key: 0 }))
: _createCommentVNode("v-if", true),
_createCommentVNode("if"),
_createCommentVNode("p]"),
_createCommentVNode("]]"),
_createVNode("span")
]),
_createCommentVNode("<!--if-->")
@ -340,29 +340,29 @@ describe('insertion anchors', () => {
: (_ctx.bar)
? (_openBlock(), _createBlock(_Fragment, { key: 1 }, [
_createVNode("span", null, [
_createCommentVNode("[p"),
_createCommentVNode("[["),
(_ctx.bar1)
? (_openBlock(), _createBlock("span", { key: 0 }))
: _createCommentVNode("v-if", true),
_createCommentVNode("if"),
_createCommentVNode("p]"),
_createCommentVNode("]]"),
_createVNode("span")
]),
_createCommentVNode("<!--if--><!--if-->")
], 64 /* STABLE_FRAGMENT */))
: (_openBlock(), _createBlock(_Fragment, { key: 2 }, [
_createVNode("span", null, [
_createCommentVNode("[p"),
_createCommentVNode("[["),
(_ctx.bar2)
? (_openBlock(), _createBlock("span", { key: 0 }))
: _createCommentVNode("v-if", true),
_createCommentVNode("if"),
_createCommentVNode("p]"),
_createCommentVNode("]]"),
_createVNode("span")
]),
_createCommentVNode("<!--if--><!--if-->")
], 64 /* STABLE_FRAGMENT */)),
_createCommentVNode("p]"),
_createCommentVNode("]]"),
_createVNode("span")
])
]
@ -393,14 +393,14 @@ describe('insertion anchors', () => {
default: _withCtx((_, _push, _parent, _scopeId) => {
if (_push) {
if (_ctx.foo) {
_push(\`<div\${_scopeId}><!--[p-->\`)
_push(\`<div\${_scopeId}><!--[[-->\`)
if (_ctx.depth < 5) {
_push(\` foo \`)
_push(\`<!--if-->\`)
} else {
_push(\`<!--if-->\`)
}
_push(\`<!--p]--><div\${_scopeId}></div></div>\`)
_push(\`<!--]]--><div\${_scopeId}></div></div>\`)
_push(\`<!--if-->\`)
} else {
_push(\`<!--if-->\`)
@ -409,14 +409,14 @@ describe('insertion anchors', () => {
return [
(_ctx.foo)
? (_openBlock(), _createBlock("div", { key: 0 }, [
_createCommentVNode("[p"),
_createCommentVNode("[["),
(_ctx.depth < 5)
? (_openBlock(), _createBlock(_Fragment, { key: 0 }, [
_createTextVNode(" foo ")
], 64 /* STABLE_FRAGMENT */))
: _createCommentVNode("v-if", true),
_createCommentVNode("if"),
_createCommentVNode("p]"),
_createCommentVNode("]]"),
_createVNode("div")
]))
: _createCommentVNode("v-if", true),
@ -436,11 +436,11 @@ describe('insertion anchors', () => {
vapor: true,
}),
).toMatchInlineSnapshot(`
"\`<div><!--[p-->\`)
"\`<div><!--[[-->\`)
_ssrRenderList(_ctx.items, (item) => {
_push(\`<span></span>\`)
})
_push(\`<!--for--><!--p]--><span></span></div>\`"
_push(\`<!--for--><!--]]--><span></span></div>\`"
`)
})
@ -459,20 +459,20 @@ describe('insertion anchors', () => {
_ssrRenderVNode(_push, _createVNode(_resolveDynamicComponent('div'), null, {
default: _withCtx((_, _push, _parent, _scopeId) => {
if (_push) {
_push(\`<div\${_scopeId}><!--[p-->\`)
_push(\`<div\${_scopeId}><!--[[-->\`)
_ssrRenderList(_ctx.items, (item) => {
_push(\`<span\${_scopeId}></span>\`)
})
_push(\`<!--for--><!--p]--><span\${_scopeId}></span></div>\`)
_push(\`<!--for--><!--]]--><span\${_scopeId}></span></div>\`)
} else {
return [
_createVNode("div", null, [
_createCommentVNode("[p"),
_createCommentVNode("[["),
(_openBlock(true), _createBlock(_Fragment, null, _renderList(_ctx.items, (item) => {
return (_openBlock(), _createBlock("span"))
}), 256 /* UNKEYED_FRAGMENT */)),
_createCommentVNode("for"),
_createCommentVNode("p]"),
_createCommentVNode("]]"),
_createVNode("span")
])
]
@ -486,14 +486,14 @@ describe('insertion anchors', () => {
})
// TODO add more tests
describe('insertion anchor', () => {
describe('insert', () => {
test('insertion anchor with component', () => {
expect(
getCompiledString('<div><span/><Comp/><span/></div>', { vapor: true }),
).toMatchInlineSnapshot(`
"\`<div><span></span><!--[i-->\`)
"\`<div><span></span><!--[[-->\`)
_push(_ssrRenderComponent(_component_Comp, null, null, _parent))
_push(\`<!--i]--><span></span></div>\`"
_push(\`<!--]]--><span></span></div>\`"
`)
})
})
@ -504,11 +504,11 @@ describe('insertion anchors', () => {
expect(
getCompiledString('<div><span/><Comp/><Comp/></div>', { vapor: true }),
).toMatchInlineSnapshot(`
"\`<div><span></span><!--[a-->\`)
"\`<div><span></span><!--[[-->\`)
_push(_ssrRenderComponent(_component_Comp, null, null, _parent))
_push(\`<!--a]--><!--[a-->\`)
_push(\`<!--]]--><!--[[-->\`)
_push(_ssrRenderComponent(_component_Comp, null, null, _parent))
_push(\`<!--a]--></div>\`"
_push(\`<!--]]--></div>\`"
`)
})
})
@ -519,13 +519,13 @@ describe('insertion anchors', () => {
vapor: true,
}),
).toMatchInlineSnapshot(`
"\`<div><!--[p-->\`)
"\`<div><!--[[-->\`)
_push(_ssrRenderComponent(_component_Comp, null, null, _parent))
_push(\`<!--p]--><span></span><!--[i-->\`)
_push(\`<!--]]--><span></span><!--[[-->\`)
_push(_ssrRenderComponent(_component_Comp, null, null, _parent))
_push(\`<!--i]--><span></span><!--[a-->\`)
_push(\`<!--]]--><span></span><!--[[-->\`)
_push(_ssrRenderComponent(_component_Comp, null, null, _parent))
_push(\`<!--a]--></div>\`"
_push(\`<!--]]--></div>\`"
`)
})
@ -548,27 +548,27 @@ describe('insertion anchors', () => {
_ssrRenderVNode(_push, _createVNode(_resolveDynamicComponent('div'), null, {
default: _withCtx((_, _push, _parent, _scopeId) => {
if (_push) {
_push(\`<div\${_scopeId}><!--[p-->\`)
_push(\`<div\${_scopeId}><!--[[-->\`)
_push(_ssrRenderComponent(_component_Comp, null, null, _parent, _scopeId))
_push(\`<!--p]--><span\${_scopeId}></span><!--[i-->\`)
_push(\`<!--]]--><span\${_scopeId}></span><!--[[-->\`)
_push(_ssrRenderComponent(_component_Comp, null, null, _parent, _scopeId))
_push(\`<!--i]--><span\${_scopeId}></span><!--[a-->\`)
_push(\`<!--]]--><span\${_scopeId}></span><!--[[-->\`)
_push(_ssrRenderComponent(_component_Comp, null, null, _parent, _scopeId))
_push(\`<!--a]--></div>\`)
_push(\`<!--]]--></div>\`)
} else {
return [
_createVNode("div", null, [
_createCommentVNode("[p"),
_createCommentVNode("[["),
_createVNode(_component_Comp),
_createCommentVNode("p]"),
_createCommentVNode("]]"),
_createVNode("span"),
_createCommentVNode("[i"),
_createCommentVNode("[["),
_createVNode(_component_Comp),
_createCommentVNode("i]"),
_createCommentVNode("]]"),
_createVNode("span"),
_createCommentVNode("[a"),
_createCommentVNode("[["),
_createVNode(_component_Comp),
_createCommentVNode("a]")
_createCommentVNode("]]")
])
]
}
@ -580,7 +580,7 @@ describe('insertion anchors', () => {
})
})
describe('block anchors', () => {
describe('fragment anchors', () => {
test('if', () => {
expect(
getCompiledString(
@ -752,11 +752,11 @@ describe('block anchors', () => {
{ vapor: true },
),
).toMatchInlineSnapshot(`
"\`<div><!--[a-->\`)
"\`<div><!--[[-->\`)
_ssrRenderSlot(_ctx.$slots, "foo", {}, null, _push, _parent)
_push(\`<!--slot--><!--a]--><!--[a-->\`)
_push(\`<!--slot--><!--]]--><!--[[-->\`)
_ssrRenderSlot(_ctx.$slots, "default", {}, null, _push, _parent)
_push(\`<!--slot--><!--a]--></div>\`"
_push(\`<!--slot--><!--]]--></div>\`"
`)
})

View File

@ -25,9 +25,8 @@ import {
processExpression,
} from '@vue/compiler-dom'
import {
BLOCK_APPEND_ANCHOR_LABEL,
BLOCK_INSERTION_ANCHOR_LABEL,
BLOCK_PREPEND_ANCHOR_LABEL,
BLOCK_ANCHOR_END_LABEL,
BLOCK_ANCHOR_START_LABEL,
escapeHtml,
isString,
} from '@vue/shared'
@ -188,14 +187,19 @@ export function processChildren(
ssrProcessElement(child, context)
break
case ElementTypes.COMPONENT:
if (child.anchor) context.pushStringPart(`<!--[${child.anchor}-->`)
if (child.needAnchor)
context.pushStringPart(`<!--${BLOCK_ANCHOR_START_LABEL}-->`)
ssrProcessComponent(child, context, parent)
if (child.anchor) context.pushStringPart(`<!--${child.anchor}]-->`)
if (child.needAnchor)
context.pushStringPart(`<!--${BLOCK_ANCHOR_END_LABEL}-->`)
break
case ElementTypes.SLOT:
if (child.anchor) context.pushStringPart(`<!--[${child.anchor}-->`)
if (child.needAnchor)
context.pushStringPart(`<!--${BLOCK_ANCHOR_START_LABEL}-->`)
ssrProcessSlotOutlet(child, context)
if (child.anchor) context.pushStringPart(`<!--${child.anchor}]-->`)
if (child.needAnchor)
context.pushStringPart(`<!--${BLOCK_ANCHOR_END_LABEL}-->`)
break
case ElementTypes.TEMPLATE:
// TODO
@ -230,14 +234,18 @@ export function processChildren(
)
break
case NodeTypes.IF:
if (child.anchor) context.pushStringPart(`<!--[${child.anchor}-->`)
if (child.needAnchor)
context.pushStringPart(`<!--${BLOCK_ANCHOR_START_LABEL}-->`)
ssrProcessIf(child, context, disableNestedFragments, disableComment)
if (child.anchor) context.pushStringPart(`<!--${child.anchor}]-->`)
if (child.needAnchor)
context.pushStringPart(`<!--${BLOCK_ANCHOR_END_LABEL}-->`)
break
case NodeTypes.FOR:
if (child.anchor) context.pushStringPart(`<!--[${child.anchor}-->`)
if (child.needAnchor)
context.pushStringPart(`<!--${BLOCK_ANCHOR_START_LABEL}-->`)
ssrProcessFor(child, context, disableNestedFragments)
if (child.anchor) context.pushStringPart(`<!--${child.anchor}]-->`)
if (child.needAnchor)
context.pushStringPart(`<!--${BLOCK_ANCHOR_END_LABEL}-->`)
break
case NodeTypes.IF_BRANCH:
// no-op - handled by ssrProcessIf
@ -276,7 +284,7 @@ export function processChildrenAsStatement(
}
export function processBlockNodeAnchor(children: TemplateChildNode[]): void {
let prevBlocks: (TemplateChildNode & { anchor?: string })[] = []
let prevBlocks: (TemplateChildNode & { needAnchor?: boolean })[] = []
let hasStaticNode = false
let blockCount = 0
for (const child of children) {
@ -288,15 +296,11 @@ export function processBlockNodeAnchor(children: TemplateChildNode[]): void {
if (isStaticNode(child)) {
if (prevBlocks.length) {
if (hasStaticNode) {
// insertion anchor
prevBlocks.forEach(
child => (child.anchor = BLOCK_INSERTION_ANCHOR_LABEL),
)
// insert
prevBlocks.forEach(child => (child.needAnchor = true))
} else {
// prepend
prevBlocks.forEach(
child => (child.anchor = BLOCK_PREPEND_ANCHOR_LABEL),
)
prevBlocks.forEach(child => (child.needAnchor = true))
}
prevBlocks = []
}
@ -307,8 +311,8 @@ export function processBlockNodeAnchor(children: TemplateChildNode[]): void {
// When there is only one block node, no anchor is needed,
// firstChild is used as the hydration node
if (prevBlocks.length && !(blockCount === 1 && !hasStaticNode)) {
// append anchor
prevBlocks.forEach(child => (child.anchor = BLOCK_APPEND_ANCHOR_LABEL))
// append
prevBlocks.forEach(child => (child.needAnchor = true))
}
}

View File

@ -62,6 +62,8 @@ import {
ssrTransformTransitionGroup,
} from './ssrTransformTransitionGroup'
import {
BLOCK_ANCHOR_END_LABEL,
BLOCK_ANCHOR_START_LABEL,
DYNAMIC_COMPONENT_ANCHOR_LABEL,
FOR_ANCHOR_LABEL,
IF_ANCHOR_LABEL,
@ -416,14 +418,14 @@ function injectVaporAnchors(
}
const { tagType, props } = child
let insertionAnchor: string | undefined
let needBlockAnchor: boolean | undefined
if (
tagType === ElementTypes.COMPONENT ||
tagType === ElementTypes.SLOT ||
tagType === ElementTypes.TEMPLATE
) {
insertionAnchor = child.anchor
needBlockAnchor = child.needAnchor
} else if (tagType === ElementTypes.ELEMENT) {
let hasIf = false
let hasFor = false
@ -438,11 +440,11 @@ function injectVaporAnchors(
}
if (hasIf) {
insertionAnchor = (child as any as IfNode).anchor
needBlockAnchor = (child as any as IfNode).needAnchor
const lastBranchIndex = findLastIfBranchIndex(children, i)
if (lastBranchIndex > i) {
injectIfAnchors(
insertionAnchor,
needBlockAnchor,
newChildren,
i,
lastBranchIndex,
@ -452,22 +454,22 @@ function injectVaporAnchors(
continue
}
} else if (hasFor) {
insertionAnchor = (child as any as ForNode).anchor
needBlockAnchor = (child as any as ForNode).needAnchor
}
}
if (insertionAnchor) {
newChildren.push(createAnchor(`[${insertionAnchor}`))
if (needBlockAnchor) {
newChildren.push(createAnchor(BLOCK_ANCHOR_START_LABEL))
}
newChildren.push(child)
// inject block anchor
const blockAnchorLabel = getBlockAnchorLabel(child)
if (blockAnchorLabel) newChildren.push(createAnchor(blockAnchorLabel))
// inject fragment anchor
const fragmentAnchorLabel = getFragmentAnchorLabel(child)
if (fragmentAnchorLabel) newChildren.push(createAnchor(fragmentAnchorLabel))
if (insertionAnchor) {
newChildren.push(createAnchor(`${insertionAnchor}]`))
if (needBlockAnchor) {
newChildren.push(createAnchor(BLOCK_ANCHOR_END_LABEL))
}
child.children = injectVaporAnchors(child.children, child)
@ -477,19 +479,19 @@ function injectVaporAnchors(
}
function injectIfAnchors(
insertionAnchor: string | undefined,
needBlockAnchor: boolean | undefined,
newChildren: TemplateChildNode[],
i: number,
lastBranchIndex: number,
children: TemplateChildNode[],
) {
if (insertionAnchor) {
newChildren.push(createAnchor(`[${insertionAnchor}`))
if (needBlockAnchor) {
newChildren.push(createAnchor(BLOCK_ANCHOR_START_LABEL))
}
for (let j = i; j <= lastBranchIndex; j++) {
const node = children[j] as PlainElementNode
const blockAnchorLabel = getBlockAnchorLabel(node)
const fragmentAnchorLabel = getFragmentAnchorLabel(node)
let isElse = false
const conditionalProps: typeof node.props = []
@ -522,17 +524,17 @@ function injectIfAnchors(
}
newChildren.push(wrapperNode)
if (blockAnchorLabel) {
if (fragmentAnchorLabel) {
const repeatCount = j - i - (isElse ? 1 : 0) + 1
wrapperNode.children.push(
createAnchor(`<!--${blockAnchorLabel}-->`.repeat(repeatCount)),
createAnchor(`<!--${fragmentAnchorLabel}-->`.repeat(repeatCount)),
)
}
node.children = injectVaporAnchors(node.children, node)
}
if (insertionAnchor) {
newChildren.push(createAnchor(`${insertionAnchor}]`))
if (needBlockAnchor) {
newChildren.push(createAnchor(BLOCK_ANCHOR_END_LABEL))
}
}
@ -583,7 +585,7 @@ function findLastIfBranchIndex(
return lastIndex
}
function getBlockAnchorLabel(child: TemplateChildNode): string | undefined {
function getFragmentAnchorLabel(child: TemplateChildNode): string | undefined {
if (child.type !== NodeTypes.ELEMENT) return
if (child.tagType === ElementTypes.COMPONENT && child.tag === 'component') {

View File

@ -352,7 +352,7 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[a-->foo<!--a]-->
<!--[[-->foo<!--]]-->
</div>"
`,
)
@ -362,7 +362,7 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[a-->bar<!--a]-->
<!--[[-->bar<!--]]-->
</div>"
`,
)
@ -378,7 +378,7 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[a--><div>foo</div>-foo-<!--a]-->
<!--[[--><div>foo</div>-foo-<!--]]-->
</div>"
`,
)
@ -388,7 +388,7 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[a--><div>bar</div>-bar-<!--a]-->
<!--[[--><div>bar</div>-bar-<!--]]-->
</div>"
`,
)
@ -404,7 +404,7 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div>
<!--[p--><div>foo</div>-foo-<!--p]-->
<!--[[--><div>foo</div>-foo-<!--]]-->
<span></span></div>"
`,
)
@ -414,7 +414,7 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div>
<!--[p--><div>bar</div>-bar-<!--p]-->
<!--[[--><div>bar</div>-bar-<!--]]-->
<span></span></div>"
`,
)
@ -433,7 +433,7 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div>
<!--[p--><div></div><div>foo</div>-foo-<div></div><!--p]-->
<!--[[--><div></div><div>foo</div>-foo-<div></div><!--]]-->
<span></span></div>"
`,
)
@ -443,7 +443,7 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div>
<!--[p--><div></div><div>bar</div>-bar-<div></div><!--p]-->
<!--[[--><div></div><div>bar</div>-bar-<div></div><!--]]-->
<span></span></div>"
`,
)
@ -466,7 +466,7 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i-->foo<!--i]-->
<!--[[-->foo<!--]]-->
<span></span></div>"
`,
)
@ -476,7 +476,7 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i-->bar<!--i]-->
<!--[[-->bar<!--]]-->
<span></span></div>"
`,
)
@ -495,7 +495,7 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><div>foo</div><!--i]-->
<!--[[--><div>foo</div><!--]]-->
<span></span></div>"
`,
)
@ -505,7 +505,7 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><div>bar</div><!--i]-->
<!--[[--><div>bar</div><!--]]-->
<span></span></div>"
`,
)
@ -524,9 +524,9 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><div><span></span>
<!--[i--><div>foo</div><!--i]-->
<span></span></div><!--i]-->
<!--[[--><div><span></span>
<!--[[--><div>foo</div><!--]]-->
<span></span></div><!--]]-->
<span></span></div>"
`,
)
@ -536,9 +536,9 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><div><span></span>
<!--[i--><div>bar</div><!--i]-->
<span></span></div><!--i]-->
<!--[[--><div><span></span>
<!--[[--><div>bar</div><!--]]-->
<span></span></div><!--]]-->
<span></span></div>"
`,
)
@ -562,8 +562,8 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i-->foo<!--i]-->
<!--[i-->foo<!--i]-->
<!--[[-->foo<!--]]-->
<!--[[-->foo<!--]]-->
<span></span></div>"
`,
)
@ -573,8 +573,8 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i-->bar<!--i]-->
<!--[i-->bar<!--i]-->
<!--[[-->bar<!--]]-->
<!--[[-->bar<!--]]-->
<span></span></div>"
`,
)
@ -599,8 +599,8 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div>
<!--[a--><span>foo</span><!--a]-->
<!--[a--><span>bar</span><!--a]-->
<!--[[--><span>foo</span><!--]]-->
<!--[[--><span>bar</span><!--]]-->
</div>"
`,
)
@ -611,8 +611,8 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div>
<!--[a--><span>foo1</span><!--a]-->
<!--[a--><span>bar1</span><!--a]-->
<!--[[--><span>foo1</span><!--]]-->
<!--[[--><span>bar1</span><!--]]-->
</div>"
`,
)
@ -631,8 +631,8 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><div>foo</div><!--i]-->
<!--[i--><div>foo</div><!--i]-->
<!--[[--><div>foo</div><!--]]-->
<!--[[--><div>foo</div><!--]]-->
<span></span></div>"
`,
)
@ -642,8 +642,8 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><div>bar</div><!--i]-->
<!--[i--><div>bar</div><!--i]-->
<!--[[--><div>bar</div><!--]]-->
<!--[[--><div>bar</div><!--]]-->
<span></span></div>"
`,
)
@ -662,10 +662,10 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><div><span></span>
<!--[i--><div>foo</div><!--i]-->
<!--[i--><div>foo</div><!--i]-->
<span></span></div><!--i]-->
<!--[[--><div><span></span>
<!--[[--><div>foo</div><!--]]-->
<!--[[--><div>foo</div><!--]]-->
<span></span></div><!--]]-->
<span></span></div>"
`,
)
@ -675,10 +675,10 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><div><span></span>
<!--[i--><div>bar</div><!--i]-->
<!--[i--><div>bar</div><!--i]-->
<span></span></div><!--i]-->
<!--[[--><div><span></span>
<!--[[--><div>bar</div><!--]]-->
<!--[[--><div>bar</div><!--]]-->
<span></span></div><!--]]-->
<span></span></div>"
`,
)
@ -703,9 +703,9 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i-->foo<!--i]-->
<!--[[-->foo<!--]]-->
<span></span>
<!--[i-->foo<!--i]-->
<!--[[-->foo<!--]]-->
<span></span></div>"
`,
)
@ -715,9 +715,9 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i-->bar<!--i]-->
<!--[[-->bar<!--]]-->
<span></span>
<!--[i-->bar<!--i]-->
<!--[[-->bar<!--]]-->
<span></span></div>"
`,
)
@ -742,9 +742,9 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i-->foo<!--i]-->
<!--[[-->foo<!--]]-->
foo
<!--[i-->foo<!--i]-->
<!--[[-->foo<!--]]-->
<span></span></div>"
`,
)
@ -754,9 +754,9 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i-->bar<!--i]-->
<!--[[-->bar<!--]]-->
bar
<!--[i-->bar<!--i]-->
<!--[[-->bar<!--]]-->
<span></span></div>"
`,
)
@ -779,7 +779,7 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><div>foo</div>-foo<!--i]-->
<!--[[--><div>foo</div>-foo<!--]]-->
<span></span></div>"
`,
)
@ -789,7 +789,7 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><div>bar</div>-bar<!--i]-->
<!--[[--><div>bar</div>-bar<!--]]-->
<span></span></div>"
`,
)
@ -808,7 +808,7 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><div>foo</div>-foo-<!--i]-->
<!--[[--><div>foo</div>-foo-<!--]]-->
<span></span></div>"
`,
)
@ -818,7 +818,7 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><div>bar</div>-bar-<!--i]-->
<!--[[--><div>bar</div>-bar-<!--]]-->
<span></span></div>"
`,
)
@ -837,9 +837,9 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><div><span></span>
<!--[i--><div>foo</div>-foo-<!--i]-->
<span></span></div><!--i]-->
<!--[[--><div><span></span>
<!--[[--><div>foo</div>-foo-<!--]]-->
<span></span></div><!--]]-->
<span></span></div>"
`,
)
@ -849,9 +849,9 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><div><span></span>
<!--[i--><div>bar</div>-bar-<!--i]-->
<span></span></div><!--i]-->
<!--[[--><div><span></span>
<!--[[--><div>bar</div>-bar-<!--]]-->
<span></span></div><!--]]-->
<span></span></div>"
`,
)
@ -875,8 +875,8 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><div>foo</div>-foo<!--i]-->
<!--[i--><div>foo</div>-foo<!--i]-->
<!--[[--><div>foo</div>-foo<!--]]-->
<!--[[--><div>foo</div>-foo<!--]]-->
<span></span></div>"
`,
)
@ -886,8 +886,8 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><div>bar</div>-bar<!--i]-->
<!--[i--><div>bar</div>-bar<!--i]-->
<!--[[--><div>bar</div>-bar<!--]]-->
<!--[[--><div>bar</div>-bar<!--]]-->
<span></span></div>"
`,
)
@ -906,8 +906,8 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><div>foo</div>-foo-<!--i]-->
<!--[i--><div>foo</div>-foo-<!--i]-->
<!--[[--><div>foo</div>-foo-<!--]]-->
<!--[[--><div>foo</div>-foo-<!--]]-->
<span></span></div>"
`,
)
@ -917,8 +917,8 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><div>bar</div>-bar-<!--i]-->
<!--[i--><div>bar</div>-bar-<!--i]-->
<!--[[--><div>bar</div>-bar-<!--]]-->
<!--[[--><div>bar</div>-bar-<!--]]-->
<span></span></div>"
`,
)
@ -937,10 +937,10 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><div><span></span>
<!--[i--><div>foo</div>-foo-<!--i]-->
<!--[i--><div>foo</div>-foo-<!--i]-->
<span></span></div><!--i]-->
<!--[[--><div><span></span>
<!--[[--><div>foo</div>-foo-<!--]]-->
<!--[[--><div>foo</div>-foo-<!--]]-->
<span></span></div><!--]]-->
<span></span></div>"
`,
)
@ -950,10 +950,10 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><div><span></span>
<!--[i--><div>bar</div>-bar-<!--i]-->
<!--[i--><div>bar</div>-bar-<!--i]-->
<span></span></div><!--i]-->
<!--[[--><div><span></span>
<!--[[--><div>bar</div>-bar-<!--]]-->
<!--[[--><div>bar</div>-bar-<!--]]-->
<span></span></div><!--]]-->
<span></span></div>"
`,
)
@ -972,7 +972,7 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><div>foo</div>-foo-<div>foo</div>-foo-<!--i]-->
<!--[[--><div>foo</div>-foo-<div>foo</div>-foo-<!--]]-->
<span></span></div>"
`,
)
@ -982,7 +982,7 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><div>bar</div>-bar-<div>bar</div>-bar-<!--i]-->
<!--[[--><div>bar</div>-bar-<div>bar</div>-bar-<!--]]-->
<span></span></div>"
`,
)
@ -1007,9 +1007,9 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><div>foo</div>-foo<!--i]-->
<!--[[--><div>foo</div>-foo<!--]]-->
<span></span>
<!--[i--><div>foo</div>-foo<!--i]-->
<!--[[--><div>foo</div>-foo<!--]]-->
<span></span></div>"
`,
)
@ -1019,9 +1019,9 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><div>bar</div>-bar<!--i]-->
<!--[[--><div>bar</div>-bar<!--]]-->
<span></span>
<!--[i--><div>bar</div>-bar<!--i]-->
<!--[[--><div>bar</div>-bar<!--]]-->
<span></span></div>"
`,
)
@ -1046,9 +1046,9 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><div>foo</div>-foo<!--i]-->
<!--[[--><div>foo</div>-foo<!--]]-->
foo
<!--[i--><div>foo</div>-foo<!--i]-->
<!--[[--><div>foo</div>-foo<!--]]-->
<span></span></div>"
`,
)
@ -1058,9 +1058,9 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><div>bar</div>-bar<!--i]-->
<!--[[--><div>bar</div>-bar<!--]]-->
bar
<!--[i--><div>bar</div>-bar<!--i]-->
<!--[[--><div>bar</div>-bar<!--]]-->
<span></span></div>"
`,
)
@ -1108,7 +1108,7 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><div>foo</div><!--dynamic-component--><!--i]-->
<!--[[--><div>foo</div><!--dynamic-component--><!--]]-->
<span></span></div>"
`,
)
@ -1118,7 +1118,7 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><div>bar</div><!--dynamic-component--><!--i]-->
<!--[[--><div>bar</div><!--dynamic-component--><!--]]-->
<span></span></div>"
`,
)
@ -1143,8 +1143,8 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><div>foo</div><!--dynamic-component--><!--i]-->
<!--[i--><div>foo</div><!--dynamic-component--><!--i]-->
<!--[[--><div>foo</div><!--dynamic-component--><!--]]-->
<!--[[--><div>foo</div><!--dynamic-component--><!--]]-->
<span></span></div>"
`,
)
@ -1154,8 +1154,8 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><div>bar</div><!--dynamic-component--><!--i]-->
<!--[i--><div>bar</div><!--dynamic-component--><!--i]-->
<!--[[--><div>bar</div><!--dynamic-component--><!--]]-->
<!--[[--><div>bar</div><!--dynamic-component--><!--]]-->
<span></span></div>"
`,
)
@ -1338,7 +1338,7 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span>outer</span>
<!--[a--><div>inner</div><!--if--><!--a]-->
<!--[[--><div>inner</div><!--if--><!--]]-->
</div><!--if-->"
`,
)
@ -1348,7 +1348,7 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span>outer</span>
<!--[a--><!--if--><!--a]-->
<!--[[--><!--if--><!--]]-->
</div><!--if-->"
`,
)
@ -1433,10 +1433,10 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<span>
<!--[p--><span>foo</span><!--if--><!--p]-->
<!--[p--><span>bar</span><!--if--><!--p]-->
<!--[[--><span>foo</span><!--if--><!--]]-->
<!--[[--><span>bar</span><!--if--><!--]]-->
<span>baz</span>
<!--[i--><span>qux</span><!--if--><!--i]-->
<!--[[--><span>qux</span><!--if--><!--]]-->
<span>quux</span></span><!--if-->"
`,
)
@ -1446,10 +1446,10 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<span>
<!--[p--><span>foo</span><!--if--><!--p]-->
<!--[p--><span>bar</span><!--if--><!--p]-->
<!--[[--><span>foo</span><!--if--><!--]]-->
<!--[[--><span>bar</span><!--if--><!--]]-->
<span>baz</span>
<!--[i--><span>qux1</span><!--if--><!--i]-->
<!--[[--><span>qux1</span><!--if--><!--]]-->
<span>quux</span></span><!--if-->"
`,
)
@ -1459,10 +1459,10 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<span>
<!--[p--><span>foo1</span><!--if--><!--p]-->
<!--[p--><span>bar</span><!--if--><!--p]-->
<!--[[--><span>foo1</span><!--if--><!--]]-->
<!--[[--><span>bar</span><!--if--><!--]]-->
<span>baz</span>
<!--[i--><span>qux1</span><!--if--><!--i]-->
<!--[[--><span>qux1</span><!--if--><!--]]-->
<span>quux</span></span><!--if-->"
`,
)
@ -1522,7 +1522,7 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i-->foo<!--if--><!--i]-->
<!--[[-->foo<!--if--><!--]]-->
<span></span></div>"
`,
)
@ -1532,7 +1532,7 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><!--if--><!--i]-->
<!--[[--><!--if--><!--]]-->
<span></span></div>"
`,
)
@ -1560,8 +1560,8 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div>
<!--[a--><span>foo</span><!--a]-->
<!--[a--><span>bar</span><!--a]-->
<!--[[--><span>foo</span><!--]]-->
<!--[[--><span>bar</span><!--]]-->
</div><!--if-->"
`,
)
@ -1603,8 +1603,8 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i-->foo<!--if--><!--i]-->
<!--[i-->foo<!--if--><!--i]-->
<!--[[-->foo<!--if--><!--]]-->
<!--[[-->foo<!--if--><!--]]-->
<span></span></div>"
`,
)
@ -1614,8 +1614,8 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><!--if--><!--i]-->
<!--[i--><!--if--><!--i]-->
<!--[[--><!--if--><!--]]-->
<!--[[--><!--if--><!--]]-->
<span></span></div>"
`,
)
@ -1624,8 +1624,8 @@ describe('Vapor Mode hydration', () => {
await nextTick()
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(`
"<div><span></span>
<!--[i-->foo<!--if--><!--i]-->
<!--[i-->foo<!--if--><!--i]-->
<!--[[-->foo<!--if--><!--]]-->
<!--[[-->foo<!--if--><!--]]-->
<span></span></div>"
`)
})
@ -1678,7 +1678,7 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><div>true</div>-true-<!--if--><!--i]-->
<!--[[--><div>true</div>-true-<!--if--><!--]]-->
<span></span></div>"
`,
)
@ -1688,7 +1688,7 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><!--if--><!--i]-->
<!--[[--><!--if--><!--]]-->
<span></span></div>"
`,
)
@ -1697,7 +1697,7 @@ describe('Vapor Mode hydration', () => {
await nextTick()
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(`
"<div><span></span>
<!--[i--><div>true</div>-true-<!--if--><!--i]-->
<!--[[--><div>true</div>-true-<!--if--><!--]]-->
<span></span></div>"
`)
})
@ -1721,8 +1721,8 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><div>true</div>-true-<!--if--><!--i]-->
<!--[i--><div>true</div>-true-<!--if--><!--i]-->
<!--[[--><div>true</div>-true-<!--if--><!--]]-->
<!--[[--><div>true</div>-true-<!--if--><!--]]-->
<span></span></div>"
`,
)
@ -1732,8 +1732,8 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><!--if--><!--i]-->
<!--[i--><!--if--><!--i]-->
<!--[[--><!--if--><!--]]-->
<!--[[--><!--if--><!--]]-->
<span></span></div>"
`,
)
@ -1742,8 +1742,8 @@ describe('Vapor Mode hydration', () => {
await nextTick()
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(`
"<div><span></span>
<!--[i--><div>true</div>-true-<!--if--><!--i]-->
<!--[i--><div>true</div>-true-<!--if--><!--i]-->
<!--[[--><div>true</div>-true-<!--if--><!--]]-->
<!--[[--><div>true</div>-true-<!--if--><!--]]-->
<span></span></div>"
`)
})
@ -1764,7 +1764,7 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i-->foo<!--dynamic-component--><!--if--><!--i]-->
<!--[[-->foo<!--dynamic-component--><!--if--><!--]]-->
<span></span></div>"
`,
)
@ -1774,7 +1774,7 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><!--if--><!--i]-->
<!--[[--><!--if--><!--]]-->
<span></span></div>"
`,
)
@ -1783,7 +1783,7 @@ describe('Vapor Mode hydration', () => {
await nextTick()
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(`
"<div><span></span>
<!--[i-->foo<!--dynamic-component--><!--if--><!--i]-->
<!--[[-->foo<!--dynamic-component--><!--if--><!--]]-->
<span></span></div>"
`)
})
@ -1826,7 +1826,7 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><span>a</span><span>b</span><span>c</span><!--for--><!--i]-->
<!--[[--><span>a</span><span>b</span><span>c</span><!--for--><!--]]-->
<span></span></div>"
`,
)
@ -1836,7 +1836,7 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><span>a</span><span>b</span><span>c</span><span>d</span><!--for--><!--i]-->
<!--[[--><span>a</span><span>b</span><span>c</span><span>d</span><!--for--><!--]]-->
<span></span></div>"
`,
)
@ -1846,7 +1846,7 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><span>b</span><span>c</span><span>d</span><!--for--><!--i]-->
<!--[[--><span>b</span><span>c</span><span>d</span><!--for--><!--]]-->
<span></span></div>"
`,
)
@ -1868,8 +1868,8 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><span>a</span><span>b</span><span>c</span><!--for--><!--i]-->
<!--[i--><span>a</span><span>b</span><span>c</span><!--for--><!--i]-->
<!--[[--><span>a</span><span>b</span><span>c</span><!--for--><!--]]-->
<!--[[--><span>a</span><span>b</span><span>c</span><!--for--><!--]]-->
<span></span></div>"
`,
)
@ -1879,8 +1879,8 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><span>a</span><span>b</span><span>c</span><span>d</span><!--for--><!--i]-->
<!--[i--><span>a</span><span>b</span><span>c</span><span>d</span><!--for--><!--i]-->
<!--[[--><span>a</span><span>b</span><span>c</span><span>d</span><!--for--><!--]]-->
<!--[[--><span>a</span><span>b</span><span>c</span><span>d</span><!--for--><!--]]-->
<span></span></div>"
`,
)
@ -1890,8 +1890,8 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i--><span>c</span><span>d</span><!--for--><!--i]-->
<!--[i--><span>c</span><span>d</span><!--for--><!--i]-->
<!--[[--><span>c</span><span>d</span><!--for--><!--]]-->
<!--[[--><span>c</span><span>d</span><!--for--><!--]]-->
<span></span></div>"
`,
)
@ -2231,9 +2231,9 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div>
<!--[p-->
<!--[[-->
<!--[--><span>foo</span><!--]-->
<!--slot--><!--p]-->
<!--slot--><!--]]-->
hi</div>"
`,
)
@ -2243,9 +2243,9 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div>
<!--[p-->
<!--[[-->
<!--[--><span>foo</span><!--]-->
<!--slot--><!--p]-->
<!--slot--><!--]]-->
bar</div>"
`,
)
@ -2308,12 +2308,12 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div>
<!--[p-->
<!--[[-->
<!--[--><span>foo</span><!--]-->
<!--slot--><!--p]-->
<!--[p-->
<!--slot--><!--]]-->
<!--[[-->
<!--[--><span>bar</span><!--]-->
<!--slot--><!--p]-->
<!--slot--><!--]]-->
<div>hi</div></div>"
`,
)
@ -2323,12 +2323,12 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div>
<!--[p-->
<!--[[-->
<!--[--><span>foo</span><!--]-->
<!--slot--><!--p]-->
<!--[p-->
<!--slot--><!--]]-->
<!--[[-->
<!--[--><span>bar</span><!--]-->
<!--slot--><!--p]-->
<!--slot--><!--]]-->
<div>bar</div></div>"
`,
)
@ -2354,9 +2354,9 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div>
<!--[p-->
<!--[[-->
<!--[--><span>foo</span><!--]-->
<!--slot--><!--p]-->
<!--slot--><!--]]-->
<div>hi</div></div>"
`,
)
@ -2366,9 +2366,9 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div>
<!--[p-->
<!--[[-->
<!--[--><span>foo</span><!--]-->
<!--slot--><!--p]-->
<!--slot--><!--]]-->
<div>bar</div></div>"
`,
)
@ -2404,11 +2404,11 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div>
<!--[a--><div>bar</div><!--a]-->
<!--[a-->
<!--[[--><div>bar</div><!--]]-->
<!--[[-->
<!--[--><span>foo</span><!--]-->
<!--slot--><!--a]-->
<!--[a--><div>bar</div><!--a]-->
<!--slot--><!--]]-->
<!--[[--><div>bar</div><!--]]-->
</div>"
`,
)
@ -2418,11 +2418,11 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div>
<!--[a--><div>hello</div><!--a]-->
<!--[a-->
<!--[[--><div>hello</div><!--]]-->
<!--[[-->
<!--[--><span>foo</span><!--]-->
<!--slot--><!--a]-->
<!--[a--><div>hello</div><!--a]-->
<!--slot--><!--]]-->
<!--[[--><div>hello</div><!--]]-->
</div>"
`,
)
@ -2458,11 +2458,11 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div>
<!--[a--><div>foo</div> bar<!--a]-->
<!--[a-->
<!--[[--><div>foo</div> bar<!--]]-->
<!--[[-->
<!--[--><span>foo</span><!--]-->
<!--slot--><!--a]-->
<!--[a--><div>foo</div> bar<!--a]-->
<!--slot--><!--]]-->
<!--[[--><div>foo</div> bar<!--]]-->
</div>"
`,
)
@ -2473,11 +2473,11 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div>
<!--[a--><div>hello</div> vapor<!--a]-->
<!--[a-->
<!--[[--><div>hello</div> vapor<!--]]-->
<!--[[-->
<!--[--><span>hello</span><!--]-->
<!--slot--><!--a]-->
<!--[a--><div>hello</div> vapor<!--a]-->
<!--slot--><!--]]-->
<!--[[--><div>hello</div> vapor<!--]]-->
</div>"
`,
)
@ -2649,12 +2649,12 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i-->
<!--[[-->
<!--[--><span>foo</span><!--]-->
<!--slot--><!--i]-->
<!--[i-->
<!--slot--><!--]]-->
<!--[[-->
<!--[--><span>bar</span><!--]-->
<!--slot--><!--i]-->
<!--slot--><!--]]-->
<span></span></div>"
`,
)
@ -2665,12 +2665,12 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div><span></span>
<!--[i-->
<!--[[-->
<!--[--><span>hello</span><!--]-->
<!--slot--><!--i]-->
<!--[i-->
<!--slot--><!--]]-->
<!--[[-->
<!--[--><span>vapor</span><!--]-->
<!--slot--><!--i]-->
<!--slot--><!--]]-->
<span></span></div>"
`,
)
@ -2709,12 +2709,12 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div>
<!--[p-->
<!--[[-->
<!--[--><span>foo</span><!--]-->
<!--slot--><!--p]-->
<!--[p-->
<!--slot--><!--]]-->
<!--[[-->
<!--[--><span>bar</span><!--]-->
<!--slot--><!--p]-->
<!--slot--><!--]]-->
<div>baz</div></div>"
`,
)
@ -2725,12 +2725,12 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div>
<!--[p-->
<!--[[-->
<!--[--><span>hello</span><!--]-->
<!--slot--><!--p]-->
<!--[p-->
<!--slot--><!--]]-->
<!--[[-->
<!--[--><span>vapor</span><!--]-->
<!--slot--><!--p]-->
<!--slot--><!--]]-->
<div>baz</div></div>"
`,
)
@ -2792,11 +2792,11 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div>
<!--[p--><div><div>
<!--[[--><div><div>
<!--[-->
<!--[--><span>foo</span><!--]-->
<!--slot--><!--]-->
<!--slot--></div></div><!--p]-->
<!--slot--></div></div><!--]]-->
<div>bar</div></div>"
`,
)
@ -2807,11 +2807,11 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div>
<!--[p--><div><div>
<!--[[--><div><div>
<!--[-->
<!--[--><span>foo1</span><!--]-->
<!--slot--><!--]-->
<!--slot--></div></div><!--p]-->
<!--slot--></div></div><!--]]-->
<div>bar1</div></div>"
`,
)
@ -2893,9 +2893,9 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div>
<!--[p-->
<!--[[-->
<!--[--><!--slot--><!--slot--><!--slot--><!--]-->
<!--slot--><!--p]-->
<!--slot--><!--]]-->
<div>foo</div></div>"
`,
)
@ -2905,9 +2905,9 @@ describe('Vapor Mode hydration', () => {
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
`
"<div>
<!--[p-->
<!--[[-->
<!--[--><!--slot--><!--slot--><!--slot--><!--]-->
<!--slot--><!--p]-->
<!--slot--><!--]]-->
<div>bar</div></div>"
`,
)

View File

@ -12,11 +12,7 @@ import {
disableHydrationNodeLookup,
enableHydrationNodeLookup,
} from './node'
import {
BLOCK_APPEND_ANCHOR_LABEL,
BLOCK_INSERTION_ANCHOR_LABEL,
BLOCK_PREPEND_ANCHOR_LABEL,
} from '@vue/shared'
import { BLOCK_ANCHOR_END_LABEL, BLOCK_ANCHOR_START_LABEL } from '@vue/shared'
const isHydratingStack = [] as boolean[]
export let isHydrating = false
@ -34,10 +30,7 @@ function performHydration<T>(
locateHydrationNode = locateHydrationNodeImpl
// optimize anchor cache lookup
;(Comment.prototype as any).$fe = undefined
;(Node.prototype as any).$pns = undefined
;(Node.prototype as any).$lpn = undefined
;(Node.prototype as any).$lin = undefined
;(Node.prototype as any).$lan = undefined
;(Node.prototype as any).$lbn = undefined
isOptimized = true
}
enableHydrationNodeLookup()
@ -141,23 +134,10 @@ function adoptTemplateImpl(node: Node, template: string): Node | null {
function locateHydrationNodeImpl(): void {
let node: Node | null
if (insertionAnchor === 0) {
// prepend
node = insertionParent!.$lpn = locateHydrationNodeByAnchor(
insertionParent!.$lpn || _child(insertionParent!),
BLOCK_PREPEND_ANCHOR_LABEL,
)!
} else if (insertionAnchor) {
// insert
node = insertionParent!.$lin = locateHydrationNodeByAnchor(
insertionParent!.$lin || _child(insertionParent!),
BLOCK_INSERTION_ANCHOR_LABEL,
)!
} else if (insertionAnchor === null) {
// append
node = insertionParent!.$lan = locateHydrationNodeByAnchor(
insertionParent!.$lan || _child(insertionParent!),
BLOCK_APPEND_ANCHOR_LABEL,
if (insertionAnchor !== undefined) {
// prepend / insert / append
node = insertionParent!.$lbn = locateNextBlockNode(
insertionParent!.$lbn || _child(insertionParent!),
)!
} else {
node = currentHydrationNode
@ -212,15 +192,15 @@ export function locateFragmentAnchor(
return null
}
function locateHydrationNodeByAnchor(node: Node, label: string): Node | null {
function locateNextBlockNode(node: Node): Node | null {
while (node) {
if (isComment(node, `[${label}`)) return node.nextSibling
if (isComment(node, BLOCK_ANCHOR_START_LABEL)) return node.nextSibling
node = node.nextSibling!
}
if (__DEV__) {
throw new Error(
`Could not locate hydration node with anchor label: ${label}`,
`Could not locate hydration node with anchor label: ${BLOCK_ANCHOR_START_LABEL}`,
)
}
return null
@ -228,18 +208,11 @@ function locateHydrationNodeByAnchor(node: Node, label: string): Node | null {
export function advanceToNonBlockNode(node: Node): Node {
while (node) {
if (isComment(node, `[${BLOCK_PREPEND_ANCHOR_LABEL}`)) {
if (isComment(node, BLOCK_ANCHOR_START_LABEL)) {
node = locateEndAnchor(
node,
`[${BLOCK_PREPEND_ANCHOR_LABEL}`,
`${BLOCK_PREPEND_ANCHOR_LABEL}]`,
)!
continue
} else if (isComment(node, `[${BLOCK_INSERTION_ANCHOR_LABEL}`)) {
node = locateEndAnchor(
node,
`[${BLOCK_INSERTION_ANCHOR_LABEL}`,
`${BLOCK_INSERTION_ANCHOR_LABEL}]`,
BLOCK_ANCHOR_START_LABEL,
BLOCK_ANCHOR_END_LABEL,
)!
continue
}

View File

@ -1,5 +1,5 @@
import { advanceToNonBlockNode } from './hydration'
import { isInsertionAnchor } from '@vue/shared'
import { isBlockStartAnchor } from '@vue/shared'
/*! #__NO_SIDE_EFFECTS__ */
export function createElement(tagName: string): HTMLElement {
@ -52,7 +52,7 @@ export function _child(node: ParentNode): Node {
/*! #__NO_SIDE_EFFECTS__ */
export function __child(node: ParentNode): Node {
let n: Node = node.firstChild!
while (n && isInsertionAnchor(n)) {
while (n && isBlockStartAnchor(n)) {
n = advanceToNonBlockNode(n)
n = n.nextSibling!
}
@ -87,7 +87,7 @@ export function _next(node: Node): Node {
*/
/*! #__NO_SIDE_EFFECTS__ */
export function __next(node: Node): Node {
if (isInsertionAnchor(node)) {
if (isBlockStartAnchor(node)) {
node = advanceToNonBlockNode(node)
}
return node.nextSibling!

View File

@ -1,11 +1,7 @@
export let insertionParent:
| (ParentNode & {
// the latest prepend node
$lpn?: Node
// the latest insert node
$lin?: Node
// the latest append node
$lan?: Node
// the last hydrated block node
$lbn?: Node
})
| undefined
export let insertionAnchor: Node | 0 | undefined | null

View File

@ -1,17 +1,12 @@
export const BLOCK_INSERTION_ANCHOR_LABEL = 'i'
export const BLOCK_APPEND_ANCHOR_LABEL = 'a'
export const BLOCK_PREPEND_ANCHOR_LABEL = 'p'
export const BLOCK_ANCHOR_START_LABEL = '[['
export const BLOCK_ANCHOR_END_LABEL = ']]'
export const IF_ANCHOR_LABEL: string = 'if'
export const DYNAMIC_COMPONENT_ANCHOR_LABEL: string = 'dynamic-component'
export const FOR_ANCHOR_LABEL: string = 'for'
export const SLOT_ANCHOR_LABEL: string = 'slot'
export function isInsertionAnchor(node: Node): node is Comment {
export function isBlockStartAnchor(node: Node): node is Comment {
if (node.nodeType !== 8) return false
const data = (node as Comment).data
return (
data === `[${BLOCK_INSERTION_ANCHOR_LABEL}` ||
data === `[${BLOCK_APPEND_ANCHOR_LABEL}` ||
data === `[${BLOCK_PREPEND_ANCHOR_LABEL}`
)
return data === `${BLOCK_ANCHOR_START_LABEL}`
}