From: Eduardo San Martin Morote Date: Wed, 5 Jun 2019 13:35:17 +0000 (+0200) Subject: feat(abstract): listen for navigation X-Git-Tag: v4.0.0-alpha.0~355 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6a81fdac10b537cf8f8c90dfd909262bf9f0cf48;p=thirdparty%2Fvuejs%2Frouter.git feat(abstract): listen for navigation --- diff --git a/__tests__/abstract.spec.js b/__tests__/abstract.spec.js index c490457c..24aeb525 100644 --- a/__tests__/abstract.spec.js +++ b/__tests__/abstract.spec.js @@ -64,6 +64,7 @@ describe('Abstract/in memory history', () => { it('saves forward information', () => {}) it('can replace a location', () => {}) + it('can simulate a navigation', () => {}) it('add entries to the queue', () => { @@ -128,4 +129,36 @@ describe('Abstract/in memory history', () => { expect(history.queue).toHaveLength(2) expect(history.location).toEqual(normaliezedLoc2) }) + + it('can listen to navigations', () => { + const history = new AbstractHistory() + const spy = jest.fn() + history.listen(spy) + history.push(loc) + history.back() + expect(spy).toHaveBeenCalledTimes(1) + expect(spy).toHaveBeenCalledWith(START, normaliezedLoc, { type: 'back' }) + history.forward() + expect(spy).toHaveBeenCalledTimes(2) + expect(spy).toHaveBeenLastCalledWith(normaliezedLoc, START, { + type: 'forward', + }) + }) + + it('can stop listening to navigation', () => { + const history = new AbstractHistory() + const spy = jest.fn() + const spy2 = jest.fn() + // remove right away + history.listen(spy)() + const remove = history.listen(spy2) + history.push(loc) + history.back() + expect(spy).not.toHaveBeenCalled() + expect(spy2).toHaveBeenCalledTimes(1) + remove() + history.forward() + expect(spy).not.toHaveBeenCalled() + expect(spy2).toHaveBeenCalledTimes(1) + }) }) diff --git a/src/history/abstract.ts b/src/history/abstract.ts index 2b318321..c0434f1e 100644 --- a/src/history/abstract.ts +++ b/src/history/abstract.ts @@ -1,5 +1,10 @@ // import consola from 'consola' -import { BaseHistory, HistoryLocation, HistoryLocationNormalized } from './base' +import { + BaseHistory, + HistoryLocation, + HistoryLocationNormalized, + NavigationType, +} from './base' import { NavigationCallback, HistoryState, START } from './base' // const cs = consola.withTag('abstract') @@ -7,6 +12,7 @@ import { NavigationCallback, HistoryState, START } from './base' export class AbstractHistory extends BaseHistory { // private _listeners: NavigationCallback[] = [] private teardowns: Array<() => void> = [] + private listeners: NavigationCallback[] = [] public queue: HistoryLocationNormalized[] = [START] public position: number = 0 @@ -25,7 +31,11 @@ export class AbstractHistory extends BaseHistory { } listen(callback: NavigationCallback) { - return () => {} + this.listeners.push(callback) + return () => { + const index = this.listeners.indexOf(callback) + if (index > -1) this.listeners.splice(index, 1) + } } get location() { @@ -48,15 +58,30 @@ export class AbstractHistory extends BaseHistory { } back() { + const from = this.location if (this.position > 0) this.position-- + this.triggerListeners(this.location, from, { type: NavigationType.back }) } forward() { + const from = this.location if (this.position < this.queue.length - 1) this.position++ + this.triggerListeners(this.location, from, { type: NavigationType.forward }) } destroy() { for (const teardown of this.teardowns) teardown() this.teardowns = [] } + + private triggerListeners( + to: HistoryLocationNormalized, + from: HistoryLocationNormalized, + { type }: { type: NavigationType } + ): void { + const info = { type } + for (let callback of this.listeners) { + callback(to, from, info) + } + } }