@@ -491,7 +491,7 @@ function(SERVICES, COMPONENTS, DEMOS, PAGES, $location, $rootScope, $http, $wind
491
491
}
492
492
} ] )
493
493
494
- . directive ( 'menuLink' , function ( ) {
494
+ . directive ( 'menuLink' , [ 'scrollCache' , function ( scrollCache ) {
495
495
return {
496
496
scope : {
497
497
section : '='
@@ -508,10 +508,12 @@ function(SERVICES, COMPONENTS, DEMOS, PAGES, $location, $rootScope, $http, $wind
508
508
// set flag to be used later when
509
509
// $locationChangeSuccess calls openPage()
510
510
controller . autoFocusContent = true ;
511
+ // set flag to be used later when $routeChangeStart saves scroll position
512
+ scrollCache . linkClicked = true ;
511
513
} ;
512
514
}
513
515
} ;
514
- } )
516
+ } ] )
515
517
516
518
. directive ( 'menuToggle' , [ '$mdUtil' , '$animateCss' , '$$rAF' , function ( $mdUtil , $animateCss , $$rAF ) {
517
519
return {
@@ -881,4 +883,78 @@ function($rootScope, $scope, component, demos, $templateRequest) {
881
883
}
882
884
}
883
885
} ;
884
- } ) ;
886
+ } )
887
+
888
+ . factory ( 'scrollCache' , function ( ) {
889
+ var cache = { } ;
890
+ var linkClicked = false ;
891
+
892
+ function setScroll ( key , scrollPostion ) {
893
+ cache [ key ] = scrollPostion ;
894
+ }
895
+
896
+ function getScroll ( key ) {
897
+ return cache [ key ] || 0 ;
898
+ }
899
+
900
+ return {
901
+ getScroll : getScroll ,
902
+ setScroll : setScroll ,
903
+ linkClicked : linkClicked
904
+ } ;
905
+ } )
906
+
907
+ /**
908
+ * This directive caches the scroll position for each route + templateUrl combination.
909
+ * This helps in restoring the scroll when the user uses back or forward navigation to return
910
+ * to a page.
911
+ */
912
+ . directive ( 'cacheScrollPosition' , [ '$route' , '$mdUtil' , '$timeout' , '$location' , '$anchorScroll' ,
913
+ 'scrollCache' ,
914
+ function ( $route , $mdUtil , $timeout , $location , $anchorScroll , scrollCache ) {
915
+ var mainContentArea = document . querySelector ( "[role='main']" ) ;
916
+ var scrollContentEl = mainContentArea . querySelector ( 'md-content[md-scroll-y]' ) ;
917
+
918
+ /**
919
+ * @param {Object } event Synthetic event object
920
+ * @param {Object } next Future route information
921
+ * @param {Object } current Current route information
922
+ */
923
+ var handleRouteChangeStart = function ( event , next , current ) {
924
+ // store scroll position for the current path + template
925
+ if ( $route . current ) {
926
+ scrollCache . setScroll ( current . loadedTemplateUrl + ":" + current . $$route . originalPath ,
927
+ scrollContentEl . scrollTop ) ;
928
+ }
929
+
930
+ // set scroll to 0 for next route, if explicitly clicked on link.
931
+ if ( scrollCache . linkClicked ) {
932
+ scrollCache . setScroll ( next . $$route . templateUrl + ":" + next . $$route . originalPath , 0 ) ;
933
+ scrollCache . linkClicked = false ;
934
+ }
935
+ } ;
936
+
937
+ /**
938
+ * @param {Object } event Synthetic event object
939
+ * @param {Object } current Current route information
940
+ */
941
+ var handleRouteChangeSuccess = function ( event , current ) {
942
+ // if hash is specified explicitly, it trumps previously stored scroll position
943
+ if ( $location . hash ( ) ) {
944
+ $anchorScroll ( ) ;
945
+ } else {
946
+ // Get previous scroll position; if none, scroll to the top of the page
947
+ var prevScrollPos = scrollCache . getScroll ( current . loadedTemplateUrl + ":" +
948
+ current . $$route . originalPath ) ;
949
+
950
+ $timeout ( function ( ) {
951
+ $mdUtil . animateScrollTo ( scrollContentEl , prevScrollPos ) ;
952
+ } , 0 ) ;
953
+ }
954
+ } ;
955
+
956
+ return function ( scope ) {
957
+ scope . $on ( '$routeChangeStart' , handleRouteChangeStart ) ;
958
+ scope . $on ( '$routeChangeSuccess' , handleRouteChangeSuccess ) ;
959
+ }
960
+ } ] ) ;
0 commit comments