@@ -4,6 +4,7 @@ var React = require('react');
4
4
var Route = require ( '../components/Route' ) ;
5
5
var RouteHandler = require ( '../components/RouteHandler' ) ;
6
6
var TestLocation = require ( '../locations/TestLocation' ) ;
7
+ var ScrollToTopBehavior = require ( '../behaviors/ScrollToTopBehavior' ) ;
7
8
var getWindowScrollPosition = require ( '../utils/getWindowScrollPosition' ) ;
8
9
var Router = require ( '../index' ) ;
9
10
@@ -211,6 +212,75 @@ describe('Router.run', function () {
211
212
} ) ;
212
213
} ) ;
213
214
215
+ describe ( 'ScrollToTop scrolling' , function ( ) {
216
+ var BigPage = React . createClass ( {
217
+ render : function ( ) {
218
+ return < div style = { { width : 10000 , height : 10000 , background : 'green' } } /> ;
219
+ }
220
+ } ) ;
221
+
222
+ var routes = [
223
+ < Route name = "one" handler = { BigPage } /> ,
224
+ < Route name = "two" handler = { BigPage } />
225
+ ] ;
226
+
227
+ describe ( 'when a page is scrolled' , function ( ) {
228
+ var position , div , renderCount ;
229
+ beforeEach ( function ( done ) {
230
+ TestLocation . history = [ '/one' ] ;
231
+
232
+ div = document . createElement ( 'div' ) ;
233
+ document . body . appendChild ( div ) ;
234
+
235
+ renderCount = 0 ;
236
+
237
+ Router . create ( {
238
+ routes : routes ,
239
+ location : TestLocation ,
240
+ scrollBehavior : ScrollToTopBehavior
241
+ } ) . run ( function ( Handler ) {
242
+ React . render ( < Handler /> , div , function ( ) {
243
+ if ( renderCount === 0 ) {
244
+ position = { x : 20 , y : 50 } ;
245
+ window . scrollTo ( position . x , position . y ) ;
246
+
247
+ setTimeout ( function ( ) {
248
+ expect ( getWindowScrollPosition ( ) ) . toEqual ( position ) ;
249
+ done ( ) ;
250
+ } , 20 ) ;
251
+ }
252
+
253
+ renderCount += 1 ;
254
+ } ) ;
255
+ } ) ;
256
+ } ) ;
257
+
258
+ afterEach ( function ( ) {
259
+ div . parentNode . removeChild ( div ) ;
260
+ } ) ;
261
+
262
+ describe ( 'navigating to a new page' , function ( ) {
263
+ beforeEach ( function ( ) {
264
+ TestLocation . push ( '/two' ) ;
265
+ } ) ;
266
+
267
+ it ( 'resets the scroll position' , function ( ) {
268
+ expect ( getWindowScrollPosition ( ) ) . toEqual ( { x : 0 , y : 0 } ) ;
269
+ } ) ;
270
+
271
+ describe ( 'then returning to the previous page' , function ( ) {
272
+ beforeEach ( function ( ) {
273
+ TestLocation . pop ( ) ;
274
+ } ) ;
275
+
276
+ it ( 'resets the scroll position' , function ( ) {
277
+ expect ( getWindowScrollPosition ( ) ) . toEqual ( { x : 0 , y : 0 } ) ;
278
+ } ) ;
279
+ } ) ;
280
+ } ) ;
281
+ } ) ;
282
+ } ) ;
283
+
214
284
describe ( 'ImitateBrowserBehavior scrolling' , function ( ) {
215
285
var BigPage = React . createClass ( {
216
286
render : function ( ) {
@@ -276,6 +346,116 @@ describe('Router.run', function () {
276
346
} ) ;
277
347
} ) ;
278
348
349
+ describe ( 'ignoreScrollBehavior' , function ( ) {
350
+ var routes = (
351
+ < Route handler = { Nested } >
352
+ < Route handler = { Foo } ignoreScrollBehavior >
353
+ < Route handler = { Foo } path = '/feed' />
354
+ < Route handler = { Foo } path = '/discover' />
355
+ </ Route >
356
+ < Route path = '/search/:q' handler = { Foo } ignoreScrollBehavior />
357
+ < Route path = '/users/:id/posts' handler = { Foo } />
358
+ < Route path = '/about' handler = { Foo } />
359
+ </ Route >
360
+ ) ;
361
+
362
+ var div , didUpdateScroll ;
363
+ beforeEach ( function ( done ) {
364
+ TestLocation . history = [ '/feed' ] ;
365
+
366
+ div = document . createElement ( 'div' ) ;
367
+ document . body . appendChild ( div ) ;
368
+
369
+ var MockScrollBehavior = {
370
+ updateScrollPosition ( ) {
371
+ didUpdateScroll = true ;
372
+ }
373
+ } ;
374
+
375
+ Router . create ( {
376
+ routes : routes ,
377
+ location : TestLocation ,
378
+ scrollBehavior : MockScrollBehavior
379
+ } ) . run ( function ( Handler ) {
380
+ React . render ( < Handler /> , div , function ( ) {
381
+ done ( ) ;
382
+ } ) ;
383
+ } ) ;
384
+ } ) ;
385
+
386
+ afterEach ( function ( ) {
387
+ div . parentNode . removeChild ( div ) ;
388
+ didUpdateScroll = false ;
389
+ } ) ;
390
+
391
+ it ( 'calls updateScroll the first time' , function ( ) {
392
+ expect ( didUpdateScroll ) . toBe ( true ) ;
393
+ } ) ;
394
+
395
+ describe ( 'decides whether to update scroll on transition' , function ( ) {
396
+ beforeEach ( function ( ) {
397
+ didUpdateScroll = false ;
398
+ } ) ;
399
+
400
+ afterEach ( function ( ) {
401
+ TestLocation . pop ( ) ;
402
+ } ) ;
403
+
404
+ it ( 'calls updateScroll when no ancestors ignore scroll' , function ( ) {
405
+ TestLocation . push ( '/about' ) ;
406
+ expect ( didUpdateScroll ) . toBe ( true ) ;
407
+ } ) ;
408
+
409
+ it ( 'calls updateScroll when no ancestors ignore scroll although source and target do' , function ( ) {
410
+ TestLocation . push ( '/search/foo' ) ;
411
+ expect ( didUpdateScroll ) . toBe ( true ) ;
412
+ } ) ;
413
+
414
+ it ( 'calls updateScroll when route does not ignore scroll and only params change' , function ( ) {
415
+ TestLocation . replace ( '/users/3/posts' ) ;
416
+ didUpdateScroll = false ;
417
+
418
+ TestLocation . push ( '/users/5/posts' ) ;
419
+ expect ( didUpdateScroll ) . toBe ( true ) ;
420
+ } ) ;
421
+
422
+ it ( 'calls updateScroll when route does not ignore scroll and both params and query change' , function ( ) {
423
+ TestLocation . replace ( '/users/3/posts' ) ;
424
+ didUpdateScroll = false ;
425
+
426
+ TestLocation . push ( '/users/5/posts?page=2' ) ;
427
+ expect ( didUpdateScroll ) . toBe ( true ) ;
428
+ } ) ;
429
+
430
+ it ( 'does not call updateScroll when route does not ignore scroll but only query changes' , function ( ) {
431
+ TestLocation . replace ( '/users/3/posts' ) ;
432
+ didUpdateScroll = false ;
433
+
434
+ TestLocation . push ( '/users/3/posts?page=2' ) ;
435
+ expect ( didUpdateScroll ) . toBe ( false ) ;
436
+ } ) ;
437
+
438
+ it ( 'does not call updateScroll when common ancestor ignores scroll' , function ( ) {
439
+ TestLocation . push ( '/discover' ) ;
440
+ expect ( didUpdateScroll ) . toBe ( false ) ;
441
+ } ) ;
442
+
443
+ it ( 'does not call updateScroll when route ignores scroll' , function ( ) {
444
+ TestLocation . replace ( '/search/foo' ) ;
445
+ didUpdateScroll = false ;
446
+
447
+ TestLocation . push ( '/search/bar' ) ;
448
+ expect ( didUpdateScroll ) . toBe ( false ) ;
449
+
450
+ TestLocation . replace ( '/search/bar?safe=0' ) ;
451
+ expect ( didUpdateScroll ) . toBe ( false ) ;
452
+
453
+ TestLocation . replace ( '/search/whatever' ) ;
454
+ expect ( didUpdateScroll ) . toBe ( false ) ;
455
+ } ) ;
456
+ } ) ;
457
+ } ) ;
458
+
279
459
describe ( 'makePath' , function ( ) {
280
460
var router ;
281
461
beforeEach ( function ( ) {
0 commit comments