"const _Vue = Vue
const { createVNode: _createVNode } = _Vue
-const _hoisted_1 = _createVNode(\\"span\\", null, [
- \\"foo \\",
- _toDisplayString(1),
- \\" \\",
- _toDisplayString(true)
-])
+const _hoisted_1 = _createVNode(\\"span\\", null, \\"foo \\" + _toDisplayString(1) + \\" \\" + _toDisplayString(true))
return function render(_ctx, _cache) {
with (this) {
return function render(_ctx, _cache) {
with (this) {
- const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue
+ const { toDisplayString: _toDisplayString, createTextVNode: _createTextVNode, resolveComponent: _resolveComponent, createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue
const _component_Comp = _resolveComponent(\\"Comp\\")
return (_openBlock(), _createBlock(_component_Comp, null, {
- default: ({ foo }) => [_toDisplayString(_ctx.foo)],
+ default: ({ foo }) => [
+ _createTextVNode(_toDisplayString(_ctx.foo), 1 /* TEXT */)
+ ],
_compiled: true
}))
}
CREATE_VNODE,
WITH_DIRECTIVES,
FRAGMENT,
- RENDER_LIST
+ RENDER_LIST,
+ CREATE_TEXT
} from '../../src/runtimeHelpers'
import { transformElement } from '../../src/transforms/transformElement'
import { transformExpression } from '../../src/transforms/transformExpression'
import { transformOn } from '../../src/transforms/vOn'
import { createObjectMatcher, genFlagText } from '../testUtils'
import { PatchFlags } from '@vue/shared'
+import { transformText } from '../../src/transforms/transformText'
function transformWithHoist(template: string, options: CompilerOptions = {}) {
const ast = parse(template)
transformIf,
transformFor,
...(options.prefixIdentifiers ? [transformExpression] : []),
- transformElement
+ transformElement,
+ transformText
],
directiveTransforms: {
on: transformOn,
expect(generate(root).code).toMatchSnapshot()
})
+ test('hoist static text node between elements', () => {
+ const { root } = transformWithHoist(`<div>static<div>static</div></div>`)
+ expect(root.hoists).toMatchObject([
+ {
+ callee: CREATE_TEXT,
+ arguments: [
+ {
+ type: NodeTypes.TEXT,
+ content: `static`
+ }
+ ]
+ },
+ {
+ callee: CREATE_VNODE
+ }
+ ])
+ })
+
describe('prefixIdentifiers', () => {
test('hoist nested static tree with static interpolation', () => {
const { root, args } = transformWithHoist(
arguments: [
`"span"`,
`null`,
- [
- {
- type: NodeTypes.TEXT,
- content: `foo `
- },
- {
- type: NodeTypes.INTERPOLATION,
- content: {
- content: `1`,
- isStatic: false,
- isConstant: true
- }
- },
- {
- type: NodeTypes.TEXT,
- content: ` `
- },
- {
- type: NodeTypes.INTERPOLATION,
- content: {
- content: `true`,
- isStatic: false,
- isConstant: true
- }
- }
- ]
+ {
+ type: NodeTypes.COMPOUND_EXPRESSION
+ }
]
}
])
export interface TextCallNode extends Node {
type: NodeTypes.TEXT_CALL
content: TextNode | InterpolationNode | CompoundExpressionNode
- codegenNode: CallExpression
+ codegenNode: CallExpression | SimpleExpressionNode // when hoisted
}
// JS Node Types ---------------------------------------------------------------
root.children,
context,
new Map(),
+ // Root node is unfortuantely non-hoistable due to potential parent
+ // fallthrough attributes.
isSingleElementRoot(root, root.children[0])
)
}
// Do not hoist v-if single child because it has to be a block
walk(branchChildren, context, resultCache, branchChildren.length === 1)
}
+ } else if (
+ child.type === NodeTypes.TEXT_CALL &&
+ isStaticNode(child.content, resultCache)
+ ) {
+ child.codegenNode = context.hoist(child.codegenNode)
}
}
}
template: string,
options: CompilerOptions = {}
): CodegenResult {
- return baseCompile(template, {
+ const result = baseCompile(template, {
...parserOptions,
...options,
nodeTransforms: [...DOMNodeTransforms, ...(options.nodeTransforms || [])],
...(options.directiveTransforms || {})
}
})
+ // debugger
+ return result
}
export function parse(template: string, options: ParserOptions = {}): RootNode {