- From: Jonas Sicking <jonas@sicking.cc>
- Date: Thu, 15 May 2008 14:22:28 -0700
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