@@ -18,38 +18,49 @@ describe('svg+text utils', function() {
18
18
. attr ( 'transform' , 'translate(50,50)' ) ;
19
19
}
20
20
21
- function assertAnchorLink ( node , href ) {
21
+ function assertAnchorLink ( node , href , target , show , msg ) {
22
22
var a = node . select ( 'a' ) ;
23
23
24
- expect ( a . attr ( 'xlink:href' ) ) . toBe ( href ) ;
25
- expect ( a . attr ( 'xlink:show' ) ) . toBe ( href === null ? null : 'new' ) ;
24
+ if ( target === undefined ) target = href === null ? null : '_blank' ;
25
+ if ( show === undefined ) show = href === null ? null : 'new' ;
26
+
27
+ expect ( a . attr ( 'xlink:href' ) ) . toBe ( href , msg ) ;
28
+ expect ( a . attr ( 'target' ) ) . toBe ( target , msg ) ;
29
+ expect ( a . attr ( 'xlink:show' ) ) . toBe ( show , msg ) ;
26
30
}
27
31
28
- function assertTspanStyle ( node , style ) {
32
+ function assertTspanStyle ( node , style , msg ) {
29
33
var tspan = node . select ( 'tspan' ) ;
30
- expect ( tspan . attr ( 'style' ) ) . toBe ( style ) ;
34
+ expect ( tspan . attr ( 'style' ) ) . toBe ( style , msg ) ;
31
35
}
32
36
33
- function assertAnchorAttrs ( node , style ) {
37
+ function assertAnchorAttrs ( node , expectedAttrs , msg ) {
34
38
var a = node . select ( 'a' ) ;
35
39
36
- var WHITE_LIST = [ 'xlink:href' , 'xlink:show' , 'style' ] ,
40
+ if ( ! expectedAttrs ) expectedAttrs = { } ;
41
+
42
+ var WHITE_LIST = [ 'xlink:href' , 'xlink:show' , 'style' , 'target' , 'onclick' ] ,
37
43
attrs = listAttributes ( a . node ( ) ) ;
38
44
39
45
// check that no other attribute are found in anchor,
40
46
// which can be lead to XSS attacks.
41
47
42
- var hasWrongAttr = attrs . some ( function ( attr ) {
43
- return WHITE_LIST . indexOf ( attr ) === - 1 ;
48
+ var wrongAttrs = [ ] ;
49
+ attrs . forEach ( function ( attr ) {
50
+ if ( WHITE_LIST . indexOf ( attr ) === - 1 ) wrongAttrs . push ( attr ) ;
44
51
} ) ;
45
52
46
- expect ( hasWrongAttr ) . toBe ( false ) ;
53
+ expect ( wrongAttrs ) . toEqual ( [ ] , msg ) ;
47
54
55
+ var style = expectedAttrs . style || '' ;
48
56
var fullStyle = style || '' ;
49
57
if ( style ) fullStyle += ';' ;
50
58
fullStyle += 'cursor:pointer' ;
51
59
52
- expect ( a . attr ( 'style' ) ) . toBe ( fullStyle ) ;
60
+ expect ( a . attr ( 'style' ) ) . toBe ( fullStyle , msg ) ;
61
+
62
+ expect ( a . attr ( 'onclick' ) ) . toBe ( expectedAttrs . onclick || null , msg ) ;
63
+
53
64
}
54
65
55
66
function listAttributes ( node ) {
@@ -137,7 +148,7 @@ describe('svg+text utils', function() {
137
148
var node = mockTextSVGElement ( textCase ) ;
138
149
139
150
expect ( node . text ( ) ) . toEqual ( 'Subtitle' ) ;
140
- assertAnchorAttrs ( node , 'font-size:300px' ) ;
151
+ assertAnchorAttrs ( node , { style : 'font-size:300px' } ) ;
141
152
assertAnchorLink ( node , 'XSS' ) ;
142
153
} ) ;
143
154
} ) ;
@@ -157,11 +168,31 @@ describe('svg+text utils', function() {
157
168
var node = mockTextSVGElement ( textCase ) ;
158
169
159
170
expect ( node . text ( ) ) . toEqual ( 'z' ) ;
160
- assertAnchorAttrs ( node , 'y' ) ;
171
+ assertAnchorAttrs ( node , { style : 'y' } ) ;
161
172
assertAnchorLink ( node , 'x' ) ;
162
173
} ) ;
163
174
} ) ;
164
175
176
+ it ( 'accepts `target` with links and tries to translate it to `xlink:show`' , function ( ) {
177
+ var specs = [
178
+ { target : '_blank' , show : 'new' } ,
179
+ { target : '_self' , show : 'replace' } ,
180
+ { target : '_parent' , show : 'replace' } ,
181
+ { target : '_top' , show : 'replace' } ,
182
+ { target : 'some_frame_name' , show : 'new' }
183
+ ] ;
184
+ specs . forEach ( function ( spec ) {
185
+ var node = mockTextSVGElement ( '<a href="x" target="' + spec . target + '">link</a>' ) ;
186
+ assertAnchorLink ( node , 'x' , spec . target , spec . show , spec . target ) ;
187
+ } ) ;
188
+ } ) ;
189
+
190
+ it ( 'attaches onclick if popup is specified' , function ( ) {
191
+ var node = mockTextSVGElement ( '<a href="x" target="fred" popup="width=500,height=400">link</a>' ) ;
192
+ assertAnchorLink ( node , 'x' , 'fred' , 'new' ) ;
193
+ assertAnchorAttrs ( node , { onclick : 'window.open(\'x\',\'fred\',\'width=500,height=400\');return false;' } ) ;
194
+ } ) ;
195
+
165
196
it ( 'keeps query parameters in href' , function ( ) {
166
197
var textCases = [
167
198
'<a href="https://abc.com/myFeature.jsp?name=abc&pwd=def">abc.com?shared-key</a>' ,
@@ -171,9 +202,9 @@ describe('svg+text utils', function() {
171
202
textCases . forEach ( function ( textCase ) {
172
203
var node = mockTextSVGElement ( textCase ) ;
173
204
174
- assertAnchorAttrs ( node ) ;
175
- expect ( node . text ( ) ) . toEqual ( 'abc.com?shared-key' ) ;
176
- assertAnchorLink ( node , 'https://abc.com/myFeature.jsp?name=abc&pwd=def' ) ;
205
+ assertAnchorAttrs ( node , { } , textCase ) ;
206
+ expect ( node . text ( ) ) . toEqual ( 'abc.com?shared-key' , textCase ) ;
207
+ assertAnchorLink ( node , 'https://abc.com/myFeature.jsp?name=abc&pwd=def' , undefined , undefined , textCase ) ;
177
208
} ) ;
178
209
} ) ;
179
210
0 commit comments