[whatwg] Proposed changes to the History API

I'm in the process of implementing the HTML5 History API
(History.pushState(), History.clearState(), and the PopState event) in
Firefox.  I'd like to discuss whether the API might benefit from some
changes.  To my knowledge, no other browser implements this API, so
I'm assuming we have freedom to make large alterations to it.

My basic proposal is that History.pushState() be split into a function
for creating new history entries and functions or a property for
getting/setting an object associated with that entry.

In its current form, the History API allows us to identify session
history entries by way of an arbitrary object, which we pass as the
first argument to pushState() and which we receive as part of the
PopState event when that history entry is activated.  If the page gets
a null popstate, it's supposed to use the URL to decide what state to
display.

Notably unsupported by this API is support for pages altering their
saved state.  For instance, a page might want to save a text box's
edit history to implement a fancy undo.  It could store the edit
history in a cookie or in the session storage, but then if we loaded
the page twice in the same tab, those two instances would step on each
other when we went back and forth between them.

The page could just store its state in variables in the document, but
then it would loose that state when the browser crashed or was closed,
or when the browser decided to kick the document out of the history.

I think this page would be better served by a History.setStateObject()
function, which does exactly what the page wants in a simple fashion.

We'd still keep the history-entry-creating functionality of
History.pushState() in a new History function (I'll call it
createNewEntry(), but it probably needs a better name), which takes a
title and URL, as pushState() does now.

The API might be more intuitive if we had a History.stateObject
propery, but I'm concerned that then we'd be promising the page that
we'll keep around literally any objects it wants, including DOM
objects.  In fact, I'd be happy restricting the state object to being
a string.  If a page wants to store an object, it can convert it to
JSON, or it can store a GUID as its state string and index into the
session storage.

Pages could retrieve the state object just as they do now, in a
PopState event, although we'd probably want to change the name of the
event.  We'd probably want to fire PopState on all loads and history
navigations, since any document might have a state to pop, and even
those documents which didn't call setStateObject() might store state
in their URI which they need to restore when their history entry is
activated.

Last, I'm not sure that we need the History.clearState() function.
It's confusing (why do we end up at the last entry for the current
document instead of staying at the current entry?) and I haven't been
able to come up with a compelling use case.

I think the main benefit of these changes is added simplicity.
There's a right and wrong way to use pushState, and
setState/createNewEntry doesn't require such rules.  But additionally,
these changes allow pages flexibility to do things we haven't yet
thought of.  I don't know what those things might be, but I suspect
they may be pretty cool.  :)

-Justin

Received on Tuesday, 18 August 2009 17:04:38 UTC