-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Should navigating to the current URL preserve history.state? #6213
Comments
This fixes several related issues surrounding the "update the session history with the new page" and "traverse the history" algorithms. * A mistaken attempted refactoring in #6039 got the wrong Document for the newDocument variable in "traverse the history". To fix this, we explicitly pass in the new document to the algorithm from all its call sites. (Discussed in #6197.) * As discussed more extensively in #6197, the same-URL and entry update/reload conditions in "update the session history with the new page" were not correctly triggering the new-document clause in "traverse the history", despite replacing the document. This was partially due to #6039, although the phrasing before #6039 was extremely ambiguous, so #6039 was mostly a transition from "unclear" to "clearly wrong". * This fixes the "easy bug" discussed in #6202, where the same-URL case was using the wrong URL to determine sameness. That bug was also introduced in #6039. The harder bug, as well as the action-at-a-distance nature of the same-URL check, remain tracked in #6202. * For years, the spec has required deleting the future session history entries after performing a navigation with history handling of "replace", e.g. via location.replace(). This is not correct; a "replace" navigation does not delete future session history entries. Instead it just replaces the current entry, leaving future entries alone. * The latter point makes the handling of same-URL navigations almost identical to "replace" navigations (including non-same-URL "replace" navigations). This change makes this clear, by using the same text for both, but adding a pointer to #6213 which highlights the fact that some browsers treat them slightly differently (and some treat them the same). * Finally, this adds or modifies a few assertions to check that we're in the "default" history handling behavior, so it's clearer to the reader what the non-exceptional path through the spec is. Closes #6197.
In another venue @rakina notes that Chrome's comparison is between does not compare the URL that started the navigation with the browsing context's active document's URL, but instead compares the final URL of the navigation to the browsing context's active document's URL. Also, Chrome ignores fragments. Fortunately, after #6476, the red XXX box talking about sometimes copying over the state also compares the final URL (i.e., the URL of newDocument) to the browsing context's active document's URL (i.e., the URL of sessionHistory's current entry that is about to be replaced). So the XXX box is getting closer to at least one browser, which is nice. |
I tested this out with a modified version of Domenic's test above. I checked No fragment (sameurl.html -> sameurl.html)
With fragment (sameurl.html#bottom -> sameurl.html#bottom)
Reloads
Same-URL navigations
General
I think since Chrome & Safari behaves the same way, maybe it makes sense to copy |
Thanks for continuing the investigation Rakina!
I think we should spend a small amount of time on this. If writing tests is easy, and it aligns well with other pieces of state (e.g. is always copied over in the same way as history.state), then let's try to make sure it's specced and tested well. If it's too hard to write tests for, or gives weird results due to how it interacts with other parts of the system, then we can set it aside.
Agreed.
Could we restore the scroll offsets too? Everyone seems to restore the viewport scroll offset according to your table above. And we can say that the lack of consistency for textarea scroll offset restoration is down to the "may" clause in https://html.spec.whatwg.org/multipage/browsing-the-web.html#restore-persisted-state . Note that once we get this more solid, especially if we copy over most (all?) of the fields, the next natural question will be whether we should maintain the distinction between the "entry update"/"reload" case and the "replace" case in https://html.spec.whatwg.org/#update-the-session-history-with-the-new-page . Maybe we can merge them. But figuring out the full consequences of that will be tricky, so my instinct is to wait and tackle it after we improve the spec for the "replace" case, like we're doing here. |
@rakina, do you think you'd be able to help with web platform tests for this? I'd love to get this spec issue resolved. |
Here's another fun one:
Chrome, Safari, Firefox:
Firefox:
Firefox, Safari: The correlates with the findings in #6680, including "I have no idea what Safari is doing". |
Chiming in with another oddity with Firefox around events. (I'm not sure this needs a whole new bug although happy to file one.) Demo here, for the "With fragment" case above (re: @rakina's demo). When a fragment is loaded, the two internal navigations (
|
I do see popstate in Firefox when clicking a link. |
Spinning off from #6197 (comment).
Test page: https://boom-bath.glitch.me/session-history-2.html
Results:
location.reload()
retainshistory.state
. All other mechanisms clear it.history.state
is always retained.Also of note: both browsers agree that overall document scroll position is retained on
location.reload()
and cleared otherwise. Chrome, however, clears the textbox scroll position and its value (if updated) in all cases, includinglocation.reload()
; Firefox retains those pieces of data inlocation.reload()
.At a spec level, discussed a bit in #6197 (comment), we have several distinguishable actions:
location.replace()
) to the same URL as the current URLlocation.reload()
) to the same URL as the current URLand we have the following potential behaviors:
So from I can see:
history.state
, but not copying over most scroll positions. It does copy over the main document scroll position for case (Z).I'm not sure what the best behavior is here. At a spec level, the simplest thing would be (B) for all cases (X), (Y), and (Z), but that matches no browsers. This is all complicated by the fact that the other pieces of a session history entry are harder to test and in some cases not totally specified.
/cc @natechapin @smaug----
The text was updated successfully, but these errors were encountered: