1+ import ns from 'web-namespaces' ;
12import info from 'property-information' ;
23
3- function transform ( node , options = { } ) {
4+ function transform ( node , options ) {
45 switch ( node . type ) {
56 case 'root' :
67 return root ( node , options ) ;
@@ -18,7 +19,7 @@ function transform(node, options = {}) {
1819}
1920
2021// Create a document.
21- function root ( node , options = { } ) {
22+ function root ( node , options ) {
2223 const { fragment, namespace : optionsNamespace } = options ;
2324 const { children = [ ] } = node ;
2425 const { length : childrenLength } = children ;
@@ -27,19 +28,15 @@ function root(node, options = {}) {
2728 let rootIsDocument = childrenLength === 0 ;
2829
2930 for ( let i = 0 ; i < childrenLength ; i += 1 ) {
30- const { tagName, properties : { xmlns } = { } } = children [ i ] ;
31+ const { tagName, properties = { } } = children [ i ] ;
3132
3233 if ( tagName === 'html' ) {
3334 // If we have a root HTML node, we don’t need to render as a fragment.
3435 rootIsDocument = true ;
3536
3637 // Take namespace of the first child.
3738 if ( typeof optionsNamespace === 'undefined' ) {
38- if ( xmlns ) {
39- namespace = xmlns ;
40- } else if ( children [ 0 ] . tagName === 'html' ) {
41- namespace = 'http://www.w3.org/1999/xhtml' ;
42- }
39+ namespace = properties . xmlns || ns . html ;
4340 }
4441 }
4542 }
@@ -55,18 +52,7 @@ function root(node, options = {}) {
5552 el = document . createElement ( 'html' ) ;
5653 }
5754
58- // Transform children.
59- const childOptions = Object . assign ( { fragment, namespace } , options ) ;
60-
61- for ( let i = 0 ; i < childrenLength ; i += 1 ) {
62- const childEl = transform ( children [ i ] , childOptions ) ;
63-
64- if ( childEl ) {
65- el . appendChild ( childEl ) ;
66- }
67- }
68-
69- return el ;
55+ return appendAll ( el , children , Object . assign ( { fragment, namespace } , options ) ) ;
7056}
7157
7258// Create a `doctype`.
@@ -89,9 +75,10 @@ function comment(node) {
8975}
9076
9177// Create an `element`.
92- function element ( node , options = { } ) {
78+ function element ( node , options ) {
9379 const { namespace } = options ;
94- const { tagName, properties, children = [ ] } = node ;
80+ // TODO: use `g` in SVG space.
81+ const { tagName = 'div' , properties = { } , children = [ ] } = node ;
9582 const el = typeof namespace !== 'undefined'
9683 ? document . createElementNS ( namespace , tagName )
9784 : document . createElement ( tagName ) ;
@@ -106,7 +93,7 @@ function element(node, options = {}) {
10693 const {
10794 attribute,
10895 property,
109- mustUseAttribute,
96+ // ` mustUseAttribute` ,
11097 mustUseProperty,
11198 boolean,
11299 booleanish,
@@ -116,59 +103,48 @@ function element(node, options = {}) {
116103 commaSeparated,
117104 // `spaceSeparated`,
118105 // `commaOrSpaceSeparated`,
119- } = info . find ( info . html , key ) || { attribute : key , property : key } ;
106+ } = info . find ( info . html , key ) ;
120107
121108 let value = properties [ key ] ;
122109
123110 if ( Array . isArray ( value ) ) {
124- if ( commaSeparated ) {
125- value = value . join ( ', ' ) ;
126- } else {
127- value = value . join ( ' ' ) ;
128- }
111+ value = value . join ( commaSeparated ? ', ' : ' ' ) ;
129112 }
130113
131- try {
132- if ( mustUseProperty ) {
133- el [ property ] = value ;
134- }
114+ if ( mustUseProperty ) {
115+ el [ property ] = value ;
116+ }
135117
136- if ( boolean || ( overloadedBoolean && typeof value === 'boolean' ) ) {
137- if ( value ) {
138- el . setAttribute ( attribute , '' ) ;
139- } else {
140- el . removeAttribute ( attribute ) ;
141- }
142- } else if ( booleanish ) {
143- el . setAttribute ( attribute , value ) ;
144- } else if ( value === true ) {
118+ if ( boolean || ( overloadedBoolean && typeof value === 'boolean' ) ) {
119+ if ( value ) {
145120 el . setAttribute ( attribute , '' ) ;
146- } else if ( value || value === 0 || value === '' ) {
147- el . setAttribute ( attribute , value ) ;
148- }
149- } catch ( e ) {
150- if ( ! mustUseAttribute && property ) {
151- el [ property ] = value ;
121+ } else {
122+ el . removeAttribute ( attribute ) ;
152123 }
153-
154- // Otherwise silently ignore.
124+ } else if ( booleanish ) {
125+ el . setAttribute ( attribute , value ) ;
126+ } else if ( value === true ) {
127+ el . setAttribute ( attribute , '' ) ;
128+ } else if ( value || value === 0 || value === '' ) {
129+ el . setAttribute ( attribute , value ) ;
155130 }
156131 }
157132
158- // Transform children.
159- const { length : childrenLength } = children ;
133+ return appendAll ( el , children , options ) ;
134+ }
160135
161- for ( let i = 0 ; i < childrenLength ; i += 1 ) {
162- const childEl = transform ( children [ i ] , options ) ;
136+ // Add all children.
137+ function appendAll ( node , children , options ) {
138+ const childrenLength = children . length ;
163139
164- if ( childEl ) {
165- el . appendChild ( childEl ) ;
166- }
140+ for ( let i = 0 ; i < childrenLength ; i += 1 ) {
141+ node . appendChild ( transform ( children [ i ] , options ) ) ;
167142 }
168143
169- return el ;
144+ return node ;
170145}
171146
147+
172148export default function toDOM ( hast , options = { } ) {
173149 return transform ( hast , options ) ;
174150}
0 commit comments