refactor(ssr): adjust helper structure + renderList
This commit is contained in:
5
packages/server-renderer/src/helpers/interpolate.ts
Normal file
5
packages/server-renderer/src/helpers/interpolate.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { escapeHtml, toDisplayString } from '@vue/shared'
|
||||
|
||||
export function interpolate(value: unknown): string {
|
||||
return escapeHtml(toDisplayString(value))
|
||||
}
|
||||
84
packages/server-renderer/src/helpers/renderAttrs.ts
Normal file
84
packages/server-renderer/src/helpers/renderAttrs.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
import { escapeHtml } from '@vue/shared'
|
||||
import {
|
||||
normalizeClass,
|
||||
normalizeStyle,
|
||||
propsToAttrMap,
|
||||
hyphenate,
|
||||
isString,
|
||||
isNoUnitNumericStyleProp,
|
||||
isOn,
|
||||
isSSRSafeAttrName,
|
||||
isBooleanAttr,
|
||||
makeMap
|
||||
} from '@vue/shared'
|
||||
|
||||
const shouldIgnoreProp = makeMap(`key,ref,innerHTML,textContent`)
|
||||
|
||||
export function renderAttrs(
|
||||
props: Record<string, unknown>,
|
||||
tag?: string
|
||||
): string {
|
||||
let ret = ''
|
||||
for (const key in props) {
|
||||
if (
|
||||
shouldIgnoreProp(key) ||
|
||||
isOn(key) ||
|
||||
(tag === 'textarea' && key === 'value')
|
||||
) {
|
||||
continue
|
||||
}
|
||||
const value = props[key]
|
||||
if (key === 'class') {
|
||||
ret += ` class="${renderClass(value)}"`
|
||||
} else if (key === 'style') {
|
||||
ret += ` style="${renderStyle(value)}"`
|
||||
} else {
|
||||
ret += renderAttr(key, value, tag)
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
export function renderAttr(key: string, value: unknown, tag?: string): string {
|
||||
if (value == null) {
|
||||
return ``
|
||||
}
|
||||
const attrKey =
|
||||
tag && tag.indexOf('-') > 0
|
||||
? key // preserve raw name on custom elements
|
||||
: propsToAttrMap[key] || key.toLowerCase()
|
||||
if (isBooleanAttr(attrKey)) {
|
||||
return value === false ? `` : ` ${attrKey}`
|
||||
} else if (isSSRSafeAttrName(attrKey)) {
|
||||
return ` ${attrKey}="${escapeHtml(value)}"`
|
||||
} else {
|
||||
return ``
|
||||
}
|
||||
}
|
||||
|
||||
export function renderClass(raw: unknown): string {
|
||||
return escapeHtml(normalizeClass(raw))
|
||||
}
|
||||
|
||||
export function renderStyle(raw: unknown): string {
|
||||
if (!raw) {
|
||||
return ''
|
||||
}
|
||||
if (isString(raw)) {
|
||||
return escapeHtml(raw)
|
||||
}
|
||||
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)
|
||||
}
|
||||
29
packages/server-renderer/src/helpers/renderList.ts
Normal file
29
packages/server-renderer/src/helpers/renderList.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { isArray, isString, isObject } from '@vue/shared'
|
||||
|
||||
export function renderList(
|
||||
source: unknown,
|
||||
renderItem: (value: unknown, key: string | number, index?: number) => void
|
||||
) {
|
||||
if (isArray(source) || isString(source)) {
|
||||
for (let i = 0, l = source.length; i < l; i++) {
|
||||
renderItem(source[i], i)
|
||||
}
|
||||
} else if (typeof source === 'number') {
|
||||
for (let i = 0; i < source; i++) {
|
||||
renderItem(i + 1, i)
|
||||
}
|
||||
} else if (isObject(source)) {
|
||||
if (source[Symbol.iterator as any]) {
|
||||
const arr = Array.from(source as Iterable<any>)
|
||||
for (let i = 0, l = arr.length; i < l; i++) {
|
||||
renderItem(arr[i], i)
|
||||
}
|
||||
} else {
|
||||
const keys = Object.keys(source)
|
||||
for (let i = 0, l = keys.length; i < l; i++) {
|
||||
const key = keys[i]
|
||||
renderItem(source[key], key, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user