1
1
'use strict'
2
2
3
- var xtend = require ( 'xtend' )
4
- var zwitch = require ( 'zwitch' )
5
- var namespaces = require ( 'web-namespaces ' )
3
+ module . exports = toXast
4
+
5
+ var comma = require ( 'comma-separated-tokens ' )
6
6
var html = require ( 'property-information/html' )
7
7
var svg = require ( 'property-information/svg' )
8
8
var find = require ( 'property-information/find' )
9
- var spaces = require ( 'space-separated-tokens' ) . stringify
10
- var commas = require ( 'comma-separated-tokens' ) . stringify
9
+ var space = require ( 'space-separated-tokens' )
11
10
var position = require ( 'unist-util-position' )
11
+ var namespaces = require ( 'web-namespaces' )
12
+ var xtend = require ( 'xtend' )
13
+ var zwitch = require ( 'zwitch' )
12
14
13
- module . exports = toXast
14
-
15
- var one = zwitch ( 'type' )
16
-
17
- one . invalid = invalid
18
- one . unknown = unknown
19
- one . handlers . root = root
20
- one . handlers . element = element
21
- one . handlers . text = text
22
- one . handlers . comment = comment
23
- one . handlers . doctype = doctype
15
+ var one = zwitch ( 'type' , {
16
+ handlers : {
17
+ root : root ,
18
+ element : element ,
19
+ text : text ,
20
+ comment : comment ,
21
+ doctype : doctype
22
+ } ,
23
+ invalid : invalid ,
24
+ unknown : unknown
25
+ } )
24
26
25
27
function invalid ( value ) {
26
28
throw new Error ( 'Expected node, not `' + value + '`' )
@@ -31,9 +33,7 @@ function unknown(value) {
31
33
}
32
34
33
35
function toXast ( tree , options ) {
34
- var settings = typeof options === 'string' ? { space : options } : options || { }
35
- var space = settings . space === 'svg' ? 'svg' : 'html'
36
-
36
+ var space = typeof options === 'string' ? options : ( options || { } ) . space
37
37
return one ( tree , { schema : space === 'svg' ? svg : html , ns : null } )
38
38
}
39
39
@@ -55,123 +55,102 @@ function doctype(node, config) {
55
55
{
56
56
type : 'doctype' ,
57
57
name : node . name || '' ,
58
- public : node . public || undefined ,
59
- system : node . system || undefined
58
+ public : node . public ,
59
+ system : node . system
60
60
} ,
61
61
config
62
62
)
63
63
}
64
64
65
65
function element ( node , parentConfig ) {
66
- var schema = parentConfig . schema
67
- var name = node . tagName
68
66
var props = node . properties || { }
69
- var xmlns = props . xmlns || null
70
- var ns = namespaces [ schema . space ]
71
- var attrs = { }
67
+ var schema = parentConfig . schema
68
+ var attributes = { }
72
69
var config
70
+ var value
71
+ var key
72
+ var info
73
73
74
- if ( xmlns ) {
75
- if ( xmlns === namespaces . svg ) {
76
- schema = svg
77
- ns = xmlns
78
- } else if ( xmlns === namespaces . html ) {
79
- schema = html
80
- ns = xmlns
81
- } else {
82
- // We don’t support non-HTML, non-SVG namespaces, so stay in the same.
83
- }
84
- } else if ( ns === namespaces . html && name === 'svg' ) {
74
+ if ( props . xmlns === namespaces . html ) {
75
+ schema = html
76
+ } else if ( props . xmlns === namespaces . svg ) {
77
+ schema = svg
78
+ } else if ( props . xmlns ) {
79
+ // We don’t support non-HTML, non-SVG namespaces, so stay in the same.
80
+ } else if ( schema === html && node . tagName === 'svg' ) {
85
81
schema = svg
86
- ns = namespaces . svg
87
- }
88
-
89
- if ( parentConfig . ns !== ns ) {
90
- attrs . xmlns = ns
91
82
}
92
83
93
- config = xtend ( parentConfig , { schema : schema , ns : ns } )
94
- attrs = xtend ( attrs , toAttributes ( props , config ) )
95
-
96
- return patch ( node , { type : 'element' , name : name , attributes : attrs } , config )
97
- }
98
-
99
- function patch ( origin , node , config ) {
100
- var pos = origin . position
101
- var hastChildren = origin . children
102
- var length
103
- var children
104
- var index
84
+ config = xtend ( parentConfig , { schema : schema , ns : namespaces [ schema . space ] } )
105
85
106
- if (
107
- config . ns === namespaces . html &&
108
- origin . type === 'element' &&
109
- origin . tagName === 'template'
110
- ) {
111
- node . children = root ( origin . content , config ) . children
112
- } else if ( origin . type === 'element' || origin . type === 'root' ) {
113
- length = hastChildren && hastChildren . length
114
- children = [ ]
115
- index = - 1
116
-
117
- while ( ++ index < length ) {
118
- children [ index ] = one ( hastChildren [ index ] , config )
119
- }
120
-
121
- node . children = children
122
- }
123
-
124
- if ( pos ) {
125
- node . position = {
126
- start : position . start ( origin ) ,
127
- end : position . end ( origin )
128
- }
86
+ if ( parentConfig . ns !== config . ns ) {
87
+ attributes . xmlns = config . ns
129
88
}
130
89
131
- return node
132
- }
133
-
134
- function toAttributes ( props , config ) {
135
- var attributes = { }
136
- var value
137
- var key
138
- var info
139
- var name
140
-
141
90
for ( key in props ) {
142
- info = find ( config . schema , key )
143
- name = info . attribute
91
+ info = find ( schema , key )
144
92
value = props [ key ]
145
93
146
94
// Ignore nullish, false, and `NaN` values, and falsey known booleans.
147
95
if (
148
- value === null ||
149
- value === undefined ||
96
+ value == null ||
150
97
value === false ||
151
98
value !== value ||
152
- ( info . boolean && ! value )
99
+ ( ! value && info . boolean )
153
100
) {
154
101
continue
155
102
}
156
103
157
- // Accept `array`.
158
- // Most props are space-separated.
159
- if ( typeof value === 'object' && 'length' in value ) {
160
- value = ( info . commaSeparated ? commas : spaces ) ( value )
161
- }
162
-
163
104
// Treat `true` and truthy known booleans.
164
105
if ( value === true || info . boolean ) {
165
106
value = ''
166
107
}
167
-
108
+ // Accept `array`.
109
+ // Most props are space-separated.
110
+ else if ( typeof value === 'object' && 'length' in value ) {
111
+ value = info . commaSeparated
112
+ ? comma . stringify ( value )
113
+ : space . stringify ( value )
114
+ }
168
115
// Cast everything else to string.
169
- if ( typeof value !== 'string' ) {
116
+ else if ( typeof value !== 'string' ) {
170
117
value = String ( value )
171
118
}
172
119
173
- attributes [ name ] = value
120
+ attributes [ info . attribute ] = value
174
121
}
175
122
176
- return attributes
123
+ return patch (
124
+ node ,
125
+ { type : 'element' , name : node . tagName , attributes : attributes } ,
126
+ config
127
+ )
128
+ }
129
+
130
+ function patch ( origin , node , config ) {
131
+ var index
132
+
133
+ if (
134
+ config . schema === html &&
135
+ origin . type === 'element' &&
136
+ origin . tagName === 'template'
137
+ ) {
138
+ node . children = root ( origin . content , config ) . children
139
+ } else if (
140
+ origin . children &&
141
+ ( origin . type === 'element' || origin . type === 'root' )
142
+ ) {
143
+ node . children = [ ]
144
+ index = - 1
145
+
146
+ while ( ++ index < origin . children . length ) {
147
+ node . children [ index ] = one ( origin . children [ index ] , config )
148
+ }
149
+ }
150
+
151
+ if ( origin . position ) {
152
+ node . position = position ( origin )
153
+ }
154
+
155
+ return node
177
156
}
0 commit comments