[whatwg] Proposed changes to the History API

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 url"s.

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 needed as it needs to trigger 
     while the "old" session history entry is still active for calls 
     to History.{get|set}State
  3) PopState event is no longer needed.
  4) History.{get|set}State may be called at any time and allow
     access to the current session history entry's state object.

In addition to the above we need to look at programmatic entry
creation and URL-less entries, but I think the above builds a
good ground to base things off.

Best regards
Mike

Received on Thursday, 20 August 2009 03:43:01 UTC