]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(cssVars): cssVar names should be double-escaped when generating code for ssr...
authoredison <daiwei521@126.com>
Thu, 30 Nov 2023 10:35:20 +0000 (18:35 +0800)
committerGitHub <noreply@github.com>
Thu, 30 Nov 2023 10:35:20 +0000 (18:35 +0800)
close #7823

packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap
packages/compiler-sfc/__tests__/compileScript.spec.ts
packages/compiler-sfc/src/script/utils.ts
packages/compiler-sfc/src/style/cssVars.ts

index 073874363b8033744b9d7507c7ed7ef8ad6e4e9e..b0076294efea13ff6c7dff058f25038565c6b1df 100644 (file)
@@ -1003,10 +1003,12 @@ export default {
   setup(__props) {
 
         const count = ref(0)
+        const style = { color: 'red' }
         
 return (_ctx, _push, _parent, _attrs) => {
   const _cssVars = { style: {
-  \\"--xxxxxxxx-count\\": (count.value)
+  \\"--xxxxxxxx-count\\": (count.value),
+  \\"--xxxxxxxx-style\\\\\\\\.color\\": (style.color)
 }}
   _push(\`<!--[--><div\${
     _ssrRenderAttrs(_cssVars)
index 312e93fccbedd45b096ddfe44a31faca66e02e56..d046fbd9d34df4a9a6fb205cac4cc839d2c250a3 100644 (file)
@@ -778,6 +778,7 @@ describe('SFC compile <script setup>', () => {
         <script setup>
         import { ref } from 'vue'
         const count = ref(0)
+        const style = { color: 'red' }
         </script>
         <template>
           <div>{{ count }}</div>
@@ -785,6 +786,7 @@ describe('SFC compile <script setup>', () => {
         </template>
         <style>
         div { color: v-bind(count) }
+        span { color: v-bind(style.color) }
         </style>
         `,
         {
@@ -799,6 +801,7 @@ describe('SFC compile <script setup>', () => {
       expect(content).toMatch(`ssrInterpolate`)
       expect(content).not.toMatch(`useCssVars`)
       expect(content).toMatch(`"--${mockId}-count": (count.value)`)
+      expect(content).toMatch(`"--${mockId}-style\\\\.color": (style.color)`)
       assertCode(content)
     })
 
index 3cbc270269a8fd204e3a992d1fa40c635d8435f8..bc621d2584062da7aa39a036d3042b0e93316e3f 100644 (file)
@@ -121,6 +121,8 @@ export function getEscapedPropName(key: string) {
 
 export const cssVarNameEscapeSymbolsRE = /[ !"#$%&'()*+,./:;<=>?@[\\\]^`{|}~]/g
 
-export function getEscapedCssVarName(key: string) {
-  return key.replace(cssVarNameEscapeSymbolsRE, s => `\\${s}`)
+export function getEscapedCssVarName(key: string, doubleEscape: boolean) {
+  return key.replace(cssVarNameEscapeSymbolsRE, s =>
+    doubleEscape ? `\\\\${s}` : `\\${s}`
+  )
 }
index 9fe727bc5dcbed537316c2922d8744491c3a4045..cb5274bc287a6f7a578af7a493aa1d92568ff6dd 100644 (file)
@@ -22,17 +22,25 @@ export function genCssVarsFromList(
 ): string {
   return `{\n  ${vars
     .map(
-      key => `"${isSSR ? `--` : ``}${genVarName(id, key, isProd)}": (${key})`
+      key =>
+        `"${isSSR ? `--` : ``}${genVarName(id, key, isProd, isSSR)}": (${key})`
     )
     .join(',\n  ')}\n}`
 }
 
-function genVarName(id: string, raw: string, isProd: boolean): string {
+function genVarName(
+  id: string,
+  raw: string,
+  isProd: boolean,
+  isSSR = false
+): string {
   if (isProd) {
     return hash(id + raw)
   } else {
     // escape ASCII Punctuation & Symbols
-    return `${id}-${getEscapedCssVarName(raw)}`
+    // #7823 need to double-escape in SSR because the attributes are rendered
+    // into an HTML string
+    return `${id}-${getEscapedCssVarName(raw, isSSR)}`
   }
 }