[whatwg] pushState

Jonas Sicking jonas at sicking.cc
Fri Jul 25 16:27:16 PDT 2008

Hmm.. I'm sort of seeing where the spec was trying to head. However I 
think it too poorly supports the browser restart case.

Comments below.

Ian Hickson wrote:
> On Fri, 25 Jul 2008, Jonas Sicking wrote:
>>> The idea is to use this title in the session history. It's distinct 
>>> than the <title> and document.title because when the session history 
>>> might need to say something like "Mail - after opening 'compose 
>>> mail'", "Mail - after typing paragraph ending in 'JSON-ifyable 
>>> object.'", and so forth, while the whole time the actual page title 
>>> just says "Mail - New Mail".
>> So the idea is that this is the title that we'd display for example in 
>> the drop down where you can select a history entry to navigate to?
>> If so, why wouldn't you want document.title to also say "Mail - after 
>> opening 'compose mail'" as well? Seems like good UI to keep the two in 
>> sync.
> My mail client just keeps the same title the whole time I'm using it. But 
> seeing the name of my mail client six hundred times in a row without any 
> hint as to what each entry means (in the session history) wouldn't be 
> useful. So I guess my answer is no.
> I think it makes sense that the entry you see in the session history and 
> the entry you see in your OS pager would have different strings.
> FWIW, the title parameter was added in response to requests in feedback 
> from application authors, who didn't want to change document.title for 
> this.

Requesting is easy. *Why* did they request this? Still seems like better 
UI design to have this affect the title. The title of my mail client 
changes to show what part of the UI I'm in. Currently it says "whatwg 
for jonas at sicking.cc" indicating that i'm watching the whatwg folder on 
the "jonas at sicking.cc" account.

>>>> What is the purpose of the url attribute? Why would you want to 
>>>> reload a separate page when returning to a given state, then what 
>>>> was used to load that state initially?
>>> If the Document gets discarded (e.g. it gets evicted from the 
>>> bfcache), the URL allows the client to still pretend it has the state, 
>>> allowing the server to regenerate it based on the data in the URL.
>> But why would you want to recreate the same document using a different 
>> page than the page that originally created the document. I.e. if I have 
>> a single page that I use to show various views, why would I all of a 
>> sudden want to use another page to render one of those views just 
>> because the user restarted the browser?
> Consider an AJAX version of Bugzilla. Each bug page has a different URL. 
> As you navigate from bug to bug, the URL should change to point to the 
> currently showing bug. But you want to do that without actually doing a 
> reload (changing the Document object).

Yes, this is a decent example. Or gmail could show a different URI 
depending on which mail you are currently reading, or which folder you 
are currently browsing.

>>> Also, the URL can be used when bookmarking the page. It could also be 
>>> displayed in the location bar.
>> Hmm.. bookmarking is indeed tricky. If a site really want to support 
>> bookmarking it seems like the best solution is to use the old hack of 
>> setting location.hash.
> The hash isn't sent to the server.

Why would you want to send something to the server? The original page 
was loaded without that data being sent to the server.

> Again, fwiw, the URL parameter was added in response to author feedback to 
> the effect that only having control over the hash was insufficient for 
> what they wanted to do.


The argument against using the hash that I can see is that it has 
another semantic meaning. This causes troubles such as scrolling 
whenever it is set.

>>> (The Location object should not be updated, however.)
>> Why not?
> Changing it would introduce a gratuitous difference between legacy UAs and 
> UAs implementing this feature, as well as complexity that I'm not sure I 
> really want to have to test.

How exactly were you envisioning that people do fallback to legacy UAs?

The solution that I can think of is to either set location = ... causing 
a reload on legacy UAs. Or you could set the hash which seems to work 
sufficiently well today.

In both cases the Location changes.

>>>> I would like to store the session states created using pushState on 
>>>> disk so that the state can be restored in the event of a crash or a 
>>>> restart. The only thing that would be needed to support this is that 
>>>> the 'data' object is a string rather than a generic object. This is 
>>>> because a generic object can't be serialized and saved to disk. 
>>>> Actually, what would be even better is if the API accepted a string 
>>>> or a JSON-ifyable object.
>>> That's what the URL is for.
>> Then what is the point of the data object? It seems very bug prone that 
>> the data object is just dropped on the floor if the browser is 
>> restarted. I.e. we should recommend everyone not to use the data object 
>> (except for some sort of cache?) since it will always fail to work if 
>> the user restarts the browser.
> The data object is for when the page still exists, so that the state can 
> be updated on the fly, e.g. bringing back the exact same <video> element 
> to the front, or whatever.

You can still do this, it's just that we won't encourage it using an API.

You can just store your <video> or whatnot in some cache in some global 
object. You could even store it in an array and store the index of that 
array in the stored data object.

Storing objects in the history state isn't going to extend the lifetime 
past that of the Document anyway. The UA is going to want to tear down 
all stored objects when tearing down the Document since otherwise its 
very likely that those objects would keep the Document alive, if nothing 
else through the JS __parent__.

This actually means that even when not talking about a restart, in order 
to better support long history chains where the Document is likely to be 
evicted from the fastback cache, we should enforce that the data objects 
be serializable (JSON-able).

>>> The data will, in many non-trivial cases, be some very complex object 
>>> with actual Object references and pointers to DOM nodes and so forth. 
>>> Imagine, for instance, a text editor using this. I don't think we want 
>>> to require that the data be "plain structured data" (is there a term 
>>> for this better than "JSON-ifiable"?), as that would preclude a number 
>>> of complex cases.
>> But all those complex cases will fail on a browser restart. It is much 
>> better if we encourage people to write stable code.
> The original feature wasn't expected to work at all across a browser 
> restart.

Well, consider it requested ;)

This is a very important aspect of this for us in order to reduce data 
loss at crashes, and to encourage that people restart for security 
upgrades as soon as possible.

> The URL is optional. When it is omitted, the session history entry is just 
> discarded when the Document is lost.
> To use GMail as an example again, one might want to pushState() for every 
> change of selected e-mails, but only pushState() with a URL when the 
> search query changes.

Seems ok to me.

>> My goal with this was to provide a clean API to avoid having to muck 
>> around with location.hash trickery (as that really should be used for 
>> other things), and that would work in the event of a browser restart. It 
>> doesn't seem like the current API meets that goal.
> The current API is written specificially to meet that goal for a variety 
> of different applications with a broad set of requirements.

As of now I don't think it supports the browser restart requirement well 
enough. Nor the case of long history chains.

/ Jonas

More information about the whatwg mailing list