wip: account for text call nodes in stringify chunks
This commit is contained in:
parent
b26976b6d8
commit
59d50dad9c
@ -13,7 +13,8 @@ import {
|
||||
ExpressionNode,
|
||||
ElementTypes,
|
||||
PlainElementNode,
|
||||
JSChildNode
|
||||
JSChildNode,
|
||||
TextCallNode
|
||||
} from '@vue/compiler-core'
|
||||
import {
|
||||
isVoidTag,
|
||||
@ -32,13 +33,15 @@ export const enum StringifyThresholds {
|
||||
NODE_COUNT = 20
|
||||
}
|
||||
|
||||
type StringiableNode = PlainElementNode | TextCallNode
|
||||
|
||||
// Turn eligible hoisted static trees into stringied static nodes, e.g.
|
||||
// const _hoisted_1 = createStaticVNode(`<div class="foo">bar</div>`)
|
||||
// This is only performed in non-in-browser compilations.
|
||||
export const stringifyStatic: HoistTransform = (children, context) => {
|
||||
let nc = 0 // current node count
|
||||
let ec = 0 // current element with binding count
|
||||
const currentChunk: PlainElementNode[] = []
|
||||
const currentChunk: StringiableNode[] = []
|
||||
|
||||
const stringifyCurrentChunk = (currentIndex: number): number => {
|
||||
if (
|
||||
@ -48,7 +51,7 @@ export const stringifyStatic: HoistTransform = (children, context) => {
|
||||
// combine all currently eligible nodes into a single static vnode call
|
||||
const staticCall = createCallExpression(context.helper(CREATE_STATIC), [
|
||||
JSON.stringify(
|
||||
currentChunk.map(node => stringifyElement(node, context)).join('')
|
||||
currentChunk.map(node => stringifyNode(node, context)).join('')
|
||||
),
|
||||
// the 2nd argument indicates the number of DOM nodes this static vnode
|
||||
// will insert / hydrate
|
||||
@ -77,8 +80,8 @@ export const stringifyStatic: HoistTransform = (children, context) => {
|
||||
const child = children[i]
|
||||
const hoisted = getHoistedNode(child)
|
||||
if (hoisted) {
|
||||
// presence of hoisted means child must be a plain element Node
|
||||
const node = child as PlainElementNode
|
||||
// presence of hoisted means child must be a stringifiable node
|
||||
const node = child as StringiableNode
|
||||
const result = analyzeNode(node)
|
||||
if (result) {
|
||||
// node is stringifiable, record state
|
||||
@ -102,8 +105,8 @@ export const stringifyStatic: HoistTransform = (children, context) => {
|
||||
}
|
||||
|
||||
const getHoistedNode = (node: TemplateChildNode) =>
|
||||
node.type === NodeTypes.ELEMENT &&
|
||||
node.tagType === ElementTypes.ELEMENT &&
|
||||
((node.type === NodeTypes.ELEMENT && node.tagType === ElementTypes.ELEMENT) ||
|
||||
node.type == NodeTypes.TEXT_CALL) &&
|
||||
node.codegenNode &&
|
||||
node.codegenNode.type === NodeTypes.SIMPLE_EXPRESSION &&
|
||||
node.codegenNode.hoisted
|
||||
@ -114,7 +117,7 @@ const isStringifiableAttr = (name: string) => {
|
||||
}
|
||||
|
||||
const replaceHoist = (
|
||||
node: PlainElementNode,
|
||||
node: StringiableNode,
|
||||
replacement: JSChildNode | null,
|
||||
context: TransformContext
|
||||
) => {
|
||||
@ -125,11 +128,15 @@ const replaceHoist = (
|
||||
/**
|
||||
* for a hoisted node, analyze it and return:
|
||||
* - false: bailed (contains runtime constant)
|
||||
* - [x, y] where
|
||||
* - x is the number of nodes inside
|
||||
* - y is the number of element with bindings inside
|
||||
* - [nc, ec] where
|
||||
* - nc is the number of nodes inside
|
||||
* - ec is the number of element with bindings inside
|
||||
*/
|
||||
function analyzeNode(node: PlainElementNode): [number, number] | false {
|
||||
function analyzeNode(node: StringiableNode): [number, number] | false {
|
||||
if (node.type === NodeTypes.TEXT_CALL) {
|
||||
return [1, 0]
|
||||
}
|
||||
|
||||
let nc = 1 // node count
|
||||
let ec = node.props.length > 0 ? 1 : 0 // element w/ binding count
|
||||
let bailed = false
|
||||
@ -196,6 +203,35 @@ function analyzeNode(node: PlainElementNode): [number, number] | false {
|
||||
return walk(node) ? [nc, ec] : false
|
||||
}
|
||||
|
||||
function stringifyNode(
|
||||
node: string | TemplateChildNode,
|
||||
context: TransformContext
|
||||
): string {
|
||||
if (isString(node)) {
|
||||
return node
|
||||
}
|
||||
if (isSymbol(node)) {
|
||||
return ``
|
||||
}
|
||||
switch (node.type) {
|
||||
case NodeTypes.ELEMENT:
|
||||
return stringifyElement(node, context)
|
||||
case NodeTypes.TEXT:
|
||||
return escapeHtml(node.content)
|
||||
case NodeTypes.COMMENT:
|
||||
return `<!--${escapeHtml(node.content)}-->`
|
||||
case NodeTypes.INTERPOLATION:
|
||||
return escapeHtml(toDisplayString(evaluateConstant(node.content)))
|
||||
case NodeTypes.COMPOUND_EXPRESSION:
|
||||
return escapeHtml(evaluateConstant(node))
|
||||
case NodeTypes.TEXT_CALL:
|
||||
return stringifyNode(node.content, context)
|
||||
default:
|
||||
// static trees will not contain if/for nodes
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
function stringifyElement(
|
||||
node: ElementNode,
|
||||
context: TransformContext
|
||||
@ -235,35 +271,6 @@ function stringifyElement(
|
||||
return res
|
||||
}
|
||||
|
||||
function stringifyNode(
|
||||
node: string | TemplateChildNode,
|
||||
context: TransformContext
|
||||
): string {
|
||||
if (isString(node)) {
|
||||
return node
|
||||
}
|
||||
if (isSymbol(node)) {
|
||||
return ``
|
||||
}
|
||||
switch (node.type) {
|
||||
case NodeTypes.ELEMENT:
|
||||
return stringifyElement(node, context)
|
||||
case NodeTypes.TEXT:
|
||||
return escapeHtml(node.content)
|
||||
case NodeTypes.COMMENT:
|
||||
return `<!--${escapeHtml(node.content)}-->`
|
||||
case NodeTypes.INTERPOLATION:
|
||||
return escapeHtml(toDisplayString(evaluateConstant(node.content)))
|
||||
case NodeTypes.COMPOUND_EXPRESSION:
|
||||
return escapeHtml(evaluateConstant(node))
|
||||
case NodeTypes.TEXT_CALL:
|
||||
return stringifyNode(node.content, context)
|
||||
default:
|
||||
// static trees will not contain if/for nodes
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
// __UNSAFE__
|
||||
// Reason: eval.
|
||||
// It's technically safe to eval because only constant expressions are possible
|
||||
|
Loading…
Reference in New Issue
Block a user