8
8
// Rule Definition
9
9
// ------------------------------------------------------------------------------
10
10
11
+ function isTargetBlank ( attr ) {
12
+ return attr . name . name === 'target' &&
13
+ attr . value . type === 'Literal' &&
14
+ attr . value . value . toLowerCase ( ) === '_blank' ;
15
+ }
16
+
17
+ function hasExternalLink ( element ) {
18
+ return element . attributes . find ( function ( attr ) {
19
+ return attr . name &&
20
+ attr . name . name === 'href' &&
21
+ attr . value . type === 'Literal' &&
22
+ / ^ (?: \w + : | \/ \/ ) / . test ( attr . value . value ) ;
23
+ } ) ;
24
+ }
25
+
26
+ function hasSecureRel ( element ) {
27
+ return element . attributes . find ( function ( attr ) {
28
+ if ( attr . name . name === 'rel' ) {
29
+ var tags = attr . value . type === 'Literal' && attr . value . value . toLowerCase ( ) . split ( ' ' ) ;
30
+ return ! tags || ( tags . indexOf ( 'noopener' ) >= 0 && tags . indexOf ( 'noreferrer' ) >= 0 ) ;
31
+ }
32
+ return false ;
33
+ } ) ;
34
+ }
35
+
11
36
module . exports = {
12
37
meta : {
13
38
docs : {
@@ -26,38 +51,12 @@ module.exports = {
26
51
}
27
52
28
53
if (
29
- node . name . name === 'target' &&
30
- node . value . type === 'Literal' &&
31
- node . value . value . toLowerCase ( ) === '_blank'
54
+ isTargetBlank ( node ) &&
55
+ hasExternalLink ( node . parent ) &&
56
+ ! hasSecureRel ( node . parent )
32
57
) {
33
- var relFound = false ;
34
- var attrs = node . parent . attributes ;
35
- for ( var idx in attrs ) {
36
- if ( ! Object . prototype . hasOwnProperty . call ( attrs , idx ) ) {
37
- continue ;
38
- }
39
- var attr = attrs [ idx ] ;
40
- if ( ! attr . name ) {
41
- continue ;
42
- }
43
- if ( attr . name . name === 'href' ) {
44
- if ( attr . value . type === 'Literal' && ! / ^ (?: \w + : | \/ \/ ) / . test ( attr . value . value ) ) {
45
- // it's safe because it is not an external link (i.e. doesn't start with a protocol)
46
- return ;
47
- }
48
- }
49
- if ( attr . name . name === 'rel' ) {
50
- var tags = attr . value . type === 'Literal' && attr . value . value . toLowerCase ( ) . split ( ' ' ) ;
51
- if ( ! tags || ( tags . indexOf ( 'noopener' ) >= 0 && tags . indexOf ( 'noreferrer' ) >= 0 ) ) {
52
- relFound = true ;
53
- break ;
54
- }
55
- }
56
- }
57
- if ( ! relFound ) {
58
- context . report ( node , 'Using target="_blank" without rel="noopener noreferrer" ' +
59
- 'is a security risk: see https://mathiasbynens.github.io/rel-noopener' ) ;
60
- }
58
+ context . report ( node , 'Using target="_blank" without rel="noopener noreferrer" ' +
59
+ 'is a security risk: see https://mathiasbynens.github.io/rel-noopener' ) ;
61
60
}
62
61
}
63
62
} ;
0 commit comments