W3C home > Mailing lists > Public > whatwg@whatwg.org > May 2008

[whatwg] Scripts not in the active document

From: Jonas Sicking <jonas@sicking.cc>
Date: Thu, 15 May 2008 14:22:28 -0700
Message-ID: <482CA994.1060806@sicking.cc>
Ian Hickson wrote:
> On Mon, 29 Oct 2007, Jonas Sicking wrote:
>> Ian Hickson wrote:
>>>> I believe this can happen in a number of ways, the simplest being that
>>>> Page A calls a function on Page B. But I suspect there are also events
>>>> that can fire in Page B even after it has closed.
>>> Actually per spec, if I recall, you can't run script if you're not an active
>>> document. (To start with, your Window object won't have your properties any
>>> more, which makes things difficult if we allow script.)
>> Scripts can actually still run fine even if you navigate away from a page. But
>> there are definitely weird things happening (such as global scope being
>> different from 'window').
> 
> Could you elaborate on this? I'm not clear on how to define this.

Generally saying that "scripts won't run once you've navigated away from 
a page" is wrong. For example I think that if you mutate the DOM of 
document that has been navigated away from mutation-event handlers will 
still fire. And UserDataHandlers will likely fire as described by spec.

Doesn't look like eventhandlers will fire in firefox if you call 
myInputElement.click(), but it might in other browsers.

And if you mutate any expando properties on any DOM object that will 
cause javascript property watchers [1] will execute.

Not to mention that there can still be script executing for a page when 
the page is navigated away from. For example:

var value = "hello nurse";
onload = function() {
   alert("i'm still the active page");
   document.write("new page");
   alert("I'm script running in the context of a page that has been " +
         "navigated away from. See, |value| is still there:" + value);
}


I can describe how the "global scope is different from window" thing 
works in firefox. Though you probably don't want to put that in the spec 
as it's something that is likely going to be hard for other UAs to 
replicate exactly, and something that might even change in firefox some day.

Basically we always create 2 window objects. An inner and an outer. The 
outer is the one that you always get a reference to. It's the one 
returned if you use 'myIFrame.contentWindow' or simply 'window'. The 
inner is the one we use as global scope and is where all properties get set.

There is magic that causes all property accesses (both getting and 
setting) on the outer window to be forwarded to the inner window.

There is also magic to ensure that any time you try to get a reference 
to a window you get the outer one.

When the user navigates away from a page we leave all the properties in 
the inner window, but remove the connection between the inner and outer 
window. The outer window remains and gets a new inner window created. 
The old inner window will likely be garbage collected unless there are 
still things holding references to it.

Some of this stuff is there for web compat. Such as the fact that this 
results in the code executing after the document.write above still is 
able to access global variables that were defined before the call. I.e. 
the |value| in the second alert still works.

Other parts of this is there for us to prevent leaking properties from 
one page to another, thus allowing XSS attacks.

/ Jonas

[1] 
http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Object:watch
Received on Thursday, 15 May 2008 14:22:28 UTC

This archive was generated by hypermail 2.4.0 : Wednesday, 22 January 2020 16:59:02 UTC