mirror of https://github.com/vuejs/core.git
wip: refactor
This commit is contained in:
parent
34b9a4b5cd
commit
aad75fd7c4
|
@ -39,6 +39,7 @@ describe('ssr: components', () => {
|
||||||
|
|
||||||
return function ssrRender(_ctx, _push, _parent, _attrs) {
|
return function ssrRender(_ctx, _push, _parent, _attrs) {
|
||||||
_ssrRenderVNode(_push, _createVNode(_resolveDynamicComponent("foo"), _mergeProps({ prop: "b" }, _attrs), null), _parent)
|
_ssrRenderVNode(_push, _createVNode(_resolveDynamicComponent("foo"), _mergeProps({ prop: "b" }, _attrs), null), _parent)
|
||||||
|
_push(\`<!--dynamic-component-->\`)
|
||||||
}"
|
}"
|
||||||
`)
|
`)
|
||||||
|
|
||||||
|
@ -49,6 +50,7 @@ describe('ssr: components', () => {
|
||||||
|
|
||||||
return function ssrRender(_ctx, _push, _parent, _attrs) {
|
return function ssrRender(_ctx, _push, _parent, _attrs) {
|
||||||
_ssrRenderVNode(_push, _createVNode(_resolveDynamicComponent(_ctx.foo), _mergeProps({ prop: "b" }, _attrs), null), _parent)
|
_ssrRenderVNode(_push, _createVNode(_resolveDynamicComponent(_ctx.foo), _mergeProps({ prop: "b" }, _attrs), null), _parent)
|
||||||
|
_push(\`<!--dynamic-component-->\`)
|
||||||
}"
|
}"
|
||||||
`)
|
`)
|
||||||
})
|
})
|
||||||
|
@ -245,7 +247,7 @@ describe('ssr: components', () => {
|
||||||
_push(\`<span\${_scopeId}></span>\`)
|
_push(\`<span\${_scopeId}></span>\`)
|
||||||
})
|
})
|
||||||
_push(\`<!--]--></div>\`)
|
_push(\`<!--]--></div>\`)
|
||||||
_push(\`<!--$-->\`)
|
_push(\`<!--if-->\`)
|
||||||
} else {
|
} else {
|
||||||
_push(\`<!---->\`)
|
_push(\`<!---->\`)
|
||||||
}
|
}
|
||||||
|
@ -269,7 +271,7 @@ describe('ssr: components', () => {
|
||||||
_push(\`<span\${_scopeId}></span>\`)
|
_push(\`<span\${_scopeId}></span>\`)
|
||||||
})
|
})
|
||||||
_push(\`<!--]--></div>\`)
|
_push(\`<!--]--></div>\`)
|
||||||
_push(\`<!--$-->\`)
|
_push(\`<!--if-->\`)
|
||||||
} else {
|
} else {
|
||||||
_push(\`<!---->\`)
|
_push(\`<!---->\`)
|
||||||
}
|
}
|
||||||
|
@ -363,7 +365,7 @@ describe('ssr: components', () => {
|
||||||
_push(\`\`)
|
_push(\`\`)
|
||||||
if (false) {
|
if (false) {
|
||||||
_push(\`<div\${_scopeId}></div>\`)
|
_push(\`<div\${_scopeId}></div>\`)
|
||||||
_push(\`<!--$-->\`)
|
_push(\`<!--if-->\`)
|
||||||
} else {
|
} else {
|
||||||
_push(\`<!---->\`)
|
_push(\`<!---->\`)
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ describe('ssr: attrs fallthrough', () => {
|
||||||
_push(\`<!--[-->\`)
|
_push(\`<!--[-->\`)
|
||||||
if (true) {
|
if (true) {
|
||||||
_push(\`<div></div>\`)
|
_push(\`<div></div>\`)
|
||||||
_push(\`<!--$-->\`)
|
_push(\`<!--if-->\`)
|
||||||
} else {
|
} else {
|
||||||
_push(\`<!---->\`)
|
_push(\`<!---->\`)
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ describe('ssr: inject <style vars>', () => {
|
||||||
const _cssVars = { style: { color: _ctx.color }}
|
const _cssVars = { style: { color: _ctx.color }}
|
||||||
if (_ctx.ok) {
|
if (_ctx.ok) {
|
||||||
_push(\`<div\${_ssrRenderAttrs(_mergeProps(_attrs, _cssVars))}></div>\`)
|
_push(\`<div\${_ssrRenderAttrs(_mergeProps(_attrs, _cssVars))}></div>\`)
|
||||||
_push(\`<!--$-->\`)
|
_push(\`<!--if-->\`)
|
||||||
} else {
|
} else {
|
||||||
_push(\`<!--[--><div\${
|
_push(\`<!--[--><div\${
|
||||||
_ssrRenderAttrs(_cssVars)
|
_ssrRenderAttrs(_cssVars)
|
||||||
|
|
|
@ -153,7 +153,7 @@ describe('ssr: <slot>', () => {
|
||||||
return function ssrRender(_ctx, _push, _parent, _attrs) {
|
return function ssrRender(_ctx, _push, _parent, _attrs) {
|
||||||
if (true) {
|
if (true) {
|
||||||
_ssrRenderSlotInner(_ctx.$slots, "default", {}, null, _push, _parent, null, true)
|
_ssrRenderSlotInner(_ctx.$slots, "default", {}, null, _push, _parent, null, true)
|
||||||
_push(\`<!--$-->\`)
|
_push(\`<!--if-->\`)
|
||||||
} else {
|
} else {
|
||||||
_push(\`<!---->\`)
|
_push(\`<!---->\`)
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ describe('transition-group', () => {
|
||||||
})
|
})
|
||||||
if (false) {
|
if (false) {
|
||||||
_push(\`<div></div>\`)
|
_push(\`<div></div>\`)
|
||||||
_push(\`<!--$-->\`)
|
_push(\`<!--if-->\`)
|
||||||
}
|
}
|
||||||
_push(\`</ul>\`)
|
_push(\`</ul>\`)
|
||||||
}"
|
}"
|
||||||
|
@ -124,7 +124,7 @@ describe('transition-group', () => {
|
||||||
})
|
})
|
||||||
if (_ctx.ok) {
|
if (_ctx.ok) {
|
||||||
_push(\`<div>ok</div>\`)
|
_push(\`<div>ok</div>\`)
|
||||||
_push(\`<!--$-->\`)
|
_push(\`<!--if-->\`)
|
||||||
}
|
}
|
||||||
_push(\`<!--]-->\`)
|
_push(\`<!--]-->\`)
|
||||||
}"
|
}"
|
||||||
|
|
|
@ -8,7 +8,7 @@ describe('ssr: v-if', () => {
|
||||||
return function ssrRender(_ctx, _push, _parent, _attrs) {
|
return function ssrRender(_ctx, _push, _parent, _attrs) {
|
||||||
if (_ctx.foo) {
|
if (_ctx.foo) {
|
||||||
_push(\`<div\${_ssrRenderAttrs(_attrs)}></div>\`)
|
_push(\`<div\${_ssrRenderAttrs(_attrs)}></div>\`)
|
||||||
_push(\`<!--$-->\`)
|
_push(\`<!--if-->\`)
|
||||||
} else {
|
} else {
|
||||||
_push(\`<!---->\`)
|
_push(\`<!---->\`)
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ describe('ssr: v-if', () => {
|
||||||
return function ssrRender(_ctx, _push, _parent, _attrs) {
|
return function ssrRender(_ctx, _push, _parent, _attrs) {
|
||||||
if (_ctx.foo) {
|
if (_ctx.foo) {
|
||||||
_push(\`<div\${_ssrRenderAttrs(_attrs)}>hello<span>ok</span></div>\`)
|
_push(\`<div\${_ssrRenderAttrs(_attrs)}>hello<span>ok</span></div>\`)
|
||||||
_push(\`<!--$-->\`)
|
_push(\`<!--if-->\`)
|
||||||
} else {
|
} else {
|
||||||
_push(\`<!---->\`)
|
_push(\`<!---->\`)
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ describe('ssr: v-if', () => {
|
||||||
return function ssrRender(_ctx, _push, _parent, _attrs) {
|
return function ssrRender(_ctx, _push, _parent, _attrs) {
|
||||||
if (_ctx.foo) {
|
if (_ctx.foo) {
|
||||||
_push(\`<div\${_ssrRenderAttrs(_attrs)}></div>\`)
|
_push(\`<div\${_ssrRenderAttrs(_attrs)}></div>\`)
|
||||||
_push(\`<!--$-->\`)
|
_push(\`<!--if-->\`)
|
||||||
} else {
|
} else {
|
||||||
_push(\`<span\${_ssrRenderAttrs(_attrs)}></span>\`)
|
_push(\`<span\${_ssrRenderAttrs(_attrs)}></span>\`)
|
||||||
}
|
}
|
||||||
|
@ -56,10 +56,10 @@ describe('ssr: v-if', () => {
|
||||||
return function ssrRender(_ctx, _push, _parent, _attrs) {
|
return function ssrRender(_ctx, _push, _parent, _attrs) {
|
||||||
if (_ctx.foo) {
|
if (_ctx.foo) {
|
||||||
_push(\`<div\${_ssrRenderAttrs(_attrs)}></div>\`)
|
_push(\`<div\${_ssrRenderAttrs(_attrs)}></div>\`)
|
||||||
_push(\`<!--$-->\`)
|
_push(\`<!--if-->\`)
|
||||||
} else if (_ctx.bar) {
|
} else if (_ctx.bar) {
|
||||||
_push(\`<span\${_ssrRenderAttrs(_attrs)}></span>\`)
|
_push(\`<span\${_ssrRenderAttrs(_attrs)}></span>\`)
|
||||||
_push(\`<!--$-->\`)
|
_push(\`<!--if-->\`)
|
||||||
} else {
|
} else {
|
||||||
_push(\`<!---->\`)
|
_push(\`<!---->\`)
|
||||||
}
|
}
|
||||||
|
@ -75,10 +75,10 @@ describe('ssr: v-if', () => {
|
||||||
return function ssrRender(_ctx, _push, _parent, _attrs) {
|
return function ssrRender(_ctx, _push, _parent, _attrs) {
|
||||||
if (_ctx.foo) {
|
if (_ctx.foo) {
|
||||||
_push(\`<div\${_ssrRenderAttrs(_attrs)}></div>\`)
|
_push(\`<div\${_ssrRenderAttrs(_attrs)}></div>\`)
|
||||||
_push(\`<!--$-->\`)
|
_push(\`<!--if-->\`)
|
||||||
} else if (_ctx.bar) {
|
} else if (_ctx.bar) {
|
||||||
_push(\`<span\${_ssrRenderAttrs(_attrs)}></span>\`)
|
_push(\`<span\${_ssrRenderAttrs(_attrs)}></span>\`)
|
||||||
_push(\`<!--$-->\`)
|
_push(\`<!--if-->\`)
|
||||||
} else {
|
} else {
|
||||||
_push(\`<p\${_ssrRenderAttrs(_attrs)}></p>\`)
|
_push(\`<p\${_ssrRenderAttrs(_attrs)}></p>\`)
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ describe('ssr: v-if', () => {
|
||||||
return function ssrRender(_ctx, _push, _parent, _attrs) {
|
return function ssrRender(_ctx, _push, _parent, _attrs) {
|
||||||
if (_ctx.foo) {
|
if (_ctx.foo) {
|
||||||
_push(\`<!--[-->hello<!--]-->\`)
|
_push(\`<!--[-->hello<!--]-->\`)
|
||||||
_push(\`<!--$-->\`)
|
_push(\`<!--if-->\`)
|
||||||
} else {
|
} else {
|
||||||
_push(\`<!---->\`)
|
_push(\`<!---->\`)
|
||||||
}
|
}
|
||||||
|
@ -110,7 +110,7 @@ describe('ssr: v-if', () => {
|
||||||
return function ssrRender(_ctx, _push, _parent, _attrs) {
|
return function ssrRender(_ctx, _push, _parent, _attrs) {
|
||||||
if (_ctx.foo) {
|
if (_ctx.foo) {
|
||||||
_push(\`<div\${_ssrRenderAttrs(_attrs)}>hi</div>\`)
|
_push(\`<div\${_ssrRenderAttrs(_attrs)}>hi</div>\`)
|
||||||
_push(\`<!--$-->\`)
|
_push(\`<!--if-->\`)
|
||||||
} else {
|
} else {
|
||||||
_push(\`<!---->\`)
|
_push(\`<!---->\`)
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,7 @@ describe('ssr: v-if', () => {
|
||||||
return function ssrRender(_ctx, _push, _parent, _attrs) {
|
return function ssrRender(_ctx, _push, _parent, _attrs) {
|
||||||
if (_ctx.foo) {
|
if (_ctx.foo) {
|
||||||
_push(\`<!--[--><div>hi</div><div>ho</div><!--]-->\`)
|
_push(\`<!--[--><div>hi</div><div>ho</div><!--]-->\`)
|
||||||
_push(\`<!--$-->\`)
|
_push(\`<!--if-->\`)
|
||||||
} else {
|
} else {
|
||||||
_push(\`<!---->\`)
|
_push(\`<!---->\`)
|
||||||
}
|
}
|
||||||
|
@ -148,7 +148,7 @@ describe('ssr: v-if', () => {
|
||||||
_push(\`<div></div>\`)
|
_push(\`<div></div>\`)
|
||||||
})
|
})
|
||||||
_push(\`<!--]-->\`)
|
_push(\`<!--]-->\`)
|
||||||
_push(\`<!--$-->\`)
|
_push(\`<!--if-->\`)
|
||||||
} else {
|
} else {
|
||||||
_push(\`<!---->\`)
|
_push(\`<!---->\`)
|
||||||
}
|
}
|
||||||
|
@ -167,7 +167,7 @@ describe('ssr: v-if', () => {
|
||||||
return function ssrRender(_ctx, _push, _parent, _attrs) {
|
return function ssrRender(_ctx, _push, _parent, _attrs) {
|
||||||
if (_ctx.foo) {
|
if (_ctx.foo) {
|
||||||
_push(\`<!--[--><div>hi</div><div>ho</div><!--]-->\`)
|
_push(\`<!--[--><div>hi</div><div>ho</div><!--]-->\`)
|
||||||
_push(\`<!--$-->\`)
|
_push(\`<!--if-->\`)
|
||||||
} else {
|
} else {
|
||||||
_push(\`<div\${_ssrRenderAttrs(_attrs)}></div>\`)
|
_push(\`<div\${_ssrRenderAttrs(_attrs)}></div>\`)
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,7 +91,7 @@ describe('ssr: v-model', () => {
|
||||||
? _ssrLooseContain(_ctx.model, _ctx.i)
|
? _ssrLooseContain(_ctx.model, _ctx.i)
|
||||||
: _ssrLooseEqual(_ctx.model, _ctx.i))) ? " selected" : ""
|
: _ssrLooseEqual(_ctx.model, _ctx.i))) ? " selected" : ""
|
||||||
}></option>\`)
|
}></option>\`)
|
||||||
_push(\`<!--$-->\`)
|
_push(\`<!--if-->\`)
|
||||||
} else {
|
} else {
|
||||||
_push(\`<!---->\`)
|
_push(\`<!---->\`)
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,12 @@ import {
|
||||||
isText,
|
isText,
|
||||||
processExpression,
|
processExpression,
|
||||||
} from '@vue/compiler-dom'
|
} from '@vue/compiler-dom'
|
||||||
import { escapeHtml, isString } from '@vue/shared'
|
import {
|
||||||
|
DYNAMIC_END_ANCHOR_LABEL,
|
||||||
|
DYNAMIC_START_ANCHOR_LABEL,
|
||||||
|
escapeHtml,
|
||||||
|
isString,
|
||||||
|
} from '@vue/shared'
|
||||||
import { SSR_INTERPOLATE, ssrHelpers } from './runtimeHelpers'
|
import { SSR_INTERPOLATE, ssrHelpers } from './runtimeHelpers'
|
||||||
import { ssrProcessIf } from './transforms/ssrVIf'
|
import { ssrProcessIf } from './transforms/ssrVIf'
|
||||||
import { ssrProcessFor } from './transforms/ssrVFor'
|
import { ssrProcessFor } from './transforms/ssrVFor'
|
||||||
|
@ -161,7 +166,7 @@ export function processChildren(
|
||||||
asDynamic = false,
|
asDynamic = false,
|
||||||
): void {
|
): void {
|
||||||
if (asDynamic) {
|
if (asDynamic) {
|
||||||
context.pushStringPart(`<!--[[-->`)
|
context.pushStringPart(`<!--${DYNAMIC_START_ANCHOR_LABEL}-->`)
|
||||||
}
|
}
|
||||||
if (asFragment) {
|
if (asFragment) {
|
||||||
context.pushStringPart(`<!--[-->`)
|
context.pushStringPart(`<!--[-->`)
|
||||||
|
@ -259,7 +264,7 @@ export function processChildren(
|
||||||
context.pushStringPart(`<!--]-->`)
|
context.pushStringPart(`<!--]-->`)
|
||||||
}
|
}
|
||||||
if (asDynamic) {
|
if (asDynamic) {
|
||||||
context.pushStringPart(`<!--]]-->`)
|
context.pushStringPart(`<!--${DYNAMIC_END_ANCHOR_LABEL}-->`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,14 @@ import {
|
||||||
ssrProcessTransitionGroup,
|
ssrProcessTransitionGroup,
|
||||||
ssrTransformTransitionGroup,
|
ssrTransformTransitionGroup,
|
||||||
} from './ssrTransformTransitionGroup'
|
} from './ssrTransformTransitionGroup'
|
||||||
import { extend, isArray, isObject, isPlainObject, isSymbol } from '@vue/shared'
|
import {
|
||||||
|
DYNAMIC_COMPONENT_ANCHOR_LABEL,
|
||||||
|
extend,
|
||||||
|
isArray,
|
||||||
|
isObject,
|
||||||
|
isPlainObject,
|
||||||
|
isSymbol,
|
||||||
|
} from '@vue/shared'
|
||||||
import { buildSSRProps } from './ssrTransformElement'
|
import { buildSSRProps } from './ssrTransformElement'
|
||||||
import {
|
import {
|
||||||
ssrProcessTransition,
|
ssrProcessTransition,
|
||||||
|
@ -264,6 +271,8 @@ export function ssrProcessComponent(
|
||||||
// dynamic component (`resolveDynamicComponent` call)
|
// dynamic component (`resolveDynamicComponent` call)
|
||||||
// the codegen node is a `renderVNode` call
|
// the codegen node is a `renderVNode` call
|
||||||
context.pushStatement(node.ssrCodegenNode)
|
context.pushStatement(node.ssrCodegenNode)
|
||||||
|
// anchor for dynamic component for vapor hydration
|
||||||
|
context.pushStringPart(`<!--${DYNAMIC_COMPONENT_ANCHOR_LABEL}-->`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import {
|
||||||
type SSRTransformContext,
|
type SSRTransformContext,
|
||||||
processChildrenAsStatement,
|
processChildrenAsStatement,
|
||||||
} from '../ssrCodegenTransform'
|
} from '../ssrCodegenTransform'
|
||||||
|
import { IF_ANCHOR_LABEL } from '@vue/shared'
|
||||||
|
|
||||||
// Plugin for the first transform pass, which simply constructs the AST node
|
// Plugin for the first transform pass, which simply constructs the AST node
|
||||||
export const ssrTransformIf: NodeTransform = createStructuralDirectiveTransform(
|
export const ssrTransformIf: NodeTransform = createStructuralDirectiveTransform(
|
||||||
|
@ -80,7 +81,10 @@ function processIfBranch(
|
||||||
needFragmentWrapper,
|
needFragmentWrapper,
|
||||||
)
|
)
|
||||||
if (branch.condition) {
|
if (branch.condition) {
|
||||||
statement.body.push(createCallExpression(`_push`, ['`<!--$-->`']))
|
// v-if/v-else-if anchor for vapor hydration
|
||||||
|
statement.body.push(
|
||||||
|
createCallExpression(`_push`, [`\`<!--${IF_ANCHOR_LABEL}-->\``]),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
return statement
|
return statement
|
||||||
}
|
}
|
||||||
|
|
|
@ -598,14 +598,14 @@ describe('SSR hydration', () => {
|
||||||
const ctx: SSRContext = {}
|
const ctx: SSRContext = {}
|
||||||
container.innerHTML = await renderToString(h(App), ctx)
|
container.innerHTML = await renderToString(h(App), ctx)
|
||||||
expect(container.innerHTML).toBe(
|
expect(container.innerHTML).toBe(
|
||||||
'<div><!--teleport start--><!--teleport end--><!--$--></div>',
|
'<div><!--teleport start--><!--teleport end--><!--if--></div>',
|
||||||
)
|
)
|
||||||
teleportContainer.innerHTML = ctx.teleports!['#target']
|
teleportContainer.innerHTML = ctx.teleports!['#target']
|
||||||
|
|
||||||
// hydrate
|
// hydrate
|
||||||
createSSRApp(App).mount(container)
|
createSSRApp(App).mount(container)
|
||||||
expect(container.innerHTML).toBe(
|
expect(container.innerHTML).toBe(
|
||||||
'<div><!--teleport start--><!--teleport end--><!--$--></div>',
|
'<div><!--teleport start--><!--teleport end--><!--if--></div>',
|
||||||
)
|
)
|
||||||
expect(teleportContainer.innerHTML).toBe(
|
expect(teleportContainer.innerHTML).toBe(
|
||||||
'<!--teleport start anchor--><span>Teleported Comp1</span><!--teleport anchor-->',
|
'<!--teleport start anchor--><span>Teleported Comp1</span><!--teleport anchor-->',
|
||||||
|
@ -614,7 +614,7 @@ describe('SSR hydration', () => {
|
||||||
|
|
||||||
toggle.value = false
|
toggle.value = false
|
||||||
await nextTick()
|
await nextTick()
|
||||||
expect(container.innerHTML).toBe('<div><div>Comp2</div><!--$--></div>')
|
expect(container.innerHTML).toBe('<div><div>Comp2</div><!--if--></div>')
|
||||||
expect(teleportContainer.innerHTML).toBe('')
|
expect(teleportContainer.innerHTML).toBe('')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -657,21 +657,21 @@ describe('SSR hydration', () => {
|
||||||
// server render
|
// server render
|
||||||
container.innerHTML = await renderToString(h(App))
|
container.innerHTML = await renderToString(h(App))
|
||||||
expect(container.innerHTML).toBe(
|
expect(container.innerHTML).toBe(
|
||||||
'<div><!--teleport start--><!--teleport end--><!--$--></div>',
|
'<div><!--teleport start--><!--teleport end--><!--if--></div>',
|
||||||
)
|
)
|
||||||
expect(teleportContainer.innerHTML).toBe('')
|
expect(teleportContainer.innerHTML).toBe('')
|
||||||
|
|
||||||
// hydrate
|
// hydrate
|
||||||
createSSRApp(App).mount(container)
|
createSSRApp(App).mount(container)
|
||||||
expect(container.innerHTML).toBe(
|
expect(container.innerHTML).toBe(
|
||||||
'<div><!--teleport start--><!--teleport end--><!--$--></div>',
|
'<div><!--teleport start--><!--teleport end--><!--if--></div>',
|
||||||
)
|
)
|
||||||
expect(teleportContainer.innerHTML).toBe('<span>Teleported Comp1</span>')
|
expect(teleportContainer.innerHTML).toBe('<span>Teleported Comp1</span>')
|
||||||
expect(`Hydration children mismatch`).toHaveBeenWarned()
|
expect(`Hydration children mismatch`).toHaveBeenWarned()
|
||||||
|
|
||||||
toggle.value = false
|
toggle.value = false
|
||||||
await nextTick()
|
await nextTick()
|
||||||
expect(container.innerHTML).toBe('<div><div>Comp2</div><!--$--></div>')
|
expect(container.innerHTML).toBe('<div><div>Comp2</div><!--if--></div>')
|
||||||
expect(teleportContainer.innerHTML).toBe('')
|
expect(teleportContainer.innerHTML).toBe('')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,8 @@ import {
|
||||||
getEscapedCssVarName,
|
getEscapedCssVarName,
|
||||||
includeBooleanAttr,
|
includeBooleanAttr,
|
||||||
isBooleanAttr,
|
isBooleanAttr,
|
||||||
|
isDynamicAnchor,
|
||||||
|
isDynamicFragmentEndAnchor,
|
||||||
isKnownHtmlAttr,
|
isKnownHtmlAttr,
|
||||||
isKnownSvgAttr,
|
isKnownSvgAttr,
|
||||||
isOn,
|
isOn,
|
||||||
|
@ -84,14 +86,6 @@ const getContainerType = (
|
||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isDynamicAnchor(node: Node): node is Comment {
|
|
||||||
return isComment(node) && (node.data === '[[' || node.data === ']]')
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isDynamicFragmentEndAnchor(node: Node): node is Comment {
|
|
||||||
return isComment(node) && node.data === '$'
|
|
||||||
}
|
|
||||||
|
|
||||||
export const isComment = (node: Node): node is Comment =>
|
export const isComment = (node: Node): node is Comment =>
|
||||||
node.nodeType === DOMNodeTypes.COMMENT
|
node.nodeType === DOMNodeTypes.COMMENT
|
||||||
|
|
||||||
|
@ -130,8 +124,8 @@ export function createHydrationFunctions(
|
||||||
function nextSibling(node: Node) {
|
function nextSibling(node: Node) {
|
||||||
let n = next(node)
|
let n = next(node)
|
||||||
// skip if:
|
// skip if:
|
||||||
// - dynamic anchors (`<!--[-->`, `<!--]-->`)
|
// - dynamic anchors (`<!--[[-->`, `<!--][-->`)
|
||||||
// - dynamic fragment end anchors (`<!--$-->`)
|
// - dynamic fragment end anchors (e.g. `<!--if-->`, `<!--for-->`)
|
||||||
if (n && (isDynamicAnchor(n) || isDynamicFragmentEndAnchor(n))) {
|
if (n && (isDynamicAnchor(n) || isDynamicFragmentEndAnchor(n))) {
|
||||||
n = next(n)
|
n = next(n)
|
||||||
}
|
}
|
||||||
|
|
|
@ -557,7 +557,3 @@ export { startMeasure, endMeasure } from './profiling'
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
export { initFeatureFlags } from './featureFlags'
|
export { initFeatureFlags } from './featureFlags'
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
export { isDynamicAnchor, isDynamicFragmentEndAnchor } from './hydration'
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -9,7 +9,8 @@ import {
|
||||||
insertionParent,
|
insertionParent,
|
||||||
resetInsertionState,
|
resetInsertionState,
|
||||||
} from './insertionState'
|
} from './insertionState'
|
||||||
import { isHydrating, locateHydrationNode } from './dom/hydration'
|
import { isHydrating } from './dom/hydration'
|
||||||
|
import { DYNAMIC_COMPONENT_ANCHOR_LABEL } from '@vue/shared'
|
||||||
|
|
||||||
export function createDynamicComponent(
|
export function createDynamicComponent(
|
||||||
getter: () => any,
|
getter: () => any,
|
||||||
|
@ -19,15 +20,9 @@ export function createDynamicComponent(
|
||||||
): VaporFragment {
|
): VaporFragment {
|
||||||
const _insertionParent = insertionParent
|
const _insertionParent = insertionParent
|
||||||
const _insertionAnchor = insertionAnchor
|
const _insertionAnchor = insertionAnchor
|
||||||
if (isHydrating) {
|
if (!isHydrating) resetInsertionState()
|
||||||
locateHydrationNode(true)
|
|
||||||
} else {
|
|
||||||
resetInsertionState()
|
|
||||||
}
|
|
||||||
|
|
||||||
const frag = __DEV__
|
const frag = new DynamicFragment(DYNAMIC_COMPONENT_ANCHOR_LABEL)
|
||||||
? new DynamicFragment('dynamic-component')
|
|
||||||
: new DynamicFragment()
|
|
||||||
renderEffect(() => {
|
renderEffect(() => {
|
||||||
const value = getter()
|
const value = getter()
|
||||||
frag.update(
|
frag.update(
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
|
import { IF_ANCHOR_LABEL } from '@vue/shared'
|
||||||
import { type Block, type BlockFn, DynamicFragment, insert } from './block'
|
import { type Block, type BlockFn, DynamicFragment, insert } from './block'
|
||||||
import { isHydrating, locateHydrationNode } from './dom/hydration'
|
import { isHydrating } from './dom/hydration'
|
||||||
import { insertionAnchor, insertionParent } from './insertionState'
|
import {
|
||||||
|
insertionAnchor,
|
||||||
|
insertionParent,
|
||||||
|
resetInsertionState,
|
||||||
|
} from './insertionState'
|
||||||
import { renderEffect } from './renderEffect'
|
import { renderEffect } from './renderEffect'
|
||||||
|
|
||||||
export function createIf(
|
export function createIf(
|
||||||
|
@ -11,15 +16,13 @@ export function createIf(
|
||||||
): Block {
|
): Block {
|
||||||
const _insertionParent = insertionParent
|
const _insertionParent = insertionParent
|
||||||
const _insertionAnchor = insertionAnchor
|
const _insertionAnchor = insertionAnchor
|
||||||
if (isHydrating) {
|
if (!isHydrating) resetInsertionState()
|
||||||
locateHydrationNode(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
let frag: Block
|
let frag: Block
|
||||||
if (once) {
|
if (once) {
|
||||||
frag = condition() ? b1() : b2 ? b2() : []
|
frag = condition() ? b1() : b2 ? b2() : []
|
||||||
} else {
|
} else {
|
||||||
frag = __DEV__ ? new DynamicFragment('if') : new DynamicFragment()
|
frag = new DynamicFragment(IF_ANCHOR_LABEL)
|
||||||
renderEffect(() => (frag as DynamicFragment).update(condition() ? b1 : b2))
|
renderEffect(() => (frag as DynamicFragment).update(condition() ? b1 : b2))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { isArray } from '@vue/shared'
|
import { isArray, isDynamicFragmentEndAnchor } from '@vue/shared'
|
||||||
import {
|
import {
|
||||||
type VaporComponentInstance,
|
type VaporComponentInstance,
|
||||||
isVaporComponent,
|
isVaporComponent,
|
||||||
|
@ -7,8 +7,13 @@ import {
|
||||||
} from './component'
|
} from './component'
|
||||||
import { createComment, createTextNode, nextSiblingAnchor } from './dom/node'
|
import { createComment, createTextNode, nextSiblingAnchor } from './dom/node'
|
||||||
import { EffectScope, pauseTracking, resetTracking } from '@vue/reactivity'
|
import { EffectScope, pauseTracking, resetTracking } from '@vue/reactivity'
|
||||||
import { currentHydrationNode, isComment, isHydrating } from './dom/hydration'
|
import {
|
||||||
import { isDynamicFragmentEndAnchor, warn } from '@vue/runtime-dom'
|
currentHydrationNode,
|
||||||
|
isComment,
|
||||||
|
isHydrating,
|
||||||
|
locateHydrationNode,
|
||||||
|
} from './dom/hydration'
|
||||||
|
import { warn } from '@vue/runtime-dom'
|
||||||
|
|
||||||
export type Block =
|
export type Block =
|
||||||
| Node
|
| Node
|
||||||
|
@ -39,7 +44,8 @@ export class DynamicFragment extends VaporFragment {
|
||||||
constructor(anchorLabel?: string) {
|
constructor(anchorLabel?: string) {
|
||||||
super([])
|
super([])
|
||||||
if (isHydrating) {
|
if (isHydrating) {
|
||||||
this.hydrate(anchorLabel)
|
locateHydrationNode(true)
|
||||||
|
this.hydrate(anchorLabel!)
|
||||||
} else {
|
} else {
|
||||||
this.anchor =
|
this.anchor =
|
||||||
__DEV__ && anchorLabel ? createComment(anchorLabel) : createTextNode()
|
__DEV__ && anchorLabel ? createComment(anchorLabel) : createTextNode()
|
||||||
|
@ -81,15 +87,15 @@ export class DynamicFragment extends VaporFragment {
|
||||||
resetTracking()
|
resetTracking()
|
||||||
}
|
}
|
||||||
|
|
||||||
hydrate(label?: string): void {
|
hydrate(label: string): void {
|
||||||
// for v-if="false" the hydrationNode will be a empty comment node
|
// for v-if="false" the hydrationNode will be a empty comment node
|
||||||
// use it as anchor.
|
// use it as anchor.
|
||||||
// otherwise, use the next sibling comment node as anchor
|
// otherwise, use the next sibling comment node as anchor
|
||||||
if (isComment(currentHydrationNode!, '')) {
|
if (isComment(currentHydrationNode!, '')) {
|
||||||
this.anchor = currentHydrationNode
|
this.anchor = currentHydrationNode
|
||||||
} else {
|
} else {
|
||||||
// find next sibling `<!--$-->` as anchor
|
// find next sibling dynamic fragment end anchor
|
||||||
const anchor = nextSiblingAnchor(currentHydrationNode!, '$')!
|
const anchor = nextSiblingAnchor(currentHydrationNode!, label)!
|
||||||
if (anchor && isDynamicFragmentEndAnchor(anchor)) {
|
if (anchor && isDynamicFragmentEndAnchor(anchor)) {
|
||||||
this.anchor = anchor
|
this.anchor = anchor
|
||||||
} else if (__DEV__) {
|
} else if (__DEV__) {
|
||||||
|
@ -97,7 +103,6 @@ export class DynamicFragment extends VaporFragment {
|
||||||
warn(`DynamicFragment anchor not found...`)
|
warn(`DynamicFragment anchor not found...`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (__DEV__ && label && this.anchor) (this.anchor as Comment).data = label
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { isDynamicFragmentEndAnchor, warn } from '@vue/runtime-dom'
|
import { warn } from '@vue/runtime-dom'
|
||||||
import {
|
import {
|
||||||
insertionAnchor,
|
insertionAnchor,
|
||||||
insertionParent,
|
insertionParent,
|
||||||
|
@ -12,6 +12,7 @@ import {
|
||||||
next,
|
next,
|
||||||
prev,
|
prev,
|
||||||
} from './node'
|
} from './node'
|
||||||
|
import { isDynamicFragmentEndAnchor } from '@vue/shared'
|
||||||
|
|
||||||
export let isHydrating = false
|
export let isHydrating = false
|
||||||
export let currentHydrationNode: Node | null = null
|
export let currentHydrationNode: Node | null = null
|
||||||
|
|
|
@ -1,10 +1,15 @@
|
||||||
import { isDynamicAnchor } from '@vue/runtime-dom'
|
|
||||||
import {
|
import {
|
||||||
isComment,
|
isComment,
|
||||||
isEmptyText,
|
isEmptyText,
|
||||||
locateEndAnchor,
|
locateEndAnchor,
|
||||||
locateStartAnchor,
|
locateStartAnchor,
|
||||||
} from './hydration'
|
} from './hydration'
|
||||||
|
import {
|
||||||
|
DYNAMIC_END_ANCHOR_LABEL,
|
||||||
|
DYNAMIC_START_ANCHOR_LABEL,
|
||||||
|
isDynamicAnchor,
|
||||||
|
isDynamicFragmentEndAnchor,
|
||||||
|
} from '@vue/shared'
|
||||||
|
|
||||||
/*! #__NO_SIDE_EFFECTS__ */
|
/*! #__NO_SIDE_EFFECTS__ */
|
||||||
export function createTextNode(value = ''): Text {
|
export function createTextNode(value = ''): Text {
|
||||||
|
@ -102,8 +107,12 @@ export function disableHydrationNodeLookup(): void {
|
||||||
/*! #__NO_SIDE_EFFECTS__ */
|
/*! #__NO_SIDE_EFFECTS__ */
|
||||||
export function prev(node: Node): Node | null {
|
export function prev(node: Node): Node | null {
|
||||||
// process dynamic node (<!--[[-->...<!--]]-->) as a single one
|
// process dynamic node (<!--[[-->...<!--]]-->) as a single one
|
||||||
if (isComment(node, ']]')) {
|
if (isComment(node, DYNAMIC_END_ANCHOR_LABEL)) {
|
||||||
node = locateStartAnchor(node, '[[', ']]')!
|
node = locateStartAnchor(
|
||||||
|
node,
|
||||||
|
DYNAMIC_START_ANCHOR_LABEL,
|
||||||
|
DYNAMIC_END_ANCHOR_LABEL,
|
||||||
|
)!
|
||||||
}
|
}
|
||||||
|
|
||||||
// process fragment node (<!--[-->...<!--]-->) as a single one
|
// process fragment node (<!--[-->...<!--]-->) as a single one
|
||||||
|
@ -122,21 +131,12 @@ function isNonHydrationNode(node: Node) {
|
||||||
return (
|
return (
|
||||||
// empty text nodes, no need to hydrate
|
// empty text nodes, no need to hydrate
|
||||||
isEmptyText(node) ||
|
isEmptyText(node) ||
|
||||||
// dynamic anchors (<!--[[-->, <!--]]-->)
|
// dynamic node anchors (<!--[[-->, <!--]]-->)
|
||||||
isDynamicAnchor(node) ||
|
isDynamicAnchor(node) ||
|
||||||
// fragment end anchor (`<!--]-->`)
|
// fragment end anchor (`<!--]-->`)
|
||||||
isComment(node, ']') ||
|
isComment(node, ']') ||
|
||||||
// dynamic fragment anchors
|
// dynamic fragment end anchors
|
||||||
(__DEV__
|
isDynamicFragmentEndAnchor(node)
|
||||||
? // v-if anchor (`<!--if-->`)
|
|
||||||
isComment(node, 'if') ||
|
|
||||||
// v-for anchor (`<!--for-->`)
|
|
||||||
isComment(node, 'for') ||
|
|
||||||
// v-slot anchor (`<!--slot-->`)
|
|
||||||
isComment(node, 'slot') ||
|
|
||||||
// dynamic-component anchor (`<!--dynamic-component-->`)
|
|
||||||
isComment(node, 'dynamic-component')
|
|
||||||
: isComment(node, '$'))
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,8 +157,12 @@ export function nextSiblingAnchor(
|
||||||
|
|
||||||
function handleWrappedNode(node: Node): Node {
|
function handleWrappedNode(node: Node): Node {
|
||||||
// process dynamic node (<!--[[-->...<!--]]-->) as a single one
|
// process dynamic node (<!--[[-->...<!--]]-->) as a single one
|
||||||
if (isComment(node, '[[')) {
|
if (isComment(node, DYNAMIC_START_ANCHOR_LABEL)) {
|
||||||
return locateEndAnchor(node, '[[', ']]')!
|
return locateEndAnchor(
|
||||||
|
node,
|
||||||
|
DYNAMIC_START_ANCHOR_LABEL,
|
||||||
|
DYNAMIC_END_ANCHOR_LABEL,
|
||||||
|
)!
|
||||||
}
|
}
|
||||||
|
|
||||||
// process fragment (<!--[-->...<!--]-->) as a single one
|
// process fragment (<!--[-->...<!--]-->) as a single one
|
||||||
|
|
|
@ -25,7 +25,7 @@ describe('ssr: attr fallthrough', () => {
|
||||||
template: `<child :ok="ok" class="bar"/>`,
|
template: `<child :ok="ok" class="bar"/>`,
|
||||||
}
|
}
|
||||||
expect(await renderToString(createApp(Parent, { ok: true }))).toBe(
|
expect(await renderToString(createApp(Parent, { ok: true }))).toBe(
|
||||||
`<div class="foo bar"></div><!--$-->`,
|
`<div class="foo bar"></div><!--if-->`,
|
||||||
)
|
)
|
||||||
expect(await renderToString(createApp(Parent, { ok: false }))).toBe(
|
expect(await renderToString(createApp(Parent, { ok: false }))).toBe(
|
||||||
`<span class="bar"></span>`,
|
`<span class="bar"></span>`,
|
||||||
|
|
|
@ -14,7 +14,9 @@ describe('ssr: dynamic component', () => {
|
||||||
template: `<component :is="'one'"><span>slot</span></component>`,
|
template: `<component :is="'one'"><span>slot</span></component>`,
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
).toBe(`<div><!--[--><span>slot</span><!--]--></div>`)
|
).toBe(
|
||||||
|
`<div><!--[--><span>slot</span><!--]--></div><!--dynamic-component-->`,
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('resolved to component with v-show', async () => {
|
test('resolved to component with v-show', async () => {
|
||||||
|
@ -30,7 +32,7 @@ describe('ssr: dynamic component', () => {
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
).toBe(
|
).toBe(
|
||||||
`<div><!--[--><div style=\"display:none;\"><!--[-->hi<!--]--></div><!--]--></div>`,
|
`<div><!--[--><div style="display:none;"><!--[-->hi<!--]--></div><!--dynamic-component--><!--]--></div><!--dynamic-component-->`,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -41,7 +43,7 @@ describe('ssr: dynamic component', () => {
|
||||||
template: `<component :is="'p'"><span>slot</span></component>`,
|
template: `<component :is="'p'"><span>slot</span></component>`,
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
).toBe(`<p><span>slot</span></p>`)
|
).toBe(`<p><span>slot</span></p><!--dynamic-component-->`)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('resolve to component vnode', async () => {
|
test('resolve to component vnode', async () => {
|
||||||
|
@ -60,7 +62,9 @@ describe('ssr: dynamic component', () => {
|
||||||
template: `<component :is="vnode"><span>slot</span></component>`,
|
template: `<component :is="vnode"><span>slot</span></component>`,
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
).toBe(`<div>test<!--[--><span>slot</span><!--]--></div>`)
|
).toBe(
|
||||||
|
`<div>test<!--[--><span>slot</span><!--]--></div><!--dynamic-component-->`,
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('resolve to element vnode', async () => {
|
test('resolve to element vnode', async () => {
|
||||||
|
@ -75,6 +79,6 @@ describe('ssr: dynamic component', () => {
|
||||||
template: `<component :is="vnode"><span>slot</span></component>`,
|
template: `<component :is="vnode"><span>slot</span></component>`,
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
).toBe(`<div id="test"><span>slot</span></div>`)
|
).toBe(`<div id="test"><span>slot</span></div><!--dynamic-component-->`)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -94,7 +94,7 @@ describe('ssr: slot', () => {
|
||||||
template: `<one><template v-if="true">hello</template></one>`,
|
template: `<one><template v-if="true">hello</template></one>`,
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
).toBe(`<div><!--[--><!--[-->hello<!--]--><!--$--><!--]--></div>`)
|
).toBe(`<div><!--[--><!--[-->hello<!--]--><!--if--><!--]--></div>`)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('fragment slot (template v-if + multiple elements)', async () => {
|
test('fragment slot (template v-if + multiple elements)', async () => {
|
||||||
|
@ -106,7 +106,7 @@ describe('ssr: slot', () => {
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
).toBe(
|
).toBe(
|
||||||
`<div><!--[--><!--[--><div>one</div><div>two</div><!--]--><!--$--><!--]--></div>`,
|
`<div><!--[--><!--[--><div>one</div><div>two</div><!--]--><!--if--><!--]--></div>`,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ describe('ssr: slot', () => {
|
||||||
template: `<one><div v-if="true">foo</div></one>`,
|
template: `<one><div v-if="true">foo</div></one>`,
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
).toBe(`<div>foo</div><!--$-->`)
|
).toBe(`<div>foo</div><!--if-->`)
|
||||||
})
|
})
|
||||||
|
|
||||||
// #9933
|
// #9933
|
||||||
|
@ -170,7 +170,9 @@ describe('ssr: slot', () => {
|
||||||
template: `<ButtonComp><Wrap><div v-if="false">hello</div></Wrap></ButtonComp>`,
|
template: `<ButtonComp><Wrap><div v-if="false">hello</div></Wrap></ButtonComp>`,
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
).toBe(`<button><!--[--><div><!--[--><!--]--></div><!--]--></button>`)
|
).toBe(
|
||||||
|
`<button><!--[--><div><!--[--><!--]--></div><!--]--></button><!--dynamic-component-->`,
|
||||||
|
)
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
await renderToString(
|
await renderToString(
|
||||||
|
@ -187,7 +189,7 @@ describe('ssr: slot', () => {
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
).toBe(
|
).toBe(
|
||||||
`<button><!--[--><div><!--[--><div>hello</div><!--]--></div><!--]--></button>`,
|
`<button><!--[--><div><!--[--><div>hello</div><!--]--></div><!--]--></button><!--dynamic-component-->`,
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
|
@ -201,6 +203,6 @@ describe('ssr: slot', () => {
|
||||||
template: `<ButtonComp><template v-if="false">hello</template></ButtonComp>`,
|
template: `<ButtonComp><template v-if="false">hello</template></ButtonComp>`,
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
).toBe(`<button><!--[--><!--]--></button>`)
|
).toBe(`<button><!--[--><!--]--></button><!--dynamic-component-->`)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -264,7 +264,6 @@ export function renderVNode(
|
||||||
renderElementVNode(push, vnode, parentComponent, slotScopeId)
|
renderElementVNode(push, vnode, parentComponent, slotScopeId)
|
||||||
} else if (shapeFlag & ShapeFlags.COMPONENT) {
|
} else if (shapeFlag & ShapeFlags.COMPONENT) {
|
||||||
push(renderComponentVNode(vnode, parentComponent, slotScopeId))
|
push(renderComponentVNode(vnode, parentComponent, slotScopeId))
|
||||||
push(`<!--$-->`) // anchor for vapor hydration
|
|
||||||
} else if (shapeFlag & ShapeFlags.TELEPORT) {
|
} else if (shapeFlag & ShapeFlags.TELEPORT) {
|
||||||
renderTeleportVNode(push, vnode, parentComponent, slotScopeId)
|
renderTeleportVNode(push, vnode, parentComponent, slotScopeId)
|
||||||
} else if (shapeFlag & ShapeFlags.SUSPENSE) {
|
} else if (shapeFlag & ShapeFlags.SUSPENSE) {
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
export const DYNAMIC_START_ANCHOR_LABEL = '[['
|
||||||
|
export const DYNAMIC_END_ANCHOR_LABEL = ']]'
|
||||||
|
|
||||||
|
export const IF_ANCHOR_LABEL: string = __DEV__ ? 'if' : '$'
|
||||||
|
export const DYNAMIC_COMPONENT_ANCHOR_LABEL: string = __DEV__
|
||||||
|
? 'dynamic-component'
|
||||||
|
: '$2'
|
||||||
|
export const FOR_ANCHOR_LABEL: string = __DEV__ ? 'for' : '$3'
|
||||||
|
export const SLOT_ANCHOR_LABEL: string = __DEV__ ? 'slot' : '$4'
|
||||||
|
|
||||||
|
export function isDynamicAnchor(node: Node): node is Comment {
|
||||||
|
if (node.nodeType !== 8) return false
|
||||||
|
|
||||||
|
const data = (node as Comment).data
|
||||||
|
return (
|
||||||
|
data === DYNAMIC_START_ANCHOR_LABEL || data === DYNAMIC_END_ANCHOR_LABEL
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isDynamicFragmentEndAnchor(node: Node): node is Comment {
|
||||||
|
if (node.nodeType !== 8) return false
|
||||||
|
|
||||||
|
const data = (node as Comment).data
|
||||||
|
return (
|
||||||
|
data === IF_ANCHOR_LABEL ||
|
||||||
|
data === FOR_ANCHOR_LABEL ||
|
||||||
|
data === SLOT_ANCHOR_LABEL ||
|
||||||
|
data === DYNAMIC_COMPONENT_ANCHOR_LABEL
|
||||||
|
)
|
||||||
|
}
|
|
@ -13,3 +13,4 @@ export * from './looseEqual'
|
||||||
export * from './toDisplayString'
|
export * from './toDisplayString'
|
||||||
export * from './typeUtils'
|
export * from './typeUtils'
|
||||||
export * from './subSequence'
|
export * from './subSequence'
|
||||||
|
export * from './domAnchors'
|
||||||
|
|
Loading…
Reference in New Issue