2024-01-18 11:23:59 +08:00
|
|
|
import {
|
|
|
|
escapeHtml,
|
|
|
|
isRenderableAttrValue,
|
|
|
|
isSVGTag,
|
|
|
|
stringifyStyle,
|
|
|
|
} from '@vue/shared'
|
2020-01-29 07:48:27 +08:00
|
|
|
import {
|
2021-08-17 06:18:36 +08:00
|
|
|
includeBooleanAttr,
|
2020-01-30 06:36:06 +08:00
|
|
|
isBooleanAttr,
|
2023-12-26 19:39:47 +08:00
|
|
|
isOn,
|
2020-01-29 07:48:27 +08:00
|
|
|
isSSRSafeAttrName,
|
|
|
|
isString,
|
2023-12-26 19:39:47 +08:00
|
|
|
makeMap,
|
2020-01-29 07:48:27 +08:00
|
|
|
normalizeClass,
|
|
|
|
normalizeStyle,
|
|
|
|
propsToAttrMap,
|
2020-01-30 04:10:45 +08:00
|
|
|
} from '@vue/shared'
|
2020-01-28 07:06:37 +08:00
|
|
|
|
2020-10-20 05:15:53 +08:00
|
|
|
// leading comma for empty string ""
|
2024-03-13 21:48:45 +08:00
|
|
|
const shouldIgnoreProp = /*#__PURE__*/ makeMap(
|
2022-05-13 07:10:00 +08:00
|
|
|
`,key,ref,innerHTML,textContent,ref_key,ref_for`,
|
|
|
|
)
|
2020-01-30 06:36:06 +08:00
|
|
|
|
2020-02-07 01:07:25 +08:00
|
|
|
export function ssrRenderAttrs(
|
2020-01-29 07:48:27 +08:00
|
|
|
props: Record<string, unknown>,
|
2020-01-30 06:36:06 +08:00
|
|
|
tag?: string,
|
2020-01-29 07:48:27 +08:00
|
|
|
): string {
|
|
|
|
let ret = ''
|
|
|
|
for (const key in props) {
|
2020-01-30 06:36:06 +08:00
|
|
|
if (
|
|
|
|
shouldIgnoreProp(key) ||
|
|
|
|
isOn(key) ||
|
|
|
|
(tag === 'textarea' && key === 'value')
|
|
|
|
) {
|
2020-01-29 07:48:27 +08:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
const value = props[key]
|
|
|
|
if (key === 'class') {
|
2020-02-07 01:07:25 +08:00
|
|
|
ret += ` class="${ssrRenderClass(value)}"`
|
2020-01-29 07:48:27 +08:00
|
|
|
} else if (key === 'style') {
|
2020-02-07 01:07:25 +08:00
|
|
|
ret += ` style="${ssrRenderStyle(value)}"`
|
2020-02-04 07:16:09 +08:00
|
|
|
} else {
|
2020-02-07 01:07:25 +08:00
|
|
|
ret += ssrRenderDynamicAttr(key, value, tag)
|
2020-01-29 07:48:27 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return ret
|
|
|
|
}
|
2020-01-28 07:06:37 +08:00
|
|
|
|
2020-02-05 05:47:12 +08:00
|
|
|
// render an attr with dynamic (unknown) key.
|
2020-02-07 01:07:25 +08:00
|
|
|
export function ssrRenderDynamicAttr(
|
2020-02-05 05:47:12 +08:00
|
|
|
key: string,
|
|
|
|
value: unknown,
|
|
|
|
tag?: string,
|
|
|
|
): string {
|
2024-01-18 11:23:59 +08:00
|
|
|
if (!isRenderableAttrValue(value)) {
|
2020-02-04 07:16:09 +08:00
|
|
|
return ``
|
|
|
|
}
|
|
|
|
const attrKey =
|
2022-09-27 17:40:22 +08:00
|
|
|
tag && (tag.indexOf('-') > 0 || isSVGTag(tag))
|
|
|
|
? key // preserve raw name on custom elements and svg
|
2020-02-04 07:16:09 +08:00
|
|
|
: propsToAttrMap[key] || key.toLowerCase()
|
|
|
|
if (isBooleanAttr(attrKey)) {
|
2021-08-17 06:18:36 +08:00
|
|
|
return includeBooleanAttr(value) ? ` ${attrKey}` : ``
|
2020-02-04 07:16:09 +08:00
|
|
|
} else if (isSSRSafeAttrName(attrKey)) {
|
2020-04-15 22:51:07 +08:00
|
|
|
return value === '' ? ` ${attrKey}` : ` ${attrKey}="${escapeHtml(value)}"`
|
2020-02-04 07:16:09 +08:00
|
|
|
} else {
|
2020-02-10 02:19:10 +08:00
|
|
|
console.warn(
|
|
|
|
`[@vue/server-renderer] Skipped rendering unsafe attribute name: ${attrKey}`,
|
|
|
|
)
|
2020-02-04 07:16:09 +08:00
|
|
|
return ``
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-05 05:47:12 +08:00
|
|
|
// Render a v-bind attr with static key. The key is pre-processed at compile
|
|
|
|
// time and we only need to check and escape value.
|
2020-02-07 01:07:25 +08:00
|
|
|
export function ssrRenderAttr(key: string, value: unknown): string {
|
2024-01-18 11:23:59 +08:00
|
|
|
if (!isRenderableAttrValue(value)) {
|
2020-02-05 05:47:12 +08:00
|
|
|
return ``
|
|
|
|
}
|
|
|
|
return ` ${key}="${escapeHtml(value)}"`
|
|
|
|
}
|
|
|
|
|
2020-02-07 01:07:25 +08:00
|
|
|
export function ssrRenderClass(raw: unknown): string {
|
2020-01-30 04:10:45 +08:00
|
|
|
return escapeHtml(normalizeClass(raw))
|
2020-01-29 07:48:27 +08:00
|
|
|
}
|
|
|
|
|
2020-02-07 01:07:25 +08:00
|
|
|
export function ssrRenderStyle(raw: unknown): string {
|
2020-01-29 07:48:27 +08:00
|
|
|
if (!raw) {
|
|
|
|
return ''
|
|
|
|
}
|
2020-01-30 04:10:45 +08:00
|
|
|
if (isString(raw)) {
|
|
|
|
return escapeHtml(raw)
|
|
|
|
}
|
2020-01-29 07:48:27 +08:00
|
|
|
const styles = normalizeStyle(raw)
|
2020-02-21 20:10:13 +08:00
|
|
|
return escapeHtml(stringifyStyle(styles))
|
2020-01-29 07:48:27 +08:00
|
|
|
}
|