/
get-props-from-attributes.js
75 lines (63 loc) · 2.02 KB
/
get-props-from-attributes.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import ReactProperties from './react-properties-map'
export default function getPropsFromAttributes (element) {
const attributes = Array.from(element.attributes || [])
return attributes.reduce((props, { name, value }) => {
const propName = getPropName(name, element)
const propValue = getPropValue(propName, value)
return {
...props,
[propName]: propValue
}
}, {})
}
function formatStylePropName (propName) {
// Vendor prefixes other than "ms" should begin with a capital letter.
// See: https://facebook.github.io/react/tips/inline-styles.html.
propName = propName.replace(/^(\s+)?-(?=ms)/, '').trim()
// Turn, for instance, "-webkit-property" into "WebkitProperty"
// and "font-size" into "fontSize.
return propName.replace(/(\-\w)/g, (match) => {
return match[1].toUpperCase()
})
}
function getStylePropValue (attrValue) {
const props = attrValue.split(';').filter((prop) => {
return !!prop
})
return props.reduce((props, prop) => {
let [propName, propValue] = prop.split(/:(.*)/)
propName = formatStylePropName(propName)
return {
...props,
[propName]: propValue && propValue.trim(),
}
}, {})
}
function getPropName (attrName, element) {
const lowerAttrName = attrName.toLowerCase()
if (lowerAttrName === 'value') {
const tagName = element.tagName.toLowerCase()
// https://facebook.github.io/react/docs/forms.html#default-value
// https://facebook.github.io/react/docs/forms.html#why-select-value
if (tagName === 'input' || tagName === 'select') {
return 'defaultValue'
}
} else if (lowerAttrName === 'checked') {
return 'defaultChecked'
}
return ReactProperties[attrName] || attrName
}
function getPropValue (propName, attrValue) {
const lowerPropName = propName.toLowerCase()
if (lowerPropName === 'style') {
return getStylePropValue(attrValue)
}
switch (lowerPropName) {
case 'checked':
case 'defaultchecked':
case 'readonly':
case 'disabled':
return true;
}
return attrValue
}