A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/vuejs/core/commit/c85f1b5a132eb8ec25f71b250e25e65a5c20964f below:

nullish v-bind in style should not lead to unexpected … · vuejs/core@c85f1b5 · GitHub

File tree Expand file treeCollapse file tree 12 files changed

+136

-20

lines changed

Filter options

Expand file treeCollapse file tree 12 files changed

+136

-20

lines changed Original file line number Diff line number Diff line change

@@ -884,9 +884,9 @@ export default {

884 884 885 885

return (_ctx, _push, _parent, _attrs) => {

886 886

const _cssVars = { style: {

887 -

"--xxxxxxxx-count": (count.value),

888 -

"--xxxxxxxx-style\\\\.color": (style.color),

889 -

"--xxxxxxxx-height\\\\ \\\\+\\\\ \\\\\\"px\\\\\\"": (height.value + "px")

887 +

":--xxxxxxxx-count": (count.value),

888 +

":--xxxxxxxx-style\\\\.color": (style.color),

889 +

":--xxxxxxxx-height\\\\ \\\\+\\\\ \\\\\\"px\\\\\\"": (height.value + "px")

890 890

}}

891 891

_push(\`<!--[--><div\${

892 892

_ssrRenderAttrs(_cssVars)

Original file line number Diff line number Diff line change

@@ -652,10 +652,10 @@ describe('SFC compile <script setup>', () => {

652 652

expect(content).toMatch(`return (_ctx, _push`)

653 653

expect(content).toMatch(`ssrInterpolate`)

654 654

expect(content).not.toMatch(`useCssVars`)

655 -

expect(content).toMatch(`"--${mockId}-count": (count.value)`)

656 -

expect(content).toMatch(`"--${mockId}-style\\\\.color": (style.color)`)

655 +

expect(content).toMatch(`":--${mockId}-count": (count.value)`)

656 +

expect(content).toMatch(`":--${mockId}-style\\\\.color": (style.color)`)

657 657

expect(content).toMatch(

658 -

`"--${mockId}-height\\\\ \\\\+\\\\ \\\\\\"px\\\\\\"": (height.value + "px")`,

658 +

`":--${mockId}-height\\\\ \\\\+\\\\ \\\\\\"px\\\\\\"": (height.value + "px")`,

659 659

)

660 660

assertCode(content)

661 661

})

Original file line number Diff line number Diff line change

@@ -23,7 +23,12 @@ export function genCssVarsFromList(

23 23

return `{\n ${vars

24 24

.map(

25 25

key =>

26 -

`"${isSSR ? `--` : ``}${genVarName(id, key, isProd, isSSR)}": (${key})`,

26 +

// The `:` prefix here is used in `ssrRenderStyle` to distinguish whether

27 +

// a custom property comes from `ssrCssVars`. If it does, we need to reset

28 +

// its value to `initial` on the component instance to avoid unintentionally

29 +

// inheriting the same property value from a different instance of the same

30 +

// component in the outer scope.

31 +

`"${isSSR ? `:--` : ``}${genVarName(id, key, isProd, isSSR)}": (${key})`,

27 32

)

28 33

.join(',\n ')}\n}`

29 34

}

Original file line number Diff line number Diff line change

@@ -585,13 +585,13 @@ export interface ComponentInternalInstance {

585 585

* For updating css vars on contained teleports

586 586

* @internal

587 587

*/

588 -

ut?: (vars?: Record<string, string>) => void

588 +

ut?: (vars?: Record<string, unknown>) => void

589 589 590 590

/**

591 591

* dev only. For style v-bind hydration mismatch checks

592 592

* @internal

593 593

*/

594 -

getCssVars?: () => Record<string, string>

594 +

getCssVars?: () => Record<string, unknown>

595 595 596 596

/**

597 597

* v2 compat only, for caching mutated $options

Original file line number Diff line number Diff line change

@@ -28,6 +28,7 @@ import {

28 28

isReservedProp,

29 29

isString,

30 30

normalizeClass,

31 +

normalizeCssVarValue,

31 32

normalizeStyle,

32 33

stringifyStyle,

33 34

} from '@vue/shared'

@@ -945,10 +946,8 @@ function resolveCssVars(

945 946

) {

946 947

const cssVars = instance.getCssVars()

947 948

for (const key in cssVars) {

948 -

expectedMap.set(

949 -

`--${getEscapedCssVarName(key, false)}`,

950 -

String(cssVars[key]),

951 -

)

949 +

const value = normalizeCssVarValue(cssVars[key])

950 +

expectedMap.set(`--${getEscapedCssVarName(key, false)}`, value)

952 951

}

953 952

}

954 953

if (vnode === root && instance.parent) {

Original file line number Diff line number Diff line change

@@ -465,4 +465,27 @@ describe('useCssVars', () => {

465 465

render(h(App), root)

466 466

expect(colorInOnMount).toBe(`red`)

467 467

})

468 + 469 +

test('should set vars as `initial` for nullish values', async () => {

470 +

// `getPropertyValue` cannot reflect the real value for white spaces and JSDOM also

471 +

// doesn't 100% reflect the real behavior of browsers, so we only keep the test for

472 +

// `initial` value here.

473 +

// The value normalization is tested in packages/shared/__tests__/cssVars.spec.ts.

474 +

const state = reactive<Record<string, unknown>>({

475 +

foo: undefined,

476 +

bar: null,

477 +

})

478 +

const root = document.createElement('div')

479 +

const App = {

480 +

setup() {

481 +

useCssVars(() => state)

482 +

return () => h('div')

483 +

},

484 +

}

485 +

render(h(App), root)

486 +

await nextTick()

487 +

const style = (root.children[0] as HTMLElement).style

488 +

expect(style.getPropertyValue('--foo')).toBe('initial')

489 +

expect(style.getPropertyValue('--bar')).toBe('initial')

490 +

})

468 491

})

Original file line number Diff line number Diff line change

@@ -10,14 +10,16 @@ import {

10 10

warn,

11 11

watch,

12 12

} from '@vue/runtime-core'

13 -

import { NOOP, ShapeFlags } from '@vue/shared'

13 +

import { NOOP, ShapeFlags, normalizeCssVarValue } from '@vue/shared'

14 14 15 15

export const CSS_VAR_TEXT: unique symbol = Symbol(__DEV__ ? 'CSS_VAR_TEXT' : '')

16 16

/**

17 17

* Runtime helper for SFC's CSS variable injection feature.

18 18

* @private

19 19

*/

20 -

export function useCssVars(getter: (ctx: any) => Record<string, string>): void {

20 +

export function useCssVars(

21 +

getter: (ctx: any) => Record<string, unknown>,

22 +

): void {

21 23

if (!__BROWSER__ && !__TEST__) return

22 24 23 25

const instance = getCurrentInstance()

@@ -64,7 +66,7 @@ export function useCssVars(getter: (ctx: any) => Record<string, string>): void {

64 66

})

65 67

}

66 68 67 -

function setVarsOnVNode(vnode: VNode, vars: Record<string, string>) {

69 +

function setVarsOnVNode(vnode: VNode, vars: Record<string, unknown>) {

68 70

if (__FEATURE_SUSPENSE__ && vnode.shapeFlag & ShapeFlags.SUSPENSE) {

69 71

const suspense = vnode.suspense!

70 72

vnode = suspense.activeBranch!

@@ -94,13 +96,14 @@ function setVarsOnVNode(vnode: VNode, vars: Record<string, string>) {

94 96

}

95 97

}

96 98 97 -

function setVarsOnNode(el: Node, vars: Record<string, string>) {

99 +

function setVarsOnNode(el: Node, vars: Record<string, unknown>) {

98 100

if (el.nodeType === 1) {

99 101

const style = (el as HTMLElement).style

100 102

let cssText = ''

101 103

for (const key in vars) {

102 -

style.setProperty(`--${key}`, vars[key])

103 -

cssText += `--${key}: ${vars[key]};`

104 +

const value = normalizeCssVarValue(vars[key])

105 +

style.setProperty(`--${key}`, value)

106 +

cssText += `--${key}: ${value};`

104 107

}

105 108

;(style as any)[CSS_VAR_TEXT] = cssText

106 109

}

Original file line number Diff line number Diff line change

@@ -203,4 +203,19 @@ describe('ssr: renderStyle', () => {

203 203

}),

204 204

).toBe(`color:&quot;&gt;&lt;script;`)

205 205

})

206 + 207 +

test('useCssVars handling', () => {

208 +

expect(

209 +

ssrRenderStyle({

210 +

fontSize: null,

211 +

':--v1': undefined,

212 +

':--v2': null,

213 +

':--v3': '',

214 +

':--v4': ' ',

215 +

':--v5': 'foo',

216 +

':--v6': 0,

217 +

'--foo': 1,

218 +

}),

219 +

).toBe(`--v1:initial;--v2:initial;--v3: ;--v4: ;--v5:foo;--v6:0;--foo:1;`)

220 +

})

206 221

})

Original file line number Diff line number Diff line change

@@ -1,5 +1,7 @@

1 1

import {

2 2

escapeHtml,

3 +

isArray,

4 +

isObject,

3 5

isRenderableAttrValue,

4 6

isSVGTag,

5 7

stringifyStyle,

@@ -12,6 +14,7 @@ import {

12 14

isString,

13 15

makeMap,

14 16

normalizeClass,

17 +

normalizeCssVarValue,

15 18

normalizeStyle,

16 19

propsToAttrMap,

17 20

} from '@vue/shared'

@@ -93,6 +96,22 @@ export function ssrRenderStyle(raw: unknown): string {

93 96

if (isString(raw)) {

94 97

return escapeHtml(raw)

95 98

}

96 -

const styles = normalizeStyle(raw)

99 +

const styles = normalizeStyle(ssrResetCssVars(raw))

97 100

return escapeHtml(stringifyStyle(styles))

98 101

}

102 + 103 +

function ssrResetCssVars(raw: unknown) {

104 +

if (!isArray(raw) && isObject(raw)) {

105 +

const res: Record<string, unknown> = {}

106 +

for (const key in raw) {

107 +

// `:` prefixed keys are coming from `ssrCssVars`

108 +

if (key.startsWith(':--')) {

109 +

res[key.slice(1)] = normalizeCssVarValue(raw[key])

110 +

} else {

111 +

res[key] = raw[key]

112 +

}

113 +

}

114 +

return res

115 +

}

116 +

return raw

117 +

}

Original file line number Diff line number Diff line change

@@ -0,0 +1,27 @@

1 +

import { normalizeCssVarValue } from '../src'

2 + 3 +

describe('utils/cssVars', () => {

4 +

test('should normalize css binding values correctly', () => {

5 +

expect(normalizeCssVarValue(null)).toBe('initial')

6 +

expect(normalizeCssVarValue(undefined)).toBe('initial')

7 +

expect(normalizeCssVarValue('')).toBe(' ')

8 +

expect(normalizeCssVarValue(' ')).toBe(' ')

9 +

expect(normalizeCssVarValue('foo')).toBe('foo')

10 +

expect(normalizeCssVarValue(0)).toBe('0')

11 +

})

12 + 13 +

test('should warn on invalid css binding values', () => {

14 +

const warning =

15 +

'[Vue warn] Invalid value used for CSS binding. Expected a string or a finite number but received:'

16 +

expect(normalizeCssVarValue(NaN)).toBe('NaN')

17 +

expect(warning).toHaveBeenWarnedTimes(1)

18 +

expect(normalizeCssVarValue(Infinity)).toBe('Infinity')

19 +

expect(warning).toHaveBeenWarnedTimes(2)

20 +

expect(normalizeCssVarValue(-Infinity)).toBe('-Infinity')

21 +

expect(warning).toHaveBeenWarnedTimes(3)

22 +

expect(normalizeCssVarValue({})).toBe('[object Object]')

23 +

expect(warning).toHaveBeenWarnedTimes(4)

24 +

expect(normalizeCssVarValue([])).toBe('')

25 +

expect(warning).toHaveBeenWarnedTimes(5)

26 +

})

27 +

})

You can’t perform that action at this time.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4