@@ -87,49 +87,23 @@ export default function jsxToHtmBabelPlugin({ types: t }, options = {}) {
8787 } ) ) ;
8888 buffer = '' ;
8989 }
90-
91- function processNode ( node , path , isRoot ) {
92- const open = node . openingElement ;
93- const { name } = open . name ;
94-
95- if ( name . match ( / ^ [ _ A - Z ] / ) ) {
96- raw ( '<' ) ;
97- expr ( t . identifier ( name ) ) ;
98- }
99- else {
100- raw ( '<' ) ;
101- raw ( name ) ;
102- }
103-
104- if ( open . attributes ) {
105- for ( let i = 0 ; i < open . attributes . length ; i ++ ) {
106- const attr = open . attributes [ i ] ;
107- raw ( ' ' ) ;
108- if ( t . isJSXSpreadAttribute ( attr ) ) {
109- raw ( '...' ) ;
110- expr ( attr . argument ) ;
111- continue ;
112- }
113- const { name, value } = attr ;
114- raw ( name . name ) ;
115- if ( value ) {
116- raw ( '=' ) ;
117- if ( value . expression ) {
118- expr ( value . expression ) ;
119- }
120- else if ( t . isStringLiteral ( value ) ) {
121- escapePropValue ( value ) ;
122- }
123- else {
124- expr ( value ) ;
125- }
126- }
127- }
90+
91+ function getName ( node ) {
92+ switch ( node . type ) {
93+ case 'JSXMemberExpression' :
94+ return `${ node . object . name } .${ node . property . name } `
95+
96+ default :
97+ return node . name ;
12898 }
99+ }
129100
101+ function processChildren ( node , name , isFragment ) {
130102 const children = t . react . buildChildren ( node ) ;
131103 if ( children && children . length !== 0 ) {
132- raw ( '>' ) ;
104+ if ( ! isFragment ) {
105+ raw ( '>' ) ;
106+ }
133107 for ( let i = 0 ; i < children . length ; i ++ ) {
134108 let child = children [ i ] ;
135109 if ( t . isStringLiteral ( child ) ) {
@@ -144,27 +118,100 @@ export default function jsxToHtmBabelPlugin({ types: t }, options = {}) {
144118 }
145119 }
146120
147- if ( name . match ( / ^ [ _ A - Z ] / ) ) {
148- raw ( '</' ) ;
121+ if ( ! isFragment ) {
122+ if ( name . match ( / ^ [ $ _ A - Z ] / ) ) {
123+ raw ( '</' ) ;
124+ expr ( t . identifier ( name ) ) ;
125+ raw ( '>' ) ;
126+ }
127+ else {
128+ raw ( '</' ) ;
129+ raw ( name ) ;
130+ raw ( '>' ) ;
131+ }
132+ }
133+ }
134+ else if ( ! isFragment ) {
135+ raw ( '/>' ) ;
136+ }
137+ }
138+
139+ function processNode ( node , path , isRoot ) {
140+ const open = node . openingElement ;
141+ const name = getName ( open . name ) ;
142+ const isFragment = name === 'React.Fragment' ;
143+
144+ if ( ! isFragment ) {
145+ if ( name . match ( / ^ [ $ _ A - Z ] / ) ) {
146+ raw ( '<' ) ;
149147 expr ( t . identifier ( name ) ) ;
150- raw ( '>' ) ;
151148 }
152149 else {
153- raw ( '</ ' ) ;
150+ raw ( '<' ) ;
154151 raw ( name ) ;
155- raw ( '>' ) ;
152+ }
153+
154+ if ( open . attributes ) {
155+ for ( let i = 0 ; i < open . attributes . length ; i ++ ) {
156+ const attr = open . attributes [ i ] ;
157+ raw ( ' ' ) ;
158+ if ( t . isJSXSpreadAttribute ( attr ) ) {
159+ raw ( '...' ) ;
160+ expr ( attr . argument ) ;
161+ continue ;
162+ }
163+ const { name, value } = attr ;
164+ raw ( name . name ) ;
165+ if ( value ) {
166+ raw ( '=' ) ;
167+ if ( value . expression ) {
168+ expr ( value . expression ) ;
169+ }
170+ else if ( t . isStringLiteral ( value ) ) {
171+ escapePropValue ( value ) ;
172+ }
173+ else {
174+ expr ( value ) ;
175+ }
176+ }
177+ }
156178 }
157179 }
158- else {
159- raw ( '/>' ) ;
160- }
180+
181+ processChildren ( node , name , isFragment ) ;
161182
162183 if ( isRoot ) {
184+ commit ( true ) ;
185+ const template = t . templateLiteral ( quasis , expressions ) ;
186+ const replacement = t . taggedTemplateExpression ( tag , template ) ;
187+ path . replaceWith ( replacement ) ;
188+ }
189+ }
190+
191+ function jsxVisitorHandler ( path , state , isFragment ) {
192+ let quasisBefore = quasis . slice ( ) ;
193+ let expressionsBefore = expressions . slice ( ) ;
194+ let bufferBefore = buffer ;
195+
196+ buffer = '' ;
197+ quasis . length = 0 ;
198+ expressions . length = 0 ;
199+
200+ if ( isFragment ) {
201+ processChildren ( path . node , '' , true ) ;
163202 commit ( ) ;
164203 const template = t . templateLiteral ( quasis , expressions ) ;
165204 const replacement = t . taggedTemplateExpression ( tag , template ) ;
166205 path . replaceWith ( replacement ) ;
206+ } else {
207+ processNode ( path . node , path , true ) ;
167208 }
209+
210+ quasis = quasisBefore ;
211+ expressions = expressionsBefore ;
212+ buffer = bufferBefore ;
213+
214+ state . set ( 'jsxElement' , true ) ;
168215 }
169216
170217 return {
@@ -180,21 +227,11 @@ export default function jsxToHtmBabelPlugin({ types: t }, options = {}) {
180227 } ,
181228
182229 JSXElement ( path , state ) {
183- let quasisBefore = quasis . slice ( ) ;
184- let expressionsBefore = expressions . slice ( ) ;
185- let bufferBefore = buffer ;
186-
187- buffer = '' ;
188- quasis . length = 0 ;
189- expressions . length = 0 ;
190-
191- processNode ( path . node , path , true ) ;
192-
193- quasis = quasisBefore ;
194- expressions = expressionsBefore ;
195- buffer = bufferBefore ;
196-
197- state . set ( 'jsxElement' , true ) ;
230+ jsxVisitorHandler ( path , state , false ) ;
231+ } ,
232+
233+ JSXFragment ( path , state ) {
234+ jsxVisitorHandler ( path , state , true ) ;
198235 }
199236 }
200237 } ;
0 commit comments