From: Eduardo San Martin Morote Date: Wed, 9 Oct 2019 11:51:06 +0000 (+0200) Subject: feat: add direction to navigation information X-Git-Tag: v4.0.0-alpha.0~213 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c63f2a07efa7fc503647060f054e7936ea4a1f0a;p=thirdparty%2Fvuejs%2Frouter.git feat: add direction to navigation information --- diff --git a/explorations/html5.ts b/explorations/html5.ts index 13d2f814..abaaebbf 100644 --- a/explorations/html5.ts +++ b/explorations/html5.ts @@ -70,10 +70,10 @@ const ComponentWithData: RouteComponent = { // @ts-ignore data: () => ({ data: 'nope' }), beforeRouteEnter(to, from, next) { - console.log('this in beforeRouteEnter', this) + // console.log('this in beforeRouteEnter', this) setTimeout(() => { next(vm => { - console.log('got vm', vm) + // console.log('got vm', vm) vm.data = 'Hola' }) }, 300) @@ -157,7 +157,7 @@ window.r = router const delay = (t: number) => new Promise(resolve => setTimeout(resolve, t)) router.beforeEach(async (to, from, next) => { - console.log(`Guard from ${from.fullPath} to ${to.fullPath}`) + // console.log(`Guard from ${from.fullPath} to ${to.fullPath}`) if (to.params.id === 'no-name') return next(false) const time = Number(to.query.delay) @@ -174,20 +174,25 @@ router.beforeEach((to, from, next) => { }) router.afterEach((to, from) => { - console.log( - `After guard: from ${from.fullPath} to ${ - to.fullPath - } | location = ${location.href.replace(location.origin, '')}` - ) + // console.log( + // `After guard: from ${from.fullPath} to ${ + // to.fullPath + // } | location = ${location.href.replace(location.origin, '')}` + // ) }) router.beforeEach((to, from, next) => { - console.log('second guard') + // console.log('second guard') next() }) +const dirLog = { + '': '?', + back: '⏪', + forward: '⏩', +} routerHistory.listen((to, from, info) => { - console.log(`popstate(${info})`, { to, from }) + console.log(`${dirLog[info.direction]} as a ${info.type}`) }) async function run() { diff --git a/src/history/common.ts b/src/history/common.ts index a5c4ee82..1da7659f 100644 --- a/src/history/common.ts +++ b/src/history/common.ts @@ -46,11 +46,17 @@ export enum NavigationType { push = 'push', } +export enum NavigationDirection { + back = 'back', + forward = 'forward', + unknown = '', +} + export interface NavigationCallback { ( to: HistoryLocationNormalized, from: HistoryLocationNormalized, - information: { type: NavigationType } + information: { type: NavigationType; direction: NavigationDirection } ): void } diff --git a/src/history/html5.2.ts b/src/history/html5.2.ts index 747b005e..01bb8f0c 100644 --- a/src/history/html5.2.ts +++ b/src/history/html5.2.ts @@ -3,7 +3,8 @@ import { NavigationCallback, parseQuery, normalizeLocation, - NavigationType + NavigationType, + NavigationDirection, } from './common' import { HistoryLocationNormalized, HistoryState } from './base' import { computeScrollPosition, ScrollToPosition } from '../utils/scroll' @@ -17,6 +18,7 @@ interface StateEntry { back: HistoryLocationNormalized | null current: HistoryLocationNormalized forward: HistoryLocationNormalized | null + position: number replaced: boolean scroll: ScrollToPosition | null } @@ -36,7 +38,7 @@ export default function createHistory(): RouterHistory { fullPath: location.pathname + location.search + location.hash, path: location.pathname, query: parseQuery(location.search), - hash: location.hash + hash: location.hash, } } @@ -55,21 +57,40 @@ export default function createHistory(): RouterHistory { current, forward, replaced, - scroll: computeScroll ? computeScrollPosition() : null + position: window.history.length, + scroll: computeScroll ? computeScrollPosition() : null, } } - // private state of History - let location: HistoryLocationNormalized = normalizeLocation( - window.location.href + // private variables + let location: HistoryLocationNormalized = createCurrentLocation( + window.location ) + let historyState: StateEntry = history.state + // build current history entry as this is a fresh navigation + if (!historyState) { + changeLocation( + { + back: null, + current: location, + forward: null, + // the length is off by one, we need to decrease it + position: history.length - 1, + replaced: true, + scroll: computeScrollPosition(), + }, + '', + location.fullPath, + true + ) + } let listeners: NavigationCallback[] = [] let teardowns: Array<() => void> = [] // TODO: should it be a stack? a Dict. Check if the popstate listener // can trigger twice const popStateHandler: PopStateListener = ({ - state + state, }: { state: StateEntry }) => { @@ -78,12 +99,21 @@ export default function createHistory(): RouterHistory { // TODO: handle go(-2) and go(2) (skipping entries) const from = location + const fromState = historyState location = createCurrentLocation(window.location) - + historyState = state + const deltaFromCurrent = fromState + ? state.position - fromState.position + : '' // call all listeners listeners.forEach(listener => listener(location, from, { - type: NavigationType.pop + type: NavigationType.pop, + direction: deltaFromCurrent + ? deltaFromCurrent > 0 + ? NavigationDirection.forward + : NavigationDirection.back + : NavigationDirection.unknown, }) ) } @@ -101,6 +131,7 @@ export default function createHistory(): RouterHistory { // BROWSER QUIRK // NOTE: Safari throws a SecurityError when calling this function 100 times in 30 seconds history[replace ? 'replaceState' : 'pushState'](state, title, url) + historyState = state } catch (err) { cs.log('[vue-router]: Error with push/replace State', err) // Force the navigation, this also resets the call count @@ -116,8 +147,16 @@ export default function createHistory(): RouterHistory { cs.info('replace', location, normalized) + const state: StateEntry = buildState( + historyState.back, + normalized, + historyState.forward, + true + ) + if (historyState) state.position = historyState.position changeLocation( - buildState(history.state.back, normalized, null, true), + // TODO: refactor state building + state, '', normalized.fullPath, true @@ -129,14 +168,27 @@ export default function createHistory(): RouterHistory { const normalized = normalizeLocation(to) // Add to current entry the information of where we are going - history.state.forward = normalized + const currentState = { + ...historyState, + forward: normalized, + scroll: computeScrollPosition(), + } + changeLocation(currentState, '', currentState.current.fullPath, true) - const state = { + const state: StateEntry = { ...buildState(location, normalized, null), - ...data + position: currentState.position + 1, + ...data, } - cs.info('push', location, '->', normalized, 'with state', state) + cs.info( + 'push', + location.fullPath, + '->', + normalized.fullPath, + 'with state', + state + ) changeLocation(state, '', normalized.fullPath, false) location = normalized @@ -159,6 +211,6 @@ export default function createHistory(): RouterHistory { for (const teardown of teardowns) teardown() teardowns = [] window.removeEventListener('popstate', popStateHandler) - } + }, } }