]> git.ipfire.org Git - thirdparty/vuejs/router.git/commitdiff
fix(history): allow go to navigate further than 1 entry
authorEduardo San Martin Morote <posva13@gmail.com>
Sat, 12 Oct 2019 14:10:33 +0000 (16:10 +0200)
committerEduardo San Martin Morote <posva13@gmail.com>
Sat, 12 Oct 2019 14:10:33 +0000 (16:10 +0200)
src/history/common.ts
src/history/html5.2.ts
src/router.ts

index 222b81e4329a0c4a6f34d059426e6fb82508ca70..d656f22673bc3d77c785ca5138ca2fd0861236ba 100644 (file)
@@ -52,11 +52,17 @@ export enum NavigationDirection {
   unknown = '',
 }
 
+export interface NavigationInformation {
+  type: NavigationType
+  direction: NavigationDirection
+  distance: number
+}
+
 export interface NavigationCallback {
   (
     to: HistoryLocationNormalized,
     from: HistoryLocationNormalized,
-    information: { type: NavigationType; direction: NavigationDirection }
+    information: NavigationInformation
   ): void
 }
 
@@ -76,6 +82,7 @@ export interface RouterHistory {
 
   back(triggerListeners?: boolean): void
   forward(triggerListeners?: boolean): void
+  go(distance: number, triggerListeners?: boolean): void
 
   listen(callback: NavigationCallback): ListenerRemover
   destroy(): void
index da46380ec40429f29254f12079f898c6f5b9bfdb..a8d655616c8c4d6dbf016bad8584d15b08b8f613 100644 (file)
@@ -27,7 +27,8 @@ interface StateEntry {
 interface PauseState {
   currentLocation: HistoryLocationNormalized
   // location we are going to after pausing
-  to: HistoryLocationNormalized
+  distance: number
+  // to: HistoryLocationNormalized
 }
 
 export default function createHistory(): RouterHistory {
@@ -104,7 +105,8 @@ export default function createHistory(): RouterHistory {
   }: {
     state: StateEntry
   }) => {
-    cs.info('popstate fired', { state, location })
+    cs.info('popstate fired', state)
+    cs.info('currentState', historyState)
 
     // TODO: handle go(-2) and go(2) (skipping entries)
 
@@ -114,19 +116,21 @@ export default function createHistory(): RouterHistory {
     location = to
     historyState = state
 
-    if (pauseState && pauseState.to && pauseState.to.fullPath === to.fullPath) {
-      cs.info('Ignored beacuse paused')
+    if (pauseState && pauseState.currentLocation.fullPath === from.fullPath) {
+      cs.info('❌ Ignored beacuse paused for', pauseState.distance)
       // reset pauseState
-      pauseState = null
+      if (--pauseState.distance < 1) pauseState = null
       return
     }
 
     const deltaFromCurrent = fromState
       ? state.position - fromState.position
       : ''
+    console.log({ deltaFromCurrent })
     // call all listeners
     listeners.forEach(listener =>
       listener(location, from, {
+        distance: deltaFromCurrent || 0,
         type: NavigationType.pop,
         direction: deltaFromCurrent
           ? deltaFromCurrent > 0
@@ -158,10 +162,11 @@ export default function createHistory(): RouterHistory {
     }
   }
 
-  function pauseListeners(to: HistoryLocationNormalized) {
+  function pauseListeners(distance: number) {
+    cs.info(`⏸ for ${distance} steps at ${location.fullPath}`)
     pauseState = {
       currentLocation: location,
-      to,
+      distance,
     }
   }
 
@@ -224,17 +229,16 @@ export default function createHistory(): RouterHistory {
     },
 
     back(triggerListeners = true) {
-      const to = historyState.back
-      if (!to) throw new Error('Cannot go back')
-      if (!triggerListeners) pauseListeners(to)
-      history.back()
+      this.go(-1, triggerListeners)
     },
 
     forward(triggerListeners = true) {
-      const to = historyState.forward
-      if (!to) throw new Error('Cannot go forward')
-      if (!triggerListeners) pauseListeners(to)
-      history.forward()
+      this.go(1, triggerListeners)
+    },
+
+    go(distance, triggerListeners = true) {
+      if (!triggerListeners) pauseListeners(1)
+      history.go(distance)
     },
 
     listen(callback) {
index 20d63d3348af6606532690cef1d097414f8e9d36..babf70fc6fde82b2c8360a9c0e88abfb92c884f8 100644 (file)
@@ -5,7 +5,6 @@ import {
   normalizeQuery,
   HistoryLocationNormalized,
   START,
-  NavigationDirection,
 } from './history/common'
 import { RouterMatcher } from './matcher'
 import {
@@ -120,18 +119,20 @@ export class Router {
           // we just want to avoid logging the error
           this.push(error.to).catch(() => {})
         } else if (NavigationAborted.is(error)) {
+          console.log('Cancelled, going to', -info.distance)
+          this.history.go(-info.distance, false)
           // TODO: test on different browsers ensure consistent behavior
           // Maybe we could write the length the first time we do a navigation and use that for direction
           // TODO: this doesn't work if the user directly calls window.history.go(-n) with n > 1
           // We can override the go method to retrieve the number but not sure if all browsers allow that
-          if (info.direction === NavigationDirection.back) {
-            this.history.forward(false)
-          } else {
-            // TODO: go back because we cancelled, then
-            // or replace and not discard the rest of history. Check issues, there was one talking about this
-            // behaviour, maybe we can do better
-            this.history.back(false)
-          }
+          // if (info.direction === NavigationDirection.back) {
+          //   this.history.forward(false)
+          // } else {
+          // TODO: go back because we cancelled, then
+          // or replace and not discard the rest of history. Check issues, there was one talking about this
+          // behaviour, maybe we can do better
+          // this.history.back(false)
+          // }
         } else {
           this.triggerError(error, false)
         }