vue3-core/packages/server-renderer/src/renderProps.ts

70 lines
1.6 KiB
TypeScript
Raw Normal View History

import { escapeHtml } from './ssrUtils'
2020-01-29 07:48:27 +08:00
import {
normalizeClass,
normalizeStyle,
propsToAttrMap,
hyphenate,
isString,
isNoUnitNumericStyleProp,
isOn,
isSSRSafeAttrName,
isBooleanAttr
} from '@vue/shared'
2020-01-28 07:06:37 +08:00
2020-01-29 07:48:27 +08:00
export function renderProps(
props: Record<string, unknown>,
isCustomElement: boolean = false
): string {
let ret = ''
for (const key in props) {
if (key === 'key' || key === 'ref' || isOn(key)) {
continue
}
const value = props[key]
if (key === 'class') {
ret += ` class="${renderClass(value)}"`
} else if (key === 'style') {
ret += ` style="${renderStyle(value)}"`
} else if (value != null) {
const attrKey = isCustomElement
? key
: propsToAttrMap[key] || key.toLowerCase()
if (isBooleanAttr(attrKey)) {
if (value !== false) {
ret += ` ${attrKey}`
}
2020-01-29 07:48:27 +08:00
} else if (isSSRSafeAttrName(attrKey)) {
ret += ` ${attrKey}="${escapeHtml(value)}"`
2020-01-29 07:48:27 +08:00
}
}
}
return ret
}
2020-01-28 07:06:37 +08:00
2020-01-29 07:48:27 +08:00
export function renderClass(raw: unknown): string {
return escapeHtml(normalizeClass(raw))
2020-01-29 07:48:27 +08:00
}
export function renderStyle(raw: unknown): string {
if (!raw) {
return ''
}
if (isString(raw)) {
return escapeHtml(raw)
}
2020-01-29 07:48:27 +08:00
const styles = normalizeStyle(raw)
let ret = ''
for (const key in styles) {
const value = styles[key]
const normalizedKey = key.indexOf(`--`) === 0 ? key : hyphenate(key)
if (
isString(value) ||
(typeof value === 'number' && isNoUnitNumericStyleProp(normalizedKey))
) {
// only render valid values
ret += `${normalizedKey}:${value};`
}
}
return escapeHtml(ret)
2020-01-29 07:48:27 +08:00
}