diff --git a/docs/src/rules/no-irregular-whitespace.md b/docs/src/rules/no-irregular-whitespace.md
index 258733b0827..cb2c62bda58 100644
--- a/docs/src/rules/no-irregular-whitespace.md
+++ b/docs/src/rules/no-irregular-whitespace.md
@@ -63,6 +63,7 @@ This rule has an object option for exceptions:
* `"skipComments": true` allows any whitespace characters in comments
* `"skipRegExps": true` allows any whitespace characters in regular expression literals
* `"skipTemplates": true` allows any whitespace characters in template literals
+* `"skipJSXText": true` allows any whitespace characters in JSX text
### skipStrings
@@ -192,6 +193,23 @@ function thing() {
:::
+### skipJSXText
+
+Examples of additional **correct** code for this rule with the `{ "skipJSXText": true }` option:
+
+::: correct
+
+```js
+/*eslint no-irregular-whitespace: ["error", { "skipJSXText": true }]*/
+/*eslint-env es6*/
+
+function Thing() {
+ return
text in JSX
;
+}
+```
+
+:::
+
## When Not To Use It
If you decide that you wish to use whitespace other than tabs and spaces outside of strings in your application.
diff --git a/lib/rules/no-irregular-whitespace.js b/lib/rules/no-irregular-whitespace.js
index 0badc58b87a..ab7ccac54e4 100644
--- a/lib/rules/no-irregular-whitespace.js
+++ b/lib/rules/no-irregular-whitespace.js
@@ -55,6 +55,10 @@ module.exports = {
skipRegExps: {
type: "boolean",
default: false
+ },
+ skipJSXText: {
+ type: "boolean",
+ default: false
}
},
additionalProperties: false
@@ -77,6 +81,7 @@ module.exports = {
const skipStrings = options.skipStrings !== false;
const skipRegExps = !!options.skipRegExps;
const skipTemplates = !!options.skipTemplates;
+ const skipJSXText = !!options.skipJSXText;
const sourceCode = context.sourceCode;
const commentNodes = sourceCode.getAllComments();
@@ -144,6 +149,18 @@ module.exports = {
}
}
+ /**
+ * Checks JSX nodes for errors that we are choosing to ignore and calls the relevant methods to remove the errors
+ * @param {ASTNode} node to check for matching errors.
+ * @returns {void}
+ * @private
+ */
+ function removeInvalidNodeErrorsInJSXText(node) {
+ if (ALL_IRREGULARS.test(node.raw)) {
+ removeWhitespaceError(node);
+ }
+ }
+
/**
* Checks the program source for irregular whitespace
* @param {ASTNode} node The program node
@@ -239,6 +256,7 @@ module.exports = {
nodes.Literal = removeInvalidNodeErrorsInLiteral;
nodes.TemplateElement = skipTemplates ? removeInvalidNodeErrorsInTemplateLiteral : noop;
+ nodes.JSXText = skipJSXText ? removeInvalidNodeErrorsInJSXText : noop;
nodes["Program:exit"] = function() {
if (skipComments) {
diff --git a/tests/lib/rules/no-irregular-whitespace.js b/tests/lib/rules/no-irregular-whitespace.js
index 9becb5a9ecf..e6ca5d111b6 100644
--- a/tests/lib/rules/no-irregular-whitespace.js
+++ b/tests/lib/rules/no-irregular-whitespace.js
@@ -171,6 +171,28 @@ ruleTester.run("no-irregular-whitespace", rule, {
{ code: "const error = `\n\u3000\n`;", options: [{ skipTemplates: true }], parserOptions: { ecmaVersion: 6 } },
{ code: "const error = `foo\u3000bar\nfoo\u3000bar`;", options: [{ skipTemplates: true }], parserOptions: { ecmaVersion: 6 } },
+ { code: "\u000B
;", options: [{ skipJSXText: true }], parserOptions: { ecmaFeatures: { jsx: true } } },
+ { code: "\u000C
;", options: [{ skipJSXText: true }], parserOptions: { ecmaFeatures: { jsx: true } } },
+ { code: "\u0085
;", options: [{ skipJSXText: true }], parserOptions: { ecmaFeatures: { jsx: true } } },
+ { code: "\u00A0
;", options: [{ skipJSXText: true }], parserOptions: { ecmaFeatures: { jsx: true } } },
+ { code: "\u180E
;", options: [{ skipJSXText: true }], parserOptions: { ecmaFeatures: { jsx: true } } },
+ { code: "\ufeff
;", options: [{ skipJSXText: true }], parserOptions: { ecmaFeatures: { jsx: true } } },
+ { code: "\u2000
;", options: [{ skipJSXText: true }], parserOptions: { ecmaFeatures: { jsx: true } } },
+ { code: "\u2001
;", options: [{ skipJSXText: true }], parserOptions: { ecmaFeatures: { jsx: true } } },
+ { code: "\u2002
;", options: [{ skipJSXText: true }], parserOptions: { ecmaFeatures: { jsx: true } } },
+ { code: "\u2003
;", options: [{ skipJSXText: true }], parserOptions: { ecmaFeatures: { jsx: true } } },
+ { code: "\u2004
;", options: [{ skipJSXText: true }], parserOptions: { ecmaFeatures: { jsx: true } } },
+ { code: "\u2005
;", options: [{ skipJSXText: true }], parserOptions: { ecmaFeatures: { jsx: true } } },
+ { code: "\u2006
;", options: [{ skipJSXText: true }], parserOptions: { ecmaFeatures: { jsx: true } } },
+ { code: "\u2007
;", options: [{ skipJSXText: true }], parserOptions: { ecmaFeatures: { jsx: true } } },
+ { code: "\u2008
;", options: [{ skipJSXText: true }], parserOptions: { ecmaFeatures: { jsx: true } } },
+ { code: "\u2009
;", options: [{ skipJSXText: true }], parserOptions: { ecmaFeatures: { jsx: true } } },
+ { code: "\u200A
;", options: [{ skipJSXText: true }], parserOptions: { ecmaFeatures: { jsx: true } } },
+ { code: "\u200B
;", options: [{ skipJSXText: true }], parserOptions: { ecmaFeatures: { jsx: true } } },
+ { code: "\u202F
;", options: [{ skipJSXText: true }], parserOptions: { ecmaFeatures: { jsx: true } } },
+ { code: "\u205f
;", options: [{ skipJSXText: true }], parserOptions: { ecmaFeatures: { jsx: true } } },
+ { code: "\u3000
;", options: [{ skipJSXText: true }], parserOptions: { ecmaFeatures: { jsx: true } } },
+
// Unicode BOM.
"\uFEFFconsole.log('hello BOM');"
],
@@ -993,6 +1015,342 @@ ruleTester.run("no-irregular-whitespace", rule, {
endColumn: 2
}
]
+ },
+ {
+ code: "\u000B
;",
+ parserOptions: {
+ ecmaFeatures: {
+ jsx: true
+ }
+ },
+ errors: [
+ {
+ messageId: "noIrregularWhitespace",
+ type: "Program",
+ line: 1,
+ column: 6
+ }
+ ]
+ },
+ {
+ code: "\u000C
;",
+ parserOptions: {
+ ecmaFeatures: {
+ jsx: true
+ }
+ },
+ errors: [
+ {
+ messageId: "noIrregularWhitespace",
+ type: "Program",
+ line: 1,
+ column: 6
+ }
+ ]
+ },
+ {
+ code: "\u0085
;",
+ parserOptions: {
+ ecmaFeatures: {
+ jsx: true
+ }
+ },
+ errors: [
+ {
+ messageId: "noIrregularWhitespace",
+ type: "Program",
+ line: 1,
+ column: 6
+ }
+ ]
+ },
+ {
+ code: "\u00A0
;",
+ parserOptions: {
+ ecmaFeatures: {
+ jsx: true
+ }
+ },
+ errors: [
+ {
+ messageId: "noIrregularWhitespace",
+ type: "Program",
+ line: 1,
+ column: 6
+ }
+ ]
+ },
+ {
+ code: "\u180E
;",
+ parserOptions: {
+ ecmaFeatures: {
+ jsx: true
+ }
+ },
+ errors: [
+ {
+ messageId: "noIrregularWhitespace",
+ type: "Program",
+ line: 1,
+ column: 6
+ }
+ ]
+ },
+ {
+ code: "\ufeff
;",
+ parserOptions: {
+ ecmaFeatures: {
+ jsx: true
+ }
+ },
+ errors: [
+ {
+ messageId: "noIrregularWhitespace",
+ type: "Program",
+ line: 1,
+ column: 6
+ }
+ ]
+ },
+ {
+ code: "\u2000
;",
+ parserOptions: {
+ ecmaFeatures: {
+ jsx: true
+ }
+ },
+ errors: [
+ {
+ messageId: "noIrregularWhitespace",
+ type: "Program",
+ line: 1,
+ column: 6
+ }
+ ]
+ },
+ {
+ code: "\u2001
;",
+ parserOptions: {
+ ecmaFeatures: {
+ jsx: true
+ }
+ },
+ errors: [
+ {
+ messageId: "noIrregularWhitespace",
+ type: "Program",
+ line: 1,
+ column: 6
+ }
+ ]
+ },
+ {
+ code: "\u2002
;",
+ parserOptions: {
+ ecmaFeatures: {
+ jsx: true
+ }
+ },
+ errors: [
+ {
+ messageId: "noIrregularWhitespace",
+ type: "Program",
+ line: 1,
+ column: 6
+ }
+ ]
+ },
+ {
+ code: "\u2003
;",
+ parserOptions: {
+ ecmaFeatures: {
+ jsx: true
+ }
+ },
+ errors: [
+ {
+ messageId: "noIrregularWhitespace",
+ type: "Program",
+ line: 1,
+ column: 6
+ }
+ ]
+ },
+ {
+ code: "\u2004
;",
+ parserOptions: {
+ ecmaFeatures: {
+ jsx: true
+ }
+ },
+ errors: [
+ {
+ messageId: "noIrregularWhitespace",
+ type: "Program",
+ line: 1,
+ column: 6
+ }
+ ]
+ },
+ {
+ code: "\u2005
;",
+ parserOptions: {
+ ecmaFeatures: {
+ jsx: true
+ }
+ },
+ errors: [
+ {
+ messageId: "noIrregularWhitespace",
+ type: "Program",
+ line: 1,
+ column: 6
+ }
+ ]
+ },
+ {
+ code: "\u2006
;",
+ parserOptions: {
+ ecmaFeatures: {
+ jsx: true
+ }
+ },
+ errors: [
+ {
+ messageId: "noIrregularWhitespace",
+ type: "Program",
+ line: 1,
+ column: 6
+ }
+ ]
+ },
+ {
+ code: "\u2007
;",
+ parserOptions: {
+ ecmaFeatures: {
+ jsx: true
+ }
+ },
+ errors: [
+ {
+ messageId: "noIrregularWhitespace",
+ type: "Program",
+ line: 1,
+ column: 6
+ }
+ ]
+ },
+ {
+ code: "\u2008
;",
+ parserOptions: {
+ ecmaFeatures: {
+ jsx: true
+ }
+ },
+ errors: [
+ {
+ messageId: "noIrregularWhitespace",
+ type: "Program",
+ line: 1,
+ column: 6
+ }
+ ]
+ },
+ {
+ code: "\u2009
;",
+ parserOptions: {
+ ecmaFeatures: {
+ jsx: true
+ }
+ },
+ errors: [
+ {
+ messageId: "noIrregularWhitespace",
+ type: "Program",
+ line: 1,
+ column: 6
+ }
+ ]
+ },
+ {
+ code: "\u200A
;",
+ parserOptions: {
+ ecmaFeatures: {
+ jsx: true
+ }
+ },
+ errors: [
+ {
+ messageId: "noIrregularWhitespace",
+ type: "Program",
+ line: 1,
+ column: 6
+ }
+ ]
+ },
+ {
+ code: "\u200B
;",
+ parserOptions: {
+ ecmaFeatures: {
+ jsx: true
+ }
+ },
+ errors: [
+ {
+ messageId: "noIrregularWhitespace",
+ type: "Program",
+ line: 1,
+ column: 6
+ }
+ ]
+ },
+ {
+ code: "\u202F
;",
+ parserOptions: {
+ ecmaFeatures: {
+ jsx: true
+ }
+ },
+ errors: [
+ {
+ messageId: "noIrregularWhitespace",
+ type: "Program",
+ line: 1,
+ column: 6
+ }
+ ]
+ },
+ {
+ code: "\u205f
;",
+ parserOptions: {
+ ecmaFeatures: {
+ jsx: true
+ }
+ },
+ errors: [
+ {
+ messageId: "noIrregularWhitespace",
+ type: "Program",
+ line: 1,
+ column: 6
+ }
+ ]
+ },
+ {
+ code: "\u3000
;",
+ parserOptions: {
+ ecmaFeatures: {
+ jsx: true
+ }
+ },
+ errors: [
+ {
+ messageId: "noIrregularWhitespace",
+ type: "Program",
+ line: 1,
+ column: 6
+ }
+ ]
}
]
});