1
1
'use strict' ;
2
+
2
3
describe ( '$anchorScroll' , function ( ) {
3
4
4
5
var elmSpy ;
6
+ var docSpies ;
7
+ var windowSpies ;
5
8
6
9
function addElements ( ) {
7
10
var elements = sliceArgs ( arguments ) ;
8
11
9
- return function ( ) {
12
+ return function ( $window ) {
10
13
forEach ( elements , function ( identifier ) {
11
- var match = identifier . match ( / ( \w * ) ? ( \w * ) = ( \w * ) / ) ,
12
- jqElm = jqLite ( '<' + ( match [ 1 ] || 'a ' ) + match [ 2 ] + '="' + match [ 3 ] + '"/>' ) ,
14
+ var match = identifier . match ( / (?: ( \w * ) ) ? ( \w * ) = ( \w * ) / ) ,
15
+ nodeName = match [ 1 ] || 'a' ,
16
+ tmpl = '<' + nodeName + ' ' + match [ 2 ] + '="' + match [ 3 ] + '">' +
17
+ match [ 3 ] + // add some content or else Firefox and IE place the element
18
+ // in weird ways that break yOffset-testing.
19
+ '</' + nodeName + '>' ,
20
+ jqElm = jqLite ( tmpl ) ,
13
21
elm = jqElm [ 0 ] ;
22
+ // Inline elements cause Firefox to report an unexpected value for
23
+ // `getBoundingClientRect().top` on some platforms (depending on the default font and
24
+ // line-height). Using inline-block elements prevents this.
25
+ // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1014738
26
+ elm . style . display = 'inline-block' ;
14
27
15
28
elmSpy [ identifier ] = spyOn ( elm , 'scrollIntoView' ) ;
16
- jqLite ( document . body ) . append ( jqElm ) ;
29
+ jqLite ( $window . document . body ) . append ( jqElm ) ;
17
30
} ) ;
18
31
} ;
19
32
}
20
33
34
+ function callAnchorScroll ( ) {
35
+ return function ( $anchorScroll ) {
36
+ $anchorScroll ( ) ;
37
+ } ;
38
+ }
39
+
21
40
function changeHashAndScroll ( hash ) {
22
41
return function ( $location , $anchorScroll ) {
23
42
$location . hash ( hash ) ;
24
43
$anchorScroll ( ) ;
25
44
} ;
26
45
}
27
46
47
+ function changeHashTo ( hash ) {
48
+ return function ( $anchorScroll , $location , $rootScope ) {
49
+ $rootScope . $apply ( function ( ) {
50
+ $location . hash ( hash ) ;
51
+ } ) ;
52
+ } ;
53
+ }
54
+
55
+ function createMockDocument ( initialReadyState ) {
56
+ var mockedDoc = { } ;
57
+ docSpies = { } ;
58
+
59
+ initialReadyState = initialReadyState || 'complete' ;
60
+ var propsToPassThrough = [ 'body' , 'documentElement' ] ;
61
+ var methodsToPassThrough = [
62
+ 'getElementById' ,
63
+ 'getElementsByName' ,
64
+ 'addEventListener' ,
65
+ 'removeEventListener'
66
+ ] ;
67
+
68
+ var document_ = document ;
69
+
70
+ propsToPassThrough . forEach ( function ( prop ) {
71
+ mockedDoc [ prop ] = document_ [ prop ] ;
72
+ } ) ;
73
+ methodsToPassThrough . forEach ( function ( method ) {
74
+ mockedDoc [ method ] = document_ [ method ] . bind ( document_ ) ;
75
+ docSpies [ method ] = spyOn ( mockedDoc , method ) . andCallThrough ( ) ;
76
+ } ) ;
77
+
78
+ mockedDoc . readyState = initialReadyState || 'complete' ;
79
+ mockedDoc . dispatchFakeReadyStateChangeEvent = function ( ) {
80
+ var evt = document_ . createEvent ( 'Event' ) ;
81
+ evt . initEvent ( 'readystatechange' , false , false ) ;
82
+ document_ . dispatchEvent ( evt ) ;
83
+ } ;
84
+ mockedDoc . updateReadyState = function ( newState ) {
85
+ this . readyState = newState ;
86
+ this . dispatchFakeReadyStateChangeEvent ( ) ;
87
+ } ;
88
+
89
+ return mockedDoc ;
90
+ }
91
+
92
+ function createMockWindow ( initialReadyState ) {
93
+ return function ( ) {
94
+ module ( function ( $provide ) {
95
+ elmSpy = { } ;
96
+ windowSpies = { } ;
97
+
98
+ $provide . value ( '$window' , {
99
+ scrollTo : ( windowSpies . scrollTo = jasmine . createSpy ( '$window.scrollTo' ) ) ,
100
+ scrollBy : ( windowSpies . scrollBy = jasmine . createSpy ( '$window.scrollBy' ) ) ,
101
+ document : createMockDocument ( initialReadyState ) ,
102
+ navigator : { } ,
103
+ pageYOffset : 0 ,
104
+ getComputedStyle : function ( elem ) {
105
+ return getComputedStyle ( elem ) ;
106
+ }
107
+ } ) ;
108
+ } ) ;
109
+ } ;
110
+ }
111
+
112
+ function expectNoScrolling ( ) {
113
+ return expectScrollingTo ( NaN ) ;
114
+ }
115
+
116
+ function expectScrollingTo ( identifierCountMap ) {
117
+ var map = { } ;
118
+ if ( isString ( identifierCountMap ) ) {
119
+ map [ identifierCountMap ] = 1 ;
120
+ } else if ( isArray ( identifierCountMap ) ) {
121
+ forEach ( identifierCountMap , function ( identifier ) {
122
+ map [ identifier ] = 1 ;
123
+ } ) ;
124
+ } else {
125
+ map = identifierCountMap ;
126
+ }
127
+
128
+ return function ( $window ) {
129
+ forEach ( elmSpy , function ( spy , id ) {
130
+ var count = map [ id ] || 0 ;
131
+ expect ( spy . callCount ) . toBe ( count ) ;
132
+ } ) ;
133
+ expect ( $window . scrollTo ) . not . toHaveBeenCalled ( ) ;
134
+ } ;
135
+ }
136
+
28
137
function expectScrollingToTop ( $window ) {
29
138
forEach ( elmSpy , function ( spy , id ) {
30
139
expect ( spy ) . not . toHaveBeenCalled ( ) ;
@@ -33,75 +142,156 @@ describe('$anchorScroll', function() {
33
142
expect ( $window . scrollTo ) . toHaveBeenCalledWith ( 0 , 0 ) ;
34
143
}
35
144
36
- function expectScrollingTo ( identifier ) {
145
+ function resetAllSpies ( ) {
146
+ function resetSpy ( spy ) {
147
+ spy . reset ( ) ;
148
+ }
149
+
37
150
return function ( $window ) {
38
- forEach ( elmSpy , function ( spy , id ) {
39
- if ( identifier === id ) expect ( spy ) . toHaveBeenCalledOnce ( ) ;
40
- else expect ( spy ) . not . toHaveBeenCalled ( ) ;
41
- } ) ;
42
- expect ( $window . scrollTo ) . not . toHaveBeenCalled ( ) ;
151
+ forEach ( elmSpy , resetSpy ) ;
152
+ forEach ( docSpies , resetSpy ) ;
153
+ forEach ( windowSpies , resetSpy ) ;
43
154
} ;
44
155
}
45
156
46
- function expectNoScrolling ( ) {
47
- return expectScrollingTo ( NaN ) ;
157
+ function updateMockReadyState ( newState ) {
158
+ return function ( $browser , $window ) {
159
+ // It is possible that this operation adds tasks to the asyncQueue (needs flushing)
160
+ $window . document . updateReadyState ( newState ) ;
161
+ if ( $browser . deferredFns . length ) {
162
+ $browser . defer . flush ( ) ;
163
+ }
164
+ } ;
48
165
}
49
166
50
167
51
- beforeEach ( module ( function ( $provide ) {
52
- elmSpy = { } ;
53
- $provide . value ( '$window' , {
54
- scrollTo : jasmine . createSpy ( '$window.scrollTo' ) ,
55
- document : document ,
56
- navigator : { }
57
- } ) ;
168
+ afterEach ( inject ( function ( $browser , $document ) {
169
+ expect ( $browser . deferredFns . length ) . toBe ( 0 ) ;
170
+ dealoc ( $document ) ;
58
171
} ) ) ;
59
172
60
173
61
- it ( 'should scroll to top of the window if empty hash' , inject (
62
- changeHashAndScroll ( '' ) ,
63
- expectScrollingToTop ) ) ;
174
+ describe ( 'when explicitly called' , function ( ) {
175
+
176
+ beforeEach ( createMockWindow ( ) ) ;
177
+
178
+
179
+ it ( 'should scroll to top of the window if empty hash' , inject (
180
+ changeHashAndScroll ( '' ) ,
181
+ expectScrollingToTop ) ) ;
182
+
183
+
184
+ it ( 'should not scroll if hash does not match any element' , inject (
185
+ addElements ( 'id=one' , 'id=two' ) ,
186
+ changeHashAndScroll ( 'non-existing' ) ,
187
+ expectNoScrolling ( ) ) ) ;
188
+
64
189
190
+ it ( 'should scroll to anchor element with name' , inject (
191
+ addElements ( 'a name=abc' ) ,
192
+ changeHashAndScroll ( 'abc' ) ,
193
+ expectScrollingTo ( 'a name=abc' ) ) ) ;
65
194
66
- it ( 'should not scroll if hash does not match any element' , inject (
67
- addElements ( 'id=one' , 'id=two' ) ,
68
- changeHashAndScroll ( 'non-existing' ) ,
69
- expectNoScrolling ( ) ) ) ;
70
195
196
+ it ( 'should not scroll to other than anchor element with name' , inject (
197
+ addElements ( 'input name=xxl' , 'select name=xxl' , 'form name=xxl' ) ,
198
+ changeHashAndScroll ( 'xxl' ) ,
199
+ expectNoScrolling ( ) ) ) ;
71
200
72
- it ( 'should scroll to anchor element with name' , inject (
73
- addElements ( 'a name=abc' ) ,
74
- changeHashAndScroll ( 'abc' ) ,
75
- expectScrollingTo ( 'a name=abc' ) ) ) ;
76
201
202
+ it ( 'should scroll to anchor even if other element with given name exist' , inject (
203
+ addElements ( 'input name=some' , 'a name=some' ) ,
204
+ changeHashAndScroll ( 'some' ) ,
205
+ expectScrollingTo ( 'a name=some' ) ) ) ;
77
206
78
- it ( 'should not scroll to other than anchor element with name' , inject (
79
- addElements ( 'input name=xxl' , 'select name=xxl' , 'form name=xxl' ) ,
80
- changeHashAndScroll ( 'xxl' ) ,
81
- expectNoScrolling ( ) ) ) ;
82
207
208
+ it ( 'should scroll to element with id with precedence over name' , inject (
209
+ addElements ( 'name=abc' , 'id=abc' ) ,
210
+ changeHashAndScroll ( 'abc' ) ,
211
+ expectScrollingTo ( 'id=abc' ) ) ) ;
83
212
84
- it ( 'should scroll to anchor even if other element with given name exist' , inject (
85
- addElements ( 'input name=some' , 'a name=some' ) ,
86
- changeHashAndScroll ( 'some' ) ,
87
- expectScrollingTo ( 'a name=some' ) ) ) ;
88
213
214
+ it ( 'should scroll to top if hash == "top" and no matching element' , inject (
215
+ changeHashAndScroll ( 'top' ) ,
216
+ expectScrollingToTop ) ) ;
89
217
90
- it ( 'should scroll to element with id with precedence over name' , inject (
91
- addElements ( 'name=abc' , 'id=abc' ) ,
92
- changeHashAndScroll ( 'abc' ) ,
93
- expectScrollingTo ( 'id=abc' ) ) ) ;
218
+
219
+ it ( 'should scroll to element with id "top" if present' , inject (
220
+ addElements ( 'id=top' ) ,
221
+ changeHashAndScroll ( 'top' ) ,
222
+ expectScrollingTo ( 'id=top' ) ) ) ;
223
+ } ) ;
224
+
225
+
226
+ describe ( 'in respect to `document.readyState`' , function ( ) {
227
+
228
+ beforeEach ( createMockWindow ( 'mocked' ) ) ;
229
+
230
+
231
+ it ( 'should wait for `document.readyState === "complete"' , inject (
232
+ addElements ( 'id=some1' ) ,
233
+
234
+ changeHashTo ( 'some1' ) ,
235
+ expectNoScrolling ( ) ,
236
+
237
+ updateMockReadyState ( 'some-arbitrary-state' ) ,
238
+ expectNoScrolling ( ) ,
239
+
240
+ updateMockReadyState ( 'complete' ) ,
241
+ expectScrollingTo ( 'id=some1' ) ) ) ;
94
242
95
243
96
- it ( 'should scroll to top if hash == "top" and no matching element' , inject (
97
- changeHashAndScroll ( 'top' ) ,
98
- expectScrollingToTop ) ) ;
244
+ it ( 'should only register once for execution when `document.readyState === "complete"' , inject (
245
+ addElements ( 'id=some1' , 'id=some2' ) ,
99
246
247
+ changeHashTo ( 'some1' ) ,
248
+ changeHashTo ( 'some2' ) ,
249
+ updateMockReadyState ( 'some-other-arbitrary-state' ) ,
250
+ changeHashTo ( 'some1' ) ,
251
+ changeHashTo ( 'some2' ) ,
252
+ expectNoScrolling ( ) ,
100
253
101
- it ( 'should scroll to element with id "top" if present' , inject (
102
- addElements ( 'id=top' ) ,
103
- changeHashAndScroll ( 'top' ) ,
104
- expectScrollingTo ( 'id=top' ) ) ) ;
254
+ updateMockReadyState ( 'complete' ) ,
255
+ expectScrollingTo ( 'id=some2' ) ) ) ;
256
+
257
+
258
+ it ( 'should properly register and unregister listeners for `readystatechange` event' , inject (
259
+ addElements ( 'id=some1' , 'id=some2' ) ,
260
+
261
+ changeHashTo ( 'some1' ) ,
262
+ changeHashTo ( 'some2' ) ,
263
+ updateMockReadyState ( 'some-other-arbitrary-state' ) ,
264
+ changeHashTo ( 'some1' ) ,
265
+ changeHashTo ( 'some2' ) ,
266
+ updateMockReadyState ( 'complete' ) ,
267
+
268
+ function ( ) {
269
+ expect ( docSpies . addEventListener . callCount ) . toBe ( 1 ) ;
270
+ expect ( docSpies . addEventListener ) .
271
+ toHaveBeenCalledWith ( 'readystatechange' , jasmine . any ( Function ) ) ;
272
+
273
+ expect ( docSpies . removeEventListener . callCount ) . toBe ( 1 ) ;
274
+ expect ( docSpies . removeEventListener ) .
275
+ toHaveBeenCalledWith ( 'readystatechange' , jasmine . any ( Function ) ) ;
276
+
277
+ var registeredListener = docSpies . addEventListener . calls [ 0 ] . args [ 1 ] ;
278
+ var unregisteredListener = docSpies . removeEventListener . calls [ 0 ] . args [ 1 ] ;
279
+ expect ( unregisteredListener ) . toBe ( registeredListener ) ;
280
+ } ) ) ;
281
+
282
+
283
+ it ( 'should scroll immediately if already `readyState === "complete"`' , inject (
284
+ addElements ( 'id=some1' ) ,
285
+
286
+ updateMockReadyState ( 'complete' ) ,
287
+ changeHashTo ( 'some1' ) ,
288
+
289
+ expectScrollingTo ( 'id=some1' ) ,
290
+ function ( ) {
291
+ expect ( docSpies . addEventListener . callCount ) . toBe ( 0 ) ;
292
+ expect ( docSpies . removeEventListener . callCount ) . toBe ( 0 ) ;
293
+ } ) ) ;
294
+ } ) ;
105
295
106
296
107
297
describe ( 'watcher' , function ( ) {
@@ -119,23 +309,13 @@ describe('$anchorScroll', function() {
119
309
} ;
120
310
}
121
311
122
- function changeHashTo ( hash ) {
123
- return function ( $location , $rootScope , $anchorScroll ) {
124
- $rootScope . $apply ( function ( ) {
125
- $location . hash ( hash ) ;
126
- } ) ;
127
- } ;
128
- }
129
-
130
312
function disableAutoScrolling ( ) {
131
313
return function ( $anchorScrollProvider ) {
132
314
$anchorScrollProvider . disableAutoScrolling ( ) ;
133
315
} ;
134
316
}
135
317
136
- afterEach ( inject ( function ( $document ) {
137
- dealoc ( $document ) ;
138
- } ) ) ;
318
+ beforeEach ( createMockWindow ( ) ) ;
139
319
140
320
141
321
it ( 'should scroll to element when hash change in hashbang mode' , function ( ) {
@@ -189,7 +369,7 @@ describe('$anchorScroll', function() {
189
369
} ) ;
190
370
191
371
192
- it ( 'should not scroll when disabled' , function ( ) {
372
+ it ( 'should not scroll when auto-scrolling is disabled' , function ( ) {
193
373
module (
194
374
disableAutoScrolling ( ) ,
195
375
initLocation ( { html5Mode : false , historyApi : false } )
@@ -200,6 +380,212 @@ describe('$anchorScroll', function() {
200
380
expectNoScrolling ( )
201
381
) ;
202
382
} ) ;
383
+
384
+
385
+ it ( 'should scroll when called explicitly (even if auto-scrolling is disabled)' , function ( ) {
386
+ module (
387
+ disableAutoScrolling ( ) ,
388
+ initLocation ( { html5Mode : false , historyApi : false } )
389
+ ) ;
390
+ inject (
391
+ addElements ( 'id=fake' ) ,
392
+ changeHashTo ( 'fake' ) ,
393
+ expectNoScrolling ( ) ,
394
+ callAnchorScroll ( ) ,
395
+ expectScrollingTo ( 'id=fake' )
396
+ ) ;
397
+ } ) ;
203
398
} ) ;
204
- } ) ;
205
399
400
+
401
+ // TODO: Add tests for <body> with:
402
+ // 1. border/margin/padding !== 0
403
+ // 2. box-sizing === border-box
404
+ describe ( 'yOffset' , function ( ) {
405
+
406
+ function expectScrollingWithOffset ( identifierCountMap , offsetList ) {
407
+ var list = isArray ( offsetList ) ? offsetList : [ offsetList ] ;
408
+
409
+ return function ( $rootScope , $window ) {
410
+ inject ( expectScrollingTo ( identifierCountMap ) ) ;
411
+ expect ( $window . scrollBy . callCount ) . toBe ( list . length ) ;
412
+ forEach ( list , function ( offset , idx ) {
413
+ // Due to sub-pixel rendering, there is a +/-1 error margin in the actual offset
414
+ var args = $window . scrollBy . calls [ idx ] . args ;
415
+ expect ( args [ 0 ] ) . toBe ( 0 ) ;
416
+ expect ( Math . abs ( offset + args [ 1 ] ) ) . toBeLessThan ( 1 ) ;
417
+ } ) ;
418
+ } ;
419
+ }
420
+
421
+ function expectScrollingWithoutOffset ( identifierCountMap ) {
422
+ return expectScrollingWithOffset ( identifierCountMap , [ ] ) ;
423
+ }
424
+
425
+ function setupBodyForOffsetTesting ( ) {
426
+ return function ( $window ) {
427
+ var style = $window . document . body . style ;
428
+ style . border = 'none' ;
429
+ style . margin = '0' ;
430
+ style . padding = '0' ;
431
+ } ;
432
+ }
433
+
434
+ function setYOffset ( yOffset ) {
435
+ return function ( $anchorScroll ) {
436
+ $anchorScroll . yOffset = yOffset ;
437
+ } ;
438
+ }
439
+
440
+ function updateMockPageYOffset ( ) {
441
+ return function ( $window ) {
442
+ $window . pageYOffset = window . pageYOffset ;
443
+ } ;
444
+ }
445
+
446
+ beforeEach ( createMockWindow ( ) ) ;
447
+ beforeEach ( inject ( setupBodyForOffsetTesting ( ) ) ) ;
448
+
449
+
450
+ describe ( 'when set as a fixed number' , function ( ) {
451
+
452
+ var yOffsetNumber = 50 ;
453
+
454
+ beforeEach ( inject ( setYOffset ( yOffsetNumber ) ) ) ;
455
+
456
+
457
+ it ( 'should scroll with vertical offset' , inject (
458
+ addElements ( 'id=some' ) ,
459
+ changeHashTo ( 'some' ) ,
460
+ expectScrollingWithOffset ( 'id=some' , yOffsetNumber ) ) ) ;
461
+
462
+
463
+ it ( 'should use the correct vertical offset when changing `yOffset` at runtime' , inject (
464
+ addElements ( 'id=some' ) ,
465
+ changeHashTo ( 'some' ) ,
466
+ setYOffset ( yOffsetNumber - 10 ) ,
467
+ callAnchorScroll ( ) ,
468
+ expectScrollingWithOffset ( { 'id=some' : 2 } , [ yOffsetNumber , yOffsetNumber - 10 ] ) ) ) ;
469
+
470
+
471
+ it ( 'should adjust the vertical offset for elements near the end of the page' , function ( ) {
472
+
473
+ var targetAdjustedOffset = 25 ;
474
+
475
+ inject (
476
+ addElements ( 'id=some1' , 'id=some2' ) ,
477
+ function ( $window ) {
478
+ // Make sure the elements are just a little shorter than the viewport height
479
+ var viewportHeight = $window . document . documentElement . clientHeight ;
480
+ var elemHeight = viewportHeight - ( yOffsetNumber - targetAdjustedOffset ) ;
481
+ var cssText = [
482
+ 'border:none' ,
483
+ 'display:block' ,
484
+ 'height:' + elemHeight + 'px' ,
485
+ 'margin:0' ,
486
+ 'padding:0' ,
487
+ '' ] . join ( ';' ) ;
488
+
489
+ forEach ( $window . document . body . children , function ( elem ) {
490
+ elem . style . cssText = cssText ;
491
+ } ) ;
492
+
493
+ // Make sure scrolling does actually take place
494
+ // (this is necessary for the current test)
495
+ forEach ( elmSpy , function ( spy , identifier ) {
496
+ elmSpy [ identifier ] = spy . andCallThrough ( ) ;
497
+ } ) ;
498
+ } ,
499
+ changeHashTo ( 'some2' ) ,
500
+ updateMockPageYOffset ( ) ,
501
+ resetAllSpies ( ) ,
502
+ callAnchorScroll ( ) ,
503
+ expectScrollingWithOffset ( 'id=some2' , targetAdjustedOffset ) ) ;
504
+ } ) ;
505
+ } ) ;
506
+
507
+
508
+ describe ( 'when set as a function' , function ( ) {
509
+
510
+ it ( 'should scroll with vertical offset' , function ( ) {
511
+
512
+ var val = 0 ;
513
+ var increment = 10 ;
514
+
515
+ function yOffsetFunction ( ) {
516
+ val += increment ;
517
+ return val ;
518
+ }
519
+
520
+ inject (
521
+ addElements ( 'id=id1' , 'name=name2' ) ,
522
+ setYOffset ( yOffsetFunction ) ,
523
+ changeHashTo ( 'id1' ) ,
524
+ changeHashTo ( 'name2' ) ,
525
+ changeHashTo ( 'id1' ) ,
526
+ callAnchorScroll ( ) ,
527
+ expectScrollingWithOffset ( {
528
+ 'id=id1' : 3 ,
529
+ 'name=name2' : 1
530
+ } , [
531
+ 1 * increment ,
532
+ 2 * increment ,
533
+ 3 * increment ,
534
+ 4 * increment
535
+ ] ) ) ;
536
+ } ) ;
537
+ } ) ;
538
+
539
+
540
+ describe ( 'when set as a jqLite element' , function ( ) {
541
+
542
+ function createAndSetYOffsetElement ( styleSpecs ) {
543
+ var cssText = '' ;
544
+ forEach ( styleSpecs , function ( value , key ) {
545
+ cssText += key + ':' + value + ';' ;
546
+ } ) ;
547
+
548
+ var jqElem = jqLite ( '<div style="' + cssText + '"></div>' ) ;
549
+
550
+ return function ( $anchorScroll , $window ) {
551
+ jqLite ( $window . document . body ) . append ( jqElem ) ;
552
+ $anchorScroll . yOffset = jqElem ;
553
+ } ;
554
+ }
555
+
556
+
557
+ it ( 'should scroll with vertical offset when `top === 0`' , inject (
558
+ createAndSetYOffsetElement ( {
559
+ background : 'DarkOrchid' ,
560
+ height : '50px' ,
561
+ position : 'fixed' ,
562
+ top : '0' ,
563
+ } ) ,
564
+ addElements ( 'id=some' ) ,
565
+ changeHashTo ( 'some' ) ,
566
+ expectScrollingWithOffset ( 'id=some' , 50 ) ) ) ;
567
+
568
+
569
+ it ( 'should scroll with vertical offset when `top > 0`' , inject (
570
+ createAndSetYOffsetElement ( {
571
+ height : '50px' ,
572
+ position : 'fixed' ,
573
+ top : '50px' ,
574
+ } ) ,
575
+ addElements ( 'id=some' ) ,
576
+ changeHashTo ( 'some' ) ,
577
+ expectScrollingWithOffset ( 'id=some' , 100 ) ) ) ;
578
+
579
+
580
+ it ( 'should scroll without vertical offset when `position !== fixed`' , inject (
581
+ createAndSetYOffsetElement ( {
582
+ height : '50px' ,
583
+ position : 'absolute' ,
584
+ top : '0' ,
585
+ } ) ,
586
+ addElements ( 'id=some' ) ,
587
+ changeHashTo ( 'some' ) ,
588
+ expectScrollingWithoutOffset ( 'id=some' ) ) ) ;
589
+ } ) ;
590
+ } ) ;
591
+ } ) ;
0 commit comments