Skip to content

Commit

Permalink
Version 1.1. See release notes.
Browse files Browse the repository at this point in the history
  • Loading branch information
Brandon Cheng committed Sep 3, 2016
1 parent 6f8c5bd commit 38e1c85
Show file tree
Hide file tree
Showing 5 changed files with 309 additions and 92 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# macOS
.DS_Store
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,8 @@ Set a tag for a location you may want to return to. Get a key with

### goToLocationWithTag(tag)
Goes backward or forward to reach a tag.

# Changes

### 1.1
- Add pathname support
257 changes: 166 additions & 91 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,117 +1,192 @@
const SESSIONSTORAGE_PREFIX = 'BackForwardHistory_';
'use strict';

class BackForwardHistory {
browserHistory
historyStack
currentIndex
titles
tags
Object.defineProperty(exports, "__esModule", {
value: true
});

get firstLocationKey() {
return this.historyStack[0];
}

get currentLocationKey() {
return this.historyStack[this.currentIndex];
}
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

canGoBack(n = 1) {
return this.currentIndex >= n;
}

canGoForward(n = 1) {
return this.currentIndex < (this.historyStack.length - n)
}
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

get currentlyOnFirstPage() {
return this.currentLocationKey == this.firstLocationKey;
}
var SESSIONSTORAGE_PREFIX = 'BackForwardHistory_';

get currentlyOnLastPage() {
return !this.canGoForward()
}
var BackForwardHistory = function () {
function BackForwardHistory() {
_classCallCheck(this, BackForwardHistory);

constructor() {
this.loadStateFromSession();
}

listenTo(browserHistory) {
this.browserHistory = browserHistory
browserHistory.listen(this.onHistoryEvent.bind(this));
}

loadStateFromSession() {
this.historyStack = JSON.parse(sessionStorage.getItem(SESSIONSTORAGE_PREFIX + 'historyStack')) || [];
this.currentIndex = sessionStorage.getItem(SESSIONSTORAGE_PREFIX + 'currentIndex') || 0;
this.titles = JSON.parse(sessionStorage.getItem(SESSIONSTORAGE_PREFIX + 'titles')) || {};
this.tags = JSON.parse(sessionStorage.getItem(SESSIONSTORAGE_PREFIX + 'tags')) || {};
}

saveStateToSession() {
sessionStorage.setItem(SESSIONSTORAGE_PREFIX + 'historyStack', JSON.stringify(this.historyStack));
sessionStorage.setItem(SESSIONSTORAGE_PREFIX + 'currentIndex', this.currentIndex);
sessionStorage.setItem(SESSIONSTORAGE_PREFIX + 'titles', JSON.stringify(this.titles));
sessionStorage.setItem(SESSIONSTORAGE_PREFIX + 'tags', JSON.stringify(this.tags));
}

resetState() {
this.historyStack = [];
this.currentIndex = 0;
this.titles = new Map();
this.tags = new Map();
saveStateToSession();
}
_createClass(BackForwardHistory, [{
key: 'listenTo',
value: function listenTo(browserHistory) {
this.browserHistory = browserHistory;
browserHistory.listen(this.onHistoryEvent.bind(this));
}
}, {
key: 'canGoBack',
value: function canGoBack() {
var n = arguments.length <= 0 || arguments[0] === undefined ? 1 : arguments[0];

onHistoryEvent({ pathname, key, action }) {
if (this.historyStack.length === 0) {
this.historyStack.push(key);
return this.currentIndex >= n;
}
}, {
key: 'canGoForward',
value: function canGoForward() {
var n = arguments.length <= 0 || arguments[0] === undefined ? 1 : arguments[0];

if (action === 'PUSH') {
if (!this.currentlyOnLastPage) {
this.historyStack = this.historyStack.splice(0, this.currentIndex+1)
return this.currentIndex < this.historyStack.length - n;
}
}, {
key: 'loadStateFromSession',
value: function loadStateFromSession() {
this.historyStack = JSON.parse(sessionStorage.getItem(SESSIONSTORAGE_PREFIX + 'historyStack')) || [];
this.currentIndex = sessionStorage.getItem(SESSIONSTORAGE_PREFIX + 'currentIndex') || 0;
this.tags = JSON.parse(sessionStorage.getItem(SESSIONSTORAGE_PREFIX + 'tags')) || {};
}
}, {
key: 'saveStateToSession',
value: function saveStateToSession() {
sessionStorage.setItem(SESSIONSTORAGE_PREFIX + 'historyStack', JSON.stringify(this.historyStack));
sessionStorage.setItem(SESSIONSTORAGE_PREFIX + 'currentIndex', this.currentIndex);
sessionStorage.setItem(SESSIONSTORAGE_PREFIX + 'tags', JSON.stringify(this.tags));
}
}, {
key: 'resetState',
value: function resetState() {
this.historyStack = [];
this.currentIndex = 0;
this.tags = {};
this.saveStateToSession();
}
}, {
key: 'onHistoryEvent',
value: function onHistoryEvent(_ref) {
var pathname = _ref.pathname;
var key = _ref.key;
var action = _ref.action;

if (this.historyStack.length === 0) {
this.historyStack.push({ key: key, pathname: pathname });
return;
}

this.historyStack.push(key);
this.currentIndex++;
} else if (action === 'POP') {
const potentialIndex = this.historyStack.indexOf(key);
if (action === 'PUSH') {
if (!this.currentlyOnLastPage) {
this.historyStack = this.historyStack.splice(0, this.currentIndex + 1);
}

if (potentialIndex === -1) {
// User hit go on url bar. Reset history stack.
this.historyStack = [key]
this.historyStack.push({ key: key, pathname: pathname });
this.currentIndex++;
}

this.currentIndex = this.historyStack.indexOf(key);
}
if (action === 'POP') {
var potentialIndex = this.getIndexForKey(key);
if (potentialIndex === -1) {
// User hit go on url bar. Reset history stack.
this.resetState();
this.historyStack = [{ key: key, pathname: pathname }];
}

this.saveStateToSession()
}
this.currentIndex = this.getIndexForKey(key);
}

getLastLocationTitle() {
return this.titles[this.historyStack[this.currentIndex-1]]
}
this.saveStateToSession();
}
}, {
key: 'getIndexForKey',
value: function getIndexForKey(key) {
return this.historyStack.findIndex(function (i) {
return i.key === key;
});
}
}, {
key: 'getIndexForTag',
value: function getIndexForTag(tag) {
return this.getIndexForKey(this.tags[tag]);
}
}, {
key: 'getKeyForTag',
value: function getKeyForTag(tag) {
return this.tags[tag];
}
}, {
key: 'getCurrentPathname',
value: function getCurrentPathname() {
var n = arguments.length <= 0 || arguments[0] === undefined ? 0 : arguments[0];

getTitleForKey(key) {
return this.titles[key]
}
return this.historyStack[this.currentIndex + n].pathname;
}
}, {
key: 'getCurrentLocationTitle',
value: function getCurrentLocationTitle() {
var n = arguments.length <= 0 || arguments[0] === undefined ? 0 : arguments[0];

setTitleForKey(key, title) {
this.titles[key] = title
}
return this.historyStack[this.currentIndex + n].title;
}
}, {
key: 'getTitleForKey',
value: function getTitleForKey(key) {
return this.historyStack[this.getIndexForKey(key)].title;
}
}, {
key: 'setTitleForKey',
value: function setTitleForKey(key, title) {
this.historyStack[this.getIndexForKey(key)].title = title;
}
}, {
key: 'setTitleForCurrentLocation',
value: function setTitleForCurrentLocation(title) {
var n = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1];

setTagForKey(key, tag) {
this.tags[tag] = key
}
this.historyStack[this.currentIndex + n].title = title;
}
}, {
key: 'setTagForKey',
value: function setTagForKey(key, tag) {
this.tags[tag] = key;
}
}, {
key: 'isCurrentlyOnTag',
value: function isCurrentlyOnTag(tag) {
return this.currentLocationKey == this.tags[tag];
}
}, {
key: 'goToLocationWithTag',
value: function goToLocationWithTag(tag) {
var n = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1];

var indexOfTag = this.getIndexForTag(tag);
if (indexOfTag === -1) {
throw new Error('No index found for tag: ' + tag);
}

goToLocationWithTag(tag) {
const indexOfTag = this.historyStack.indexOf(this.tags[tag]);
if (indexOfTag === -1) {
throw new Error('No index found for key')
this.browserHistory.go(indexOfTag - this.currentIndex + n);
}
}, {
key: 'firstLocationKey',
get: function get() {
return this.historyStack[0].key;
}
}, {
key: 'currentLocationKey',
get: function get() {
return this.historyStack[this.currentIndex].key;
}
}, {
key: 'currentlyOnFirstPage',
get: function get() {
return this.currentLocationKey == this.firstLocationKey;
}
}, {
key: 'currentlyOnLastPage',
get: function get() {
return !this.canGoForward();
}
}]);

this.browserHistory.go(indexOfTag - this.currentIndex)
}
}
return BackForwardHistory;
}();

exports.default = new BackForwardHistory();

export default new BackForwardHistory()
Loading

0 comments on commit 38e1c85

Please sign in to comment.