-
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
Unclear what to do with fragments on document.open #2555
Comments
Just changing the URL of a document doesn't cause any scrolling to occur though. Navigation to a fragment only happens as part of the navigate algorithm, which isn't invoked there as far as I can tell. (There are unfortunately various interoperability issues with |
I see, thanks. It seems Chrome attempts to scroll a fragment into view as part of loading/parsing rather than as part of navigation. FWIW, Firefox too scrolls a document.open() frame when the parent has a fragment. The difference is that the scroll-into-view isn't recursive so the main frame doesn't get scrolled. See http://bokand.github.io/document-open-fragment.html#test. Interestingly, navigating anew from the URL bar doesn't cause it to scroll-into-view again but a refresh does. It seems like the purpose of setting the URL in this case is to preserve origin with the parent. Preserving the fragment seems like it's never what you'd want. Could we specify that we should clear it from the URL before setting? That seems like it'd be a safe and easy fix. |
We could do that. Though I'm not familiar enough with this algorithm to think through all the implications. We'd still have the mismatch with when fragments take effect though. @smaug---- how familiar are you with |
This is very edge case of document.open(). Dropping the fragment might break some pages which re-write themselves using document.open/write and rely on the scrolling. Would it be odd to have different behavior when document.open call is coming from outside the page itself? (In general, I'd very much would like to see document.open()/write() to disappear. It is rather bad API) |
Dropping it on a cross frame document.open sounds fine to me. FYI, I've updated Chrome's implementation to do that: https://crrev.com/2801093002/ |
FWIW, it seems that Edge has the same behavior. Firefox and Safari however both keep the fragment. |
Tests in progress at web-platform-tests/wpt#10817. |
I have spent some time investigating this issue, and it seems like the reality is more complicated than it seems here. The key issue here is that in Blink, Gecko, and WebKit, In the specification, scrolling based on the fragment happens through the scroll to the fragment algorithm. This algorithm is then only called in two places: update the session history with the new page and traverse the history. These two algorithms are called in several places (like page load processing model for HTML files, which calls the former), but tracing the call chain always goes back to either the navigate algorithm or the The problem is that, for Blink and WebKit, the part of update the session history with the new page (which should ordinarily be called from the navigate algorithm by way of page load processing model for HTML files) that runs fragment scrolling is in fact embedded into the parser itself. Here's the relevant spec text from update the session history with the new page:
In short, the spec calls for the user agent to poll the document for the part of the document indicated by the fragment, while the document is still loading, in order to scroll to it. The polling interval is however user-agent-defined. Blink and WebKit use the "user-agent-defined amount of time" concept liberally, and does not implement the polling. Instead, they only attempt to scroll just before the parser stops parsing, regardless of if the parser was created by navigation. When In fact, if one were to use current WebKit, or a version of Blink that has @bokand's CL above reverted, and tries to execute the CL's regression test but with Backtrace from Blink when fragment-scrolling is attempted due to
|
After thinking a bit more about this, I've become convinced that doing what Chrome is doing is the best solution to this issue. It's logically reasonable for the fragment to not get propagated to a different document, and it is the easiest way to get around the scrolling bug, which removes the implementation barrier a "proper" solution (detailed in my last comment) would possibly require. |
This is another part of the effort to overhaul document.open() as outlined in #3818. Tests: web-platform-tests/wpt#10817. Fixes #2555.
This is another part of the effort to overhaul document.open() as outlined in whatwg#3818. Tests: web-platform-tests/wpt#10817. Fixes whatwg#2555.
This is another part of the effort to overhaul document.open() as outlined in whatwg#3818. Tests: web-platform-tests/wpt#10817. Fixes whatwg#2555.
I'm hoping someone can clarify intent and correct behavior when loading a document using document.open.
Step 23 of https://html.spec.whatwg.org/multipage/webappapis.html#dom-document-open says to set the URL of the open()ed document to that of the "responsible document" and we do that by setting the URL from the document we're loading. However, if the responsible document has a fragment identifier, that gets set on the document.open(). This is problematic for the empty fragment which tries to scroll the iframe into view (the scroll into view algorithm specified to use for fragment navigation is recursive for frames). So any page loaded with an empty fragment will always try to scroll any document.open()'d iframes into view.
Should the document-open algorithm specify we should clear fragments? I've noticed a frame loaded via document.open in Firefox keeps the fragment on document.URL and document.baseURI but window.location is about:blank. In contrast, Chrome keeps the URL with fragment on window.location (as well as document.{URL,baseURI}. That seems like a discrepancy too but I'm not sure if it's the cause or incidental.
The text was updated successfully, but these errors were encountered: