fix(compiler-sfc): only escape parsing-breaking characters in v-bind css var names (#6816)

close #6803
This commit is contained in:
三咲智子 Kevin Deng 2022-11-09 11:30:05 +08:00 committed by GitHub
parent 2c27556fe5
commit 57c9013837
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 23 additions and 11 deletions

View File

@ -75,9 +75,9 @@ export default {
_useCssVars(_ctx => ({ _useCssVars(_ctx => ({
\\"xxxxxxxx-foo\\": (_unref(foo)), \\"xxxxxxxx-foo\\": (_unref(foo)),
\\"xxxxxxxx-foo____px_\\": (_unref(foo) + 'px'), \\"xxxxxxxx-foo\\\\ \\\\+\\\\ \\\\'px\\\\'\\": (_unref(foo) + 'px'),
\\"xxxxxxxx-_a___b____2____px_\\": ((_unref(a) + _unref(b)) / 2 + 'px'), \\"xxxxxxxx-\\\\(a\\\\ \\\\+\\\\ b\\\\)\\\\ \\\\/\\\\ 2\\\\ \\\\+\\\\ \\\\'px\\\\'\\": ((_unref(a) + _unref(b)) / 2 + 'px'),
\\"xxxxxxxx-__a___b______2___a_\\": (((_unref(a) + _unref(b))) / (2 * _unref(a))) \\"xxxxxxxx-\\\\(\\\\(a\\\\ \\\\+\\\\ b\\\\)\\\\)\\\\ \\\\/\\\\ \\\\(2\\\\ \\\\*\\\\ a\\\\)\\": (((_unref(a) + _unref(b))) / (2 * _unref(a)))
})) }))
let a = 100 let a = 100
@ -133,7 +133,7 @@ import { useCssVars as _useCssVars } from 'vue'
const __injectCSSVars__ = () => { const __injectCSSVars__ = () => {
_useCssVars(_ctx => ({ _useCssVars(_ctx => ({
\\"xxxxxxxx-color\\": (_ctx.color), \\"xxxxxxxx-color\\": (_ctx.color),
\\"xxxxxxxx-font_size\\": (_ctx.font.size) \\"xxxxxxxx-font\\\\.size\\": (_ctx.font.size)
}))} }))}
const __setup__ = __default__.setup const __setup__ = __default__.setup
__default__.setup = __setup__ __default__.setup = __setup__

View File

@ -12,7 +12,7 @@ describe('CSS vars injection', () => {
) )
expect(content).toMatch(`_useCssVars(_ctx => ({ expect(content).toMatch(`_useCssVars(_ctx => ({
"${mockId}-color": (_ctx.color), "${mockId}-color": (_ctx.color),
"${mockId}-font_size": (_ctx.font.size) "${mockId}-font\\.size": (_ctx.font.size)
})`) })`)
assertCode(content) assertCode(content)
}) })
@ -79,6 +79,10 @@ describe('CSS vars injection', () => {
source: `.foo { source: `.foo {
color: v-bind(color); color: v-bind(color);
font-size: v-bind('font.size'); font-size: v-bind('font.size');
font-weight: v-bind();
font-size: v-bind(1-);
font-family: v-bind();
}`, }`,
filename: 'test.css', filename: 'test.css',
id: 'data-v-test' id: 'data-v-test'
@ -86,7 +90,11 @@ describe('CSS vars injection', () => {
expect(code).toMatchInlineSnapshot(` expect(code).toMatchInlineSnapshot(`
".foo { ".foo {
color: var(--test-color); color: var(--test-color);
font-size: var(--test-font_size); font-size: var(--test-font\\\\.size);
font-weight: var(--test-);
font-size: var(--test-1-);
font-family: var(--test-);
}" }"
`) `)
}) })
@ -225,10 +233,10 @@ describe('CSS vars injection', () => {
) )
expect(content).toMatch(`_useCssVars(_ctx => ({ expect(content).toMatch(`_useCssVars(_ctx => ({
"${mockId}-foo": (_unref(foo)), "${mockId}-foo": (_unref(foo)),
"${mockId}-foo____px_": (_unref(foo) + 'px'), "${mockId}-foo\\ \\+\\ \\'px\\'": (_unref(foo) + 'px'),
"${mockId}-_a___b____2____px_": ((_unref(a) + _unref(b)) / 2 + 'px'), "${mockId}-\\(a\\ \\+\\ b\\)\\ \\/\\ 2\\ \\+\\ \\'px\\'": ((_unref(a) + _unref(b)) / 2 + 'px'),
"${mockId}-__a___b______2___a_": (((_unref(a) + _unref(b))) / (2 * _unref(a))) "${mockId}-\\(\\(a\\ \\+\\ b\\)\\)\\ \\/\\ \\(2\\ \\*\\ a\\)": (((_unref(a) + _unref(b))) / (2 * _unref(a)))
})`) }))`)
assertCode(content) assertCode(content)
}) })

View File

@ -30,7 +30,11 @@ function genVarName(id: string, raw: string, isProd: boolean): string {
if (isProd) { if (isProd) {
return hash(id + raw) return hash(id + raw)
} else { } else {
return `${id}-${raw.replace(/([^\w-])/g, '_')}` // escape ASCII Punctuation & Symbols
return `${id}-${raw.replace(
/[ !"#$%&'()*+,./:;<=>?@[\\\]^`{|}~]/g,
s => `\\${s}`
)}`
} }
} }