-
Notifications
You must be signed in to change notification settings - Fork 14
/
xml.js
100 lines (83 loc) · 2.68 KB
/
xml.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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
var AttributeHook = require('virtual-dom/virtual-hyperscript/hooks/attribute-hook')
var namespaceRegex = /^([a-z0-9_-]+)(--|:)([a-z0-9_-]+)$/i
var xmlnsRegex = /^xmlns(--|:)([a-z0-9_-]+)$/i
var SVG_NAMESPACE = 'http://www.w3.org/2000/svg'
function transformTanName (vnode, namespaces) {
var tagNamespace = namespaceRegex.exec(vnode.tagName)
if (tagNamespace) {
var namespaceKey = tagNamespace[1]
var namespace = namespaces[namespaceKey]
if (namespace) {
vnode.tagName = tagNamespace[1] + ':' + tagNamespace[3]
vnode.namespace = namespace
}
} else if (!vnode.namespace) {
vnode.namespace = namespaces['']
}
}
function transformProperties (vnode, namespaces) {
var properties = vnode.properties
if (properties) {
var attributes = properties.attributes || (properties.attributes = {})
var keys = Object.keys(properties)
for (var k = 0, l = keys.length; k < l; k++) {
var key = keys[k]
if (key !== 'style' && key !== 'attributes') {
var match = namespaceRegex.exec(key)
if (match) {
properties[match[1] + ':' + match[3]] = new AttributeHook(namespaces[match[1]], properties[key])
delete properties[key]
} else {
if (vnode.namespace === SVG_NAMESPACE && key === 'className') {
attributes['class'] = properties.className
delete properties.className
} else {
var property = properties[key]
var type = typeof property
if (type === 'string' || type === 'number' || type === 'boolean') {
attributes[key] = property
}
}
}
}
}
}
}
function declaredNamespaces (vnode) {
var namespaces = {
'': vnode.properties.xmlns,
xmlns: 'http://www.w3.org/2000/xmlns/'
}
var keys = Object.keys(vnode.properties)
for (var k = 0, l = keys.length; k < l; k++) {
var key = keys[k]
var value = vnode.properties[key]
if (key === 'xmlns') {
namespaces[''] = value
} else {
var match = xmlnsRegex.exec(key)
if (match) {
namespaces[match[2]] = value
}
}
}
return namespaces
}
function transform (vnode) {
var namespaces = declaredNamespaces(vnode)
function transformChildren (vnode, namespaces) {
transformTanName(vnode, namespaces)
transformProperties(vnode, namespaces)
if (vnode.children) {
for (var c = 0, l = vnode.children.length; c < l; c++) {
var child = vnode.children[c]
if (!(child.properties && child.properties.xmlns)) {
transformChildren(child, namespaces)
}
}
}
}
transformChildren(vnode, namespaces)
return vnode
}
module.exports.transform = transform