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