Răsfoiți Sursa

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

close #6803
三咲智子 Kevin Deng 3 ani în urmă
părinte
comite
57c9013837

+ 4 - 4
packages/compiler-sfc/__tests__/__snapshots__/cssVars.spec.ts.snap

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

+ 14 - 6
packages/compiler-sfc/__tests__/cssVars.spec.ts

@@ -12,7 +12,7 @@ describe('CSS vars injection', () => {
     )
     expect(content).toMatch(`_useCssVars(_ctx => ({
   "${mockId}-color": (_ctx.color),
-  "${mockId}-font_size": (_ctx.font.size)
+  "${mockId}-font\\.size": (_ctx.font.size)
 })`)
     assertCode(content)
   })
@@ -79,6 +79,10 @@ describe('CSS vars injection', () => {
       source: `.foo {
         color: v-bind(color);
         font-size: v-bind('font.size');
+
+        font-weight: v-bind(_φ);
+        font-size: v-bind(1-字号);
+        font-family: v-bind(フォント);
       }`,
       filename: 'test.css',
       id: 'data-v-test'
@@ -86,7 +90,11 @@ describe('CSS vars injection', () => {
     expect(code).toMatchInlineSnapshot(`
       ".foo {
               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 => ({
   "${mockId}-foo": (_unref(foo)),
-  "${mockId}-foo____px_": (_unref(foo) + '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}-foo\\ \\+\\ \\'px\\'": (_unref(foo) + 'px'),
+  "${mockId}-\\(a\\ \\+\\ b\\)\\ \\/\\ 2\\ \\+\\ \\'px\\'": ((_unref(a) + _unref(b)) / 2 + 'px'),
+  "${mockId}-\\(\\(a\\ \\+\\ b\\)\\)\\ \\/\\ \\(2\\ \\*\\ a\\)": (((_unref(a) + _unref(b))) / (2 * _unref(a)))
+}))`)
       assertCode(content)
     })
 

+ 5 - 1
packages/compiler-sfc/src/cssVars.ts

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