Right now, pushState and replaceState serialize their state objects to JSON. We should use structured clone to be compliant with the spec.
On the other hand, JSON serialization is convenient because it lets us easily serialize state objects for session restore.
Right, what we need here is not the structured clone code developed over in bug 550275. What we need is code to serialize and deserialize such that
obj1 --serialize--> ser --deserialize--> obj2
obj2 is a structured clone of obj1. We'll need this code both for pushState and for localStorage.
Did a quick experiment and it appears that WebKit is doing something similar to us: If you create a state object which contains a function, the function doesn't exist when you get the state object back on popstate.
I like the fact that we can serialize state objects to disk, so I'm not sure we even want to do this. But if we don't, maybe we should get the spec changed.
We should definitely serialize. Everything supported by the structured clone algorithm is serializable. The user-visible effect of fixing this bug is that you can pushState objects that contain things like ImageData, dates and regexps (the latter not being terribly important obviously).
For my reference, it looks like the JSAPI functions are JS_WriteStructuredClone and JS_ReadStructuredClone. When we write out to storage, we can Base64-encode the value. And when we read back in, we'll have to convert any JSON-encoded state objects to the new format.
Created attachment 525039 [details] [diff] [review]
I'll ask for review here once I push to try and verify that this works.
(In reply to comment #4)
> We should definitely serialize. Everything supported by the structured clone
> algorithm is serializable. The user-visible effect of fixing this bug is that
> you can pushState objects that contain things like ImageData, dates and regexps
Most importantly, File. Once structured clones support them, it should be possible to store Files that the user has opened to the history, and to restore them from a serialized session, so users don't have to reopen files each time they restart their browser.
Created attachment 527605 [details] [diff] [review]
Is there a reason why nsIStructuredCloneContainer need to live under docshell/ ?
It looks like a very useful interface/class for other use too.
Maybe it could be under dom/intefaces/base ?
Patch is ready for review. I fixed the one bug from my last try push, so things *should* be green, but I'll push again to be sure.
I'd originally used JS_AutoStructuredClone inside nsIStructuredCloneContainer, but I was getting strange memory management errors. (I know you don't have to JS_free with the same cx you JS_malloc'ed with, so I'm not exactly sure what I was doing wrong.) In any case, I think malloc'ing and free'ing manually is sufficiently simple not to worry about this.
(In reply to comment #9)
> Is there a reason why nsIStructuredCloneContainer need to live under docshell/
> Maybe it could be under dom/intefaces/base ?
That's fine with me!
Created attachment 527617 [details] [diff] [review]
Moved nsIContentUtils, per Smaug's suggestion.
er...I moved nsIStructuredCloneContainer (and kin), not nsIContentUtils (which hopefully will cease to exist soon).
(In reply to comment #10)
> Patch is ready for review. I fixed the one bug from my last try push, so
> things *should* be green, but I'll push again to be sure.
Paul, can you have a look at the sessionstore changes?
I should mention that this change will cause a one-time loss of state objects upon session restore; I make no attempt to read the old JSON state objects and convert them to the new format. I think this isn't a big deal, since persisting state across session restore didn't even work properly until we fixed bug 647028 yesterday.
Comment on attachment 527617 [details] [diff] [review]
Can I assume that since there are no tests here, this is covered under some of the other tests you've written? r=me assuming that, but I'll take it back if you tell me I'm wrong.
I'm ok with the one-time data loss. pushState isn't that widely used yet that most people wouldn't even notice.
Although I think we get decent coverage with the other tests I wrote, it would be trivial to add a test specifically for session restore to browser_500328.js. I'll definitely add this.
Created attachment 530390 [details] [diff] [review]
Added session restore test.
Comment on attachment 530390 [details] [diff] [review]
Wow, this looks great
Created attachment 530622 [details] [diff] [review]
I forgot to update nsIDocument's CID and check the return value of JSAutoEnterCompartment::Enter in nsStructuredCloneContainer::InitFromVariant.
Also mentioned on Firefox 6 for developers.