@@ -15,7 +15,14 @@ import type {
15
15
Program ,
16
16
SpreadElement ,
17
17
} from 'estree'
18
- import type { JSXClosingElement , JSXElement , JSXFragment } from 'estree-jsx'
18
+ import type {
19
+ JSXClosingElement ,
20
+ JSXElement ,
21
+ JSXFragment ,
22
+ JSXIdentifier ,
23
+ JSXMemberExpression ,
24
+ JSXNamespacedName ,
25
+ } from 'estree-jsx'
19
26
import type {
20
27
BlockContent ,
21
28
PhrasingContent ,
@@ -289,6 +296,58 @@ runAsWorker(
289
296
raw : text . slice ( start , end ) ,
290
297
} )
291
298
299
+ const handleJsxName = (
300
+ nodeName : string ,
301
+ start : number ,
302
+ ) : JSXIdentifier | JSXMemberExpression | JSXNamespacedName => {
303
+ const name = nodeName . trim ( )
304
+ const nameIndex = nodeName . indexOf ( name )
305
+
306
+ const colonIndex = nodeName . indexOf ( ':' )
307
+ if ( colonIndex !== - 1 ) {
308
+ const [ fullNamespace , fullName ] = nodeName . split ( ':' )
309
+ return {
310
+ ...normalizeNode (
311
+ start + nameIndex ,
312
+ start + nameIndex + name . length ,
313
+ ) ,
314
+ type : 'JSXNamespacedName' ,
315
+ namespace : handleJsxName ( fullNamespace , start ) as JSXIdentifier ,
316
+ name : handleJsxName (
317
+ fullName ,
318
+ start + colonIndex + 1 ,
319
+ ) as JSXIdentifier ,
320
+ }
321
+ }
322
+
323
+ const lastPointIndex = nodeName . lastIndexOf ( '.' )
324
+ if ( lastPointIndex === - 1 ) {
325
+ return {
326
+ ...normalizeNode (
327
+ start + nameIndex ,
328
+ start + nameIndex + name . length ,
329
+ ) ,
330
+ type : 'JSXIdentifier' ,
331
+ name,
332
+ }
333
+ }
334
+
335
+ const objectName = nodeName . slice ( 0 , lastPointIndex )
336
+ const propertyName = nodeName . slice ( lastPointIndex + 1 )
337
+
338
+ return {
339
+ ...normalizeNode ( start + nameIndex , start + nameIndex + name . length ) ,
340
+ type : 'JSXMemberExpression' ,
341
+ object : handleJsxName ( objectName , start ) as
342
+ | JSXIdentifier
343
+ | JSXMemberExpression ,
344
+ property : handleJsxName (
345
+ propertyName ,
346
+ start + lastPointIndex + 1 ,
347
+ ) as JSXIdentifier ,
348
+ }
349
+ }
350
+
292
351
visit ( root , node => {
293
352
if (
294
353
processed . has ( node ) ||
@@ -374,20 +433,16 @@ runAsWorker(
374
433
if ( ! selfClosing ) {
375
434
const prevOffset = prevCharOffset ( lastCharOffset )
376
435
const slashOffset = prevCharOffset ( prevOffset - nodeNameLength )
377
- assert ( text [ slashOffset ] === '/' )
436
+ assert (
437
+ text [ slashOffset ] === '/' ,
438
+ `expect \`${ text [ slashOffset ] } \` to be \`/\`, the node is ${ node . name } ` ,
439
+ )
378
440
const tagStartOffset = prevCharOffset ( slashOffset - 1 )
379
441
assert ( text [ tagStartOffset ] === '<' )
380
442
closingElement = {
381
443
...normalizeNode ( tagStartOffset , nodeEnd ) ,
382
444
type : 'JSXClosingElement' ,
383
- name : {
384
- ...normalizeNode (
385
- prevOffset + 1 - nodeNameLength ,
386
- prevOffset + 1 ,
387
- ) ,
388
- type : 'JSXIdentifier' ,
389
- name : node . name ,
390
- } ,
445
+ name : handleJsxName ( node . name , prevOffset + 1 - nodeNameLength ) ,
391
446
}
392
447
}
393
448
@@ -396,14 +451,7 @@ runAsWorker(
396
451
type : 'JSXElement' ,
397
452
openingElement : {
398
453
type : 'JSXOpeningElement' ,
399
- name : {
400
- ...normalizeNode (
401
- nodeNameStart ,
402
- nodeNameStart + nodeNameLength ,
403
- ) ,
404
- type : 'JSXIdentifier' ,
405
- name : node . name ,
406
- } ,
454
+ name : handleJsxName ( node . name , nodeNameStart ) ,
407
455
attributes : node . attributes . map ( attr => {
408
456
if ( attr . type === 'mdxJsxExpressionAttribute' ) {
409
457
assert ( attr . data )
0 commit comments