@@ -65,7 +65,13 @@ function hasDynamicLink(node, linkAttribute) {
65
65
}
66
66
}
67
67
68
- function getStringFromValue ( value ) {
68
+ /**
69
+ * Get the string(s) from a value
70
+ * @param {ASTNode } value The AST node being checked.
71
+ * @param {ASTNode } targetValue The AST node being checked.
72
+ * @returns {String | String[] | null } The string value, or null if not a string.
73
+ */
74
+ function getStringFromValue ( value , targetValue ) {
69
75
if ( value ) {
70
76
if ( value . type === 'Literal' ) {
71
77
return value . value ;
@@ -75,24 +81,34 @@ function getStringFromValue(value) {
75
81
return value . expression . quasis [ 0 ] . value . cooked ;
76
82
}
77
83
const expr = value . expression ;
78
- return expr && (
79
- expr . type === 'ConditionalExpression'
80
- ? [ expr . consequent . value , expr . alternate . value ]
81
- : expr . value
82
- ) ;
84
+ if ( expr && expr . type === 'ConditionalExpression' ) {
85
+ const relValues = [ expr . consequent . value , expr . alternate . value ] ;
86
+ if ( targetValue . type === 'JSXExpressionContainer' && targetValue . expression && targetValue . expression . type === 'ConditionalExpression' ) {
87
+ const targetTestCond = targetValue . expression . test . name ;
88
+ const relTestCond = value . expression . test . name ;
89
+ if ( targetTestCond === relTestCond ) {
90
+ const targetBlankIndex = [ targetValue . expression . consequent . value , targetValue . expression . alternate . value ] . indexOf ( '_blank' ) ;
91
+ return relValues [ targetBlankIndex ] ;
92
+ }
93
+ }
94
+ return relValues ;
95
+ }
96
+ return expr . value ;
83
97
}
84
98
}
85
99
return null ;
86
100
}
87
101
88
102
function hasSecureRel ( node , allowReferrer , warnOnSpreadAttributes , spreadAttributeIndex ) {
89
103
const relIndex = findLastIndex ( node . attributes , ( attr ) => ( attr . type === 'JSXAttribute' && attr . name . name === 'rel' ) ) ;
104
+ const targetIndex = findLastIndex ( node . attributes , ( attr ) => ( attr . type === 'JSXAttribute' && attr . name . name === 'target' ) ) ;
90
105
if ( relIndex === - 1 || ( warnOnSpreadAttributes && relIndex < spreadAttributeIndex ) ) {
91
106
return false ;
92
107
}
93
108
94
109
const relAttribute = node . attributes [ relIndex ] ;
95
- const value = getStringFromValue ( relAttribute . value ) ;
110
+ const targetAttributeValue = node . attributes [ targetIndex ] && node . attributes [ targetIndex ] . value ;
111
+ const value = getStringFromValue ( relAttribute . value , targetAttributeValue ) ;
96
112
return [ ] . concat ( value ) . every ( ( item ) => {
97
113
const tags = typeof item === 'string' ? item . toLowerCase ( ) . split ( ' ' ) : false ;
98
114
const noreferrer = tags && tags . indexOf ( 'noreferrer' ) >= 0 ;
0 commit comments