Skip to content

Commit

Permalink
fix(cssVars): cssVar names should be double-escaped when generating c…
Browse files Browse the repository at this point in the history
…ode for ssr (#8824)

close #7823
  • Loading branch information
edison1105 authored Nov 30, 2023
1 parent 6fcec3b commit 5199a12
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
3 changes: 3 additions & 0 deletions packages/compiler-sfc/__tests__/compileScript.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -778,13 +778,15 @@ describe('SFC compile <script setup>', () => {
<script setup>
import { ref } from 'vue'
const count = ref(0)
const style = { color: 'red' }
</script>
<template>
<div>{{ count }}</div>
<div>static</div>
</template>
<style>
div { color: v-bind(count) }
span { color: v-bind(style.color) }
</style>
`,
{
Expand All @@ -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)
})

Expand Down
6 changes: 4 additions & 2 deletions packages/compiler-sfc/src/script/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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}`
)
}
14 changes: 11 additions & 3 deletions packages/compiler-sfc/src/style/cssVars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)}`
}
}

Expand Down

0 comments on commit 5199a12

Please sign in to comment.