wip(ssr): vdom serialization
This commit is contained in:
50
packages/shared/src/domAttrConfig.ts
Normal file
50
packages/shared/src/domAttrConfig.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import { makeMap } from './makeMap'
|
||||
|
||||
// TODO validate this list!
|
||||
// on the client, most of these probably has corresponding prop
|
||||
// or, like allowFullscreen on iframe, although case is different, the attr
|
||||
// affects the property properly...
|
||||
// Basically, we can skip this check on the client
|
||||
// but they are still needed during SSR to produce correct initial markup
|
||||
export const isBooleanAttr = makeMap(
|
||||
'allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,' +
|
||||
'default,defaultchecked,defaultmuted,defaultselected,defer,disabled,' +
|
||||
'enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,' +
|
||||
'muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,' +
|
||||
'required,reversed,scoped,seamless,selected,sortable,translate,' +
|
||||
'truespeed,typemustmatch,visible'
|
||||
)
|
||||
|
||||
const unsafeAttrCharRE = /[>/="'\u0009\u000a\u000c\u0020]/
|
||||
const attrValidationCache: Record<string, boolean> = {}
|
||||
|
||||
export function isSSRSafeAttrName(name: string): boolean {
|
||||
if (attrValidationCache.hasOwnProperty(name)) {
|
||||
return attrValidationCache[name]
|
||||
}
|
||||
const isUnsafe = unsafeAttrCharRE.test(name)
|
||||
if (isUnsafe) {
|
||||
console.error(`unsafe attribute name: ${name}`)
|
||||
}
|
||||
return (attrValidationCache[name] = !isUnsafe)
|
||||
}
|
||||
|
||||
export const propsToAttrMap: Record<string, string | undefined> = {
|
||||
acceptCharset: 'accept-charset',
|
||||
className: 'class',
|
||||
htmlFor: 'for',
|
||||
httpEquiv: 'http-equiv'
|
||||
}
|
||||
|
||||
// CSS properties that accept plain numbers
|
||||
export const isNoUnitNumericStyleProp = makeMap(
|
||||
`animation-iteration-count,border-image-outset,border-image-slice,` +
|
||||
`border-image-width,box-flex,box-flex-group,box-ordinal-group,column-count,` +
|
||||
`columns,flex,flex-grow,flex-positive,flex-shrink,flex-negative,flex-order,` +
|
||||
`grid-row,grid-row-end,grid-row-span,grid-row-start,grid-column,` +
|
||||
`grid-column-end,grid-column-span,grid-column-start,font-weight,line-clamp,` +
|
||||
`line-height,opacity,order,orphans,tab-size,widows,z-index,zoom,` +
|
||||
// SVG
|
||||
`fill-opacity,flood-opacity,stop-opacity,stroke-dasharray,stroke-dashoffset,` +
|
||||
`stroke-miterlimit,stroke-opacity,stroke-width`
|
||||
)
|
||||
@@ -4,9 +4,10 @@ export { makeMap }
|
||||
export * from './patchFlags'
|
||||
export * from './globalsWhitelist'
|
||||
export * from './codeframe'
|
||||
export * from './domTagConfig'
|
||||
export * from './mockWarn'
|
||||
export * from './normalizeProp'
|
||||
export * from './domTagConfig'
|
||||
export * from './domAttrConfig'
|
||||
|
||||
export const EMPTY_OBJ: { readonly [key: string]: any } = __DEV__
|
||||
? Object.freeze({})
|
||||
|
||||
@@ -2,7 +2,7 @@ import { isArray, isString, isObject } from './'
|
||||
|
||||
export function normalizeStyle(
|
||||
value: unknown
|
||||
): Record<string, string | number> | void {
|
||||
): Record<string, string | number> | undefined {
|
||||
if (isArray(value)) {
|
||||
const res: Record<string, string | number> = {}
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
|
||||
Reference in New Issue
Block a user