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
}
back(triggerListeners?: boolean): void
forward(triggerListeners?: boolean): void
+ go(distance: number, triggerListeners?: boolean): void
listen(callback: NavigationCallback): ListenerRemover
destroy(): void
interface PauseState {
currentLocation: HistoryLocationNormalized
// location we are going to after pausing
- to: HistoryLocationNormalized
+ distance: number
+ // to: HistoryLocationNormalized
}
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)
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
}
}
- function pauseListeners(to: HistoryLocationNormalized) {
+ function pauseListeners(distance: number) {
+ cs.info(`⏸ for ${distance} steps at ${location.fullPath}`)
pauseState = {
currentLocation: location,
- to,
+ distance,
}
}
},
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) {
normalizeQuery,
HistoryLocationNormalized,
START,
- NavigationDirection,
} from './history/common'
import { RouterMatcher } from './matcher'
import {
// 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)
}