mirror of https://github.com/vuejs/core.git
fix(hydration): escape css var name to avoid mismatch (#11739)
close #11735
This commit is contained in:
parent
cb843e0be3
commit
ca12e776bc
|
@ -121,15 +121,3 @@ export const propNameEscapeSymbolsRE: RegExp =
|
||||||
export function getEscapedPropName(key: string): string {
|
export function getEscapedPropName(key: string): string {
|
||||||
return propNameEscapeSymbolsRE.test(key) ? JSON.stringify(key) : key
|
return propNameEscapeSymbolsRE.test(key) ? JSON.stringify(key) : key
|
||||||
}
|
}
|
||||||
|
|
||||||
export const cssVarNameEscapeSymbolsRE: RegExp =
|
|
||||||
/[ !"#$%&'()*+,./:;<=>?@[\\\]^`{|}~]/g
|
|
||||||
|
|
||||||
export function getEscapedCssVarName(
|
|
||||||
key: string,
|
|
||||||
doubleEscape: boolean,
|
|
||||||
): string {
|
|
||||||
return key.replace(cssVarNameEscapeSymbolsRE, s =>
|
|
||||||
doubleEscape ? `\\\\${s}` : `\\${s}`,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
|
@ -8,9 +8,9 @@ import {
|
||||||
processExpression,
|
processExpression,
|
||||||
} from '@vue/compiler-dom'
|
} from '@vue/compiler-dom'
|
||||||
import type { SFCDescriptor } from '../parse'
|
import type { SFCDescriptor } from '../parse'
|
||||||
import { getEscapedCssVarName } from '../script/utils'
|
|
||||||
import type { PluginCreator } from 'postcss'
|
import type { PluginCreator } from 'postcss'
|
||||||
import hash from 'hash-sum'
|
import hash from 'hash-sum'
|
||||||
|
import { getEscapedCssVarName } from '@vue/shared'
|
||||||
|
|
||||||
export const CSS_VARS_HELPER = `useCssVars`
|
export const CSS_VARS_HELPER = `useCssVars`
|
||||||
|
|
||||||
|
|
|
@ -2021,6 +2021,26 @@ describe('SSR hydration', () => {
|
||||||
app.mount(container)
|
app.mount(container)
|
||||||
expect(`Hydration style mismatch`).not.toHaveBeenWarned()
|
expect(`Hydration style mismatch`).not.toHaveBeenWarned()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('escape css var name', () => {
|
||||||
|
const container = document.createElement('div')
|
||||||
|
container.innerHTML = `<div style="padding: 4px;--foo\\.bar:red;"></div>`
|
||||||
|
const app = createSSRApp({
|
||||||
|
setup() {
|
||||||
|
useCssVars(() => ({
|
||||||
|
'foo.bar': 'red',
|
||||||
|
}))
|
||||||
|
return () => h(Child)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
const Child = {
|
||||||
|
setup() {
|
||||||
|
return () => h('div', { style: 'padding: 4px' })
|
||||||
|
},
|
||||||
|
}
|
||||||
|
app.mount(container)
|
||||||
|
expect(`Hydration style mismatch`).not.toHaveBeenWarned()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('data-allow-mismatch', () => {
|
describe('data-allow-mismatch', () => {
|
||||||
|
|
|
@ -18,6 +18,7 @@ import {
|
||||||
PatchFlags,
|
PatchFlags,
|
||||||
ShapeFlags,
|
ShapeFlags,
|
||||||
def,
|
def,
|
||||||
|
getEscapedCssVarName,
|
||||||
includeBooleanAttr,
|
includeBooleanAttr,
|
||||||
isBooleanAttr,
|
isBooleanAttr,
|
||||||
isKnownHtmlAttr,
|
isKnownHtmlAttr,
|
||||||
|
@ -915,7 +916,10 @@ function resolveCssVars(
|
||||||
) {
|
) {
|
||||||
const cssVars = instance.getCssVars()
|
const cssVars = instance.getCssVars()
|
||||||
for (const key in cssVars) {
|
for (const key in cssVars) {
|
||||||
expectedMap.set(`--${key}`, String(cssVars[key]))
|
expectedMap.set(
|
||||||
|
`--${getEscapedCssVarName(key, false)}`,
|
||||||
|
String(cssVars[key]),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (vnode === root && instance.parent) {
|
if (vnode === root && instance.parent) {
|
||||||
|
|
|
@ -50,3 +50,15 @@ const commentStripRE = /^-?>|<!--|-->|--!>|<!-$/g
|
||||||
export function escapeHtmlComment(src: string): string {
|
export function escapeHtmlComment(src: string): string {
|
||||||
return src.replace(commentStripRE, '')
|
return src.replace(commentStripRE, '')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const cssVarNameEscapeSymbolsRE: RegExp =
|
||||||
|
/[ !"#$%&'()*+,./:;<=>?@[\\\]^`{|}~]/g
|
||||||
|
|
||||||
|
export function getEscapedCssVarName(
|
||||||
|
key: string,
|
||||||
|
doubleEscape: boolean,
|
||||||
|
): string {
|
||||||
|
return key.replace(cssVarNameEscapeSymbolsRE, s =>
|
||||||
|
doubleEscape ? `\\\\${s}` : `\\${s}`,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue