import VNode from 'core/vdom/vnode'
|
import { isDef, isObject } from 'shared/util'
|
import type { VNodeData, VNodeWithData } from 'types/vnode'
|
|
export function genClassForVnode(vnode: VNodeWithData): string {
|
let data = vnode.data
|
let parentNode: VNode | VNodeWithData | undefined = vnode
|
let childNode: VNode | VNodeWithData = vnode
|
while (isDef(childNode.componentInstance)) {
|
childNode = childNode.componentInstance._vnode!
|
if (childNode && childNode.data) {
|
data = mergeClassData(childNode.data, data)
|
}
|
}
|
// @ts-expect-error parentNode.parent not VNodeWithData
|
while (isDef((parentNode = parentNode.parent))) {
|
if (parentNode && parentNode.data) {
|
data = mergeClassData(data, parentNode.data)
|
}
|
}
|
return renderClass(data.staticClass!, data.class)
|
}
|
|
function mergeClassData(
|
child: VNodeData,
|
parent: VNodeData
|
): {
|
staticClass: string
|
class: any
|
} {
|
return {
|
staticClass: concat(child.staticClass, parent.staticClass),
|
class: isDef(child.class) ? [child.class, parent.class] : parent.class
|
}
|
}
|
|
export function renderClass(
|
staticClass: string | null | undefined,
|
dynamicClass: any
|
): string {
|
if (isDef(staticClass) || isDef(dynamicClass)) {
|
return concat(staticClass, stringifyClass(dynamicClass))
|
}
|
/* istanbul ignore next */
|
return ''
|
}
|
|
export function concat(a?: string | null, b?: string | null): string {
|
return a ? (b ? a + ' ' + b : a) : b || ''
|
}
|
|
export function stringifyClass(value: any): string {
|
if (Array.isArray(value)) {
|
return stringifyArray(value)
|
}
|
if (isObject(value)) {
|
return stringifyObject(value)
|
}
|
if (typeof value === 'string') {
|
return value
|
}
|
/* istanbul ignore next */
|
return ''
|
}
|
|
function stringifyArray(value: Array<any>): string {
|
let res = ''
|
let stringified
|
for (let i = 0, l = value.length; i < l; i++) {
|
if (isDef((stringified = stringifyClass(value[i]))) && stringified !== '') {
|
if (res) res += ' '
|
res += stringified
|
}
|
}
|
return res
|
}
|
|
function stringifyObject(value: Object): string {
|
let res = ''
|
for (const key in value) {
|
if (value[key]) {
|
if (res) res += ' '
|
res += key
|
}
|
}
|
return res
|
}
|