Re: [whatwg] HTML5 History Management

2009-08-08 Thread Nathan Hammond

Mike,
It does sound like we're asking for similar things. I think that my  
personal proposal is history.replaceState() which does exactly  
history.pushState() but pops the history stack first. Theoretically  
this wouldn't be hard to implement and mirrors the relationship  
between location.href = and history.replace().


Others: thoughts?
Nathan

On Aug 5, 2009, at 4:58 AM, Mike Wilson wrote:


Nathan Hammond wrote:

I should have stated this one with a goal: the ability
to ensure that the popstate event always fires with a
full understanding of the (app/page) state when
navigating through history. This would be lost when a
user manually changes the hash. [...]
Any other techniques for remembering data other than this
would still be a hack because, in and of itself, the data
stored are not uniquely tied to a particular history
state. [...]
Using sessionStorage I have the additional task of mapping
the stored series of states to a particular visit of the
(app/page) if the user visits the site again after
navigating away: example.com - whatwg.com - example.com


Hi Nathan,

I think I touched on the same need in my thread html5
state handling: overview and extensions, see
http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2009-June/020423.html
or
http://www.nabble.com/html5-state-handling:-overview-and-extensions-td240347
73.html

See the table on SCRIPT-CONTROLLED STATE at the end of
that mail. As you can see I am suggesting to add a state
construct for the missing Document state level. I'm just
back from vacation but I'm doing some more research and
hope to provide more information on that thread later
this month.

Best regards
Mike Wilson





Re: [whatwg] HTML5 History Management

2009-08-04 Thread Nathan Hammond

Ian,
Thanks for the comments. I've simply omitted pieces that I feel like  
are completely addressed. For all of those: Yes, I agree, right,  
right, great, and perfect. Thanks for clarifying and answering silly  
questions. For the rest, see below.



On Aug 4, 2009, at 9:29 PM, Ian Hickson wrote:

On Wed, 29 Jul 2009, Nathan Hammond wrote:




Possible Action Items
1. Specify the order in which history related events are triggered.

In what order would one expect the events triggered by
window.history.pushState({}, Title, #newhash)?


No events are triggered by doing that.


With my new understanding of pushState, not triggering popstate makes  
sense. With regards to pushState not triggering a hashchange event, I  
like it, but I do want to be absolutely sure that all implementers get  
this right. So, could we clarify this in the spec? Right now I think  
that the spec could be read where since it adjusts the document's  
current address it might should cause a hashchange event. Providing  
this specific example would do the trick.


Related, is window.location.hash = newhash; supposed to trigger a  
hashchange event? (Is this specified? I couldn't find it.) I do  
believe it does in IE8, but I don't have IE8 available to me at this  
moment to check.



2. Specify a method to allow access to the history stack. (At least
readable within the context of same-origin, possibly mutable.)

This would allow for understanding on the client side of a user's  
path
through the site, even after navigating away from the page. If this  
is

not implemented the absolute first thing I will be implementing is a
method to track this information, a rather large duplication of  
effort
for something that could easily be made available. This would  
involve a

something like currentstate = { _previous: currentstate, title:
window.title, newval: true }; plus a form-based storage mechanism to
repopulate state in case the user exits on a page which they manually
changed the hash to get to (which would not have access to the data
object upon revisiting later since there wouldn't be one stored with
that history state).

I'm aware of the privacy ramifications, but at the same time, I'm  
going

to be exposing those exact same concerns with the above method.


It turns out to be quite complex to expose this in the API currently,
because the History object exposes a mix of all the various frames at
once, and you can get to the History object of cross-origin frames,  
and

there's some other legacy baggage here also (e.g. history.length).

Since it's not entirely clear what the use case is, and since you  
can do
it to some extent already using onload, onhashchange, and  
onpopstate, I'd

rather just let authors reimplement this themselves at this point, and
maybe revisit this in a future version.


Complexity. Bah! (Then again, you don't have to tell me.) The use case  
I find is pretty simple: in the event that there are two separate ways  
to get to a specific page in the app I need to know how the person got  
there. Or this could be used to provide content tailored specifically  
to that user based upon their history (whether suggestions, ads, or  
help text). Really though, this point is far less critical (as it is  
easy enough to handle in client code) and does greatly increase the  
complexity for getting all implementers on board. If this *isn't*  
implemented however, the point below becomes more critical for being  
able to successfully track state in client code...


3. Specify a method to modify the current history state without  
adding a

new history point.


Assuming you don't mind causing the page to reload, you can use
history.replace(). I'm not sure what it would mean to replace the  
history

state without changing the Document or anything, though.


This would alleviate the need for the (incredibly brittle) form-based
storage mechanism I describe above.


Can you use sessionStorage for this?


I should have stated this one with a goal: the ability to ensure that  
the popstate event always fires with a full understanding of the (app/ 
page) state when navigating through history. This would be lost when a  
user manually changes the hash. With that as my goal, history.replace  
does not achieve what I am trying to accomplish. Neither does  
pushState without a URL as that still registers a new history point.


Any other techniques for remembering data other than this would still  
be a hack because, in and of itself, the data stored are not uniquely  
tied to a particular history state. In my semi-professional opinion  
form storage is really more appropriate for this task as it is  
correctly mapped to the document object on which the data was entered.  
Using sessionStorage I have the additional task of mapping the stored  
series of states to a particular visit of the (app/page) if the user  
visits the site again after navigating away: example.com - whatwg.com  
- example.com


(Use case is the game idea

Re: [whatwg] HTML5 History Management

2009-07-30 Thread Nathan Hammond

Hey Jonas et al.:
Thanks for the reply, forgive my disbelief on Clarification 1. :) If  
I'm completely with you, that is entirely unexpected on my part (and  
I've read this part of the spec a few times). Is this to imply that,  
no matter what the arguments to pushState(), if the path is relative  
to the current URL there will be no request for a new document and no  
user-agent initiated network activity?


This is a behavior I'm fine with and will meet my needs just as well,  
I was simply expecting to have to use the approach from Clarification  
2 in order to retain my document object. It does however lend itself  
to some confusion when paired with user agents that don't yet support  
the history portions of the spec as they will have to be handled with  
hash-based addressing while those that support pushState() will have  
more sane URLs--but that is no matter in the grand scheme of things.


Also, that would imply that the popstate only fires when you're  
navigating through history. Is that correct?


Thanks!
Nathan

On Jul 30, 2009, at 4:42 AM, Jonas Sicking wrote:

On Wed, Jul 29, 2009 at 7:38 PM, Nathan Hammondnat...@nathanhammond.com 
 wrote:

Clarifications
1. window.history.pushState({}, Title,
/path/to/new/file.html?s=newvalue#newhash) replaces the current  
document
object with the one specified by the new URL. It then causes the  
event

popstate to fire immediately after the load event, correct?


No. The above line with change the uri of the existing document to be
http://example.com/path/to/new/file.html?s=newvalue#newhash; (with
the part before 'path' obviously depending on where the original page
lives).

So no network activity takes place and the Document node remains the
same. Also no popstate event is fired.

2. window.history.pushState({}, Title, #newhash) creates a new  
history
state object with the specified data object, the specified title,  
the same
document object, and a location object that replaces the existing  
hash with

#newhash, correct?


Yes.

/ Jonas




Re: [whatwg] HTML5 History Management

2009-07-30 Thread Nathan Hammond

Sebastian,
The same-origin is pretty clearly specified, I've included the excerpt  
from the spec below. Your suggestion for clarity on updating Location  
fields in the the UI would be a part of step five in the description  
of pushState in section 6.10.2 is a good one. Ian, I feel like this  
counts as a possible action item.

Nathan

***

Possible Action Items
1. Clarify how the user agent uses the calculated location value from  
the pushState description step 2 in section 6.10.2 in terms of being  
reflected in the Location object.


It is my opinion that this URL should be reflected in the Location  
value. This would imply that it would be reflected in the location bar  
of user agents that have this as part of their UI. It seems that the  
place to include this clarification would be the pushState description  
step 5 in section 6.10.2


2. Clarify that pushState() does not cause navigation.

I read the spec quite a few times and still got this wrong,  
apparently. Making this completely clear would not hurt.



***

If a third argument is specified, run these substeps:
1. Resolve the value of the third argument, relative to the first  
script's base URL.
2. If that fails, raise a SECURITY_ERR exception and abort the  
pushState() steps.
3. Compare the resulting absolute URL to the document's address. If  
any part of these two URLs differ other than the path, query, and  
fragment components, then raise a SECURITY_ERR exception and abort  
the pushState() steps.
For the purposes of the comparison in the above substeps, the path  
and query components can only be the same if the URLs use a  
hierarchical scheme.



On Jul 30, 2009, at 10:27 AM, Sebastian Markbåge wrote:


Jonas,

That is my interpretation too. But I think it's a little unclear  
whether that means that the UA should update any Location fields in  
the UI. I understand that this may be optional or outside the scope,  
but I think that it should still be mentioned.


Now if the UA is suppose to update the Location field, shouldn't  
push state URL be subject to same-domain policies? Is that defined  
clearly?


Otherwise, this can be used during phishing attacks.

Sebastian

On Thu, Jul 30, 2009 at 4:13 PM, Nathan Hammond nat...@nathanhammond.com 
 wrote:

Hey Jonas et al.:
Thanks for the reply, forgive my disbelief on Clarification 1. :) If  
I'm completely with you, that is entirely unexpected on my part (and  
I've read this part of the spec a few times). Is this to imply that,  
no matter what the arguments to pushState(), if the path is relative  
to the current URL there will be no request for a new document and  
no user-agent initiated network activity?


This is a behavior I'm fine with and will meet my needs just as  
well, I was simply expecting to have to use the approach from  
Clarification 2 in order to retain my document object. It does  
however lend itself to some confusion when paired with user agents  
that don't yet support the history portions of the spec as they will  
have to be handled with hash-based addressing while those that  
support pushState() will have more sane URLs--but that is no matter  
in the grand scheme of things.


Also, that would imply that the popstate only fires when you're  
navigating through history. Is that correct?


Thanks!
Nathan


On Jul 30, 2009, at 4:42 AM, Jonas Sicking wrote:

On Wed, Jul 29, 2009 at 7:38 PM, Nathan Hammondnat...@nathanhammond.com 
 wrote:

Clarifications
1. window.history.pushState({}, Title,
/path/to/new/file.html?s=newvalue#newhash) replaces the current  
document

object with the one specified by the new URL. It then causes the event
popstate to fire immediately after the load event, correct?

No. The above line with change the uri of the existing document to be
http://example.com/path/to/new/file.html?s=newvalue#newhash; (with
the part before 'path' obviously depending on where the original page
lives).

So no network activity takes place and the Document node remains the
same. Also no popstate event is fired.

2. window.history.pushState({}, Title, #newhash) creates a new  
history
state object with the specified data object, the specified title,  
the same
document object, and a location object that replaces the existing  
hash with

#newhash, correct?

Yes.

/ Jonas






[whatwg] HTML5 History Management

2009-07-29 Thread Nathan Hammond

Ian et al.:
About a year ago, after I wrote the first version of my history  
manager, I began the process of looking into the HTML5 history spec  
and had a few conversations with folks like Bertrand Le Roy, Brad  
Neuberg, and Brian Dillard. Some of my notes from back then have been  
addressed, but I've still got a few more. Everything is included below  
for your reading pleasure. Enjoy!

Nathan

***

Clarifications
1. window.history.pushState({}, Title, /path/to/new/file.html? 
s=newvalue#newhash) replaces the current document object with the one  
specified by the new URL. It then causes the event popstate to fire  
immediately after the load event, correct?


2. window.history.pushState({}, Title, #newhash) creates a new  
history state object with the specified data object, the specified  
title, the same document object, and a location object that replaces  
the existing hash with #newhash, correct?


Possible Action Items
1. Specify the order in which history related events are triggered.

In what order would one expect the events triggered by  
window.history.pushState({}, Title, #newhash)? There are two  
events of interest: popstate, and hashchange. If popstate is fired  
first it will make it easy to catch programmatic versus user changes  
to the hash and respond accordingly. This would imply queueing the  
popstate event prior to changing the URL when the document isn't  
changing, or having the browser respond to the popstate event by  
changing the hash. (This concern exists only when the new URL reuses  
the same document object.) Regardless of the outcome, the order in  
which these events are triggered really needs to be specified and each  
individual triggering of these pair of events needs to be assured to  
occur entirely before the next time the pair are triggered.


2. Specify a method to allow access to the history stack. (At least  
readable within the context of same-origin, possibly mutable.)


This would allow for understanding on the client side of a user's path  
through the site, even after navigating away from the page. If this is  
not implemented the absolute first thing I will be implementing is a  
method to track this information, a rather large duplication of effort  
for something that could easily be made available. This would involve  
a something like currentstate = { _previous: currentstate, title:  
window.title, newval: true }; plus a form-based storage mechanism to  
repopulate state in case the user exits on a page which they manually  
changed the hash to get to (which would not have access to the data  
object upon revisiting later since there wouldn't be one stored with  
that history state).


I'm aware of the privacy ramifications, but at the same time, I'm  
going to be exposing those exact same concerns with the above method.


3. Specify a method to modify the current history state without adding  
a new history point.


This would alleviate the need for the (incredibly brittle) form-based  
storage mechanism I describe above.


4. Specify additional properties on the hashchange event.

Lots of possible useful information with the number one most important  
being the new hash that triggered the event to prevent race conditions  
reading window.location.hash. Other fun things that are a bit more pie  
in the sky: the previous hash and knowledge of how it was triggered  
(manually? pushState? window.location.hash = ? window.location.href  
= ?).