From 1b7faf0702b1af86b6a0ddafc37cf45d60f5d4d8 Mon Sep 17 00:00:00 2001 From: Azat S Date: Thu, 8 Jun 2023 15:54:14 +0300 Subject: [PATCH] feat: add `skipJSXText` option to `no-irregular-whitespace` rule (#17182) * feat: add `skipJSXText` option to `no-irregular-whitespace` rule * fix: remove unnecessary jsx text value check * docs: fix no-irregular-whitespace docs * test: add invalid cases for jsx in no-irregular-whitespace rule * docs: fix check jsx node func jsdoc * style: fix trailing commas --- docs/src/rules/no-irregular-whitespace.md | 18 ++ lib/rules/no-irregular-whitespace.js | 18 ++ tests/lib/rules/no-irregular-whitespace.js | 358 +++++++++++++++++++++ 3 files changed, 394 insertions(+) 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 + } + ] } ] });