Repository navigation
Rationalize behavior of Window object reuse #3267
Description
I've been looking into some bugs in Chrome where the Window object is not reused even though it should be. I wrote several tests to try to document this behavior, and I got some interesting results.
| Test | Edge | Firefox | Chrome (pre-patch) | Chrome (post-patch) |
|---|---|---|---|---|
| same-origin.html | Fail | Pass | Fail | Pass |
| same-origin-initial.html | Pass | Pass | Pass | Pass |
| explicit-about-blank.html | Pass | Fail | Pass | Pass |
| srcdoc.html | Fail | Pass | Fail | Fail |
I think these differences are because it's hard to interpret how the different areas of the spec apply. Here are several of the different sections that are relevant:
https://html.spec.whatwg.org/multipage/browsers.html#windows notes that the relationship of Window and Document is 1:1 except in the special case of navigating a browser context from the initial about:blank Document to another Document with replacement enabled (but doesn't mention that this is same-origin only).
https://html.spec.whatwg.org/multipage/browsing-the-web.html#initialise-the-document-object mentions that a new Window object is created unless the only entry in session history is the initial about:blank Document and the navigation is occurring with replacement enabled and the new Document is same-origin.
https://html.spec.whatwg.org/multipage/history.html#location-object-navigate talks about the forced navigation with replacement enabled when navigating from the initial about:blank Document when it is the only Document in session history. This is the only language I could find that specifies replacement enabled is true for navigations from the initial about:blank Document. However, since this is associated with Location, it's unclear if the same replacement enabled behavior applies to setting the src attribute of HTMLIFrameElement. Presumably it does apply. Perhaps this language should be centralized in https://html.spec.whatwg.org/multipage/browsing-the-web.html#navigate instead.
Finally, there's https://html.spec.whatwg.org/multipage/iframe-embed-object.html#process-the-iframe-attributes to describe how the src attribute is handled. It seems to imply that different behavior should happen if the src attribute is omitted vs intentionally set to "about:blank".
- If src is unset, there will be no effect other than firing the load event at the frame.
- If explicitly set to "about:blank", follow the steps in https://html.spec.whatwg.org/multipage/browsing-the-web.html#navigate . Presumably this will navigate to about:blank with replacement enabled (and now the iframe element is no longer on the initial about:blank Document, even though session history doesn't appear to have changed). This would imply that the
Windowobject should not be reused and the next navigation should not occur with replacement enabled. Note that explicit-about-blank.html seems to contradict this: in Edge and Chrome, there is no session history for the explicit navigation to "about:blank", since the next navigation still occurs with replacement enabled (though theWindowobject is not reused). Firefox also appears to perform the navigation with replacement enabled, but also reuses theWindowobject.
Activity
wanderview commentedon Dec 2, 2017
I only looked at the tests so far, but I would recommend also taking a look at:
I did add some tests recently for the declarative thing and how it interacts with service workers clients API here:
https://github.com/w3c/web-platform-tests/blob/master/service-workers/service-worker/about-blank-replacement.https.html
annevk commentedon Dec 2, 2017
See also #2545 and #2566.
zetafunction commentedon Dec 5, 2017
#546 is also somewhat related.
domenic commentedon Mar 13, 2019
In web-platform-tests/wpt#15809 @annevk tests that at least in the same-origin case, Chrome and Safari do not use "replacement enabled" for iframe navigation from the initial about:blank.
In general I think if we can get rid of the 1-Window-2-Documents cases in the platform, we should do so, so maybe we can remove
and get Firefox to align? We'd need to test the cross-origin case first though. And even then, just briefly skimming through all the related issues, maybe it's not that simple.
Change initial about:blank navigation behavior for iframes and popups
Change initial about:blank navigation behavior for iframes and popups
hsivonen commentedon Aug 31, 2022
window-reuse-in-nested-browsing-contexts.tentative.htmlappears to be testing the topic of this issue.I'm trying to make Gecko's about:blank behavior more Web-compatible. The major breakthrough so far has been no longer pursuing for
onloadpurposes what I believe to have been Presto-style initial about:blank (asynconloadwith singleabout:blankdocument as opposed to Gecko's twoabout:blankdocuments) that I've advocated for for the past 11 years and instead pursuing WebKit/Blink-styleonloadbehavior (singleabout:blankdocument with synconload).Most of
window-reuse-in-nested-browsing-contexts.tentative.htmlis explicitly written to assume asynconloadfor the initial about:blank. I now (tentatively) believe that we shouldn't pursue that.What I'm currently pursuing is:
about:blankdocument is eagerly created when a browsing context is created. (I.e. for iframes when the iframe element is inserted into a document.)src,src=""andsrc="about:blank"(all of these result in the URL being navigated to beingabout:blank).about:blankand the document in the browsing context is the synthetic initialabout:blankdocument, fire theloadevent for the document that's already in the browsing context and return early without starting a fetch.Notably, if the browsing context has been navigated away from the synthetic
about:blankand is subsequently navigated toabout:blank, the navigation happens as with any other URL with the parser parsing the empty stream and theloadevent firing async. This appears to be Chrome-compatible.I may still find problems with the above approach.
hsivonen commentedon Aug 31, 2022
Oh, and the navigation steps begin synchronously when the
iframeis inserted into the document.domenic commentedon Aug 31, 2022
Thanks @hsivonen!
We will work to incorporate that model into #6315 . In the meantime, please feel free to update any WPTs, and/or incorporate the tests that @zetafunction mentioned in the OP (from https://chromium-review.googlesource.com/c/chromium/src/+/804797), perhaps with flipped expectations. We can add a link to your comment to justify merging them despite the spec mismatch. I will happily approve such changes, and then once #6315 lands (getting close!!) the tests and spec will be aligned.
Navigation and session history rewrite
domenic commentedon Apr 9, 2025
@hsivonen @zetafunction @jdm @gterzian @avidrissman, if you have time to compare the current spec to what you see implemented, I'd love to partner on updating it.
I think some of this has gotten better since our original posts here and in #546. In particular:
iframeinsertion andsrc=""change processing has gotten centralized in process theiframeattributessrc="", empty-stringsrc="",src="about:blank", andsrc="about:blank?foo"are all processed the same way.load. (See also the discussion in completely finish loading.)The core remaining question for me is about
Windowobject reuse. In web-platform-tests/wpt#51895 @annevk has a test which seems to indicate theWindowobject is not reused in the way the spec indicates, at least in WebKit and Blink.Windowobject reuse is step 6 of https://html.spec.whatwg.org/#initialise-the-document-object . But surely it's more complicated than just removing that step, right? When do browsers reuse theWindowobject in reality?Note that
Windowobject reuse is separate from history entry reuse. The latter is covered by the choice of "replace" vs. "push" history handling and seems pretty interoperable.Fix document access in shared history push/replace steps
Fix document access in shared history push/replace steps
Fix document access in shared history push/replace steps
vinhill commentedon May 20, 2025
WebKit resets the custom element registry in LocalDOMWindow::didSecureTransitionTo when re-using the window.
annevk commentedon May 20, 2025
Interesting, that would explain some of the behavior, but not
globalAAnot being preserved.hsivonen commentedon May 21, 2025
Acknowledging the @ -mention, but @vinhill has a more up-to-date view of what's going on here in Gecko than I have.
vinhill commentedon Oct 27, 2026
https://wpt.fyi/results/html/browsers/the-window-object/window-reuse.tentative.html
I believe browsers currently only reuse the inner window if the navigable was immediately navigated to a non-
about:blankURI. But browsers differ on what properties they reset on the window element, like the navigator or custom element registry.Relevant parts of Gecko's implementation are
nsGlobalWindowOuter::WouldReuseInnerWindowand these lines inSetNewDocument.