Skip to content

Rationalize behavior of Window object reuse #3267

Open

Description

@zetafunction

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 Window object 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 the Window object is not reused). Firefox also appears to perform the navigation with replacement enabled, but also reuses the Window object.

Activity

  1. wanderview commented on Dec 2, 2017

    @wanderview
    Member

    I only looked at the tests so far, but I would recommend also taking a look at:

    1. Differences in behavior when the iframe is dynamically added before/after the load event. I think there are interop differences here.
    2. Declarative iframe with a script that modified it synchronously on evaluation. I believe this has the best interop of any of the cases right now.

    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

  2. annevk commented on Dec 2, 2017

    @annevk
    Member

    See also #2545 and #2566.

  3. zetafunction commented on Dec 5, 2017

    @zetafunction
    Author

    #546 is also somewhat related.

  4. domenic commented on Mar 13, 2019

    @domenic
    Member

    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

    Similarly, if the nested browsing context's session history contained only one Document when the process the iframe attributes algorithm was invoked, and that was the about:blank Document created when the nested browsing context was created, then any navigation required of the user agent in that algorithm must be completed with replacement enabled.

    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.

  5. hsivonen commented on Aug 31, 2022

    @hsivonen
    Member

    window-reuse-in-nested-browsing-contexts.tentative.html appears 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 onload purposes what I believe to have been Presto-style initial about:blank (async onload with single about:blank document as opposed to Gecko's two about:blank documents) that I've advocated for for the past 11 years and instead pursuing WebKit/Blink-style onload behavior (single about:blank document with sync onload).

    Most of window-reuse-in-nested-browsing-contexts.tentative.html is explicitly written to assume async onload for the initial about:blank. I now (tentatively) believe that we shouldn't pursue that.

    What I'm currently pursuing is:

    1. The synthetic (non-parser-created) initial about:blank document is eagerly created when a browsing context is created. (I.e. for iframes when the iframe element is inserted into a document.)
    2. Don't distinguish between no src, src="" and src="about:blank" (all of these result in the URL being navigated to being about:blank).
    3. When the navigation steps are about to reach the point of starting the fetch for the URL being navigated to, if the URL is about:blank and the document in the browsing context is the synthetic initial about:blank document, fire the load event 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:blank and is subsequently navigated to about:blank, the navigation happens as with any other URL with the parser parsing the empty stream and the load event firing async. This appears to be Chrome-compatible.

    I may still find problems with the above approach.

  6. hsivonen commented on Aug 31, 2022

    @hsivonen
    Member

    Oh, and the navigation steps begin synchronously when the iframe is inserted into the document.

  7. domenic commented on Aug 31, 2022

    @domenic
    Member

    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.

  8. added a commit that references this issue on Oct 31, 2022
  9. domenic commented on Apr 9, 2025

    @domenic
    Member

    @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:

    • Which initial about:blank cases are done with "replace" vs. "push" history handling is centralized in navigate step 12 (deferring to the navigation must be a replace in particular)
    • iframe insertion and src="" change processing has gotten centralized in process the iframe attributes
      • No-src="", empty-string src="", src="about:blank", and src="about:blank?foo" are all processed the same way.
      • There is a special case for inserting about:blank iframes to not do a full navigation, and to synchronously fire load. (See also the discussion in completely finish loading.)

    The core remaining question for me is about Window object reuse. In web-platform-tests/wpt#51895 @annevk has a test which seems to indicate the Window object is not reused in the way the spec indicates, at least in WebKit and Blink.

    Window object 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 the Window object in reality?

    Note that Window object reuse is separate from history entry reuse. The latter is covered by the choice of "replace" vs. "push" history handling and seems pretty interoperable.

  10. vinhill commented on May 20, 2025

    @vinhill
    Contributor

    The core remaining question for me is about Window object reuse. In web-platform-tests/wpt#51895 @annevk has a test which seems to indicate the Window object is not reused in the way the spec indicates, at least in WebKit and Blink.

    WebKit resets the custom element registry in LocalDOMWindow::didSecureTransitionTo when re-using the window.

  11. annevk commented on May 20, 2025

    @annevk
    Member

    Interesting, that would explain some of the behavior, but not globalAA not being preserved.

  12. hsivonen commented on May 21, 2025

    @hsivonen
    Member

    if you have time to compare the current spec to what you see implemented

    Acknowledging the @ -mention, but @vinhill has a more up-to-date view of what's going on here in Gecko than I have.

  13. vinhill commented on Oct 27, 2026

    @vinhill
    Contributor

    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:blank URI. 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::WouldReuseInnerWindow and these lines in SetNewDocument.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions