From fafd73759d43c6e6fe3d4c722b1fe6ca5b88f0f0 Mon Sep 17 00:00:00 2001 From: Eduardo San Martin Morote Date: Tue, 4 Jun 2019 19:05:32 +0200 Subject: [PATCH] feat(abstract): move forward in history --- __tests__/abstract.spec.js | 56 +++++++++++++++++++++++++++++++------- src/history/abstract.ts | 24 +++++++++++----- src/history/base.ts | 7 +++++ src/history/html5.ts | 4 +++ 4 files changed, 74 insertions(+), 17 deletions(-) diff --git a/__tests__/abstract.spec.js b/__tests__/abstract.spec.js index e0cb613f..c490457c 100644 --- a/__tests__/abstract.spec.js +++ b/__tests__/abstract.spec.js @@ -1,4 +1,5 @@ // @ts-check + require('./helper') const expect = require('expect') const { AbstractHistory } = require('../src/history/abstract') @@ -29,17 +30,19 @@ const normaliezedLoc2 = { describe('Abstract/in memory history', () => { it('starts at /', () => { const history = new AbstractHistory() + expect(history.location).toEqual(START) expect(history.location).toEqual({ fullPath: '/', path: '/', query: {}, hash: '', }) + expect(history.queue).toHaveLength(1) }) it('can push a location', () => { const history = new AbstractHistory() - // normalized version + // partial version history.push({ path: '/somewhere', hash: '#hey', query: { foo: 'foo' } }) expect(history.location).toEqual({ fullPath: '/somewhere?foo=foo#hey', @@ -65,13 +68,12 @@ describe('Abstract/in memory history', () => { it('add entries to the queue', () => { const history = new AbstractHistory() - expect(history.queue).toHaveLength(0) history.push(loc) - expect(history.queue).toHaveLength(1) - expect(history.queue[0]).toEqual(normaliezedLoc) - history.push(loc2) expect(history.queue).toHaveLength(2) - expect(history.queue[1]).toEqual(normaliezedLoc2) + expect(history.queue[1]).toEqual(normaliezedLoc) + history.push(loc2) + expect(history.queue).toHaveLength(3) + expect(history.queue[2]).toEqual(normaliezedLoc2) }) it('can go back', () => { @@ -79,17 +81,51 @@ describe('Abstract/in memory history', () => { history.push(loc) history.push(loc2) history.back() - expect(history.queue).toHaveLength(1) + expect(history.queue).toHaveLength(3) expect(history.location).toEqual(normaliezedLoc) history.back() - expect(history.queue).toHaveLength(0) + expect(history.queue).toHaveLength(3) + expect(history.location).toEqual(START) + }) + + it('does nothing with back if queue contains only one element', () => { + const history = new AbstractHistory() + history.back() + expect(history.location).toEqual(START) + }) + + it('does nothing with forward if at end of log', () => { + const history = new AbstractHistory() + history.forward() + expect(history.location).toEqual(START) + }) + + it('can moves back and forth in history queue', () => { + const history = new AbstractHistory() + history.push(loc) + history.push(loc2) + history.back() + history.back() expect(history.location).toEqual(START) + history.forward() + expect(history.location).toEqual(normaliezedLoc) + history.forward() + expect(history.location).toEqual(normaliezedLoc2) }) - it('does nothing with back if queue is empty', () => { + it('can push in the middle of the history', () => { const history = new AbstractHistory() + history.push(loc) + history.push(loc2) + history.back() history.back() expect(history.location).toEqual(START) + history.push(loc2) + expect(history.queue).toHaveLength(2) + expect(history.location).toEqual(normaliezedLoc2) + // does nothing + history.forward() + expect(history.queue).toHaveLength(2) + expect(history.location).toEqual(normaliezedLoc2) }) - it('does nothing with forward if at end of log', () => {}) }) diff --git a/src/history/abstract.ts b/src/history/abstract.ts index 483b82b1..2b318321 100644 --- a/src/history/abstract.ts +++ b/src/history/abstract.ts @@ -8,10 +8,10 @@ export class AbstractHistory extends BaseHistory { // private _listeners: NavigationCallback[] = [] private teardowns: Array<() => void> = [] public queue: HistoryLocationNormalized[] = [START] + public position: number = 0 constructor() { super() - debugger } // TODO: is this necessary @@ -29,20 +29,30 @@ export class AbstractHistory extends BaseHistory { } get location() { - console.log('read location', this.queue) - return this.queue[this.queue.length - 1] + return this.queue[this.position] } set location(location: HistoryLocationNormalized) { // super() call tries to push before the array is created - console.log('set location', location) if (!this.queue) this.queue = [] - // TODO: handle in the middle - this.queue.push(location) + // move the queue cursor forward + this.position++ + if (this.position === this.queue.length) { + // we are at the end, we can simply append a new entry + this.queue.push(location) + } else { + // we are in the middle, we remove everything from here in the queue + this.queue.splice(this.position) + this.queue.push(location) + } } back() { - this.queue.pop() + if (this.position > 0) this.position-- + } + + forward() { + if (this.position < this.queue.length - 1) this.position++ } destroy() { diff --git a/src/history/base.ts b/src/history/base.ts index caea1e0b..c97ef71c 100644 --- a/src/history/base.ts +++ b/src/history/base.ts @@ -85,6 +85,13 @@ export abstract class BaseHistory { */ abstract back(): void + /** + * Goes forward in history log. Should trigger any listener added via + * `listen`. If we are on the last entry, behaviour may change depending + * on implementation + */ + abstract forward(): void + /** * Notifies back whenever the location changes due to user interactions * outside of the applicaiton. For example, going back/forward on a diff --git a/src/history/html5.ts b/src/history/html5.ts index 1a111c4a..50e05685 100644 --- a/src/history/html5.ts +++ b/src/history/html5.ts @@ -95,6 +95,10 @@ export class HTML5History extends BaseHistory { // TODO: do not trigger listen this.history.back() } + forward() { + // TODO: do not trigger listen + this.history.forward() + } listen(callback: NavigationCallback) { // settup the listener and prepare teardown callbacks -- 2.47.2