23

Can someone explain why really WindowProxy object exists? I understand that real Window object does everything through this object, but can't understand the purpose.

2 Answers 2

14

This construct is in place to support the html5 browsing context model. Essentially, each script can have a centralized point of access for its primary active window, to functionally decouple transient references within the individual inner windows, document history, cache, and the need to keep track of each in a context-dependent way.

The two images below illustrate the concept:

windowProxy refers to the outer 'Browser window' here.

In the above diagram, Browser window is aliased by the windowProxy reference in each of the inner window contents.

windowProxy refers to the top-level 'Window' here.

In the above diagram, the top-level Window is aliased by the windowProxy reference in each of the inner window and iframe contents.

7

Consider the following code:

const iframe = document.appendChild(document.createElement("iframe"));

iframe.src = "/a";
iframe.onload = () => {
  const windowA = iframe.contentWindow;

  iframe.src = "/b";
  iframe.onload = () => {
    const windowB = iframe.contentWindow;
    
    console.log("window before navigation === window after navigation?", windowA === windowB);
  };
};

It turns out that this logs true. And, a lot of websites depend on this being true: they grab a reference to iframe.contentWindow, or perhaps window.frames[0], before navigation. And then they keep using it after navigation.

(Note that in our example, we initiated the navigation, by doing iframe.src = "/b". So in theory we could have known at that time to grab a new reference to iframe.contentWindow. But in the general case, the navigation could happen without the outer frame being involved, e.g. the user could click a link in the iframe, or code inside the iframe could do location.href = "/c".)

How can this be true? After all, we navigated to an entirely different page---it's going to have a new Window (with a fresh global scope, not polluted by any globals declared by the previous page), a new Document, etc. etc.

It's true because of WindowProxy. iframe.contentWindow, or window.frames[0], or any other way of attempting to access a window, return a WindowProxy object, not a Window object. That WindowProxy object delegates to whatever the current Window is. In our example, it delegates to the Window for /a before navigation, and the Window for /b after the navigation.

Not the answer you're looking for? Browse other questions tagged or ask your own question.