@@ -50,171 +50,174 @@ module.exports = {
50
50
return n . openingElement ? n . openingElement . name . name : sourceCode . getText ( n ) . replace ( / \n / g, '' ) ;
51
51
}
52
52
53
- return {
54
- JSXElement : function ( node ) {
55
- const children = node . children ;
56
-
57
- if ( ! children || ! children . length ) {
58
- return ;
59
- }
53
+ function handleJSX ( node ) {
54
+ const children = node . children ;
60
55
61
- const openingElement = node . openingElement ;
62
- const closingElement = node . closingElement ;
63
- const openingElementStartLine = openingElement . loc . start . line ;
64
- const openingElementEndLine = openingElement . loc . end . line ;
65
- const closingElementStartLine = closingElement . loc . start . line ;
66
- const closingElementEndLine = closingElement . loc . end . line ;
56
+ if ( ! children || ! children . length ) {
57
+ return ;
58
+ }
67
59
68
- if ( children . length === 1 ) {
69
- const child = children [ 0 ] ;
60
+ const openingElement = node . openingElement || node . openingFragment ;
61
+ const closingElement = node . closingElement || node . closingFragment ;
62
+ const openingElementStartLine = openingElement . loc . start . line ;
63
+ const openingElementEndLine = openingElement . loc . end . line ;
64
+ const closingElementStartLine = closingElement . loc . start . line ;
65
+ const closingElementEndLine = closingElement . loc . end . line ;
66
+
67
+ if ( children . length === 1 ) {
68
+ const child = children [ 0 ] ;
69
+ if (
70
+ openingElementStartLine === openingElementEndLine &&
71
+ openingElementEndLine === closingElementStartLine &&
72
+ closingElementStartLine === closingElementEndLine &&
73
+ closingElementEndLine === child . loc . start . line &&
74
+ child . loc . start . line === child . loc . end . line
75
+ ) {
70
76
if (
71
- openingElementStartLine === openingElementEndLine &&
72
- openingElementEndLine === closingElementStartLine &&
73
- closingElementStartLine === closingElementEndLine &&
74
- closingElementEndLine === child . loc . start . line &&
75
- child . loc . start . line === child . loc . end . line
77
+ options . allow === 'single-child' ||
78
+ options . allow === 'literal' && ( child . type === 'Literal' || child . type === 'JSXText' )
76
79
) {
77
- if (
78
- options . allow === 'single-child' ||
79
- options . allow === 'literal' && ( child . type === 'Literal' || child . type === 'JSXText' )
80
- ) {
81
- return ;
82
- }
80
+ return ;
83
81
}
84
82
}
83
+ }
85
84
86
- const childrenGroupedByLine = { } ;
87
- const fixDetailsByNode = { } ;
85
+ const childrenGroupedByLine = { } ;
86
+ const fixDetailsByNode = { } ;
88
87
89
- children . forEach ( child => {
90
- let countNewLinesBeforeContent = 0 ;
91
- let countNewLinesAfterContent = 0 ;
88
+ children . forEach ( child => {
89
+ let countNewLinesBeforeContent = 0 ;
90
+ let countNewLinesAfterContent = 0 ;
92
91
93
- if ( child . type === 'Literal' || child . type === 'JSXText' ) {
94
- if ( / ^ \s * $ / . test ( child . raw ) ) {
95
- return ;
96
- }
92
+ if ( child . type === 'Literal' || child . type === 'JSXText' ) {
93
+ if ( / ^ \s * $ / . test ( child . raw ) ) {
94
+ return ;
95
+ }
96
+
97
+ countNewLinesBeforeContent = ( child . raw . match ( / ^ * \n / g) || [ ] ) . length ;
98
+ countNewLinesAfterContent = ( child . raw . match ( / \n * $ / g) || [ ] ) . length ;
99
+ }
100
+
101
+ const startLine = child . loc . start . line + countNewLinesBeforeContent ;
102
+ const endLine = child . loc . end . line - countNewLinesAfterContent ;
97
103
98
- countNewLinesBeforeContent = ( child . raw . match ( / ^ * \n / g) || [ ] ) . length ;
99
- countNewLinesAfterContent = ( child . raw . match ( / \n * $ / g) || [ ] ) . length ;
104
+ if ( startLine === endLine ) {
105
+ if ( ! childrenGroupedByLine [ startLine ] ) {
106
+ childrenGroupedByLine [ startLine ] = [ ] ;
100
107
}
108
+ childrenGroupedByLine [ startLine ] . push ( child ) ;
109
+ } else {
110
+ if ( ! childrenGroupedByLine [ startLine ] ) {
111
+ childrenGroupedByLine [ startLine ] = [ ] ;
112
+ }
113
+ childrenGroupedByLine [ startLine ] . push ( child ) ;
114
+ if ( ! childrenGroupedByLine [ endLine ] ) {
115
+ childrenGroupedByLine [ endLine ] = [ ] ;
116
+ }
117
+ childrenGroupedByLine [ endLine ] . push ( child ) ;
118
+ }
119
+ } ) ;
101
120
102
- const startLine = child . loc . start . line + countNewLinesBeforeContent ;
103
- const endLine = child . loc . end . line - countNewLinesAfterContent ;
121
+ Object . keys ( childrenGroupedByLine ) . forEach ( _line => {
122
+ const line = parseInt ( _line , 10 ) ;
123
+ const firstIndex = 0 ;
124
+ const lastIndex = childrenGroupedByLine [ line ] . length - 1 ;
104
125
105
- if ( startLine === endLine ) {
106
- if ( ! childrenGroupedByLine [ startLine ] ) {
107
- childrenGroupedByLine [ startLine ] = [ ] ;
126
+ childrenGroupedByLine [ line ] . forEach ( ( child , i ) => {
127
+ let prevChild ;
128
+ let nextChild ;
129
+
130
+ if ( i === firstIndex ) {
131
+ if ( line === openingElementEndLine ) {
132
+ prevChild = openingElement ;
108
133
}
109
- childrenGroupedByLine [ startLine ] . push ( child ) ;
110
134
} else {
111
- if ( ! childrenGroupedByLine [ startLine ] ) {
112
- childrenGroupedByLine [ startLine ] = [ ] ;
113
- }
114
- childrenGroupedByLine [ startLine ] . push ( child ) ;
115
- if ( ! childrenGroupedByLine [ endLine ] ) {
116
- childrenGroupedByLine [ endLine ] = [ ] ;
117
- }
118
- childrenGroupedByLine [ endLine ] . push ( child ) ;
135
+ prevChild = childrenGroupedByLine [ line ] [ i - 1 ] ;
119
136
}
120
- } ) ;
121
-
122
- Object . keys ( childrenGroupedByLine ) . forEach ( _line => {
123
- const line = parseInt ( _line , 10 ) ;
124
- const firstIndex = 0 ;
125
- const lastIndex = childrenGroupedByLine [ line ] . length - 1 ;
126
-
127
- childrenGroupedByLine [ line ] . forEach ( ( child , i ) => {
128
- let prevChild ;
129
- let nextChild ;
130
-
131
- if ( i === firstIndex ) {
132
- if ( line === openingElementEndLine ) {
133
- prevChild = openingElement ;
134
- }
135
- } else {
136
- prevChild = childrenGroupedByLine [ line ] [ i - 1 ] ;
137
- }
138
137
139
- if ( i === lastIndex ) {
140
- if ( line === closingElementStartLine ) {
141
- nextChild = closingElement ;
142
- }
143
- } else {
144
- // We don't need to append a trailing because the next child will prepend a leading.
145
- // nextChild = childrenGroupedByLine[line][i + 1];
138
+ if ( i === lastIndex ) {
139
+ if ( line === closingElementStartLine ) {
140
+ nextChild = closingElement ;
146
141
}
142
+ } else {
143
+ // We don't need to append a trailing because the next child will prepend a leading.
144
+ // nextChild = childrenGroupedByLine[line][i + 1];
145
+ }
147
146
148
- function spaceBetweenPrev ( ) {
149
- return ( ( prevChild . type === 'Literal' || prevChild . type === 'JSXText' ) && / $ / . test ( prevChild . raw ) ) ||
150
- ( ( child . type === 'Literal' || child . type === 'JSXText' ) && / ^ / . test ( child . raw ) ) ||
151
- sourceCode . isSpaceBetweenTokens ( prevChild , child ) ;
152
- }
147
+ function spaceBetweenPrev ( ) {
148
+ return ( ( prevChild . type === 'Literal' || prevChild . type === 'JSXText' ) && / $ / . test ( prevChild . raw ) ) ||
149
+ ( ( child . type === 'Literal' || child . type === 'JSXText' ) && / ^ / . test ( child . raw ) ) ||
150
+ sourceCode . isSpaceBetweenTokens ( prevChild , child ) ;
151
+ }
153
152
154
- function spaceBetweenNext ( ) {
155
- return ( ( nextChild . type === 'Literal' || nextChild . type === 'JSXText' ) && / ^ / . test ( nextChild . raw ) ) ||
156
- ( ( child . type === 'Literal' || child . type === 'JSXText' ) && / $ / . test ( child . raw ) ) ||
157
- sourceCode . isSpaceBetweenTokens ( child , nextChild ) ;
158
- }
153
+ function spaceBetweenNext ( ) {
154
+ return ( ( nextChild . type === 'Literal' || nextChild . type === 'JSXText' ) && / ^ / . test ( nextChild . raw ) ) ||
155
+ ( ( child . type === 'Literal' || child . type === 'JSXText' ) && / $ / . test ( child . raw ) ) ||
156
+ sourceCode . isSpaceBetweenTokens ( child , nextChild ) ;
157
+ }
159
158
160
- if ( ! prevChild && ! nextChild ) {
161
- return ;
162
- }
159
+ if ( ! prevChild && ! nextChild ) {
160
+ return ;
161
+ }
163
162
164
- const source = sourceCode . getText ( child ) ;
165
- const leadingSpace = ! ! ( prevChild && spaceBetweenPrev ( ) ) ;
166
- const trailingSpace = ! ! ( nextChild && spaceBetweenNext ( ) ) ;
167
- const leadingNewLine = ! ! prevChild ;
168
- const trailingNewLine = ! ! nextChild ;
163
+ const source = sourceCode . getText ( child ) ;
164
+ const leadingSpace = ! ! ( prevChild && spaceBetweenPrev ( ) ) ;
165
+ const trailingSpace = ! ! ( nextChild && spaceBetweenNext ( ) ) ;
166
+ const leadingNewLine = ! ! prevChild ;
167
+ const trailingNewLine = ! ! nextChild ;
169
168
170
- const key = nodeKey ( child ) ;
169
+ const key = nodeKey ( child ) ;
171
170
172
- if ( ! fixDetailsByNode [ key ] ) {
173
- fixDetailsByNode [ key ] = {
174
- node : child ,
175
- source : source ,
176
- descriptor : nodeDescriptor ( child )
177
- } ;
178
- }
171
+ if ( ! fixDetailsByNode [ key ] ) {
172
+ fixDetailsByNode [ key ] = {
173
+ node : child ,
174
+ source : source ,
175
+ descriptor : nodeDescriptor ( child )
176
+ } ;
177
+ }
179
178
180
- if ( leadingSpace ) {
181
- fixDetailsByNode [ key ] . leadingSpace = true ;
182
- }
183
- if ( leadingNewLine ) {
184
- fixDetailsByNode [ key ] . leadingNewLine = true ;
185
- }
186
- if ( trailingNewLine ) {
187
- fixDetailsByNode [ key ] . trailingNewLine = true ;
188
- }
189
- if ( trailingSpace ) {
190
- fixDetailsByNode [ key ] . trailingSpace = true ;
191
- }
192
- } ) ;
179
+ if ( leadingSpace ) {
180
+ fixDetailsByNode [ key ] . leadingSpace = true ;
181
+ }
182
+ if ( leadingNewLine ) {
183
+ fixDetailsByNode [ key ] . leadingNewLine = true ;
184
+ }
185
+ if ( trailingNewLine ) {
186
+ fixDetailsByNode [ key ] . trailingNewLine = true ;
187
+ }
188
+ if ( trailingSpace ) {
189
+ fixDetailsByNode [ key ] . trailingSpace = true ;
190
+ }
193
191
} ) ;
192
+ } ) ;
194
193
195
- Object . keys ( fixDetailsByNode ) . forEach ( key => {
196
- const details = fixDetailsByNode [ key ] ;
194
+ Object . keys ( fixDetailsByNode ) . forEach ( key => {
195
+ const details = fixDetailsByNode [ key ] ;
197
196
198
- const nodeToReport = details . node ;
199
- const descriptor = details . descriptor ;
200
- const source = details . source . replace ( / ( ^ + | + (? = \n ) * $ ) / g, '' ) ;
197
+ const nodeToReport = details . node ;
198
+ const descriptor = details . descriptor ;
199
+ const source = details . source . replace ( / ( ^ + | + (? = \n ) * $ ) / g, '' ) ;
201
200
202
- const leadingSpaceString = details . leadingSpace ? '\n{\' \'}' : '' ;
203
- const trailingSpaceString = details . trailingSpace ? '{\' \'}\n' : '' ;
204
- const leadingNewLineString = details . leadingNewLine ? '\n' : '' ;
205
- const trailingNewLineString = details . trailingNewLine ? '\n' : '' ;
201
+ const leadingSpaceString = details . leadingSpace ? '\n{\' \'}' : '' ;
202
+ const trailingSpaceString = details . trailingSpace ? '{\' \'}\n' : '' ;
203
+ const leadingNewLineString = details . leadingNewLine ? '\n' : '' ;
204
+ const trailingNewLineString = details . trailingNewLine ? '\n' : '' ;
206
205
207
- const replaceText = `${ leadingSpaceString } ${ leadingNewLineString } ${ source } ${ trailingNewLineString } ${ trailingSpaceString } ` ;
206
+ const replaceText = `${ leadingSpaceString } ${ leadingNewLineString } ${ source } ${ trailingNewLineString } ${ trailingSpaceString } ` ;
208
207
209
- context . report ( {
210
- node : nodeToReport ,
211
- message : `\`${ descriptor } \` must be placed on a new line` ,
212
- fix : function ( fixer ) {
213
- return fixer . replaceText ( nodeToReport , replaceText ) ;
214
- }
215
- } ) ;
208
+ context . report ( {
209
+ node : nodeToReport ,
210
+ message : `\`${ descriptor } \` must be placed on a new line` ,
211
+ fix : function ( fixer ) {
212
+ return fixer . replaceText ( nodeToReport , replaceText ) ;
213
+ }
216
214
} ) ;
217
- }
215
+ } ) ;
216
+ }
217
+
218
+ return {
219
+ JSXElement : handleJSX ,
220
+ JSXFragment : handleJSX
218
221
} ;
219
222
}
220
223
} ;
0 commit comments