[whatwg] History API, pushState(), and related feedback

Ian Hickson ian at hixie.ch
Thu Apr 8 18:59:04 PDT 2010

On Thu, 18 Feb 2010, Mike Wilson wrote:
> Ian Hickson wrote:
> > On Fri, 22 Jan 2010, Mike Wilson wrote:
> > > 
> > > I'll keep this short as there is more recent discussion:
> > > 2) The pageStorage object is one incarnation of [a key
> > >    value store] solving the dependency problem that appears
> > >    when different components want to save data to the single
> > >    session history state object
> > 
> > I'm really not convinced this is a problem we need to solve. There are 
> > plenty of places where the Web platform doesn't cater for different 
> > parts of a page being written by different people who aren't 
> > coordinating. The whole DOM, for instance. Event handler attributes. 
> > All the storage APIs.
> I think the storage APIs (localStorage and sessionStorage) are the 
> better comparison of these as they are also state handling mechanisms. 
> These do allow selected parts of the state to be accessed individually 
> as they are key/value stores. Thus they allow different parties to have 
> uncoordinated access to their own data.
> Fwiw, with some good will you can say that cookies are also handled as 
> key/value stores as their values are scoped on both domain and key 
> (cookie name). This allows different parts of the code to deal with 
> their own values as long as there isn't a key (cookie name) collision.

Both with cookies and with storage, it's trivial to stomp all over some 
other person's work if you're sharing that space. It certainly wasn't 
designed for the use case you described, however, even though it might be 
usable that way.

> > > And the later part is more about general properties of
> > > API design:
> > > 3) If a key-value store is desired, then using the same API 
> > >    as the other key-value stores is a strength and not an over-
> > >    generalisation. The web doesn't need yet another API.
> > > 4) Thinking about possible future additions when choosing
> > >    names is one part (of many) of a successful design.
> > 
> > I don't understand the above points.
> The main point is: Why not use the same API as in Web Storage:
>   interface Storage {
>     readonly attribute unsigned long length;
>     getter DOMString key(in unsigned long index);
>     getter any getItem(in DOMString key);
>     setter creator void setItem(in DOMString key, in any data);
>     deleter void removeItem(in DOMString key);
>     void clear();
>   };
> and make the current entry's Storage instance always available
> as f ex:
>   interface History {
>     readonly attribute Storage state;
>   }
> Then pushState's state parameter may be removed and there is
> no longer a need for the replaceState method.

I don't understand how this would work. When does the history get updated 
in this model? How do you know you've gone back in history? I'm not at all 
convinced that this is better.

> Apart from API harmonization this also fixes the differences in semantic 
> contract. With this I mean that when Justin Lebar and I started this 
> discussion last summer the pushState API was still very restrictive and 
> only allowed retrieval of data during the popstate event and only 
> allowed storage of data when pushState:ing a new history entry.
> Making an analogy with sessionStorage would mean that it would only be 
> allowed to read data from sessionStorage during the load event and only 
> be allowed to write data at the same time as assigning window.location.
> Since then we have seen some changes to the spec and now the state 
> object may be written to at any time, and may also be written to without 
> creating a new history entry. Reading from it at any time is still 
> missing, for what reason I don't know?

Why would you read from it? What's the use case?

> Nevertheless, the semantic contract is coming closer and closer to that 
> of the other storage APIs, so I think it would be an advantage to use 
> the same interface as well.

I don't see the relevance of storage APIs here. This isn't a storage 
model. It's more a callback model.

> > > [...] Ie, this data is persisted on demand at a certain point in the 
> > > history entry's life cycle, just as I am suggesting for the 
> > > pushState state.
> > >
> > > With the same reasoning as for current pushState, the spec would 
> > > instead suggest that scroll position and form control values were 
> > > persisted immediately when changed, instead of at the "leave history 
> > > entry" event.
> > 
> > The problem is that you really want the URL to always be up to date, 
> > so that the user can copy it. And thus you really want to be calling 
> > pushState() whenever the state changes.
> Indeed a fair bit of cases should reflect their state in the URL, but, 
> referring to my earlier examples, state like scroll position and form 
> control values usually should not. I'm talking about this latter kind of 
> data.

The user agent takes care of scroll position and form control values 
already when pushing state.

> > Hitting "back" would take the user into a previous state in the 
> > application, it wouldn't affect the user's work.
> Yes and no. According to the current spec 
> http://dev.w3.org/html5/spec/Overview.html#history-traversal user agents 
> are free to persist scroll position and form control values on history 
> traversal. Naively I'd consider scroll position to be UI state and form 
> control values to be user data state, and both seem to be eligible for 
> persisting on history entries.
> So, I think there may be cases where it is desired to (temporarily) 
> store the contents of a rich-text form field on a history state, or 
> maybe store complex UI state such as the open/close status of a large 
> number of tree nodes, both of which would be overkill to replaceState on 
> every change.
> The only thing needed to support this in an efficient way is to provide 
> something like a "beforepopstate" event that fires before the new 
> history entry is made current, so that a call to replaceState will still 
> target the "old" entry.

I really don't follow your proposals.

I would recommend, if you believe that this is a better model, writing a 
specification for this model, and implementing it or convincing a browser 
vendor to implement it, so that they can be compared in context.

Ian Hickson               U+1047E                )\._.,--....,'``.    fL
http://ln.hixie.ch/       U+263A                /,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'

More information about the whatwg mailing list