Skip to content

Commit 67da70d

Browse files
committed
refactor: split server-renderer props handling into separate module
1 parent efa3fc7 commit 67da70d

File tree

4 files changed

+65
-22
lines changed

4 files changed

+65
-22
lines changed

src/platforms/web/server/modules/attrs.js

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,43 +3,42 @@
33
import {
44
isBooleanAttr,
55
isEnumeratedAttr,
6-
isFalsyAttrValue,
7-
propsToAttrMap
8-
} from 'web/util/index'
6+
isFalsyAttrValue
7+
} from 'web/util/attrs'
98

109
export default function renderAttrs (node: VNodeWithData): ?string {
11-
if (node.data.attrs || node.data.props || node.data.staticAttrs) {
10+
if (node.data.attrs || node.data.staticAttrs) {
1211
return (
13-
serialize(node.data.staticAttrs) +
14-
serialize(node.data.attrs) +
15-
serialize(node.data.props, true)
12+
render(node.data.staticAttrs) +
13+
render(node.data.attrs)
1614
)
1715
}
1816
}
1917

20-
function serialize (attrs: ?{ [key: string]: any }, asProps?: boolean): string {
18+
function render (attrs: ?{ [key: string]: any }): string {
2119
let res = ''
2220
if (!attrs) {
2321
return res
2422
}
25-
for (let key in attrs) {
23+
for (const key in attrs) {
2624
if (key === 'style') {
2725
// leave it to the style module
2826
continue
2927
}
30-
if (asProps) {
31-
key = propsToAttrMap[key] || key.toLowerCase()
32-
}
33-
const value = attrs[key]
34-
if (isBooleanAttr(key)) {
35-
if (!isFalsyAttrValue(value)) {
36-
res += ` ${key}="${key}"`
37-
}
38-
} else if (isEnumeratedAttr(key)) {
39-
res += ` ${key}="${isFalsyAttrValue(value) || value === 'false' ? 'false' : 'true'}"`
40-
} else if (!isFalsyAttrValue(value)) {
41-
res += ` ${key}="${value}"`
42-
}
28+
res += renderAttr(key, attrs[key])
4329
}
4430
return res
4531
}
32+
33+
export function renderAttr (key: string, value: string): string {
34+
if (isBooleanAttr(key)) {
35+
if (!isFalsyAttrValue(value)) {
36+
return ` ${key}="${key}"`
37+
}
38+
} else if (isEnumeratedAttr(key)) {
39+
return ` ${key}="${isFalsyAttrValue(value) || value === 'false' ? 'false' : 'true'}"`
40+
} else if (!isFalsyAttrValue(value)) {
41+
return ` ${key}="${value}"`
42+
}
43+
return ''
44+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import attrs from './attrs'
2+
import props from './props'
23
import klass from './class'
34
import style from './style'
45

56
export default [
67
attrs,
8+
props,
79
klass,
810
style
911
]
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/* @flow */
2+
3+
import { renderAttr } from './attrs'
4+
import { propsToAttrMap, isRenderableAttr } from 'web/util/attrs'
5+
6+
export default function (node: VNodeWithData): ?string {
7+
const props = node.data.props
8+
if (props) {
9+
let res = ''
10+
for (const key in props) {
11+
const attr = propsToAttrMap[key] || key.toLowerCase()
12+
if (isRenderableAttr(attr)) {
13+
res += renderAttr(attr, props[key])
14+
}
15+
}
16+
return res
17+
}
18+
}

src/platforms/web/util/attrs.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,30 @@ export const isBooleanAttr = makeMap(
1616
'truespeed,typemustmatch,visible'
1717
)
1818

19+
const isAttr = makeMap(
20+
'accept,accept-charset,accesskey,action,align,alt,async,autocomplete,' +
21+
'autofocus,autoplay,autosave,bgcolor,border,buffered,challenge,charset,' +
22+
'checked,cite,class,code,codebase,color,cols,colspan,content,http-equiv,' +
23+
'name,contenteditable,contextmenu,controls,coords,data,datetime,default,' +
24+
'defer,dir,dirname,disabled,download,draggable,dropzone,enctype,method,for,' +
25+
'form,formaction,headers,<th>,height,hidden,high,href,hreflang,http-equiv,' +
26+
'icon,id,ismap,itemprop,keytype,kind,label,lang,language,list,loop,low,' +
27+
'manifest,max,maxlength,media,method,GET,POST,min,multiple,email,file,' +
28+
'muted,name,novalidate,open,optimum,pattern,ping,placeholder,poster,' +
29+
'preload,radiogroup,readonly,rel,required,reversed,rows,rowspan,sandbox,' +
30+
'scope,scoped,seamless,selected,shape,size,type,text,password,sizes,span,' +
31+
'spellcheck,src,srcdoc,srclang,srcset,start,step,style,summary,tabindex,' +
32+
'target,title,type,usemap,value,width,wrap'
33+
)
34+
35+
export const isRenderableAttr = (name: string): boolean => {
36+
return (
37+
isAttr(name) ||
38+
name.indexOf('data-') === 0 ||
39+
name.indexOf('aria-') === 0
40+
)
41+
}
42+
1943
export const propsToAttrMap = {
2044
acceptCharset: 'accept-charset',
2145
className: 'class',

0 commit comments

Comments
 (0)