Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
}
}
)
expect(root.helpers).toContain(RESOLVE_DIRECTIVE)
expect(root.directives).toContain(`foo`)
expect(node.callee).toBe(WITH_DIRECTIVES)
expect(node.arguments).toMatchObject([
{
type: NodeTypes.JS_CALL_EXPRESSION,
callee: CREATE_VNODE,
arguments: [
`"div"`,
`null`,
`null`,
genFlagText(PatchFlags.NEED_PATCH) // should generate appropriate flag
]
},
{
type: NodeTypes.JS_ARRAY_EXPRESSION,
elements: [
{
type: NodeTypes.JS_ARRAY_EXPRESSION,
elements: [
`_directive_foo`,
// exp
{
type: NodeTypes.SIMPLE_EXPRESSION,
content: `hello`,
isStatic: false
},
// arg
// patchFlag analysis
if (hasDynamicKeys) {
patchFlag |= PatchFlags.FULL_PROPS
} else {
if (hasClassBinding) {
patchFlag |= PatchFlags.CLASS
}
if (hasStyleBinding) {
patchFlag |= PatchFlags.STYLE
}
if (dynamicPropNames.length) {
patchFlag |= PatchFlags.PROPS
}
}
if (patchFlag === 0 && (hasRef || runtimeDirectives.length > 0)) {
patchFlag |= PatchFlags.NEED_PATCH
}
return {
props: propsExpression,
directives: runtimeDirectives,
patchFlag,
dynamicPropNames
}
}
// patchFlag analysis
if (hasDynamicKeys) {
patchFlag |= PatchFlags.FULL_PROPS
} else {
if (hasClassBinding) {
patchFlag |= PatchFlags.CLASS
}
if (hasStyleBinding) {
patchFlag |= PatchFlags.STYLE
}
if (dynamicPropNames.length) {
patchFlag |= PatchFlags.PROPS
}
}
if (patchFlag === 0 && (hasRef || runtimeDirectives.length > 0)) {
patchFlag |= PatchFlags.NEED_PATCH
}
return {
props: propsExpression,
directives: runtimeDirectives,
patchFlag,
dynamicPropNames
}
}
child.type === NodeTypes.ELEMENT &&
child.tagType === ElementTypes.ELEMENT
) {
if (!doNotHoistNode && isStaticNode(child, resultCache)) {
// whole tree is static
child.codegenNode = context.hoist(child.codegenNode!)
continue
} else {
// node may contain dynamic children, but its props may be eligible for
// hoisting.
const codegenNode = child.codegenNode!
if (codegenNode.type === NodeTypes.JS_CALL_EXPRESSION) {
const flag = getPatchFlag(codegenNode)
if (
(!flag ||
flag === PatchFlags.NEED_PATCH ||
flag === PatchFlags.TEXT) &&
!hasDynamicKeyOrRef(child) &&
!hasCachedProps(child)
) {
const props = getNodeProps(child)
if (props && props !== `null`) {
getVNodeCall(codegenNode).arguments[1] = context.hoist(props)
}
}
}
}
}
if (child.type === NodeTypes.ELEMENT) {
walk(child.children, context, resultCache)
} else if (child.type === NodeTypes.FOR) {
// Do not hoist v-for single child because it has to be a block
test('NEED_PATCH (dynamic ref)', () => {
const { node } = parseWithBind(`<div>`)
expect(node.arguments.length).toBe(4)
expect(node.arguments[3]).toBe(genFlagText(PatchFlags.NEED_PATCH))
})
</div>
test('should NOT hoist element with dynamic ref', () => {
const { root, args } = transformWithHoist(`<div><div></div>`)
expect(root.hoists.length).toBe(0)
expect(args[2]).toMatchObject([
{
type: NodeTypes.ELEMENT,
codegenNode: {
callee: CREATE_VNODE,
arguments: [
`"div"`,
createObjectMatcher({
ref: `[foo]`
}),
`null`,
genFlagText(PatchFlags.NEED_PATCH)
]
}
}
])
expect(generate(root).code).toMatchSnapshot()
})
</div>
expect(args[2]).toMatchObject([
{
type: NodeTypes.ELEMENT,
codegenNode: {
callee: WITH_DIRECTIVES,
arguments: [
{
callee: CREATE_VNODE,
arguments: [
`"div"`,
{
type: NodeTypes.SIMPLE_EXPRESSION,
content: `_hoisted_1`
},
`null`,
genFlagText(PatchFlags.NEED_PATCH)
]
},
{
type: NodeTypes.JS_ARRAY_EXPRESSION
}
]
}
}
])
expect(generate(root).code).toMatchSnapshot()
})