diff --git a/lib/rules/jsx-no-useless-fragment.js b/lib/rules/jsx-no-useless-fragment.js index 6b131a5ad2..8489aeb1bf 100644 --- a/lib/rules/jsx-no-useless-fragment.js +++ b/lib/rules/jsx-no-useless-fragment.js @@ -12,6 +12,13 @@ function isJSXText(node) { return !!node && (node.type === 'JSXText' || node.type === 'Literal'); } +/** + * @param {string} text + */ +function isOnlyWhitespace(text) { + return text.trim().length === 0; +} + /** * Test if node is like `_` * @param {JSXElement} node @@ -55,7 +62,7 @@ module.exports = { */ function isPaddingSpaces(node) { return isJSXText(node) && - /^\s*$/.test(node.raw) && + isOnlyWhitespace(node.raw) && node.raw.includes('\n'); } @@ -86,7 +93,7 @@ module.exports = { } /** - * Avoid fixing case like: + * Avoid fixing cases that involve tricky whitespaces changes like: * ```jsx *
* pine<> @@ -94,6 +101,7 @@ module.exports = { * *
* ``` + * Give up fixing if one neighboring node is JSXText and is not only whitespaces * @param {JSXElement|JSXFragment} node * @returns {boolean} */ @@ -106,10 +114,14 @@ module.exports = { const previousChild = node.parent.children[i - 1]; const nextChild = node.parent.children[i + 1]; - return ( - (!isJSXText(previousChild) || /\s$/.test(previousChild.value)) && - (!isJSXText(nextChild) || /^\s/.test(nextChild.value)) - ); + if ( + (isJSXText(previousChild) && !isOnlyWhitespace(previousChild.value)) || + (isJSXText(nextChild) && !isOnlyWhitespace(nextChild.value)) + ) { + return false; + } + + return true; } function fix(node, fixer) { diff --git a/tests/lib/rules/jsx-no-useless-fragment.js b/tests/lib/rules/jsx-no-useless-fragment.js index 1dd5c84e8d..2c572d9aac 100644 --- a/tests/lib/rules/jsx-no-useless-fragment.js +++ b/tests/lib/rules/jsx-no-useless-fragment.js @@ -164,7 +164,7 @@ ruleTester.run('jsx-no-uselses-fragment', rule, { }, { code: '
a <>{""}{""} a
', - output: '
a {""}{""} a
', + output: null, errors: [{messageId: 'ChildOfHtmlElement'}], parser: parsers.BABEL_ESLINT }