diff --git a/CHANGELOG.md b/CHANGELOG.md index 90bc4e80e5..05bc33652e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange * [`jsx-key`]: avoid a crash on a non-array node.body from [#3320][] ([#3328][] @ljharb) * [`display-name`]: fix false positive for assignment of function returning null ([#3331][] @apbarrero) * [`display-name`]: fix identifying `_` as a capital letter ([#3335][] @apbarrero) +* [`jsx-no-target-blank`]: False negative when rel attribute is assigned using ConditionalExpression ([#3332][] @V2dha) ### Changed * [Refactor] [`jsx-indent-props`]: improved readability of the checkNodesIndent function ([#3315][] @caroline223) @@ -25,6 +26,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange [#3339]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3339 [#3335]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3335 +[#3332]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3332 [#3331]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3331 [#3328]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3328 [#3327]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3327 diff --git a/lib/rules/jsx-no-target-blank.js b/lib/rules/jsx-no-target-blank.js index 1f6edc9e07..e957fb509a 100644 --- a/lib/rules/jsx-no-target-blank.js +++ b/lib/rules/jsx-no-target-blank.js @@ -74,6 +74,29 @@ function getStringFromValue(value) { if (value.expression.type === 'TemplateLiteral') { return value.expression.quasis[0].value.cooked; } + const expr = value.expression; + if (expr.type === 'ConditionalExpression') { + if ( + typeof expr.consequent.value === 'string' + && ( + (expr.consequent.value && expr.consequent.value.toLowerCase() === 'noreferrer') + || (expr.consequent.value && expr.consequent.value.toLowerCase() === 'noopener noreferrer') + || (expr.consequent.value && expr.consequent.value.toLowerCase() === 'noreferrer noopener') + ) + ) { + return expr.consequent.value; + } + if ( + typeof expr.alternate.value === 'string' + && ( + (expr.alternate.value && expr.alternate.value.toLowerCase() === 'noreferrer') + || (expr.alternate.value && expr.alternate.value.toLowerCase() === 'noopener noreferrer') + || (expr.consequent.value && expr.consequent.value.toLowerCase() === 'noreferrer noopener') + ) + ) { + return expr.alternate.value; + } + } return value.expression && value.expression.value; } } diff --git a/tests/lib/rules/jsx-no-target-blank.js b/tests/lib/rules/jsx-no-target-blank.js index 27a63cb09d..aad51048d4 100644 --- a/tests/lib/rules/jsx-no-target-blank.js +++ b/tests/lib/rules/jsx-no-target-blank.js @@ -141,6 +141,21 @@ ruleTester.run('jsx-no-target-blank', rule, { { code: '', }, + { + code: '', + }, + { + code: '', + }, + { + code: '', + }, + { + code: '', + }, + { + code: '', + }, ]), invalid: parsers.all([ { @@ -352,5 +367,17 @@ ruleTester.run('jsx-no-target-blank', rule, { options: [{ forms: true, links: false }], errors: defaultErrors, }, + { + code: '', + errors: defaultErrors, + }, + { + code: '', + errors: defaultErrors, + }, + { + code: '', + errors: defaultErrors, + }, ]), });