refactor: reuse parseStringStyle across compiler and runtime
This commit is contained in:
parent
2d9f136077
commit
8df6bc0132
@ -5,6 +5,7 @@ import {
|
|||||||
SimpleExpressionNode,
|
SimpleExpressionNode,
|
||||||
SourceLocation
|
SourceLocation
|
||||||
} from '@vue/compiler-core'
|
} from '@vue/compiler-core'
|
||||||
|
import { parseStringStyle } from '@vue/shared'
|
||||||
|
|
||||||
// Parse inline CSS strings for static style attributes into an object.
|
// Parse inline CSS strings for static style attributes into an object.
|
||||||
// This is a NodeTransform since it works on the static `style` attribute and
|
// This is a NodeTransform since it works on the static `style` attribute and
|
||||||
@ -30,19 +31,10 @@ export const transformStyle: NodeTransform = (node, context) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const listDelimiterRE = /;(?![^(]*\))/g
|
const parseInlineCSS = (
|
||||||
const propertyDelimiterRE = /:(.+)/
|
|
||||||
|
|
||||||
function parseInlineCSS(
|
|
||||||
cssText: string,
|
cssText: string,
|
||||||
loc: SourceLocation
|
loc: SourceLocation
|
||||||
): SimpleExpressionNode {
|
): SimpleExpressionNode => {
|
||||||
const res: Record<string, string> = {}
|
const normalized = parseStringStyle(cssText)
|
||||||
cssText.split(listDelimiterRE).forEach(item => {
|
return createSimpleExpression(JSON.stringify(normalized), false, loc, true)
|
||||||
if (item) {
|
|
||||||
const tmp = item.split(propertyDelimiterRE)
|
|
||||||
tmp.length > 1 && (res[tmp[0].trim()] = tmp[1].trim())
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return createSimpleExpression(JSON.stringify(res), false, loc, true)
|
|
||||||
}
|
}
|
||||||
|
@ -258,7 +258,8 @@ describe('vnode', () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
test('style', () => {
|
|
||||||
|
test('style w/ strings', () => {
|
||||||
let props1: Data = {
|
let props1: Data = {
|
||||||
style: 'width:100px;right:10;top:10'
|
style: 'width:100px;right:10;top:10'
|
||||||
}
|
}
|
||||||
@ -281,8 +282,8 @@ describe('vnode', () => {
|
|||||||
width: '300px',
|
width: '300px',
|
||||||
height: '300px',
|
height: '300px',
|
||||||
fontSize: 30,
|
fontSize: 30,
|
||||||
right: 10,
|
right: '10',
|
||||||
top: 10
|
top: '10'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
import { isArray, isString, isObject, hyphenate } from './'
|
import { isArray, isString, isObject, hyphenate } from './'
|
||||||
import { isNoUnitNumericStyleProp } from './domAttrConfig'
|
import { isNoUnitNumericStyleProp } from './domAttrConfig'
|
||||||
|
|
||||||
export function normalizeStyle(
|
export type NormalizedStyle = Record<string, string | number>
|
||||||
value: unknown
|
|
||||||
): Record<string, string | number> | undefined {
|
export function normalizeStyle(value: unknown): NormalizedStyle | undefined {
|
||||||
if (isArray(value)) {
|
if (isArray(value)) {
|
||||||
const res: Record<string, string | number> = {}
|
const res: Record<string, string | number> = {}
|
||||||
for (let i = 0; i < value.length; i++) {
|
for (let i = 0; i < value.length; i++) {
|
||||||
const styles = isString(value[i]) ? strStyleToObj(value[i]) : value[i]
|
const item = value[i]
|
||||||
const normalized = normalizeStyle(styles)
|
const normalized = normalizeStyle(
|
||||||
|
isString(item) ? parseStringStyle(item) : item
|
||||||
|
)
|
||||||
if (normalized) {
|
if (normalized) {
|
||||||
for (const key in normalized) {
|
for (const key in normalized) {
|
||||||
res[key] = normalized[key]
|
res[key] = normalized[key]
|
||||||
@ -21,21 +23,21 @@ export function normalizeStyle(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function strStyleToObj(style: string) {
|
const listDelimiterRE = /;(?![^(]*\))/g
|
||||||
const ret: Record<string, string | number> = {}
|
const propertyDelimiterRE = /:(.+)/
|
||||||
style
|
|
||||||
.replace(/\s*/g, '')
|
export function parseStringStyle(cssText: string): NormalizedStyle {
|
||||||
.split(';')
|
const ret: NormalizedStyle = {}
|
||||||
.forEach((item: string) => {
|
cssText.split(listDelimiterRE).forEach(item => {
|
||||||
const [key, val] = item.split(':')
|
if (item) {
|
||||||
ret[key] = isNaN(Number(val)) ? val : Number(val)
|
const tmp = item.split(propertyDelimiterRE)
|
||||||
})
|
tmp.length > 1 && (ret[tmp[0].trim()] = tmp[1].trim())
|
||||||
|
}
|
||||||
|
})
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
export function stringifyStyle(
|
export function stringifyStyle(styles: NormalizedStyle | undefined): string {
|
||||||
styles: Record<string, string | number> | undefined
|
|
||||||
): string {
|
|
||||||
let ret = ''
|
let ret = ''
|
||||||
if (!styles) {
|
if (!styles) {
|
||||||
return ret
|
return ret
|
||||||
|
Loading…
Reference in New Issue
Block a user