Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Brandon Cheng committed Aug 30, 2016
0 parents commit 6f8c5bd
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 0 deletions.
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Back Forward History

This is an addon to the history JavaScript
[history](https://github.com/mjackson/history) library. It enables tracking of
back and forward locations.

# Setup

```js
import React from 'react'
import { render } from 'react-dom'
import { Router, Route, browserHistory } from 'react-router'

import HistoryTracker from './back-forward-history'

HistoryTracker.listenTo(browserHistory)
```

# API

### listenTo(browserHistory)
Call this method to initialize this addon. Calling it more than once will result
in unexpected behavior

### canGoBack(n = 1)
Check if you can go back n pages. Defaults to 1.

### canGoForward(n = 1)
Check if you can go forward n pages. Defaults to 1.

### setTagForKey(key, tag)
Set a tag for a location you may want to return to. Get a key with
`currentLocationKey`.

### goToLocationWithTag(tag)
Goes backward or forward to reach a tag.
117 changes: 117 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
const SESSIONSTORAGE_PREFIX = 'BackForwardHistory_';

class BackForwardHistory {
browserHistory
historyStack
currentIndex
titles
tags

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

get currentLocationKey() {
return this.historyStack[this.currentIndex];
}

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

canGoForward(n = 1) {
return this.currentIndex < (this.historyStack.length - n)
}

get currentlyOnFirstPage() {
return this.currentLocationKey == this.firstLocationKey;
}

get currentlyOnLastPage() {
return !this.canGoForward()
}

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();
}

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

if (action === 'PUSH') {
if (!this.currentlyOnLastPage) {
this.historyStack = this.historyStack.splice(0, this.currentIndex+1)
}

this.historyStack.push(key);
this.currentIndex++;
} else if (action === 'POP') {
const potentialIndex = this.historyStack.indexOf(key);

if (potentialIndex === -1) {
// User hit go on url bar. Reset history stack.
this.historyStack = [key]
}

this.currentIndex = this.historyStack.indexOf(key);
}

this.saveStateToSession()
}

getLastLocationTitle() {
return this.titles[this.historyStack[this.currentIndex-1]]
}

getTitleForKey(key) {
return this.titles[key]
}

setTitleForKey(key, title) {
this.titles[key] = title
}

setTagForKey(key, tag) {
this.tags[tag] = key
}

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)
}
}

export default new BackForwardHistory()
20 changes: 20 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "back-forward-history",
"version": "1.0.0",
"description": "This is an addon to the history JavaScript library. It enables tracking of back and forward locations.",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "UConn Center for Open Research, Resrouces, and Equipment",
"license": "MIT",
"repository": {
"type": "git",
"url": "git@github.uconn.edu:Brandon/BackForwardHistory.git"
},
"keywords": [
"history",
"react",
"react-router"
]
}

0 comments on commit 6f8c5bd

Please sign in to comment.