refactor(ssr): adjust helper structure + renderList

This commit is contained in:
Evan You
2020-02-03 18:16:09 -05:00
parent 889a0276eb
commit 2ad0eed5cd
9 changed files with 90 additions and 45 deletions

View File

@@ -0,0 +1,5 @@
import { escapeHtml, toDisplayString } from '@vue/shared'
export function interpolate(value: unknown): string {
return escapeHtml(toDisplayString(value))
}

View 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)
}

View 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)
}
}
}
}