Le 24/12/2012 23:53, Boris Zbarsky a écrit :
> On 12/24/12 2:36 PM, David Bruant wrote:
>> Scripts inside the new document think they are in a fresh browsing
>> context if I understand correctly.
>
> No. There is only one browsing context. Browsing contexts don't even
> change across navigations.
>
> Scripts created after the open() will see a new ES global. Scripts
> created before the open() keep seeing the old one as their global.
I thought the global changed. document.open Step 14 suggests that the
Window object changes... unless it's referring to the Window
"constructor" and not the window instance as I understand it?
>> From the new document point of view,
>> it "feels" like a navigation just occurred. Only the script from the
>> previous context can tell the difference.
>
> With s/context/global/ yes. Or of course script from outside the
> navigation context altogether.
>
>> What about thinking of it the following way:
>> * before the call, you're in a browsing context
>> * after the call, you're in a new browsing context (navigation)
>
> Navigation doesn't change the browsing context. It creates a new
> Window (which is the ES global) and new Document.
Yes. It mixed up all terms in my head. Sorry about that. I was talking
about navigation all along; assuming a new form of navigation preserving
the document identity could exist. But I was wrong apparently. I thought
the global changed, but it doesn't seem to.
>> and some script from the previous browsing context has survived and
>> runs *in the
>> new context* (the context change happens during the document.open call)
>
> No, the script that called open() needs to keep running against the
> old global. Not doing that breaks things, last I checked.
>
> Consider this testcase:
>
> <script>
> var x = 1;
> window.onload = function() {
> document.open();
> document.write(x);
> document.close();
> }
> </script>
Hmm... Playing with this example a bit more I've found that Gecko and
Chrome deviates in their behavior. Gecko only preserves the lexical
environment for the functions in the pre-document.open scripts and
deletes the binding to the global object while Chrome preserves the
binding to the global object. See:
<script type="text/javascript">
var x = 31;
y = 37
window.onload = function(){
var l = localStorage;
document.open("text/html");
console.log('opener context x', window.x, window.y);
console.log(x, y);
console.log("storage", l === window.localStorage);
document.write('<script>console.log("new document context x",
window.x, window.y); console.log(x, y)</scr'+'ipt>')
document.close();
};
</script>
Said differently, both preserve the WindowProxy, but Gecko changes the
underlying Window while Chrome doesn't apparently. Chrome doesn't seem
to change the localStorage object.
I fail to observe the step 14 in Chrome including the "change all the
prototypes" part, so I guess it's not web-crucial.
Maybe an opportunity to reconsider the "every prototype of every object
has to change on document.open" by changing the document.open spec?
It could be re-spec'ed as the same thing without step 14. I think it
would save a lot of trouble. What do you think?
David