@@ -386,3 +386,213 @@ QUnit.module('cone.app.scrollbar.ScrollbarX', hooks => {
386386 scrollbar . destroy ( ) ;
387387 } ) ;
388388} ) ;
389+
390+ QUnit . module ( 'cone.app.scrollbar.persist' , hooks => {
391+
392+ let container ;
393+
394+ hooks . beforeEach ( ( ) => {
395+ container = $ ( '<div />' ) . appendTo ( 'body' ) ;
396+ sessionStorage . clear ( ) ;
397+ } ) ;
398+
399+ hooks . afterEach ( ( ) => {
400+ container . remove ( ) ;
401+ sessionStorage . clear ( ) ;
402+ } ) ;
403+
404+ QUnit . test ( 'persist_scroll defaults to false' , assert => {
405+ let elem = $ ( `
406+ <div class="scrollable-y">
407+ <div class="scrollable-content" style="height: 500px;"></div>
408+ </div>
409+ ` ) . css ( { height : '200px' , position : 'relative' } ) . appendTo ( container ) ;
410+
411+ let scrollbar = new ScrollbarY ( elem ) ;
412+
413+ assert . strictEqual ( scrollbar . persist_scroll , false , 'persist_scroll is false by default' ) ;
414+
415+ scrollbar . destroy ( ) ;
416+ } ) ;
417+
418+ QUnit . test ( 'persist_scroll reads from data attribute' , assert => {
419+ let elem = $ ( `
420+ <div class="scrollable-y" data-persist-scroll="true">
421+ <div class="scrollable-content" style="height: 500px;"></div>
422+ </div>
423+ ` ) . css ( { height : '200px' , position : 'relative' } ) . appendTo ( container ) ;
424+
425+ let scrollbar = new ScrollbarY ( elem ) ;
426+
427+ assert . strictEqual ( scrollbar . persist_scroll , true , 'persist_scroll reads data attribute' ) ;
428+
429+ scrollbar . destroy ( ) ;
430+ } ) ;
431+
432+ QUnit . test ( 'storage_key uses element id' , assert => {
433+ let elem = $ ( `
434+ <div id="test_scrollbar" class="scrollable-y" data-persist-scroll="true">
435+ <div class="scrollable-content" style="height: 500px;"></div>
436+ </div>
437+ ` ) . css ( { height : '200px' , position : 'relative' } ) . appendTo ( container ) ;
438+
439+ let scrollbar = new ScrollbarY ( elem ) ;
440+
441+ assert . strictEqual ( scrollbar . storage_key , 'cone.app.scroll.test_scrollbar' , 'storage_key uses id' ) ;
442+
443+ scrollbar . destroy ( ) ;
444+ } ) ;
445+
446+ QUnit . test ( 'storage_key uses custom key from data attribute' , assert => {
447+ let elem = $ ( `
448+ <div id="test_scrollbar" class="scrollable-y"
449+ data-persist-scroll="true"
450+ data-persist-scroll-key="custom_key">
451+ <div class="scrollable-content" style="height: 500px;"></div>
452+ </div>
453+ ` ) . css ( { height : '200px' , position : 'relative' } ) . appendTo ( container ) ;
454+
455+ let scrollbar = new ScrollbarY ( elem ) ;
456+
457+ assert . strictEqual ( scrollbar . storage_key , 'cone.app.scroll.custom_key' , 'storage_key uses custom key' ) ;
458+
459+ scrollbar . destroy ( ) ;
460+ } ) ;
461+
462+ QUnit . test ( 'storage_key is null without id or custom key' , assert => {
463+ let elem = $ ( `
464+ <div class="scrollable-y" data-persist-scroll="true">
465+ <div class="scrollable-content" style="height: 500px;"></div>
466+ </div>
467+ ` ) . css ( { height : '200px' , position : 'relative' } ) . appendTo ( container ) ;
468+
469+ let scrollbar = new ScrollbarY ( elem ) ;
470+
471+ assert . strictEqual ( scrollbar . storage_key , null , 'storage_key is null without id' ) ;
472+
473+ scrollbar . destroy ( ) ;
474+ } ) ;
475+
476+ QUnit . test ( 'position is saved to sessionStorage on scroll' , assert => {
477+ let done = assert . async ( ) ;
478+ let elem = $ ( `
479+ <div id="persist_test" class="scrollable-y" data-persist-scroll="true">
480+ <div class="scrollable-content" style="height: 500px;"></div>
481+ </div>
482+ ` ) . css ( { height : '200px' , position : 'relative' } ) . appendTo ( container ) ;
483+
484+ let scrollbar = new ScrollbarY ( elem ) ;
485+ scrollbar . position = 100 ;
486+
487+ // Allow event to fire
488+ setTimeout ( ( ) => {
489+ let saved = sessionStorage . getItem ( 'cone.app.scroll.persist_test' ) ;
490+ assert . strictEqual ( saved , '100' , 'position saved to sessionStorage' ) ;
491+ scrollbar . destroy ( ) ;
492+ done ( ) ;
493+ } , 50 ) ;
494+ } ) ;
495+
496+ QUnit . test ( 'position is restored from sessionStorage' , assert => {
497+ let done = assert . async ( ) ;
498+ sessionStorage . setItem ( 'cone.app.scroll.restore_test' , '150' ) ;
499+
500+ let elem = $ ( `
501+ <div id="restore_test" class="scrollable-y" data-persist-scroll="true">
502+ <div class="scrollable-content" style="height: 500px;"></div>
503+ </div>
504+ ` ) . css ( { height : '200px' , position : 'relative' } ) . appendTo ( container ) ;
505+
506+ let scrollbar = new ScrollbarY ( elem ) ;
507+
508+ setTimeout ( ( ) => {
509+ assert . strictEqual ( scrollbar . position , 150 , 'position restored from sessionStorage' ) ;
510+ scrollbar . destroy ( ) ;
511+ done ( ) ;
512+ } , 100 ) ;
513+ } ) ;
514+
515+ QUnit . test ( 'restored position is clamped when content shrinks' , assert => {
516+ let done = assert . async ( ) ;
517+ // Save a position that will be too large
518+ sessionStorage . setItem ( 'cone.app.scroll.clamp_test' , '500' ) ;
519+
520+ let elem = $ ( `
521+ <div id="clamp_test" class="scrollable-y" data-persist-scroll="true">
522+ <div class="scrollable-content" style="height: 300px;"></div>
523+ </div>
524+ ` ) . css ( { height : '200px' , position : 'relative' } ) . appendTo ( container ) ;
525+
526+ let scrollbar = new ScrollbarY ( elem ) ;
527+
528+ // max_pos = 300 - 200 = 100
529+ setTimeout ( ( ) => {
530+ assert . strictEqual ( scrollbar . position , 100 , 'position clamped to max' ) ;
531+ scrollbar . destroy ( ) ;
532+ done ( ) ;
533+ } , 100 ) ;
534+ } ) ;
535+
536+ QUnit . test ( 'position not saved when persist_scroll is false' , assert => {
537+ let elem = $ ( `
538+ <div id="no_persist" class="scrollable-y">
539+ <div class="scrollable-content" style="height: 500px;"></div>
540+ </div>
541+ ` ) . css ( { height : '200px' , position : 'relative' } ) . appendTo ( container ) ;
542+
543+ let scrollbar = new ScrollbarY ( elem ) ;
544+ scrollbar . position = 100 ;
545+
546+ let saved = sessionStorage . getItem ( 'cone.app.scroll.no_persist' ) ;
547+ assert . strictEqual ( saved , null , 'position not saved when persist disabled' ) ;
548+
549+ scrollbar . destroy ( ) ;
550+ } ) ;
551+
552+ QUnit . test ( 'position not saved without storage_key' , assert => {
553+ let elem = $ ( `
554+ <div class="scrollable-y" data-persist-scroll="true">
555+ <div class="scrollable-content" style="height: 500px;"></div>
556+ </div>
557+ ` ) . css ( { height : '200px' , position : 'relative' } ) . appendTo ( container ) ;
558+
559+ let scrollbar = new ScrollbarY ( elem ) ;
560+ scrollbar . position = 100 ;
561+
562+ // No key to check, but should not throw
563+ assert . ok ( true , 'no error when no storage_key' ) ;
564+
565+ scrollbar . destroy ( ) ;
566+ } ) ;
567+
568+ QUnit . test ( 'destroy removes position listener' , assert => {
569+ let done = assert . async ( ) ;
570+ let elem = $ ( `
571+ <div id="destroy_test" class="scrollable-y" data-persist-scroll="true">
572+ <div class="scrollable-content" style="height: 500px;"></div>
573+ </div>
574+ ` ) . css ( { height : '200px' , position : 'relative' } ) . appendTo ( container ) ;
575+
576+ let scrollbar = new ScrollbarY ( elem ) ;
577+ scrollbar . destroy ( ) ;
578+
579+ sessionStorage . removeItem ( 'cone.app.scroll.destroy_test' ) ;
580+
581+ // Create new scrollbar on same elem to test position change
582+ let elem2 = $ ( `
583+ <div id="destroy_test2" class="scrollable-y">
584+ <div class="scrollable-content" style="height: 500px;"></div>
585+ </div>
586+ ` ) . css ( { height : '200px' , position : 'relative' } ) . appendTo ( container ) ;
587+
588+ let scrollbar2 = new ScrollbarY ( elem2 ) ;
589+ scrollbar2 . position = 200 ;
590+
591+ setTimeout ( ( ) => {
592+ let saved = sessionStorage . getItem ( 'cone.app.scroll.destroy_test' ) ;
593+ assert . strictEqual ( saved , null , 'destroyed scrollbar does not save' ) ;
594+ scrollbar2 . destroy ( ) ;
595+ done ( ) ;
596+ } , 50 ) ;
597+ } ) ;
598+ } ) ;
0 commit comments