1+ import {
2+ isOpenTag ,
3+ isCloseTag ,
4+ isVoidTag ,
5+ isComment ,
6+ isOpenCloseTag ,
7+ } from './utils'
8+
19import { Node , Parent } from 'unist'
210
311export type Traverser = ( node : Node , parent ?: Parent ) => void
@@ -13,6 +21,67 @@ export class Traverse {
1321 this . _enter = enter
1422 }
1523
24+ combineJsxNodes ( jsxNodes : Node [ ] ) : Node {
25+ return {
26+ type : 'jsx' ,
27+ value : jsxNodes . reduce ( ( acc , { value } ) => ( acc += value ) , '' ) ,
28+ position : {
29+ start : jsxNodes [ 0 ] . position . start ,
30+ end : jsxNodes [ jsxNodes . length - 1 ] . position . end ,
31+ } ,
32+ }
33+ }
34+
35+ // fix #7
36+ combineInlineJsx ( nodes : Node [ ] ) {
37+ let offset = 0
38+ const jsxNodes : Node [ ] = [ ]
39+ const { length } = nodes
40+ return nodes . reduce ( ( acc , node , index ) => {
41+ if ( node . type === 'jsx' ) {
42+ const rawText = node . value as string
43+ if ( isOpenTag ( rawText as string ) ) {
44+ offset ++
45+ jsxNodes . push ( node )
46+ } else {
47+ if ( isCloseTag ( rawText ) ) {
48+ offset --
49+ } else if (
50+ ! isComment ( rawText ) &&
51+ ! isVoidTag ( rawText ) &&
52+ ! isOpenCloseTag ( rawText )
53+ ) {
54+ const { start } = node . position
55+ throw Object . assign (
56+ new SyntaxError (
57+ `'Unknown node type: ${ JSON . stringify (
58+ node . type ,
59+ ) } , text: ${ JSON . stringify ( rawText ) } `,
60+ ) ,
61+ {
62+ lineNumber : start . line ,
63+ column : start . column ,
64+ index : start . offset ,
65+ } ,
66+ )
67+ }
68+
69+ jsxNodes . push ( node )
70+
71+ if ( ! offset || index === length - 1 ) {
72+ acc . push ( this . combineJsxNodes ( jsxNodes ) )
73+ jsxNodes . length = 0
74+ }
75+ }
76+ } else if ( offset ) {
77+ jsxNodes . push ( node )
78+ } else {
79+ acc . push ( node )
80+ }
81+ return acc
82+ } , [ ] )
83+ }
84+
1685 traverse ( node : Node , parent ?: Parent ) {
1786 if ( ! node ) {
1887 return
@@ -21,28 +90,10 @@ export class Traverse {
2190 this . _enter ( node , parent )
2291
2392 if ( node . children ) {
24- /**
25- * FIXME: inline jsx:
26- *
27- * {
28- type: 'jsx',
29- value: '<b>',
30- position: Position { start: [Object], end: [Object], indent: [] }
31- },
32- {
33- type: 'text',
34- value: 'velit',
35- position: Position { start: [Object], end: [Object], indent: [] }
36- },
37- {
38- type: 'jsx',
39- value: '</b>',
40- position: Position { start: [Object], end: [Object], indent: [] }
41- }
42- */
43- console . log ( node . children )
4493 parent = node as Parent
45- parent . children . forEach ( child => this . traverse ( child , parent ) )
94+ this . combineInlineJsx ( parent . children ) . forEach ( child =>
95+ this . traverse ( child , parent ) ,
96+ )
4697 }
4798 }
4899}
0 commit comments