Skip to content

Commit

Permalink
Strip trailing spaces
Browse files Browse the repository at this point in the history
  • Loading branch information
RobertAKARobin committed Sep 3, 2024
1 parent 9d3fb4a commit 0b9ac9c
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 28 deletions.
4 changes: 3 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@
"eslint.validate": [
"javascript", // ...
"html" // Add "html" to enable linting `.html` files.
]
],

"files.trimTrailingWhitespace": false
}
7 changes: 5 additions & 2 deletions docs/rules/no-extra-spacing-text.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,16 @@ module.exports = {

## Rule Details

[Whitespace in HTML is largely ignored](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Whitespace), so the purpose of this rule is to prevent unnecessary sequences of whitespace in text.
[Whitespace in HTML is largely ignored](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Whitespace), so the purpose of this rule is to prevent unnecessary whitespace in text, such as:

- Tab characters
- Sequences of more than 1 whitepsace character

When used with `--fix`, the rule will replace invalid whitespace with a single space.

Note:

- This rule ignores whitespace at the start and end of lines/strings so as not to conflict with indentation rules. See [./indent](@html-eslint/indent).
- This rule ignores whitespace at the start of lines in order to not conflict with indentation rules. See [./indent](@html-eslint/indent).
- This rule does **not** affect whitespace around attributes. See [./no-extra-spacing-attrs](@html-eslint/no-extra-spacing-attrs).

Examples of **incorrect** code for this rule:
Expand Down
13 changes: 7 additions & 6 deletions packages/eslint-plugin/lib/rules/no-extra-spacing-text.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ module.exports = {
},
],
messages: {
[MESSAGE_IDS.UNEXPECTED]: "Multiple consecutive spaces not allowed here",
[MESSAGE_IDS.UNEXPECTED]: "Tabs and/or multiple consecutive spaces not allowed here",
},
},

Expand Down Expand Up @@ -83,7 +83,7 @@ module.exports = {
*/
function stripConsecutiveSpaces(node) {
const text = node.value;
const matcher = /(^|[^\n \t])([ \t]{2,})($|[^\n \t])/g;
const matcher = /(^|[^\n \t])([ \t]+\n|\t[\t ]*|[ \t]{2,})/g;

// eslint-disable-next-line no-constant-condition
while (true) {
Expand All @@ -93,9 +93,7 @@ module.exports = {
}

const space = offender[2];
const spaceAfter = offender[3];
const indexStart =
node.range[0] + matcher.lastIndex - space.length - spaceAfter.length;
const indexStart = node.range[0] + matcher.lastIndex - space.length;
const indexEnd = indexStart + space.length;

context.report({
Expand All @@ -106,7 +104,10 @@ module.exports = {
},
messageId: MESSAGE_IDS.UNEXPECTED,
fix(fixer) {
return fixer.replaceTextRange([indexStart, indexEnd], ` `);
return fixer.replaceTextRange(
[indexStart, indexEnd],
space.endsWith(`\n`) ? `\n` : ` `
);
},
});
}
Expand Down
75 changes: 56 additions & 19 deletions packages/eslint-plugin/tests/rules/no-extra-spacing-text.test.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,29 @@
const createRuleTester = require("../rule-tester");
const rule = require("../../lib/rules/no-extra-spacing-text");

/**
* @param {Array<Array<number, number, number>>} positions
*/

function errorsAt(...positions) {
return positions.map(([line, column, length]) => ({
messageId: `unexpected`,
line,
column,
endLine: line,
endColumn: column + length,
}));
return positions.map(input => {
const [line, column, length] = input;
if (input.length === 3) {
return {
messageId: `unexpected`,
line,
column,
endLine: line,
endColumn: column + length,
};
} else {
const [line, column, endLine, endColumn] = input;
return {
messageId: `unexpected`,
line,
column,
endLine,
endColumn,
};
}
});
}

const ruleTester = createRuleTester();
Expand All @@ -23,7 +35,7 @@ ruleTester.run("no-extra-spacing-text", rule, {
},

{
code: `<div>\tfoo\tbar\t</div>`,
code: `<div> foo bar </div>`,
},

{
Expand All @@ -38,7 +50,7 @@ ruleTester.run("no-extra-spacing-text", rule, {
},

{
code: `<pre> foo bar </pre><script> const foo = 'bar' </script><style> .foo { bar } </style>`,
code: `<pre> foo\t\t\tbar </pre><script> const foo = 'bar' </script><style> .foo { bar } </style>`,
options: [
{
skip: [`pre`],
Expand All @@ -64,15 +76,15 @@ ruleTester.run("no-extra-spacing-text", rule, {

invalid: [
{
code: `foo bar`,
output: `foo bar`,
errors: errorsAt([1, 4, 3]),
code: `foo bar `,
output: `foo bar `,
errors: errorsAt([1, 4, 3], [1, 10, 3]),
},

{
code: `<div>\tfoo \t</div>`,
output: `<div>\tfoo </div>`,
errors: errorsAt([1, 10, 2]),
output: `<div> foo </div>`,
errors: errorsAt([1, 6, 1], [1, 10, 2]),
},

{
Expand All @@ -81,6 +93,28 @@ ruleTester.run("no-extra-spacing-text", rule, {
errors: errorsAt([1, 6, 2], [1, 11, 3]),
},

{
code: `<div>foo \n</div>`,
output: `<div>foo\n</div>`,
errors: errorsAt([1, 9, 2, 1]),
},

{
code: `<div>foo\t\n</div>`,
output: `<div>foo\n</div>`,
errors: errorsAt([1, 9, 2, 1]),
},

{
code: `<div>\n\tfoo \n</div> \n<div>\n\tbar\t\n</div>`,
output: `<div>\n\tfoo\n</div>\n<div>\n\tbar\n</div>`,
errors: errorsAt(
[2, 5, 3, 1],
[3, 7, 4, 1],
[5, 5, 6, 1],
),
},

{
code: `
<div> \t\tfoo \t\t</div>
Expand All @@ -94,15 +128,18 @@ ruleTester.run("no-extra-spacing-text", rule, {
{
code: `
<div>
foo bar
foo bar
</div>
`,
output: `
<div>
foo bar
</div>
`,
errors: errorsAt([3, 6, 5]),
errors: errorsAt(
[3, 6, 5],
[3, 14, 4, 1],
),
},

{
Expand Down

0 comments on commit 0b9ac9c

Please sign in to comment.