11'use strict'
22
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 ' )
66var html = require ( 'property-information/html' )
77var svg = require ( 'property-information/svg' )
88var 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' )
1110var position = require ( 'unist-util-position' )
11+ var namespaces = require ( 'web-namespaces' )
12+ var xtend = require ( 'xtend' )
13+ var zwitch = require ( 'zwitch' )
1214
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+ } )
2426
2527function invalid ( value ) {
2628 throw new Error ( 'Expected node, not `' + value + '`' )
@@ -31,9 +33,7 @@ function unknown(value) {
3133}
3234
3335function 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
3737 return one ( tree , { schema : space === 'svg' ? svg : html , ns : null } )
3838}
3939
@@ -55,123 +55,102 @@ function doctype(node, config) {
5555 {
5656 type : 'doctype' ,
5757 name : node . name || '' ,
58- public : node . public || undefined ,
59- system : node . system || undefined
58+ public : node . public ,
59+ system : node . system
6060 } ,
6161 config
6262 )
6363}
6464
6565function element ( node , parentConfig ) {
66- var schema = parentConfig . schema
67- var name = node . tagName
6866 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 = { }
7269 var config
70+ var value
71+ var key
72+ var info
7373
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' ) {
8581 schema = svg
86- ns = namespaces . svg
87- }
88-
89- if ( parentConfig . ns !== ns ) {
90- attrs . xmlns = ns
9182 }
9283
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 ] } )
10585
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
12988 }
13089
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-
14190 for ( key in props ) {
142- info = find ( config . schema , key )
143- name = info . attribute
91+ info = find ( schema , key )
14492 value = props [ key ]
14593
14694 // Ignore nullish, false, and `NaN` values, and falsey known booleans.
14795 if (
148- value === null ||
149- value === undefined ||
96+ value == null ||
15097 value === false ||
15198 value !== value ||
152- ( info . boolean && ! value )
99+ ( ! value && info . boolean )
153100 ) {
154101 continue
155102 }
156103
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-
163104 // Treat `true` and truthy known booleans.
164105 if ( value === true || info . boolean ) {
165106 value = ''
166107 }
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+ }
168115 // Cast everything else to string.
169- if ( typeof value !== 'string' ) {
116+ else if ( typeof value !== 'string' ) {
170117 value = String ( value )
171118 }
172119
173- attributes [ name ] = value
120+ attributes [ info . attribute ] = value
174121 }
175122
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
177156}
0 commit comments