Skip to content

Commit d1f2915

Browse files
authored
fix(compiler-vapor): handle empty interpolation (#13592)
1 parent a5e106d commit d1f2915

File tree

3 files changed

+97
-9
lines changed

3 files changed

+97
-9
lines changed

packages/compiler-vapor/__tests__/transforms/__snapshots__/expression.spec.ts.snap

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,53 @@ export function render(_ctx) {
1111
}"
1212
`;
1313

14+
exports[`compiler: expression > empty interpolation 1`] = `
15+
"import { template as _template } from 'vue';
16+
const t0 = _template(" ")
17+
18+
export function render(_ctx) {
19+
const n0 = t0()
20+
return n0
21+
}"
22+
`;
23+
24+
exports[`compiler: expression > empty interpolation 2`] = `
25+
"import { template as _template } from 'vue';
26+
const t0 = _template(" ")
27+
28+
export function render(_ctx) {
29+
const n0 = t0()
30+
return n0
31+
}"
32+
`;
33+
34+
exports[`compiler: expression > empty interpolation 3`] = `
35+
"import { template as _template } from 'vue';
36+
const t0 = _template("<div></div>", true)
37+
38+
export function render(_ctx) {
39+
const n0 = t0()
40+
return n0
41+
}"
42+
`;
43+
44+
exports[`compiler: expression > empty interpolation 4`] = `
45+
"import { child as _child, toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue';
46+
const t0 = _template("<div> </div>", true)
47+
48+
export function render(_ctx) {
49+
const n1 = t0()
50+
const n0 = _child(n1)
51+
const x1 = _child(n1)
52+
_renderEffect(() => {
53+
const _foo = _ctx.foo
54+
_setText(n0, _toDisplayString(_foo))
55+
_setText(x1, _toDisplayString(_foo))
56+
})
57+
return n1
58+
}"
59+
`;
60+
1461
exports[`compiler: expression > props 1`] = `
1562
"import { toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue';
1663
const t0 = _template(" ")

packages/compiler-vapor/__tests__/transforms/expression.spec.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,25 @@ describe('compiler: expression', () => {
4747
expect(code).toMatchSnapshot()
4848
expect(code).contains(`_String(_foo.id++)`)
4949
})
50+
51+
test('empty interpolation', () => {
52+
const { code } = compileWithExpression(`{{}}`)
53+
const { code: code2 } = compileWithExpression(`{{ }}`)
54+
const { code: code3 } = compileWithExpression(`<div>{{ }}</div>`)
55+
const { code: code4 } = compileWithExpression(`<div>{{ foo }}{{ }}</div>`)
56+
57+
expect(code).toMatchSnapshot()
58+
expect(code).not.toContain(`_toDisplayString`)
59+
expect(code).not.toContain(`_setText`)
60+
61+
expect(code2).toMatchSnapshot()
62+
expect(code2).not.toContain(`_toDisplayString`)
63+
expect(code2).not.toContain(`_setText`)
64+
65+
expect(code3).toMatchSnapshot()
66+
expect(code3).not.toContain(`_toDisplayString`)
67+
expect(code3).not.toContain(`_setText`)
68+
69+
expect(code4).toMatchSnapshot()
70+
})
5071
})

packages/compiler-vapor/src/transforms/transformText.ts

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ export const transformText: NodeTransform = (node, context) => {
8787
}
8888

8989
function processInterpolation(context: TransformContext<InterpolationNode>) {
90-
const children = context.parent!.node.children
90+
const parentNode = context.parent!.node
91+
const children = parentNode.children
9192
const nexts = children.slice(context.index)
9293
const idx = nexts.findIndex(n => !isTextLike(n))
9394
const nodes = (idx > -1 ? nexts.slice(0, idx) : nexts) as Array<TextLike>
@@ -97,10 +98,18 @@ function processInterpolation(context: TransformContext<InterpolationNode>) {
9798
if (prev && prev.type === NodeTypes.TEXT) {
9899
nodes.unshift(prev)
99100
}
101+
const values = processTextLikeChildren(nodes, context)
102+
103+
if (values.length === 0 && parentNode.type !== NodeTypes.ROOT) {
104+
return
105+
}
100106

101107
context.template += ' '
102108
const id = context.reference()
103-
const values = nodes.map(node => createTextLikeExpression(node, context))
109+
110+
if (values.length === 0) {
111+
return
112+
}
104113

105114
const nonConstantExps = values.filter(v => !isConstantExpression(v))
106115
const isStatic =
@@ -129,8 +138,10 @@ function processTextContainer(
129138
children: TextLike[],
130139
context: TransformContext<ElementNode>,
131140
) {
132-
const values = children.map(child => createTextLikeExpression(child, context))
141+
const values = processTextLikeChildren(children, context)
142+
133143
const literals = values.map(getLiteralExpressionValue)
144+
134145
if (literals.every(l => l != null)) {
135146
context.childrenTemplate = literals.map(l => String(l))
136147
} else {
@@ -149,13 +160,22 @@ function processTextContainer(
149160
}
150161
}
151162

152-
function createTextLikeExpression(node: TextLike, context: TransformContext) {
153-
markNonTemplate(node, context)
154-
if (node.type === NodeTypes.TEXT) {
155-
return createSimpleExpression(node.content, true, node.loc)
156-
} else {
157-
return node.content as SimpleExpressionNode
163+
function processTextLikeChildren(nodes: TextLike[], context: TransformContext) {
164+
const exps: SimpleExpressionNode[] = []
165+
for (const node of nodes) {
166+
let exp: SimpleExpressionNode
167+
markNonTemplate(node, context)
168+
169+
if (node.type === NodeTypes.TEXT) {
170+
exp = createSimpleExpression(node.content, true, node.loc)
171+
} else {
172+
exp = node.content as SimpleExpressionNode
173+
}
174+
175+
if (exp.content) exps.push(exp)
158176
}
177+
178+
return exps
159179
}
160180

161181
function isTextLike(node: TemplateChildNode): node is TextLike {

0 commit comments

Comments
 (0)