import VNode from 'core/vdom/vnode' import { cached, extend, toObject } from 'shared/util' import type { VNodeData, VNodeWithData } from 'types/vnode' export const parseStyleText = cached(function (cssText) { const res = {} const listDelimiter = /;(?![^(]*\))/g const propertyDelimiter = /:(.+)/ cssText.split(listDelimiter).forEach(function (item) { if (item) { const tmp = item.split(propertyDelimiter) tmp.length > 1 && (res[tmp[0].trim()] = tmp[1].trim()) } }) return res }) // merge static and dynamic style data on the same vnode function normalizeStyleData(data: VNodeData): Record { const style = normalizeStyleBinding(data.style) // static style is pre-processed into an object during compilation // and is always a fresh object, so it's safe to merge into it return data.staticStyle ? extend(data.staticStyle, style) : style } // normalize possible array / string values into Object export function normalizeStyleBinding(bindingStyle: any): Record { if (Array.isArray(bindingStyle)) { return toObject(bindingStyle) } if (typeof bindingStyle === 'string') { return parseStyleText(bindingStyle) } return bindingStyle } /** * parent component style should be after child's * so that parent component's style could override it */ export function getStyle(vnode: VNodeWithData, checkChild: boolean): Object { const res = {} let styleData if (checkChild) { let childNode: VNodeWithData | VNode = vnode while (childNode.componentInstance) { childNode = childNode.componentInstance._vnode! if ( childNode && childNode.data && (styleData = normalizeStyleData(childNode.data)) ) { extend(res, styleData) } } } if ((styleData = normalizeStyleData(vnode.data))) { extend(res, styleData) } let parentNode: VNodeWithData | VNode | undefined = vnode // @ts-expect-error parentNode.parent not VNodeWithData while ((parentNode = parentNode.parent)) { if (parentNode.data && (styleData = normalizeStyleData(parentNode.data))) { extend(res, styleData) } } return res }