Skip to content

Commit 5ba876b

Browse files
committed
fix: jsx-no-target-blank support for conditionals
1 parent bf59919 commit 5ba876b

File tree

2 files changed

+24
-7
lines changed

2 files changed

+24
-7
lines changed

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

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ function hasDynamicLink(node, linkAttribute) {
6565
}
6666
}
6767

68-
function getStringFromValue(value) {
68+
function getStringFromValue(value, targetValue) {
6969
if (value) {
7070
if (value.type === 'Literal') {
7171
return value.value;
@@ -75,24 +75,32 @@ function getStringFromValue(value) {
7575
return value.expression.quasis[0].value.cooked;
7676
}
7777
const expr = value.expression;
78-
return expr && (
79-
expr.type === 'ConditionalExpression'
80-
? [expr.consequent.value, expr.alternate.value]
81-
: expr.value
82-
);
78+
if (expr && (expr.type === 'ConditionalExpression')) {
79+
const relValues = [expr.consequent.value, expr.alternate.value];
80+
if (targetValue.type === 'JSXExpressionContainer' && targetValue.expression && targetValue.expression.type === 'ConditionalExpression') {
81+
const targetTestCond = targetValue.expression.test.name;
82+
const relTestCond = value.expression.test.name;
83+
const targetBlankIndex = [targetValue.expression.consequent.value, targetValue.expression.alternate.value].indexOf('_blank');
84+
if (targetTestCond === relTestCond) return relValues[targetBlankIndex];
85+
}
86+
return relValues;
87+
}
88+
return expr.value;
8389
}
8490
}
8591
return null;
8692
}
8793

8894
function hasSecureRel(node, allowReferrer, warnOnSpreadAttributes, spreadAttributeIndex) {
8995
const relIndex = findLastIndex(node.attributes, (attr) => (attr.type === 'JSXAttribute' && attr.name.name === 'rel'));
96+
const targetIndex = findLastIndex(node.attributes, (attr) => (attr.type === 'JSXAttribute' && attr.name.name === 'target'));
9097
if (relIndex === -1 || (warnOnSpreadAttributes && relIndex < spreadAttributeIndex)) {
9198
return false;
9299
}
93100

94101
const relAttribute = node.attributes[relIndex];
95-
const value = getStringFromValue(relAttribute.value);
102+
const targetAttributeValue = node.attributes[targetIndex] && node.attributes[targetIndex].value;
103+
const value = getStringFromValue(relAttribute.value, targetAttributeValue);
96104
return [].concat(value).every((item) => {
97105
const tags = typeof item === 'string' ? item.toLowerCase().split(' ') : false;
98106
const noreferrer = tags && tags.indexOf('noreferrer') >= 0;

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,15 @@ ruleTester.run('jsx-no-target-blank', rule, {
155155
code: '<a href={href} target="_blank" rel={isExternal ? "noreferrer" : "noopener"} />',
156156
options: [{ allowReferrer: true }],
157157
},
158+
{
159+
code: '<a href={href} target={isExternal ? "_blank" : undefined} rel={isExternal ? "noreferrer" : undefined} />',
160+
},
161+
{
162+
code: '<a href={href} target={isSelf ? "_self" : "_blank"} rel={isSelf ? undefined : "noreferrer"} />',
163+
},
164+
{
165+
code: '<a href={href} target={isSelf ? "_self" : ""} rel={isSelf ? undefined : ""} />',
166+
},
158167
]),
159168
invalid: parsers.all([
160169
{

0 commit comments

Comments
 (0)