Re: [whatwg] HTML5 History Management
Ian Hickson wrote: On Sun, 16 Aug 2009, Mike Wilson wrote: Ian Hickson wrote: I don't think we should encourage cases where the same URL can correspond to multiple states, which this would encourage. This statement confuses me as the whole point of pushState seems to be to store unique state in addition to the URL. If the URL can be used to infer the state anyway, then what's the point of storing it in the history entry? It's mostly about being able to track extra state that isn't important to the user. For example, if you have an application with many boxes, and two states, one with one box open, and another with another box open, and the boxes are randomly dotted around but move when a box is opened or closed, and you then hit back-forward-back-forward, you would want the same two boxes to move in the same way each time. However, if you just jump straight to the URI representing those two states, the exact position of the boxes doesn't matter, and might differ each time. The state object is for keeping track of that kind of thing (the position of the boxes). It seems we do indeed agree that the state object is for storing state that could differ for multiple history entries for the same URL, and what you are actually saying is that you think this feature should not be used for important state. I'm fine as long the former is true, and you are free to have an opinion about the latter. 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. I've tried to fix this by making popstate more synchronous. I still don't think this fixes my issues. I've described most of these in the thread Proposed changes to the History API so I'll wait until you reply to that before commenting further here. Best regards Mike
Re: [whatwg] HTML5 History Management
On Sun, 16 Aug 2009, Mike Wilson wrote: Ian Hickson wrote: On Wed, 5 Aug 2009, 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. 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. All the information about the state really should be in the URL, such that the state of the app after the user manually changes the hash, and the state of the app after the user returns to a point in the history where he had manually changed the hash, really should be the same. This has never been true for server-side web applications so why should it be this way for client-side apps? It's always supposed to be true for server-side Web apps too, no? My understanding of the purpose of pushState has been that it is there to aid client-side apps in behaving like server- side apps wrt history traversal. Not to make them more different and break user expectations. Your understanding is correct. I don't think we should encourage cases where the same URL can correspond to multiple states, which this would encourage. This statement confuses me as the whole point of pushState seems to be to store unique state in addition to the URL. If the URL can be used to infer the state anyway, then what's the point of storing it in the history entry? It's mostly about being able to track extra state that isn't important to the user. For example, if you have an application with many boxes, and two states, one with one box open, and another with another box open, and the boxes are randomly dotted around but move when a box is opened or closed, and you then hit back-forward-back-forward, you would want the same two boxes to move in the same way each time. However, if you just jump straight to the URI representing those two states, the exact position of the boxes doesn't matter, and might differ each time. The state object is for keeping track of that kind of thing (the position of the boxes). 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. I've tried to fix this by making popstate more synchronous. [suggesting .hashvalue on hashchange event] I really don't follow. Imagine you're updating what's visible based on the hash, and the user changes the hash twice in a row quickly such that by the time you get the first event, the location's already changed again. Why wouldn't you be happy to ignore the first location? F ex, because your client-side app may update some state based on what (or how many times) individual fragments have been visited. Maybe something in the spirit of read count or so. Fair enough. I've made hashchange synchronous also. Two other notes about the history state mechanism: 1) The popstate event is sort of a misnomer as it doesn't pop the state. Popping would imply removing it from its stack, but this is not the case as it remains in place in the history to be retrieved any number of times. A better name could be something like restorestate. That's possible. onrestorestate= is not as clear as onpopstate=, though, so I've not chnged it. 2) This text at the end of 6.10.1: | When state object entries are added, a URL can be | provided. This URL is used to replace the state object | entry if the Document is evicted. I'm not sure how to interpret this. Does it (implicitly) say that all state objects are evicted when the owning Document is evicted? That text is meaningless. I've removed it. One super-minor nit: In 6.10.3 we have: | (which happens during [[session history traversal]], as | described above) The link points to 6.11.9 which is below, not above. Thanks, fixed. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'
Re: [whatwg] HTML5 History Management
Ian Hickson wrote: On Wed, 5 Aug 2009, 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. 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. All the information about the state really should be in the URL, such that the state of the app after the user manually changes the hash, and the state of the app after the user returns to a point in the history where he had manually changed the hash, really should be the same. This has never been true for server-side web applications so why should it be this way for client-side apps? My understanding of the purpose of pushState has been that it is there to aid client-side apps in behaving like server- side apps wrt history traversal. Not to make them more different and break user expectations. I don't think we should encourage cases where the same URL can correspond to multiple states, which this would encourage. This statement confuses me as the whole point of pushState seems to be to store unique state in addition to the URL. If the URL can be used to infer the state anyway, then what's the point of storing it in the history entry? But you may have a different purpose for these state objects. I'm expecting to store things like step-for-step state from wizard-like flows, or user interface state similar to (but in addition to) the browser's own handling of saving/restoring form field values and scroll position. 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. It would be very interesting to hear about the scenarios you have in mind, to be able to comment correctly. It would be great if you could flesh out (or point to) a concrete example of correct and intended usage of this history state object mechanism. [suggesting .hashvalue on hashchange event] I really don't follow. Imagine you're updating what's visible based on the hash, and the user changes the hash twice in a row quickly such that by the time you get the first event, the location's already changed again. Why wouldn't you be happy to ignore the first location? F ex, because your client-side app may update some state based on what (or how many times) individual fragments have been visited. Maybe something in the spirit of read count or so. Two other notes about the history state mechanism: 1) The popstate event is sort of a misnomer as it doesn't pop the state. Popping would imply removing it from its stack, but this is not the case as it remains in place in the history to be retrieved any number of times. A better name could be something like restorestate. 2) This text at the end of 6.10.1: | When state object entries are added, a URL can be | provided. This URL is used to replace the state object | entry if the Document is evicted. I'm not sure how to interpret this. Does it (implicitly) say that all state objects are evicted when the owning Document is evicted? And does the popstate event really supply the URL string in its .state member, instead of the real object, in these cases? One super-minor nit: In 6.10.3 we have: | (which happens during [[session history traversal]], as | described above) The link points to 6.11.9 which is below, not above. Best regards Mike Wilson
Re: [whatwg] HTML5 History Management
On Wed, 5 Aug 2009, Nathan Hammond wrote: 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. Done. 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. Yes, and yes, it is specified. It triggers a navigation, which eventually gets around to the part that fires hashchange. 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... I don't really understand the scenario under which those use cases would be relevant. Can you show an example of someone doing something like this now? 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. All the information about the state really should be in the URL, such that the state of the app after the user manually changes the hash, and the state of the app after the user returns to a point in the history where he had manually changed the hash, really should be the same. I don't think we should encourage cases where the same URL can correspond to multiple states, which this would encourage. 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 = ?).
Re: [whatwg] HTML5 History Management
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
On Sat, Aug 8, 2009 at 5:13 AM, Nathan Hammondnat...@nathanhammond.com wrote: 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? We have been thinking about this too at Mozilla. Our current plan is to implement the current API, and then let people play around with it to gather feedback on how useful it is and where it needs to be changed/amended. The work to implement is happening here [1] [1] https://bugzilla.mozilla.org/show_bug.cgi?id=500328 / Jonas
Re: [whatwg] HTML5 History Management
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
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
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
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
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.comwrote: 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
Sorry, same domain policy is clearly defined. I just missed it. 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. On Thu, Jul 30, 2009 at 4:27 PM, Sebastian Markbåge sebast...@calyptus.euwrote: 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.comwrote: 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
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
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 = ?).