Skip to content

Commit d998b85

Browse files
V2dhaljharb
authored andcommitted
[Fix] jsx-no-target-blank: False negative when rel attribute is assigned using ConditionalExpression
1 parent 6b42731 commit d998b85

File tree

3 files changed

+52
-0
lines changed

3 files changed

+52
-0
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
1616
* [`jsx-key`]: avoid a crash on a non-array node.body from [#3320][] ([#3328][] @ljharb)
1717
* [`display-name`]: fix false positive for assignment of function returning null ([#3331][] @apbarrero)
1818
* [`display-name`]: fix identifying `_` as a capital letter ([#3335][] @apbarrero)
19+
* [`jsx-no-target-blank`]: False negative when rel attribute is assigned using ConditionalExpression ([#3332][] @V2dha)
1920

2021
### Changed
2122
* [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
2526

2627
[#3339]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3339
2728
[#3335]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3335
29+
[#3332]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3332
2830
[#3331]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3331
2931
[#3328]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3328
3032
[#3327]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3327

lib/rules/jsx-no-target-blank.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,29 @@ function getStringFromValue(value) {
7474
if (value.expression.type === 'TemplateLiteral') {
7575
return value.expression.quasis[0].value.cooked;
7676
}
77+
const expr = value.expression;
78+
if (expr.type === 'ConditionalExpression') {
79+
if (
80+
typeof expr.consequent.value === 'string'
81+
&& (
82+
(expr.consequent.value && expr.consequent.value.toLowerCase() === 'noreferrer')
83+
|| (expr.consequent.value && expr.consequent.value.toLowerCase() === 'noopener noreferrer')
84+
|| (expr.consequent.value && expr.consequent.value.toLowerCase() === 'noreferrer noopener')
85+
)
86+
) {
87+
return expr.consequent.value;
88+
}
89+
if (
90+
typeof expr.alternate.value === 'string'
91+
&& (
92+
(expr.alternate.value && expr.alternate.value.toLowerCase() === 'noreferrer')
93+
|| (expr.alternate.value && expr.alternate.value.toLowerCase() === 'noopener noreferrer')
94+
|| (expr.consequent.value && expr.consequent.value.toLowerCase() === 'noreferrer noopener')
95+
)
96+
) {
97+
return expr.alternate.value;
98+
}
99+
}
77100
return value.expression && value.expression.value;
78101
}
79102
}

tests/lib/rules/jsx-no-target-blank.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,21 @@ ruleTester.run('jsx-no-target-blank', rule, {
141141
{
142142
code: '<a href target="_blank"/>',
143143
},
144+
{
145+
code: '<a href={href} target={isExternal ? "_blank" : undefined} rel="noopener noreferrer" />',
146+
},
147+
{
148+
code: '<a href={href} target={isExternal ? "_blank" : undefined} rel={isExternal ? "noopener noreferrer" : undefined} />',
149+
},
150+
{
151+
code: '<a href={href} target={isExternal ? "_blank" : undefined} rel={isExternal ? undefined : "noopener noreferrer"} />',
152+
},
153+
{
154+
code: '<a href={href} target={isExternal ? undefined : "_blank"} rel={isExternal ? "noreferrer" : "noopener noreferrer"} />',
155+
},
156+
{
157+
code: '<a href={href} target="_blank" rel={isExternal ? "noopener" : "noopener noreferrer"} />',
158+
},
144159
]),
145160
invalid: parsers.all([
146161
{
@@ -352,5 +367,17 @@ ruleTester.run('jsx-no-target-blank', rule, {
352367
options: [{ forms: true, links: false }],
353368
errors: defaultErrors,
354369
},
370+
{
371+
code: '<a href={href} target="_blank" rel={isExternal ? "undefined" : "undefined"} />',
372+
errors: defaultErrors,
373+
},
374+
{
375+
code: '<a href={href} target="_blank" rel={isExternal ? "noopener" : "undefined"} />',
376+
errors: defaultErrors,
377+
},
378+
{
379+
code: '<a href={href} target="_blank" rel={isExternal ? "undefined" : "noopener"} />',
380+
errors: defaultErrors,
381+
},
355382
]),
356383
});

0 commit comments

Comments
 (0)