Re: [whatwg] Proposed changes to the History API

2009-08-22 Thread Mike Wilson
Justin Lebar wrote:
 Mike Wilson wrote:
  It would be interesting to see a concrete
  example on how you intend the dynamics of your solution to
  work. It would be great if you could outline the different
  events and method calls used (in order) to save and restore
  the history state object in the following situations:
  - doing a fresh navigation from page#1 to page#2
  - going back in history from page#2 to page#1
 
 Here's one way it could go:
 
 User was at http://google.com, types
 http://mozilla.com/index.html#1 into address bar.
 * onload
 * stateactivated
 User clicks on link with href #2
 * statedeactivated (until this event is complete,
   document.location.hash == #1 and the pageStorage object is 
   for the #1 state)
 * stateactivated (at the beginning of this event,
   document.location.hash == #2 and the pageStorage object is 
   for the #2 state)
 User clicks back
 * statedeactivated (for #2)
 * stateactivated (for #1)

Great, this seems to be exactly what I want too. In particular
I note the following differences from the current spec:
- events both when entering and leaving a history entry (I 
  called them hashload and hashunload but I agree it is better 
  to avoid hash as we also have state-only history entries)
- the same processing for fresh (newly navigated to) history
  entries as for historical (navigated back/forward to)
  history entries
- removal of the popstate event and exposing a read/writable 
  state object during the whole history entry session

About stateactivated naming:
Activated/deactivated is a bit longish. Could
- stateload/stateunload
- stateenter/stateleave
or others be good alternatives?
Is state the desired keyword? Or should history or others
be considered?
Or something playing on the pageshow/pagehide naming?

About pageStorage lifetime:
Adding on to your description, assuming we are navigating from 
one page (/a) to another (/b) in history without bfcache, the 
following would be a suitable chain of events:
- /a statedeactivated event
- /a unload event
- /a browser saves form fields, scrollpos, and history state obj
- browser swaps out /a and loads /b
- /b browser restores history state obj before any script runs
- /b scripts are executed and form fields and scrollpos are 
 restored while document content is built
- /b load event
- /b stateactivated event

About pageStorage naming:
I think page makes you think more of Document than of history
entries. Looking at an overview of storage areas, ordered from
large scopes down to fine-grained scopes may spawn some ideas:

  CURRENTLY DISCUSSED:

  Scope   Storage area / identifier
  -   -
  user agent  window.localStorage
  browsing contextwindow.sessionStorage
  document-
  history entry   window.pageStorage

If anticipating there could be a future storage area per 
Document, naming could be something like this:

  ALTERNATIVE:

  Scope   Storage area / identifier
  -   -
  user agent  window.localStorage
  browsing contextwindow.sessionStorage
  documentdocument.documentStorage
  history entry   window.history.entryStorage

Best regards
Mike


Re: [whatwg] Proposed changes to the History API

2009-08-21 Thread Mike Wilson
Justin Lebar wrote:
 The pushState function as currently specified allows you to do
 precisely this.  History.pushState(obj, title, url) creates a new
 history entry with the given URL, but doesn't load a new document.

Ah thanks, I had missed the part saying that path and query
were ok to change. I think this part of the spec is very
controversial though, but I'll spawn that discussion to
another thread.

   It would further be nice if your comments weren't lost even if you
  navigate away from the page.
 
  This is the way it works in most browsers, as the browser persists
  form field values when you navigate back and forth in history.
 
 Right.  But the difficulty with this page in particular is that it's
 structured such that it's difficult/impossible for the browser to
 properly restore its form state after a crash.  Onload, the page
 creates a textarea and populates it with the text of the patch.  So
 if we crash then restore, the page won't have created the textarea by
 the time the browser looks to restore the text.

Sorry, it seems we are not talking about the same application.
Jonas referred to attachment pages in your bug database, which
I assumed would f ex be a page like this one:
https://bugzilla.mozilla.org/attachment.cgi?id=386244action=edit
(The textarea in this app is not created onload, it is delivered
in the server-generated HTML and thus is subject to form field
value persistence.)

What app are you talking about?

 what we really want is a
 way to programmatically do the restore.

Certainly, that's why we are all here I guess :-)
Being able to do similar things as form field value persistence
and scroll position persistence, but for your own data, is the
purpose of history states, IMO.

Best regards
Mike



Re: [whatwg] Proposed changes to the History API

2009-08-21 Thread Mike Wilson
Justin Lebar wrote:
 On Wed, Aug 19, 2009 at 5:31 PM, Jeremy Orlow wrote:
  but here it seems like everything can just stay in memory...right?
 
 My thought was that if you had a tab open and restarted the browser,
 that the state objects would be there after the restart, so we'd have
 to serialize to disk.  I also thought that we'd persist this state
 data even after we take a Document out of memory.

This part begs a couple more questions :-)

What you're essentially saying here is that when restarting
the browser, you will also restore history data, correct?

For tabs that were open when the browser was closed, this 
will mean that these will reappear after restart with full 
history, being able to go Back and restore state on
previous pages?

But for pages that were explicitly closed, and then 
navigated to in a new tab, will you restore the full
history in these as well? And is that really desired from
a user pov? (It seems you will be haunted by the same page
history forever, even if the corresponding server state
expired a long time ago.)

And if there has been several sessions in parallel on that
URL space, which one do you respawn for a navigation to a 
related page in a new tab?

Best regards
Mike



Re: [whatwg] Proposed changes to the History API

2009-08-21 Thread Mike Wilson
Justin Lebar wrote:
 Maybe the right solution is to have a pageStorage object, which works
 just like sessionStorage but is local to a session history entry and
 perhaps carries some weak promise of persistence.

Yes, I was also thinking that being able to store key/value
pairs, instead of a single state object, would be good.
It would be nice to see the same kind of API be reused
throughout the different state/storage mechanisms.

Best regards
Mike



Re: [whatwg] Proposed changes to the History API

2009-08-21 Thread Justin Lebar
 Sorry, it seems we are not talking about the same application.
 Jonas referred to attachment pages in your bug database, which
 I assumed would f ex be a page like this one:
 https://bugzilla.mozilla.org/attachment.cgi?id=386244action=edit
 (The textarea in this app is not created onload, it is delivered
 in the server-generated HTML and thus is subject to form field
 value persistence.)

STR:
  * Open https://bugzilla.mozilla.org/attachment.cgi?id=386244action=edit
  * Click Edit as comment
  * Change the text in the textarea
  * Close and re-open your browser

Actual behavior: The textarea is back to its original state, read-only
and without your edits.  Even after you press edit as comment, the
state still doesn't reflect the changes you made before you closed the
browser.

Behavior with History API: When you click edit as comment and as you
type your comments, the page periodically saves the data to pageState.
 When the page receives a popstate, it restores the state of the
textarea.

I imagine that one could rework the Bugzilla page to function better
on browser restart using existing web technologies.  But as the page
is designed right now, some kind of pageStorage would be helpful.

-Justin


Re: [whatwg] Proposed changes to the History API

2009-08-21 Thread Justin Lebar
Mike Wilson wrote:
 What you're essentially saying here is that when restarting
 the browser, you will also restore history data, correct?

 For tabs that were open when the browser was closed, this
 will mean that these will reappear after restart with full
 history, being able to go Back and restore state on
 previous pages?

Right.  We already do this, sans popping a state object.

 But for pages that were explicitly closed, and then
 navigated to in a new tab, will you restore the full
 history in these as well?

No.  The state object is attached to the session history entry, not to
the page's URI.  If you close a tab, all its session history entries
go away.  If you navigate to a page which was open in the tab you just
closed, that new instance of the page won't be aware of the old page's
state object(s).

 And if there has been several sessions in parallel on that
 URL space, which one do you respawn for a navigation to a
 related page in a new tab?

A navigation on a new tab would get an entirely new environment.
Otherwise, like you suggested, this would be very confusing.

-Justin


Re: [whatwg] Proposed changes to the History API

2009-08-21 Thread Mike Wilson
Justin Lebar wrote:
 Mike Wilson wrote:
  Sorry, it seems we are not talking about the same application.
  Jonas referred to attachment pages in your bug database, which
  I assumed would f ex be a page like this one:
  https://bugzilla.mozilla.org/attachment.cgi?id=386244action=edit
  (The textarea in this app is not created onload, it is delivered
  in the server-generated HTML and thus is subject to form field
  value persistence.)
 
 STR:
   * Open 
 https://bugzilla.mozilla.org/attachment.cgi?id=386244action=edit
   * Click Edit as comment
   * Change the text in the textarea
   * Close and re-open your browser
 
 Actual behavior: The textarea is back to its original state, read-only
 and without your edits.  Even after you press edit as comment, the
 state still doesn't reflect the changes you made before you closed the
 browser.

Hm, it seems you didn't get my point. I was referring to
your statement saying that it wasn't possible for the form 
field value persistence to do its job because the textarea
was created and populated onload. I was pointing out that
this is not the case, as the textarea and its content
are indeed delivered in the static HTML right from the
server and not created onload. 
Thus, this textarea is fully functional with the browser's 
form field value persistence mechanism, as can be seen if 
you revisit the textarea within the same browser session.

I understand that persistence between browser restarts is
one of your goals, but I have never said that the current
incarnation of form field value persistence persists 
between browser restarts. Or are you saying that?
Indeed, if Mozilla's implementation did that, I would 
expect it to work straight off with the discussed bugzilla
page, due to its simple and form-friendly design.

Best regards
Mike



Re: [whatwg] Proposed changes to the History API

2009-08-21 Thread Jeremy Orlow
On Fri, Aug 21, 2009 at 12:26 PM, Mike Wilson mike...@hotmail.com wrote:

 Justin Lebar wrote:
  Mike Wilson wrote:
   Sorry, it seems we are not talking about the same application.
   Jonas referred to attachment pages in your bug database, which
   I assumed would f ex be a page like this one:
   https://bugzilla.mozilla.org/attachment.cgi?id=386244action=edit
   (The textarea in this app is not created onload, it is delivered
   in the server-generated HTML and thus is subject to form field
   value persistence.)
 
  STR:
* Open
  https://bugzilla.mozilla.org/attachment.cgi?id=386244action=edit
* Click Edit as comment
* Change the text in the textarea
* Close and re-open your browser
 
  Actual behavior: The textarea is back to its original state, read-only
  and without your edits.  Even after you press edit as comment, the
  state still doesn't reflect the changes you made before you closed the
  browser.

 Hm, it seems you didn't get my point. I was referring to
 your statement saying that it wasn't possible for the form
 field value persistence to do its job because the textarea
 was created and populated onload. I was pointing out that
 this is not the case, as the textarea and its content
 are indeed delivered in the static HTML right from the
 server and not created onload.
 Thus, this textarea is fully functional with the browser's
 form field value persistence mechanism, as can be seen if
 you revisit the textarea within the same browser session.

 I understand that persistence between browser restarts is
 one of your goals, but I have never said that the current
 incarnation of form field value persistence persists
 between browser restarts. Or are you saying that?
 Indeed, if Mozilla's implementation did that, I would
 expect it to work straight off with the discussed bugzilla
 page, due to its simple and form-friendly design.


I think whether or not a particular UA persists form field data (or anything
other than history API data) is completely orthogonal to this discussion.
 For the sake of this discussion, lets assume there's some UA out there that
ONLY persists history API data for recovery.  That way the history API
doesn't depend on any of these other features.  Agreed?

Getting back to your question, with both the original and the newly proposed
API this is possible.  The difference is that with the newer API, it's much
easier to update an entry.  For example, if I wanted history to include what
was typed into a particular form field, I could just keep updating the
history entry whenever the text changes or when I add a new history entry.
 With the old API, I'd have to create a unique ID that gets pushed via the
history API, and then maintain all of that state elsewhere.  I then depend
on either both or neither of those APIs surviving a recovery.

This is one of the reasons I think the proposed changes to the API are much
more usable.

J


Re: [whatwg] Proposed changes to the History API

2009-08-21 Thread Mike Wilson
Ah good, something made me think you were trying to populate
fresh history entries as well, which would have been 
awkward. 

We've been discussing general properties of the solution for 
a while now. It would be interesting to see a concrete
example on how you intend the dynamics of your solution to
work. It would be great if you could outline the different
events and method calls used (in order) to save and restore
the history state object in the following situations:
- doing a fresh navigation from page#1 to page#2
- going back in history from page#2 to page#1

If we start with this simple example (simple hash nav and
no URL impersonation) then maybe we can move on to more
advanced stuff later on. I'm assuming page#1 and page#2 are
perceived by the user as different parts of the application 
and that he wants state saved for each of them when 
navigating back and forth in history.

Best regards
Mike

Justin Lebar wrote:
 Mike Wilson wrote:
  What you're essentially saying here is that when restarting
  the browser, you will also restore history data, correct?
 
  For tabs that were open when the browser was closed, this
  will mean that these will reappear after restart with full
  history, being able to go Back and restore state on
  previous pages?
 
 Right.  We already do this, sans popping a state object.
 
  But for pages that were explicitly closed, and then
  navigated to in a new tab, will you restore the full
  history in these as well?
 
 No.  The state object is attached to the session history entry, not to
 the page's URI.  If you close a tab, all its session history entries
 go away.  If you navigate to a page which was open in the tab you just
 closed, that new instance of the page won't be aware of the old page's
 state object(s).
 
  And if there has been several sessions in parallel on that
  URL space, which one do you respawn for a navigation to a
  related page in a new tab?
 
 A navigation on a new tab would get an entirely new environment.
 Otherwise, like you suggested, this would be very confusing.



Re: [whatwg] Proposed changes to the History API

2009-08-20 Thread Mike Wilson
Jonas Sicking wrote:
 1.
 [...]
 it would be better if you could actually navigate between
 
   https://mail.google.com/mail/inbox
   https://mail.google.com/mail/label/personal
   https://mail.google.com/mail/label/whatwg
   https://mail.google.com/mail/label/whatwg/13b4711edac9c1e2
 
 and then use the fragment identifier for what it was intended.

I guess this is just a vision about what the developer really
wants to do, or are you thinking of any solutions that would
actually allow changing path (or query string) without loading 
a new Document?

I guess half of the problem (keeping loaded script and state
between page loads, but not the Document) is addressed by the
GlobalScript/SharedScope discussion in a different thread. Also,
keeping state between page loads is also the subject of some of
my previous mailings to the list.

 2.
 The ability to create several session history entries for the same
 page which the user can navigate between, and use some type of state
 object to disambiguate between these states. For example in our bug
 database we allow users to look at attachments, as well as comment on
 attachments. When starting to comment on an attachment the page
 changes from displaying the attachment, to displaying a textarea
 pre-populated with the contents of the attachment such that you can
 add comments to it. It would be nice if switching modes acted like
 navigation so that you could go back

Yes, I think this is one of the purposes of the history state entries,
in particular the URL-less ones (if you don't want your mode change
reflected in the URL hash).

  It would further be nice if your comments weren't lost even if you
 navigate away from the page.

This is the way it works in most browsers, as the browser persists
form field values when you navigate back and forth in history. Try
(in Firefox) to input some comments and navigate to a new page. When
returning to the comment page in FF3.5, the edit mode is gone (because
this was a scripted state) but if you go into edit again, you'll see
your input text, as the textarea contents was persisted by the browser.

From my incomplete tests it looks like several browsers persist form
field values per document, but scroll position per history entry.
Thus, you will not get different persisted comment text when 
navigating between two hash urls.

Though, it would be possible to build that function yourself, if 
desired, using the history state mechanism for hash urls.

 When thinking about it this way it became pretty clear that pushState
 was not the right API for two reasons. First of all it combines the
 two aspects into a single function call. The same function is used to
 navigate the user to a different API, as is used to associate data
 with a history entry.
 
 Instead having createNewEntry which deals with the first use case, and
 setState which (partially) deals with the second makes more sense.
 Though there is actually two features in the second use case:
 
 2a. Create new session history entries for the current page.
 2b. Associate data with the current session history entry.
 
 setState only does 2b. However createNewEntry could cover 2a if we
 make both the uri and title arguments optional.

I think this pretty much agrees with my view. 
I'd like to draw an analogy with how state currently is/can be 
persisted in normal page loading:

  click link to navigate from page1.html to page2.html:
...

  go back to page1.html in history:
leaving page2:
- trigger unload event so user code can save custom state
- browser saves form field values for page2 document
entering page1:
- browser restores form field values for page1 document
- trigger load event to allow user code to restore custom state

Note that there currently is no standard mechanism for saving custom
state per document above, and the form field value area is not
accessible to to user code.
Though, in the session history proposal there is a mechanism for 
saving custom state (the state object), so below I sketch on a model 
that uses this and also is symmetric with the page-load model above:

  click link to navigate from page1.html#a to page1.html#b:
leaving #a:
- trigger HashUnload event so user code can save custom state
- state may be saved using History.setState(), f ex
History.setState(hello);
entering #b:
- trigger HashLoad event so user code can restore custom state
- state may be queried with History.getState() but this is 
  null as this is a fresh history entry

  go back to page1.html#a in history:
leaving #b:
- trigger HashUnload event so user code can save custom state
- state may be saved using History.setState()
entering #a:
- trigger HashLoad event so user code can restore custom state
- state may be queried with History.getState() and hello will
  now be returned

  Note:
  1) HashLoad event is similar to the current HashChange
  2) HashUnload event is new, and is 

Re: [whatwg] Proposed changes to the History API

2009-08-20 Thread Justin Lebar
On Wed, Aug 19, 2009 at 5:31 PM, Jeremy Orlowjor...@chromium.org wrote:
 but here it seems like everything can just stay in memory...right?

My thought was that if you had a tab open and restarted the browser,
that the state objects would be there after the restart, so we'd have
to serialize to disk.  I also thought that we'd persist this state
data even after we take a Document out of memory.

It might be possible to store some subset of DOM objects while still
meeting those requirements, but that seems like it might be a serious
can of worms.  Do you have a use case which would be facilitated by
being able to store some DOM objects in this way?

-Justin


Re: [whatwg] Proposed changes to the History API

2009-08-20 Thread Jeremy Orlow
I see.  It makes more sense why you mentioned the session storage element
then.  Note that there has been some discussion about whether session
storage should survive crashes, but I know Safari and Chrome are currently
planning to _not_ serialize it to disk.
I don't have any good use cases for allowing DOM objects.  And, if history
is going to be recoverable, I completely agree that we shouldn't allow that.
 I still think we shouldn't force app developers to serialize everything to
strings.  Maybe we can just raise an exception if they try to set the
history state to something unserializable?  (I guess that's what you're
already doing?)

On Thu, Aug 20, 2009 at 11:05 AM, Justin Lebar justin.le...@gmail.comwrote:

 On Wed, Aug 19, 2009 at 5:31 PM, Jeremy Orlowjor...@chromium.org wrote:
  but here it seems like everything can just stay in memory...right?

 My thought was that if you had a tab open and restarted the browser,
 that the state objects would be there after the restart, so we'd have
 to serialize to disk.  I also thought that we'd persist this state
 data even after we take a Document out of memory.

 It might be possible to store some subset of DOM objects while still
 meeting those requirements, but that seems like it might be a serious
 can of worms.  Do you have a use case which would be facilitated by
 being able to store some DOM objects in this way?

 -Justin



Re: [whatwg] Proposed changes to the History API

2009-08-20 Thread Justin Lebar
 I guess this is just a vision about what the developer really
 wants to do, or are you thinking of any solutions that would
 actually allow changing path (or query string) without loading
 a new Document?

The pushState function as currently specified allows you to do
precisely this.  History.pushState(obj, title, url) creates a new
history entry with the given URL, but doesn't load a new document.

  It would further be nice if your comments weren't lost even if you
 navigate away from the page.

 This is the way it works in most browsers, as the browser persists
 form field values when you navigate back and forth in history.

Right.  But the difficulty with this page in particular is that it's
structured such that it's difficult/impossible for the browser to
properly restore its form state after a crash.  Onload, the page
creates a textarea and populates it with the text of the patch.  So
if we crash then restore, the page won't have created the textarea by
the time the browser looks to restore the text.

One can imagine reworking this page to make it play nicely with
session restore as it currently exists, but what we really want is a
way to programmatically do the restore.

  click link to navigate from page1.html#a to page1.html#b:

 [snip]

I think this is pretty much what we want to do, except that we'd like
to let authors use arbitrary URIs instead of constraining them to
using URIs which differ only in their hashes, so we still want
PopState to fire on all loads, not like hashchange.

The idea of having an unload event similar to PopState is intriguing, however.

-Justin


Re: [whatwg] Proposed changes to the History API

2009-08-20 Thread Justin Lebar
On Thu, Aug 20, 2009 at 11:20 AM, Jeremy Orlowjor...@chromium.org wrote:
 I see.  It makes more sense why you mentioned the session storage element
 then.  Note that there has been some discussion about whether session
 storage should survive crashes, but I know Safari and Chrome are currently
 planning to _not_ serialize it to disk.

I just did a quick test, and it appears that Firefox does save
sessionStorage across browser sessions, but IE8 does not.

Leaving aside the question of what the right thing to do is with
sessionStorage, I think there are some serious benefits to saving the
pushState'ed state across sessions.  Suppose I'm using a webmail
client which uses this new API.  I click around to a few of my folders
and messages and then close the browser.

If the page wants the back/forward buttons to work when the browser
re-opens, it needs to store all of the state for those history entries
in the URI.  At the point that pages have to do that, we might as well
not store a per-page state object.

  I still think we shouldn't force app developers to serialize everything to
 strings.  Maybe we can just raise an exception if they try to set the
 history state to something unserializable?  (I guess that's what you're
 already doing?)

Right now, I just serialize to JSON and throw an exception if that
fails.  I don't have a problem continuing to do that, at least until
we get the structured clone thing sorted out.

-Justin

 On Thu, Aug 20, 2009 at 11:05 AM, Justin Lebar justin.le...@gmail.com
 wrote:

 On Wed, Aug 19, 2009 at 5:31 PM, Jeremy Orlowjor...@chromium.org wrote:
  but here it seems like everything can just stay in memory...right?

 My thought was that if you had a tab open and restarted the browser,
 that the state objects would be there after the restart, so we'd have
 to serialize to disk.  I also thought that we'd persist this state
 data even after we take a Document out of memory.

 It might be possible to store some subset of DOM objects while still
 meeting those requirements, but that seems like it might be a serious
 can of worms.  Do you have a use case which would be facilitated by
 being able to store some DOM objects in this way?

 -Justin




Re: [whatwg] Proposed changes to the History API

2009-08-20 Thread Jeremy Orlow
On Thu, Aug 20, 2009 at 3:13 PM, Justin Lebar justin.le...@gmail.comwrote:

 On Thu, Aug 20, 2009 at 11:20 AM, Jeremy Orlowjor...@chromium.org wrote:
  I see.  It makes more sense why you mentioned the session storage element
  then.  Note that there has been some discussion about whether session
  storage should survive crashes, but I know Safari and Chrome are
 currently
  planning to _not_ serialize it to disk.

 I just did a quick test, and it appears that Firefox does save
 sessionStorage across browser sessions, but IE8 does not.

 Leaving aside the question of what the right thing to do is with
 sessionStorage,


The spec makes it clear that it's possible, but isn't session (in the
broader sense of the word) restore a UA feature, and not necessarily
something we need to all be the same on?  (Feel free to split this into
another thread if necessary.  :-)


 I think there are some serious benefits to saving the
 pushState'ed state across sessions.  Suppose I'm using a webmail
 client which uses this new API.  I click around to a few of my folders
 and messages and then close the browser.

 If the page wants the back/forward buttons to work when the browser
 re-opens, it needs to store all of the state for those history entries
 in the URI.  At the point that pages have to do that, we might as well
 not store a per-page state object.


Overall, I think preserving history API information when restoring sessions
is a good thing.  My only concern is whether web developers will program in
such a way that this works.  Unless ALL state will need to be either saved
in the history API or reconstructible from that information, bad things will
happen.  (Note that this was difficult if not impossible with the original
API, but your new proposal makes this quite practical.)

Do most web apps that use iframe hacks (for tracking history) come back
cleanly from a session restore?


   I still think we shouldn't force app developers to serialize everything
 to
  strings.  Maybe we can just raise an exception if they try to set the
  history state to something unserializable?  (I guess that's what you're
  already doing?)

 Right now, I just serialize to JSON and throw an exception if that
 fails.  I don't have a problem continuing to do that, at least until
 we get the structured clone thing sorted out.


Yeah.  I think the structured clone semantics are the right way to go here
(but JSON is a good first approximation).


Re: [whatwg] Proposed changes to the History API

2009-08-20 Thread Jeremy Orlow
On Wed, Aug 19, 2009 at 5:31 PM, Jeremy Orlow jor...@chromium.org wrote:


 Btw, storing a GUID and using session storage really isn't useful since
 session storage itself only stores strings.


Btw, I lied.  This part of the spec just changed, so now DOM Storage can
store anything that supports structured cloning as well.


Re: [whatwg] Proposed changes to the History API

2009-08-20 Thread Justin Lebar
 Overall, I think preserving history API information when restoring sessions
 is a good thing.  My only concern is whether web developers will program in
 such a way that this works.  Unless ALL state will need to be either saved
 in the history API or reconstructible from that information, bad things will
 happen.  (Note that this was difficult if not impossible with the original
 API, but your new proposal makes this quite practical.)

Maybe the right solution is to have a pageStorage object, which works
just like sessionStorage but is local to a session history entry and
perhaps carries some weak promise of persistence.  It might be a
little confusing that in the following code

  var len1 = pageStorage.length
  history.pushState(...)
  var len2 = pageStorage.length

len1 != len2, but that doesn't seem too complicated.

 Do most web apps that use iframe hacks (for tracking history) come back
 cleanly from a session restore?

I don't know, but I presume it would be possible so long as form data
is saved across session restore.

-Justin


Re: [whatwg] Proposed changes to the History API

2009-08-19 Thread Mike Wilson
Justin Lebar wrote:
 [...]
 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.
 [...]
 We'd probably want to fire PopState on all loads and history
 navigations, since any document might have a state to pop

Right, this is exactly my thoughts on the API as well, as we 
started discussing recently, see:
http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2009-August/022087.html
| Though, when taking a more thorough look at what is 
| spec:ed, it seems these use cases are indeed not supported, 
| due to state update limitations and how events are ordered.

Currently, the design with an immutable state object and the
PopEvent and HashChange events triggering at somewhat 
insufficient timings, makes it hard to build the things I'm
thinking about. 

IMO you need:
- an event each time you're *leaving* a history entry (in 
  addition to HashChange triggered when entering one)
- allow updating existing state entries
- shift the whole state entry model so that state entries 
  belong to history entries, and are not logically inserted 
  between them (this is actually a very important 
  distinction)

I'm hoping Ian will come back with the use cases he has in
mind, as I am as of yet not clear on what he wants, or does
not want, to support with the pushState model.

Best regards
Mike Wilson



Re: [whatwg] Proposed changes to the History API

2009-08-19 Thread Jeremy Orlow
On Tue, Aug 18, 2009 at 5:04 PM, Justin Lebar justin.le...@gmail.comwrote:

 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.


I really like this idea except for this one part:  What's the problem with
allowing DOM objects to be stored?  Even if it can't be open-ended, maybe we
can allow any data that can be serialized to be stored there?  Just from my
playing around with local storage, I've found the requirement of serializing
everything to a string fairly annoying.  I understand why it's necessary
there (even with session storage, there are use cases where you'd need to
serialize it to disk) but here it seems like everything can just stay in
memory...right?

Btw, storing a GUID and using session storage really isn't useful since
session storage itself only stores strings.




 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



Re: [whatwg] Proposed changes to the History API

2009-08-19 Thread Jonas Sicking
On Tue, Aug 18, 2009 at 5:04 PM, Justin Lebarjustin.le...@gmail.com wrote:
 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.  :)

I agree with Justin (unsurprisingly since we've been doing a fair
amount of discussing on the subject).

In general when I've been thinking about how to use this API i've had
a hard time wrapping my head around the intended way to use it. It
wasn't until I started thinking of it in the following way that it
made sense:

There's two aspects to the API:

1.
The ability navigate the user to a new URI without forcing the UA to
load a new page. So for example instead of using fragment-identifier
hacks, actually change the uri. So for example gmail uses URIs like:
  https://mail.google.com/mail/?#inbox
  https://mail.google.com/mail/?#label/personal
  https://mail.google.com/mail/?#label/whatwg
  https://mail.google.com/mail/?#label/whatwg/13b4711edac9c1e2

it would be better if you could actually navigate between

  https://mail.google.com/mail/inbox
  https://mail.google.com/mail/label/personal
  https://mail.google.com/mail/label/whatwg
  https://mail.google.com/mail/label/whatwg/13b4711edac9c1e2

and then use the fragment identifier for what it was intended.

2.
The ability to create several session history entries for the same
page which the user can navigate between, and use some type of state
object to disambiguate between these states. For example in our bug
database we allow users to look at attachments, as well as comment on
attachments. When starting to comment on an attachment the page
changes from displaying the attachment, to displaying a textarea
pre-populated with the contents of the attachment such that you can
add comments to it. It would be nice