1- 'use strict'
2-
3- module . exports = toEstree
4-
5- var commas = require ( 'comma-separated-tokens' )
6- var attachComments = require ( 'estree-util-attach-comments' )
7- var {
8- start : identifierStart ,
9- cont : identifierCont
10- } = require ( 'estree-util-is-identifier-name' )
11- var whitespace = require ( 'hast-util-whitespace' )
12- var find = require ( 'property-information/find' )
13- var hastToReact = require ( 'property-information/hast-to-react.json' )
14- var html = require ( 'property-information/html' )
15- var svg = require ( 'property-information/svg' )
16- var spaces = require ( 'space-separated-tokens' )
17- var style = require ( 'style-to-object' )
18- var position = require ( 'unist-util-position' )
19- var zwitch = require ( 'zwitch' )
1+ import { stringify as commas } from 'comma-separated-tokens'
2+ import { attachComments } from 'estree-util-attach-comments'
3+ import {
4+ start as identifierStart ,
5+ cont as identifierCont
6+ } from 'estree-util-is-identifier-name'
7+ import { whitespace } from 'hast-util-whitespace'
8+ import { html , svg , find , hastToReact } from 'property-information'
9+ import { stringify as spaces } from 'space-separated-tokens'
10+ import style from 'style-to-object'
11+ import { position } from 'unist-util-position'
12+ import { zwitch } from 'zwitch'
2013
2114var own = { } . hasOwnProperty
2215var push = [ ] . push
2316
24- var handlers = {
25- comment : comment ,
26- doctype : ignore ,
27- element : element ,
28- mdxjsEsm : mdxjsEsm ,
29- mdxFlowExpression : mdxExpression ,
30- mdxJsxFlowElement : mdxJsxElement ,
31- mdxJsxTextElement : mdxJsxElement ,
32- mdxTextExpression : mdxExpression ,
33- root : root ,
34- text : text
35- }
36-
37- function toEstree ( tree , options ) {
17+ export function toEstree ( tree , options = { } ) {
3818 var context = {
39- schema : options && options . space === 'svg' ? svg : html ,
19+ schema : options . space === 'svg' ? svg : html ,
4020 comments : [ ] ,
4121 esm : [ ] ,
4222 handle : zwitch ( 'type' , {
43- invalid : invalid ,
44- unknown : unknown ,
45- handlers : Object . assign ( { } , handlers , options && options . handlers )
23+ invalid,
24+ unknown,
25+ handlers : Object . assign (
26+ { } ,
27+ {
28+ comment,
29+ doctype : ignore ,
30+ element,
31+ mdxjsEsm,
32+ mdxFlowExpression : mdxExpression ,
33+ mdxJsxFlowElement : mdxJsxElement ,
34+ mdxJsxTextElement : mdxJsxElement ,
35+ mdxTextExpression : mdxExpression ,
36+ root,
37+ text
38+ } ,
39+ options . handlers
40+ )
4641 } )
4742 }
4843 var result = context . handle ( tree , context )
@@ -67,7 +62,7 @@ function toEstree(tree, options) {
6762
6863 return create ( tree , {
6964 type : 'Program' ,
70- body : body ,
65+ body,
7166 sourceType : 'module' ,
7267 comments : context . comments
7368 } )
@@ -118,85 +113,91 @@ function element(node, context) {
118113 children = all ( node , context )
119114
120115 for ( prop in props ) {
121- value = props [ prop ]
122- info = find ( schema , prop )
123-
124- // Ignore nullish and `NaN` values.
125- // Ignore `false` and falsey known booleans.
126- if (
127- value == null ||
128- value !== value ||
129- value === false ||
130- ( ! value && info . boolean )
131- ) {
132- continue
133- }
134-
135- prop = info . space
136- ? hastToReact [ info . property ] || info . property
137- : info . attribute
138-
139- if ( value && typeof value === 'object' && 'length' in value ) {
140- // Accept `array`.
141- // Most props are space-separated.
142- value = ( info . commaSeparated ? commas : spaces ) . stringify ( value )
143- }
116+ if ( own . call ( props , prop ) ) {
117+ value = props [ prop ]
118+ info = find ( schema , prop )
119+
120+ // Ignore nullish and `NaN` values.
121+ // Ignore `false` and falsey known booleans.
122+ if (
123+ value === undefined ||
124+ value === null ||
125+ ( typeof value === 'number' && Number . isNaN ( value ) ) ||
126+ value === false ||
127+ ( ! value && info . boolean )
128+ ) {
129+ continue
130+ }
144131
145- if ( prop === 'style' && typeof value === 'string' ) {
146- value = parseStyle ( value , node . tagName )
147- }
132+ prop = info . space
133+ ? hastToReact [ info . property ] || info . property
134+ : info . attribute
148135
149- if ( value === true ) {
150- value = null
151- } else if ( prop === 'style' && typeof value === 'object' ) {
152- cssProperties = [ ]
153-
154- for ( cssProp in value ) {
155- cssProperties . push ( {
156- type : 'Property' ,
157- method : false ,
158- shorthand : false ,
159- computed : false ,
160- key : { type : 'Identifier' , name : cssProp } ,
161- value : { type : 'Literal' , value : String ( value [ cssProp ] ) } ,
162- kind : 'init'
163- } )
136+ if ( value && typeof value === 'object' && 'length' in value ) {
137+ // Accept `array`.
138+ // Most props are space-separated.
139+ value = info . commaSeparated ? commas ( value ) : spaces ( value )
164140 }
165141
166- value = {
167- type : 'JSXExpressionContainer' ,
168- expression : { type : 'ObjectExpression' , properties : cssProperties }
142+ if ( prop === 'style' && typeof value === 'string' ) {
143+ value = parseStyle ( value , node . tagName )
169144 }
170- } else {
171- value = { type : 'Literal' , value : String ( value ) }
172- }
173145
174- if ( jsxIdentifierName ( prop ) ) {
175- attributes . push ( {
176- type : 'JSXAttribute' ,
177- name : { type : 'JSXIdentifier' , name : prop } ,
178- value : value
179- } )
180- } else {
181- // No need to worry about `style` (which has a `JSXExpressionContainer`
182- // value) because that’s a valid identifier.
183- attributes . push ( {
184- type : 'JSXSpreadAttribute' ,
185- argument : {
186- type : 'ObjectExpression' ,
187- properties : [
188- {
146+ if ( value === true ) {
147+ value = null
148+ } else if ( prop === 'style' && typeof value === 'object' ) {
149+ cssProperties = [ ]
150+
151+ for ( cssProp in value ) {
152+ // eslint-disable-next-line max-depth
153+ if ( own . call ( value , cssProp ) ) {
154+ cssProperties . push ( {
189155 type : 'Property' ,
190156 method : false ,
191157 shorthand : false ,
192158 computed : false ,
193- key : { type : 'Literal ' , value : String ( prop ) } ,
194- value : value || { type : 'Literal' , value : true } ,
159+ key : { type : 'Identifier ' , name : cssProp } ,
160+ value : { type : 'Literal' , value : String ( value [ cssProp ] ) } ,
195161 kind : 'init'
196- }
197- ]
162+ } )
163+ }
198164 }
199- } )
165+
166+ value = {
167+ type : 'JSXExpressionContainer' ,
168+ expression : { type : 'ObjectExpression' , properties : cssProperties }
169+ }
170+ } else {
171+ value = { type : 'Literal' , value : String ( value ) }
172+ }
173+
174+ if ( jsxIdentifierName ( prop ) ) {
175+ attributes . push ( {
176+ type : 'JSXAttribute' ,
177+ name : { type : 'JSXIdentifier' , name : prop } ,
178+ value
179+ } )
180+ } else {
181+ // No need to worry about `style` (which has a `JSXExpressionContainer`
182+ // value) because that’s a valid identifier.
183+ attributes . push ( {
184+ type : 'JSXSpreadAttribute' ,
185+ argument : {
186+ type : 'ObjectExpression' ,
187+ properties : [
188+ {
189+ type : 'Property' ,
190+ method : false ,
191+ shorthand : false ,
192+ computed : false ,
193+ key : { type : 'Literal' , value : String ( prop ) } ,
194+ value : value || { type : 'Literal' , value : true } ,
195+ kind : 'init'
196+ }
197+ ]
198+ }
199+ } )
200+ }
200201 }
201202 }
202203
@@ -207,14 +208,15 @@ function element(node, context) {
207208 type : 'JSXElement' ,
208209 openingElement : {
209210 type : 'JSXOpeningElement' ,
210- attributes : attributes ,
211+ attributes,
211212 name : createJsxName ( node . tagName ) ,
212- selfClosing : ! children . length
213+ selfClosing : children . length === 0
213214 } ,
214- closingElement : children . length
215- ? { type : 'JSXClosingElement' , name : createJsxName ( node . tagName ) }
216- : null ,
217- children : children
215+ closingElement :
216+ children . length > 0
217+ ? { type : 'JSXClosingElement' , name : createJsxName ( node . tagName ) }
218+ : null ,
219+ children
218220 } )
219221}
220222
@@ -274,7 +276,7 @@ function mdxJsxElement(node, context) {
274276 value = attr . value
275277
276278 if ( attr . type === 'mdxJsxAttribute' ) {
277- if ( value == null ) {
279+ if ( value === undefined || value === null ) {
278280 // Empty.
279281 }
280282 // `MDXJsxAttributeValueExpression`.
@@ -302,7 +304,7 @@ function mdxJsxElement(node, context) {
302304 inherit ( attr , {
303305 type : 'JSXAttribute' ,
304306 name : createJsxName ( attr . name ) ,
305- value : value
307+ value
306308 } )
307309 )
308310 }
@@ -341,14 +343,15 @@ function mdxJsxElement(node, context) {
341343 type : 'JSXElement' ,
342344 openingElement : {
343345 type : 'JSXOpeningElement' ,
344- attributes : attributes ,
346+ attributes,
345347 name : createJsxName ( node . name ) ,
346- selfClosing : ! children . length
348+ selfClosing : children . length === 0
347349 } ,
348- closingElement : children . length
349- ? { type : 'JSXClosingElement' , name : createJsxName ( node . name ) }
350- : null ,
351- children : children
350+ closingElement :
351+ children . length > 0
352+ ? { type : 'JSXClosingElement' , name : createJsxName ( node . name ) }
353+ : null ,
354+ children
352355 }
353356 : {
354357 type : 'JSXFragment' ,
@@ -358,7 +361,7 @@ function mdxJsxElement(node, context) {
358361 selfClosing : false
359362 } ,
360363 closingFragment : { type : 'JSXClosingFragment' } ,
361- children : children
364+ children
362365 }
363366 )
364367}
@@ -405,7 +408,7 @@ function text(node) {
405408
406409 return create ( node , {
407410 type : 'JSXExpressionContainer' ,
408- expression : inherit ( node , { type : 'Literal' , value : value } )
411+ expression : inherit ( node , { type : 'Literal' , value} )
409412 } )
410413}
411414
@@ -472,25 +475,25 @@ function createJsxName(name) {
472475 var parts
473476 var node
474477
475- if ( name . indexOf ( '.' ) > - 1 ) {
478+ if ( name . includes ( '.' ) ) {
476479 parts = name . split ( '.' )
477480 node = { type : 'JSXIdentifier' , name : parts . shift ( ) }
478- while ( parts . length ) {
481+ while ( parts . length > 0 ) {
479482 node = {
480483 type : 'JSXMemberExpression' ,
481484 object : node ,
482485 property : { type : 'JSXIdentifier' , name : parts . shift ( ) }
483486 }
484487 }
485- } else if ( name . indexOf ( ':' ) > - 1 ) {
488+ } else if ( name . includes ( ':' ) ) {
486489 parts = name . split ( ':' )
487490 node = {
488491 type : 'JSXNamespacedName' ,
489492 namespace : { type : 'JSXIdentifier' , name : parts [ 0 ] } ,
490493 name : { type : 'JSXIdentifier' , name : parts [ 1 ] }
491494 }
492495 } else {
493- node = { type : 'JSXIdentifier' , name : name }
496+ node = { type : 'JSXIdentifier' , name}
494497 }
495498
496499 return node
0 commit comments