uhistory

2.0.0-rc.2 • Public • Published

uhistory

Microscopically small History API based on uevents

npm license travis greenkeeper mind BLOWN

Install

npm install --save uhistory

Require

var History = require('uhistory')  

Import

import History from 'uhistory'

Use

var history = History()
history.on('change', function(){console.info('Changed!')})
history.pushState({some:'state'}, 'title', '/some/url')
//  >  'Changed!'

Why

The standard History object in browsers offers a decent API to change the history, but is a bit awkward to work with when you want to listen for changes, because you need to listen to popstate on the window object, instead of on the history object itself, and because 'pushState' and 'replaceState' don't lead to a popstate event being emitted...

uhistory is microscopically small (~0.7kB minified and gzipped) and has only one dependency, on uevents, which is a lean version of the widely popular Node JS EventEmitter library. Together, they create an API that feels natural and standard:

const history = require('uhistory')()
history.on('back', function(){
    console.info('Back!')
})
history.on('change', function(location, state, source){
    // location = new location
    // state = any state associated with the history entry
    // source = 'pushState', 'replaceState' or 'popState' (back/forward/go actions)
    console.info('Change!')
})
history.pushState({some:'state'}, 'title', '/new/page')
//  > Change!
history.back()
//  > Back!
//  > Change!

History (ctx)

Creates a history object.

ctx

The backing context for the history object.

In browsers, you don't need to pass any arguments. History will pick up the native window.history object automatically:

var History = require('uhistory')  
var history = History()

In Node, there is no native history object. So you need to pass in another context for History to use:

var History = require('uhistory')  
var MemoryContext = require('uhistory/memorycontext')  
var ctx = MemoryContext()
var history = History(ctx)

See MemoryContext for more information.

In browsers, when you create a new history object without passing in an eplicit context, uhistory will pick up window as the context and use window.history and window.location as backing mechanism, returning a new object. window.history is not affected.

var History = require('uhistory')  
var history = History()
history === window.history    // false

Sometimes, you want window.history to be affected, so any code that uses it will trigger events on it. In that case, explicitly pass window as the context:

var History = require('uhistory')  
var history = History(window) // pass in explicitly
history === window.history    // true

Events

The following events are emitted by the history object:

change (location, state, source)

The change event is emitted a a result of calling pushState() or replaceState(), or the popstate event firing.

location

The location object. location.href contains the (canonical version of the) url.

state

The state object associated with the current history entry (history.state)

source

The source of the event. One of 'pushState', 'replaceState' and 'popstate'.

popstate (event)

As a result of the popstate event firing on the context.

event

The event object that was received from ctx.popstate

back

As a result of the back() method being called.

forward

As a result of the forward() method being called.

go (delta)

As a result of the go() method being called.

delta

The number of entries to move. Can be negative to move backward. This is the number that was passed to the go() method

pushState (state, title, url)

As a result of the pushState() method being called.

state

The state object that was passed to pushState, if any

title

The title string that was passed to pushState, if any

url

The url string that was passed to pushState, if any

replaceState (state, title, url)

As a result of the replaceState() method being called.

state

The state object that was passed to pushState, if any

title

The title string that was passed to pushState, if any

url

The url string that was passed to pushState, if any

MemoryContext

To allow you to use uhistory on node, we need to provide the services it depends on. The context argument you pass to history mimics the way the history object operates on browsers and the objects it interacts with:

  • back, forward, go, pushState and replaceState affect window.location
  • back, forward and go cause a 'popstate' event to be emitted on window

So, including window.history, three objects are involved in this interaction.

MemoryContext is modeled exactly like this. It provides an object that takes the place of window, that has properties location and history to replace those services and it simulates the interaction between those objects to be consistent with how it happens in the browser.

To use it, require the separate module memorycontext from the uhistory package:

var History = require('uhistory')
var MemoryContext = require('uhistory/memorycontext')

Keeping this endpoint separate prevents it from bloating your web bundle

Now, instantiate the context object. It's location.href property will be set to 'http://localhost':

var ctx = MemoryContext()
ctx.location.href // 'http://localhost'

To set a different value, pass it as an argument:

var ctx = MemoryContext('https://www.example.com')
ctx.location.href // 'https://www.example.com'

Now, pass the created context to History:

var history = History(ctx)

MemoryContext depends on ulocation

Issues

Add an issue in this project's issue tracker to let me know of any problems you find, or questions you may have.

Copyright

Copyright 2017 by Stijn de Witt. Some rights reserved.

License

Creative Commons Attribution 4.0 (CC-BY-4.0)

Package Sidebar

Install

npm i uhistory

Weekly Downloads

11

Version

2.0.0-rc.2

License

CC-BY-4.0

Last publish

Collaborators

  • stijndewitt