]> git.ipfire.org Git - thirdparty/vuejs/router.git/commitdiff
feat(history): save scroll on leave/reload
authorEduardo San Martin Morote <posva13@gmail.com>
Thu, 30 Jan 2020 17:22:15 +0000 (18:22 +0100)
committerEduardo San Martin Morote <posva13@gmail.com>
Thu, 30 Jan 2020 17:22:15 +0000 (18:22 +0100)
src/history/html5.ts
src/router.ts

index 8d98b1677c2c74f502c40620e594bd3f7a136a88..acffcf267245d441c3f260bc760b3aade8cf48b6 100644 (file)
@@ -120,14 +120,28 @@ function useHistoryListeners(
     return teardown
   }
 
+  function beforeUnloadListener() {
+    const { history } = window
+    if (!history.state) return
+    history.replaceState(
+      {
+        ...history.state,
+        scroll: computeScrollPosition(),
+      },
+      ''
+    )
+  }
+
   function destroy() {
     for (const teardown of teardowns) teardown()
     teardowns = []
     window.removeEventListener('popstate', popStateHandler)
+    window.removeEventListener('beforeunload', beforeUnloadListener)
   }
 
-  // settup the listener and prepare teardown callbacks
+  // settup the listeners and prepare teardown callbacks
   window.addEventListener('popstate', popStateHandler)
+  window.addEventListener('beforeunload', beforeUnloadListener)
 
   return {
     pauseListeners,
@@ -259,10 +273,6 @@ function useHistoryStateNavigation(base: string) {
 }
 
 export default function createHistory(base: string = ''): RouterHistory {
-  if ('scrollRestoration' in window.history) {
-    history.scrollRestoration = 'manual'
-  }
-
   const historyNavigation = useHistoryStateNavigation(base)
   const historyListeners = useHistoryListeners(
     base,
index 5a030b10e7480a3c8c0fb100682adb1160851589..72c35214ecbc7e368d0386cb8ee65de30940b664 100644 (file)
@@ -71,6 +71,8 @@ export interface Router {
   isReady(): Promise<void>
 }
 
+const isClient = typeof window !== 'undefined'
+
 export function createRouter({
   history,
   routes,
@@ -91,6 +93,10 @@ export function createRouter({
   let errorHandlers: ErrorHandler[] = []
   let ready: boolean = false
 
+  if (isClient && 'scrollRestoration' in window.history) {
+    window.history.scrollRestoration = 'manual'
+  }
+
   function resolve(
     to: RouteLocation,
     currentLocation?: RouteLocationNormalized /*, append?: boolean */
@@ -160,7 +166,7 @@ export function createRouter({
           )
         }
 
-        // TODO: should we allow partial redirects? I think we should because it's impredictable if
+        // TODO: should we allow partial redirects? I think we should not because it's impredictable if
         // there was a redirect before
         // if (!('path' in newLocation) && !('name' in newLocation)) throw new Error('TODO: redirect canot be relative')
 
@@ -277,6 +283,7 @@ export function createRouter({
 
     const from = currentRoute.value
     currentRoute.value = markNonReactive(toLocation)
+    // TODO: this doesn't work on first load. Moving it to RouterView could allow automatically handling transitions too maybe
     if (!isFirstNavigation)
       handleScroll(toLocation, from).catch(err => triggerError(err, false))