Skip to content

Commit 72ca5b3

Browse files
authoredMar 6, 2018
Update: Correctly indent JSXText with trailing linebreaks (fixes #9878) (#10055)
This fixes a bug in the `indent` rule where a line comparison with the end of a token would use the end location of any trailing whitespace in the token, rather than the location of the last non-whitespace character in the token. This behavior went against user intuition for tokens with trailing whitespace.
1 parent 2a4c838 commit 72ca5b3

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed
 

‎lib/rules/indent.js

+18-1
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,19 @@ module.exports = {
779779
return (statement.type === "ExpressionStatement" || statement.type === "VariableDeclaration") && statement.parent.type === "Program";
780780
}
781781

782+
/**
783+
* Counts the number of linebreaks that follow the last non-whitespace character in a string
784+
* @param {string} string The string to check
785+
* @returns {number} The number of JavaScript linebreaks that follow the last non-whitespace character,
786+
* or the total number of linebreaks if the string is all whitespace.
787+
*/
788+
function countTrailingLinebreaks(string) {
789+
const trailingWhitespace = string.match(/\s*$/)[0];
790+
const linebreakMatches = trailingWhitespace.match(astUtils.createGlobalLinebreakMatcher());
791+
792+
return linebreakMatches === null ? 0 : linebreakMatches.length;
793+
}
794+
782795
/**
783796
* Check indentation for lists of elements (arrays, objects, function params)
784797
* @param {ASTNode[]} elements List of elements that should be offset
@@ -836,8 +849,12 @@ module.exports = {
836849
} else {
837850
const previousElement = elements[index - 1];
838851
const firstTokenOfPreviousElement = previousElement && getFirstToken(previousElement);
852+
const previousElementLastToken = previousElement && sourceCode.getLastToken(previousElement);
839853

840-
if (previousElement && sourceCode.getLastToken(previousElement).loc.end.line > startToken.loc.end.line) {
854+
if (
855+
previousElement &&
856+
previousElementLastToken.loc.end.line - countTrailingLinebreaks(previousElementLastToken.value) > startToken.loc.end.line
857+
) {
841858
offsets.setDesiredOffsets(element.range, firstTokenOfPreviousElement, 0);
842859
}
843860
}

‎tests/lib/rules/indent.js

+36
Original file line numberDiff line numberDiff line change
@@ -4607,6 +4607,16 @@ ruleTester.run("indent", rule, {
46074607
);
46084608
}
46094609
`,
4610+
unIndent`
4611+
<div>foo
4612+
<div>bar</div>
4613+
</div>
4614+
`,
4615+
unIndent`
4616+
<small>Foo bar&nbsp;
4617+
<a>baz qux</a>.
4618+
</small>
4619+
`,
46104620
{
46114621
code: unIndent`
46124622
a(b
@@ -9136,6 +9146,32 @@ ruleTester.run("indent", rule, {
91369146
`,
91379147
errors: expectedErrors([3, 8, 6, "Block"])
91389148
},
9149+
{
9150+
code: unIndent`
9151+
<div>foo
9152+
<div>bar</div>
9153+
</div>
9154+
`,
9155+
output: unIndent`
9156+
<div>foo
9157+
<div>bar</div>
9158+
</div>
9159+
`,
9160+
errors: expectedErrors([2, 4, 0, "Punctuator"])
9161+
},
9162+
{
9163+
code: unIndent`
9164+
<small>Foo bar&nbsp;
9165+
<a>baz qux</a>.
9166+
</small>
9167+
`,
9168+
output: unIndent`
9169+
<small>Foo bar&nbsp;
9170+
<a>baz qux</a>.
9171+
</small>
9172+
`,
9173+
errors: expectedErrors([2, 4, 0, "Punctuator"])
9174+
},
91399175
{
91409176
code: unIndent`
91419177
({

0 commit comments

Comments
 (0)