@@ -101,9 +101,9 @@ function validateBeforeSelfClosing(context, node, option) {
101101 const leftToken = getTokenBeforeClosingBracket ( node ) ;
102102 const closingSlash = sourceCode . getTokenAfter ( leftToken ) ;
103103
104- if ( node . loc . start . line !== node . loc . end . line && option === 'multiline -always' ) {
104+ if ( node . loc . start . line !== node . loc . end . line && option === 'proportional -always' ) {
105105 if ( leftToken . loc . end . line === closingSlash . loc . start . line ) {
106- report ( context , messages . beforeSelfCloseNeedNewline , 'beforeSelfCloseNeedNewline' , {
106+ return report ( context , messages . beforeSelfCloseNeedNewline , 'beforeSelfCloseNeedNewline' , {
107107 node,
108108 loc : leftToken . loc . end ,
109109 fix ( fixer ) {
@@ -117,15 +117,17 @@ function validateBeforeSelfClosing(context, node, option) {
117117 return ;
118118 }
119119
120- if ( option === 'always' && ! sourceCode . isSpaceBetweenTokens ( leftToken , closingSlash ) ) {
120+ const adjacent = ! sourceCode . isSpaceBetweenTokens ( leftToken , closingSlash ) ;
121+
122+ if ( ( option === 'always' || option === 'proportional-always' ) && adjacent ) {
121123 report ( context , messages . beforeSelfCloseNeedSpace , 'beforeSelfCloseNeedSpace' , {
122124 node,
123125 loc : closingSlash . loc . start ,
124126 fix ( fixer ) {
125127 return fixer . insertTextBefore ( closingSlash , ' ' ) ;
126128 } ,
127129 } ) ;
128- } else if ( option === 'never' && sourceCode . isSpaceBetweenTokens ( leftToken , closingSlash ) ) {
130+ } else if ( option === 'never' && ! adjacent ) {
129131 report ( context , messages . beforeSelfCloseNoSpace , 'beforeSelfCloseNoSpace' , {
130132 node,
131133 loc : closingSlash . loc . start ,
@@ -178,54 +180,68 @@ function validateAfterOpening(context, node, option) {
178180
179181function validateBeforeClosing ( context , node , option ) {
180182 // Don't enforce this rule for self closing tags
181- if ( ! node . selfClosing ) {
182- const sourceCode = context . getSourceCode ( ) ;
183- const lastTokens = sourceCode . getLastTokens ( node , 2 ) ;
184- const closingToken = lastTokens [ 1 ] ;
185- const leftToken = lastTokens [ 0 ] ;
186-
187- if ( node . loc . start . line !== node . loc . end . line && option === 'multiline-always' ) {
188- if ( leftToken . loc . end . line === closingToken . loc . start . line ) {
189- report ( context , messages . beforeCloseNeedNewline , 'beforeCloseNeedNewline' , {
190- node,
191- loc : leftToken . loc . end ,
192- fix ( fixer ) {
193- return fixer . insertTextBefore ( closingToken , '\n' ) ;
194- } ,
195- } ) ;
196- }
197- }
198-
199- if ( leftToken . loc . start . line !== closingToken . loc . start . line ) {
200- return ;
201- }
183+ if ( node . selfClosing ) {
184+ return ;
185+ }
202186
203- const adjacent = ! sourceCode . isSpaceBetweenTokens ( leftToken , closingToken ) ;
187+ const sourceCode = context . getSourceCode ( ) ;
188+ const leftToken = option === 'proportional-always'
189+ ? getTokenBeforeClosingBracket ( node )
190+ : sourceCode . getLastTokens ( node , 2 ) [ 0 ] ;
191+ const closingToken = sourceCode . getTokenAfter ( leftToken ) ;
204192
205- if ( option === 'never' && ! adjacent ) {
206- report ( context , messages . beforeCloseNoSpace , 'beforeCloseNoSpace' , {
193+ if ( node . loc . start . line !== node . loc . end . line && option === 'proportional-always' ) {
194+ if ( leftToken . loc . end . line === closingToken . loc . start . line ) {
195+ return report ( context , messages . beforeCloseNeedNewline , 'beforeCloseNeedNewline' , {
207196 node,
208- loc : {
209- start : leftToken . loc . end ,
210- end : closingToken . loc . start ,
211- } ,
212- fix ( fixer ) {
213- return fixer . removeRange ( [ leftToken . range [ 1 ] , closingToken . range [ 0 ] ] ) ;
214- } ,
215- } ) ;
216- } else if ( option === 'always' && adjacent ) {
217- report ( context , messages . beforeCloseNeedSpace , 'beforeCloseNeedSpace' , {
218- node,
219- loc : {
220- start : leftToken . loc . end ,
221- end : closingToken . loc . start ,
222- } ,
197+ loc : leftToken . loc . end ,
223198 fix ( fixer ) {
224- return fixer . insertTextBefore ( closingToken , ' ' ) ;
199+ return fixer . insertTextBefore ( closingToken , '\n ' ) ;
225200 } ,
226201 } ) ;
227202 }
228203 }
204+
205+ if ( leftToken . loc . start . line !== closingToken . loc . start . line ) {
206+ return ;
207+ }
208+
209+ const adjacent = ! sourceCode . isSpaceBetweenTokens ( leftToken , closingToken ) ;
210+
211+ if ( option === 'never' && ! adjacent ) {
212+ report ( context , messages . beforeCloseNoSpace , 'beforeCloseNoSpace' , {
213+ node,
214+ loc : {
215+ start : leftToken . loc . end ,
216+ end : closingToken . loc . start ,
217+ } ,
218+ fix ( fixer ) {
219+ return fixer . removeRange ( [ leftToken . range [ 1 ] , closingToken . range [ 0 ] ] ) ;
220+ } ,
221+ } ) ;
222+ } else if ( option === 'always' && adjacent ) {
223+ report ( context , messages . beforeCloseNeedSpace , 'beforeCloseNeedSpace' , {
224+ node,
225+ loc : {
226+ start : leftToken . loc . end ,
227+ end : closingToken . loc . start ,
228+ } ,
229+ fix ( fixer ) {
230+ return fixer . insertTextBefore ( closingToken , ' ' ) ;
231+ } ,
232+ } ) ;
233+ } else if ( option === 'proportional-always' && node . type === 'JSXOpeningElement' && adjacent !== ( node . loc . start . line === node . loc . end . line ) ) {
234+ report ( context , messages . beforeCloseNeedSpace , 'beforeCloseNeedSpace' , {
235+ node,
236+ loc : {
237+ start : leftToken . loc . end ,
238+ end : closingToken . loc . start ,
239+ } ,
240+ fix ( fixer ) {
241+ return fixer . insertTextBefore ( closingToken , ' ' ) ;
242+ } ,
243+ } ) ;
244+ }
229245}
230246
231247// ------------------------------------------------------------------------------
@@ -259,13 +275,13 @@ module.exports = {
259275 enum : [ 'always' , 'never' , 'allow' ] ,
260276 } ,
261277 beforeSelfClosing : {
262- enum : [ 'always' , 'multiline -always' , 'never' , 'allow' ] ,
278+ enum : [ 'always' , 'proportional -always' , 'never' , 'allow' ] ,
263279 } ,
264280 afterOpening : {
265281 enum : [ 'always' , 'allow-multiline' , 'never' , 'allow' ] ,
266282 } ,
267283 beforeClosing : {
268- enum : [ 'always' , 'multiline -always' , 'never' , 'allow' ] ,
284+ enum : [ 'always' , 'proportional -always' , 'never' , 'allow' ] ,
269285 } ,
270286 } ,
271287 default : optionDefaults ,
0 commit comments