This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 27128 - Definition of WindowProxy doesn't satisfy bz that it is detailed enough
Summary: Definition of WindowProxy doesn't satisfy bz that it is detailed enough
Status: RESOLVED MOVED
Alias: None
Product: WHATWG
Classification: Unclassified
Component: HTML (show other bugs)
Version: unspecified
Hardware: Other other
: P3 normal
Target Milestone: Unsorted
Assignee: Anne
QA Contact: contributor
URL: https://html.spec.whatwg.org/#the-mes...
Whiteboard:
Keywords:
Depends on: 20701
Blocks:
  Show dependency treegraph
 
Reported: 2014-10-22 15:25 UTC by contributor
Modified: 2017-03-09 08:31 UTC (History)
8 users (show)

See Also:


Attachments

Description contributor 2014-10-22 15:25:32 UTC
Specification: https://html.spec.whatwg.org/
Multipage: https://html.spec.whatwg.org/multipage/#the-messageevent-interfaces
Complete: https://html.spec.whatwg.org/#the-messageevent-interfaces
Referrer: 

Comment:
MessageEventInit should probably use Window, not WindowProxy

Posted from: 98.110.194.132
User agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:36.0) Gecko/20100101 Firefox/36.0
Comment 1 Boris Zbarsky 2014-10-22 15:26:15 UTC
At least assuming that passing a cross-origin window here should throw.

It's hard to tell for sure, since WindowProxy is not really all that defined....
Comment 2 Ian 'Hixie' Hickson 2014-10-23 17:18:01 UTC
You can't actually get a hold of a Window object, so you couldn't pass one in. I'm not sure what you mean here.
Comment 3 Boris Zbarsky 2014-10-23 17:25:43 UTC
The method expects a Window.  That is, it will take a WindowProxy, try to extract a Window from it, throw if that fails (e.g. due to same-origin checks failing), then use the resulting Window for whatever it keeps doing.

This is why we need to define how WindowProxy actually works, by the way.  It's not an actual IDL type, so the IDL as it is written right now is basically nonsense...
Comment 4 Ian 'Hixie' Hickson 2014-10-27 20:40:46 UTC
Yeah, see bug 20701 for that.
Comment 5 Ian 'Hixie' Hickson 2014-11-26 23:31:03 UTC
I don't see why MessageEventInit() would ever fail. It just takes the WindowProxy, and sticks it on the Event object's "source" attribute without a second glance.
Comment 6 Boris Zbarsky 2014-11-27 02:53:12 UTC
That's not what it does in Firefox.  

In Firefox a WindowProxy is a pure-JS thing.  There is no real concept of WindowProxy inside the engine (or rather there is at the moment, but pretty much any use of it is a security pitfall and we're working on getting rid of it).  Whenever you hand a WindowProxy to some piece of C++ code from JS, it actually gets the Window the WindowProxy is currently pointing to.  This is only allowed if the Window in question is same-origin with the current Realm at the point at which the Web IDL conversion to Window happens.

So in fact doing this:

  new MessageEvent("foo", { source: frames[0] })

will throw in Firefox if frames[0] is not same-origin with the MessageEvent constructor.  If that's not the behavior we want, then we need to actually define exactly how WindowProxy works, and then we can try to evaluate whether the resulting security invariants are reasonable or not.  As things stand, I believe that storing an actual WindowProxy or equivalent on the C++ side here would not be secure, because you could effectively spoof (from the pov of the C++ code) what the MessageEvent source is.  JS is sort of SOL on this point because of a lack of way to represent Window, but JS is also sandboxed so it's less of a problem if it screws up and gets the wrong Window here.
Comment 7 Bobby Holley (:bholley) 2014-11-27 03:25:54 UTC
(In reply to Ian 'Hixie' Hickson from comment #4)
> Yeah, see bug 20701 for that.

That still doesn't really define WindowProxy in the general case.
Comment 8 Ian 'Hixie' Hickson 2014-11-28 04:24:17 UTC
I don't understand what there is to define. It's just an object that forwards all operations to the underlying object. Or, as the spec puts it, "all operations that would be performed on it must be performed on the Window object of the browsing context's active document instead".

Note that the MessageEvent() constructor has nothing to do with initMessageEvent().

I don't see why a cross-origin Window would cause either initMessageEvent() or the constructor to throw. That's certainly not what the spec requires.

I don't see how you could do anything to harm C++ here. C++ shouldn't be operating on these events in any way in the first place.
Comment 9 Boris Zbarsky 2014-11-28 04:34:18 UTC
> It's just an object that forwards all operations to the underlying object.

Define "operations"?

If you call a Web IDL getter with the WindowProxy as "this", what exactly is being forwarded, for example, and why?

Seriously, WindowProxy needs to have actual behavior actually defined.  What's in the spec right now is "I know it when I see it" handwaving...  I'm pretty sure we have existing bugs open on clearly defining WindowProxy.

It sounds to me like you feel there are two kinds of APIs: (1) those that never examine the provided WindowProxy past ensuring it is in fact a WindowProxy and (2) those that plan to do something with the WindowProxy (and then one needs to figure out whether that "something" should really be done on the WindowProxy or on the Window the WindowProxy was a proxy for at the API invocation point; this can matter a great deal in general).  Gecko currently treats all APIs as being of the latter sort and assumes the desired things is the invocation-point Window, fwiw.  We feel that this is the least-surprising behavior from a security perspective.

> Note that the MessageEvent() constructor has nothing to do with
> initMessageEvent().

Sure.

> I don't see why a cross-origin Window would cause either initMessageEvent()
> or the constructor to throw. That's certainly not what the spec requires.

Sure.  See above.

> C++ shouldn't be operating on these events in any way in the first place.

Right, so you're arguing that we should in fact have the two types of APIs, make all spec authors think about which of the two types their API is, and make this particular API an API of type 1, right?
Comment 10 Ian 'Hixie' Hickson 2014-12-01 18:57:25 UTC
Another way to describe what I'm trying to describe here is that when a WindowProxy object would change what it points to, you go in and change every single reference to the old Window object to be a reference to the new Window object, and you just pretend you always have actual Window objects everywhere instead of Window objects.

So when you call a Web IDL getter with the WindowProxy as "this", it does exactly the same as it would if you could call the Web IDL getter with the current relevant Window as "this".

There's only one kind of API. An API that takes a WindowProxy, and then acts on the underlying Window. You can't act on the WindowProxy itself, there's no "there" there. You can't get a reference to the underlying Window, you only ever get a reference to the WindowProxy.

The reason C++ code would never operate on these events is just that there's nothing in the spec that ever requires that any browser code react to these events.
Comment 11 Boris Zbarsky 2014-12-01 20:37:33 UTC
> you go in and change every single reference to the old Window object to be a
> reference to the new Window object

Every JS reference?  Or every internal reference?

In any case, that's not something you can do in ES without violating basic language invariants (e.g. the scope chain of a function is not mutable in ES).  You could try to convince the ES folks to change their invariants, but I'm not sure how interested they would be in doing that, nor how interested implementors would be in implementing such violations.

This is why we need an actual spec for WindowProxy, like I've kept saying for a while.  What you want to describe is not something that can actually exist, so your mental model needs to change as far as I can tell.

> So when you call a Web IDL getter with the WindowProxy as "this", it does
> exactly the same as it would if you could call the Web IDL getter with the
> current relevant Window as "this".

OK.  That needs to actually be specified somewhere, probably in Web IDL.  Which is probably where the WindowProxy spec should really live...

> An API that takes a WindowProxy, and then acts on the underlying Window.

The question is this: if you _store_ something for use later, do you store the WindowProxy or the Window?

> You can't act on the WindowProxy itself, there's no "there" there.

I don't know what you mean.  There is an actual ES object for the WindowProxy.  It just happens to be a proxy with an interesting proxy handler and a mutable proxy target.

At least as everyone but you seems to be thinking about this right now, in spec terms, that's the case.  Again, the issue here seems to be your mental model.

And given that, if you _store_ something, you can store either the WindowProxy or its current target Window.  At least if you can get the current target.

> You can't get a reference to the underlying Window

Web script can't.  The browser implementation obviously can, and clearly does.

> there's nothing in the spec that ever requires that any browser code react to
> these events

There's nothing in the spec that requires browser extensions to exist and work, or indeed requires a browser to have any UI at all.  And yet such things exist, need to work, and browser implementors need to worry about how they will work.
Comment 12 Ian 'Hixie' Hickson 2014-12-03 19:51:13 UTC
(In reply to Boris Zbarsky from comment #11)
> > you go in and change every single reference to the old Window object to be a
> > reference to the new Window object
> 
> Every JS reference?  Or every internal reference?

Every JS reference that is described as a WindowProxy. WindowProxy is only a JS thing, you can't reference it from C++. Arguably even Window is just a JS thing; the UA side of the spec doesn't define things in terms of Window, it uses browsing contexts and so on.


> In any case, that's not something you can do in ES without violating basic
> language invariants (e.g. the scope chain of a function is not mutable in
> ES).

The global object is the Window object, not the WindowProxy object.


> You could try to convince the ES folks to change their invariants, but
> I'm not sure how interested they would be in doing that, nor how interested
> implementors would be in implementing such violations.
>
> This is why we need an actual spec for WindowProxy, like I've kept saying
> for a while.  What you want to describe is not something that can actually
> exist, so your mental model needs to change as far as I can tell.

Ok, well, I've described what the "actual spec" I would write is (it's what the spec says). It seems to me to be well-defined, and it matches implementations by and large (especially if you ignore areas where browsers aren't interoperable in the first place). ES language invariants aren't holy to me, indeed some of them are just flat out wrong (e.g. that "this" and the global object are the same thing is just not implemented by anyone despite the ES spec making that claim), and what is an invariant changes from year to year anyway (e.g. WindowProxy long predates all the new invariants that ES "Proxy" objects are supposed to enforce), so saying the spec violates them is not IMHO a strong argument against.

I'm happy to put in another one if you have an alternative proposal. I'm also happy to defer to another spec if another spec wants to define this instead.
Comment 13 Boris Zbarsky 2014-12-03 20:49:05 UTC
> WindowProxy is only a JS thing, you can't reference it from C++.

You can reference JS things from C++, trivially.  Has to be supported for "any", for example.

> Arguably even Window is just a JS thing

No, it's just not.  Not in the spec, not in implementations.

> The global object is the Window object, not the WindowProxy object.

Yes, I'm aware.  What was unclear to me what you meant by "every single reference".  So you mean the "JS references" but not the "JS references" coming from function scope chains, or Realm global associations.  What other exceptions?

> and it matches implementations by and large

Except when it doesn't, right.  And yes, implementations don't match each other, but our goal here should be figuring out something they could converge on.

> ES language invariants aren't holy to me

Sure, but if JS engines are enforcing them then it makes it hard to implement specs that don't take them into account.

> indeed some of them are just flat out wrong

Everyone involved thinks the "this" business is wrong and there is a plan to fix that on the ES side, as far as I can tell.

The non-configurable property invariants are a different beastie.

> so saying the spec violates them is not IMHO a strong argument against.

It's an argument against the spec being implementable, sadly.  This isn't a theoretical concern, also sadly.

I filed bug 27502 on speccing out WindowProxy, with an outline of what I think we should be doing.  If Domenic is not interested in turning it into spec language, I'll do it.

But ok, let's see if I can summarize what we agree on:

1)  There is a WindowProxy object.  It's a JS object, with no corresponding IDL/C++ reflection.  C++ code can hold a reference to a WindowProxy, just like any JS object.

2)  There is a Window object.  It has a JS reflection and an IDL/C++ reflection.

I think that still means that my API categorization from comment 9 holds and the only real question is which APIs fall in which bucket.  This only affects writable attributes and method call arguments.

Looking at Gecko's IDL, the only place where Window or WindowProxy are used as something other than readonly attributes are (this includes some non-standard Gecko extensions):

1)  CanvasRenderingContext2D.drawWindow.  This really wants to operate on the
    underlying Window, not on the WindowProxy.

2)  Various constructors for UIEvent and things inheriting from UIEvent, for
    the .viewof the UIEvent.  It's not clear to me which behavior these want.

3)  Document.createTouch, which actually ignores its "view" argument afaict.

4)  requestingWindow in PopupBlockedEventInit.  I'm pretty sure this one wants
    an actual Window, but it's also nonstandard.

That seems to be it.

I guess a viable approach then is to define that UIEvent holds a WindowProxy, which means it will just hold the JS object involved...
Comment 14 Ian 'Hixie' Hickson 2014-12-03 23:59:42 UTC
(In reply to Boris Zbarsky from comment #13)
> > WindowProxy is only a JS thing, you can't reference it from C++.
> 
> You can reference JS things from C++, trivially.  Has to be supported for
> "any", for example.

Let me rephrase that. There are no requirements that result in you referencing it from C++.


> Yes, I'm aware.  What was unclear to me what you meant by "every single
> reference".  So you mean the "JS references" but not the "JS references"
> coming from function scope chains, or Realm global associations.  What other
> exceptions?

Well I don't think "Realms" should exist (it should all be done using slots on the global object IMHOe). If a function scope chain actually uses a WindowProxy, I would have it change, yes. (This doesn't violate the invariants because it's really still the WindowProxy. It just acts as if it changed because WindowProxy proxies everything.) But mostly it'll be the Window, not the WindowProxy, on the scope chain (since 'this' is the Window).


> Everyone involved thinks the "this" business is wrong and there is a plan to
> fix that on the ES side, as far as I can tell.

That's news to me. Certainly historically there have been plenty of cases where the Web violated invariants and the editors of the specs in question (including ES) wouldn't fix their specs. So "it's an invariant" doesn't mean much. If there's a good reason to have an invariant, then we can discuss that, certainly.


> The non-configurable property invariants are a different beastie.

Those postdate WindowProxy. If people come along and invent invariants post-hoc that aren't compatible with other specs, it seems silly to me to argue that this means the older spec should change. I mean, I could define an invariant that all property names in JS must start with an underscore, but that wouldn't mean you'd go to the ES group and tell them to rename all their identifiers. They would rightly tell me I'm wrong. Just like I'm saying that these new invariants are wrong if they're not compatible with existing specs (and especially if those new invariants were added without the existing specs' editors being even remotely consulted).


> 1)  CanvasRenderingContext2D.drawWindow.  This really wants to operate on the
>     underlying Window, not on the WindowProxy.

This should just be dropped. It's non-standard and has dubious security implications.


> 2)  Various constructors for UIEvent and things inheriting from UIEvent, for
>     the .viewof the UIEvent.  It's not clear to me which behavior these want.
> 3)  Document.createTouch, which actually ignores its "view" argument afaict.

Those should be defined in their relevant specs.


> 4)  requestingWindow in PopupBlockedEventInit.  I'm pretty sure this one
>     wants an actual Window, but it's also nonstandard.

Should be dropped, IMHO.
Comment 15 Boris Zbarsky 2014-12-04 09:50:25 UTC
> There are no requirements that result in you referencing it from C++.

The fact that UIEvent has a getter that's supposed to return a WindowProxy requires it to be referenced from C++ so it can be returned from said getter.

> Well I don't think "Realms" should exist

You should make that case to TC39, I guess.

> If a function scope chain actually uses a WindowProxy

Per spec it uses the global.  UAs... unclear.  In Gecko it uses the global.

> But mostly it'll be the Window, not the WindowProxy, on the scope chain

Right.

> since 'this' is the Window

I'm not sure what you mean here, to be honest.

> That's news to me

Well, ok.  https://mail.mozilla.org/pipermail/es-discuss/2014-November/040434.html doesn't quite state it as strongly as I did, but no one has objected to Allen's proposal.

> If there's a good reason to have an invariant

The invariants in ES6 are needed to provide certain desirable security properties, apparently.  You may wish to talk to Mark Miller for details.

> Those postdate WindowProxy.

The invariants exist in ECMA-262 5th edition (see <http://www.ecma-international.org/publications/files/ECMA-ST-ARCH/ECMA-262%205th%20edition%20December%202009.pdf>) so they date back to at least 2009.

This may postdate WindowProxy, sure.  But since WindowProxy can in fact support these invariants at first glance, and they've been in the ES specs for quite a while now, why shouldn't it support them?

> This should just be dropped. It's non-standard

I told you I was including the non-standard bits, for completeness.  It's not exposed to the web, so there are no security implications.

> Should be dropped, IMHO.

Possibly, yes.
Comment 16 Boris Zbarsky 2014-12-04 11:09:34 UTC
> The invariants exist in ECMA-262 5th edition

And, importantly, there was no way to have any violation of them before that, because:

1)  Object.defineProperty did not exist.
2)  Object.defineProperties did not exist.
3)  Object.freeze did not exist.
4)  Object.preventExtensions did not exist.
5)  Object.seal did not exist.
6)  Object.getOwnPropertyDescriptor did not exist.
7)  Object.isSealed did not exist.
8)  Object.isFrozen did not exist.
9)  Object.isExtensible did not exist.

Due to #1, #2, #3 and #5 there was no way to trigger the [[DefineOwnProperty]] of a WindowProxy with a non-configurable descriptor, due to #3, #4, #5 there was no way to trigger the [[PreventExtensions]] trap, due to #7, #8, #9 there was no way to trigger the [[IsExtensible]] trap, and due to #6, #7, #8 there was no way to trigger the [[GetOwnProperty]] trap in a directly observable way.

So the only real problem was that when UAs implemented these methods from ES5 they didn't make them behave in the way ES5 already demanded on a WindowProxy.  There was no incompatibility at all between WindowProxy behavior before ES5 existed and the post-ES5 behavior; it was just a matter of making it behave correctly when the new ES5 APIs were used on it...
Comment 17 Ian 'Hixie' Hickson 2014-12-19 23:22:39 UTC
I agree that it didn't have violations before.

My point is that the problem here is that ES introduced new "invariants" that were violated when they were introduced, and thus the problem lies with ES.


> The fact that UIEvent has a getter that's supposed to return a WindowProxy
> requires it to be referenced from C++ so it can be returned from said getter.

That's an implementation detail. From the spec's point of view, this is all just part of the JS API.


> > since 'this' is the Window
> 
> I'm not sure what you mean here, to be honest.

I meant "since the global is the Window", sorry.


> Well, ok. 
> https://mail.mozilla.org/pipermail/es-discuss/2014-November/040434.html
> doesn't quite state it as strongly as I did, but no one has objected to
> Allen's proposal.

Great. Maybe they'll fix the other "invariants" to not be incompatible with HTML too.


> The invariants in ES6 are needed to provide certain desirable security
> properties, apparently.  You may wish to talk to Mark Miller for details.

If Mark wants Window to satisfy certain invariants, then he should file a bug explaining what the security problem is and make his case.


> This may postdate WindowProxy, sure.  But since WindowProxy can in fact
> support these invariants at first glance, and they've been in the ES specs
> for quite a while now, why shouldn't it support them?

Neither of those statements are an argument for why it should support them. The default position should be for not changing the spec, otherwise the spec can change on a whim and as an implementor I know you hate it when that happens. :-)


Anyway. I'm not really sure what you're asking for here anymore. The initial request is IMHO clearly wrong — MessageEventInit should use a WindowProxy, because bare Window objects are never exposed on the Web. The conceptual model is that when a page navigates, code goes in and replaces all the references to the old Window (that are labeled as WindowProxy) with references to the new Window, such that you can only ever get hold of one Window object. We handle this by describing the Window object variables as being of type WindowProxy, and defining WindowProxy as just acting like the "current Window" in every way. You can directly impact the underlying Window objects sometimes even when they're not "current", e.g. when it's the global object on the scope chain, but you can't actually get a hold of the object itself (which is why, e.g., 'this' and the global object aren't defined as being ===, unlike what JS required before a few weeks ago.)
Comment 18 Boris Zbarsky 2014-12-20 03:10:48 UTC
> Anyway. I'm not really sure what you're asking for here anymore.

Please see comment 9.

> because bare Window objects are never exposed on the Web. 

The question here is what the internals should be storing and whether they ever operate on the stored value directly (i.e. not via the web APIs, in which case they can totally operate on the Window).  There are certainly all sorts of things (e.g. the XHR constructor) that have to store the Window, not the WindowProxy.

> The conceptual model is that when a page navigates

I don't believe your conceptual model is correct.  Certainly the reference in the XHR constructor shouldn't get replaced.  So what actually needs to happen is to define which set of references "gets replaced" (those are the ones where a WindowProxy is actually stored) and which set is not replaced (those are the ones where a Window is actually stored).

> such that you can only ever get hold of one Window object.

This does not match UA behavior.  The old Window is present in things like IDL constructors, object scope chains, the Window association of the document that is no longer current, and so forth.  You can't get a direct reference to it from script, but you can invoke various spec algorithms that operate on it.
Comment 19 Boris Zbarsky 2014-12-20 18:40:29 UTC
A few last meta-comments on this whole discussion.  Last, because we're just going in circles and this is simply not worth my time.  I will just implement whatever I can, like every other browser vendor has.

1) The conceptual model you describe in comment 17 is not only not actually spelled out anywhere but is best summarized as "hey, magic".  The conceptual model where a WindowProxy is actually an ES object, distinct from the Window, with internal methods that do something sane (whether that be just forwarding to the current Window or something more complicated is not relevant for this part of the discussion) is much simpler, doesn't involve any magic "replace all the references" (whatever that would even mean in a world with WeakMap and WeakSet and so forth; the questions about what to do with those simply disappear if you have an actual WindowProxy object), and can certainly produce the behavior you seem to want by just forwarding all the internal methods.  So I believe you should switch the spec to this "WindowProxy is an object with some internal methods that do X" model no matter what else you do.  Web IDL will still need some changes to deal with WindowProxy, of course, as it does now.

2)  "The default position should be for not changing the spec" is, in this instance and given item #1, not relevant, because this is not a change on a whim: it's a change to a model that has some chance of being implemented, as opposed to the "hey, magic" of the current model.

3)  Your current model doesn't match UA behavior in practice.  For example, Safari does something quite different from what your model describes (but something that does in fact more or less preserve the ES invariants, at first glance, though it's insane in various other ways).  If the goal is to get UAs to align on something here, it would be a good idea to figure out what that "something" is.  I've been trying to do that, but given that you're not interested and I've had no response from either the Safari developers or the Blink ones, I'm going to stop wasting time on this.  Microsoft did seem moderately interested, so maybe Mozilla and Microsoft and TC39 will figure out something and then Blink and WebKit will either follow or not.  Not the best way to try to achieve interop, but I guess that's the best we can do under the circumstances.
Comment 20 Ian 'Hixie' Hickson 2014-12-23 00:07:43 UTC
> Please see comment 9.

Comment 9 essentially is saying that WindowProxy isn't sufficiently defined.

I don't understand what isn't well-enough defined.

Can you give some concrete examples of things that you think the spec doesn't answer unambiguously?


> The question here is what the internals should be storing and whether they
> ever operate on the stored value directly (i.e. not via the web APIs, in
> which case they can totally operate on the Window).

There are all kinds of requirements that are defined in terms of Window, sure. As far as I can tell this is all well-defined.


> I don't believe your conceptual model is correct.  Certainly the reference
> in the XHR constructor shouldn't get replaced.

Sure. The reference in the XHR constructor isn't labeled as WindowProxy, though, is it?


> So what actually needs to
> happen is to define which set of references "gets replaced" (those are the
> ones where a WindowProxy is actually stored) and which set is not replaced
> (those are the ones where a Window is actually stored).

That's what the spec does, by simply defining WindowProxy as a proxy (not ES Proxy, the term didn't exist when the name WindowProxy was coined) to whatever the "current" Window is.


> > such that you can only ever get hold of one Window object.
> 
> This does not match UA behavior.  The old Window is present in things like
> IDL constructors, object scope chains, the Window association of the
> document that is no longer current, and so forth.  You can't get a direct
> reference to it from script, but you can invoke various spec algorithms that
> operate on it.

I just said you couldn't get hold of one. I agree you can cause things to happen relating to Window objects (most trivially, by using a WindowProxy). But you can't, from script, get your hands onto a bare Window.

WindowProxy is only relevant to what happens in JS. Outside JS, we don't generally manipulate WindowProxy objects, we handle just raw Window objects.
Comment 21 Boris Zbarsky 2014-12-23 01:57:04 UTC
> Outside JS, we don't generally manipulate WindowProxy objects

The internal storage of MessageEvent is "outside JS", so this claim happens to not match reality.  Which is why I'm arguing that we need to just explicitly define things instead of making generalized assumptions like that.
Comment 22 Ian 'Hixie' Hickson 2015-01-06 22:30:31 UTC
That's an implementation detail. The behaviour is entirely defined in JS terms, and the testable behaviour is all in JS terms.

Can you give some concrete examples of things that you think the spec doesn't answer unambiguously?
Comment 23 Boris Zbarsky 2015-01-07 02:47:46 UTC
> The behaviour is entirely defined in JS terms, and the testable behaviour is
> all in JS terms.

Until someone adds some API that takes a MessageEvent and gets the document from the member it's storing and works with it.  And at that point it becomes black-box testable whether MessageEvent is storing a Window or a WindowProxy.

I, personally, would prefer MessageEvent to store a Window, because if it stores a WindowProxy then "which global is this event associated with?" can effectively change.  That's unfortunate.  Just as unfortunate is the fact that there is no way to get your hands on an actual Window in JS proper so things can change out from under you due to holding a WindowProxy; I think that's a design mistake in browsers that we should try to fix, long-term.

> Can you give some concrete examples of things that you think the spec doesn't
> answer unambiguously?

In general?  What the actual internal methods of WindowProxy do.
Comment 24 Boris Zbarsky 2015-01-07 02:49:00 UTC
But, given the start of comment 19, unccing.  I really am tired of all the repetition, and it's not being good for my general sanity at this point.  Whenever you decide that you actually want to work with others on this stuff, please ping me.
Comment 25 contributor 2015-01-08 18:40:41 UTC
Checked in as WHATWG revision r8878.
Check-in comment: Put back nntp to the scheme whitelist, since it was removed completely accidentally.
https://html5.org/tools/web-apps-tracker?from=8877&to=8878
Comment 26 Bobby Holley (:bholley) 2015-01-08 18:44:58 UTC
(In reply to contributor from comment #25)
> Checked in as WHATWG revision r8878.
> Check-in comment: Put back nntp to the scheme whitelist, since it was
> removed completely accidentally.
> https://html5.org/tools/web-apps-tracker?from=8877&to=8878

This seems erroneous...
Comment 27 Ian 'Hixie' Hickson 2015-01-08 18:53:33 UTC
(In reply to Boris Zbarsky from comment #23)
> > The behaviour is entirely defined in JS terms, and the testable behaviour is
> > all in JS terms.
> 
> Until someone adds some API that takes a MessageEvent and gets the document
> from the member it's storing and works with it.

That would be a _terrible_ API (and not just because of the ambiguity of what it would mean — I mean, what the heck would a browser be doing interpreting event attributes anyway? That's inconsistent with the platform). If anyone does that, you should rightly take them to task on it.


> I, personally, would prefer MessageEvent to store a Window, because if it
> stores a WindowProxy then "which global is this event associated with?" can
> effectively change.

How can it change? The object has a prototype that's from a specific Window, that's not going to change even if the page navigates. How is this different to how, say, document.defaultView changes? We wouldn't argue that the Document changes what global it's associated with, would we?


> That's unfortunate.  Just as unfortunate is the fact
> that there is no way to get your hands on an actual Window in JS proper so
> things can change out from under you due to holding a WindowProxy; I think
> that's a design mistake in browsers that we should try to fix, long-term.

That ship sailed decades ago.


> > Can you give some concrete examples of things that you think the spec doesn't
> > answer unambiguously?
> 
> In general?  What the actual internal methods of WindowProxy do.

They just forward to Window. It's exactly like if you had a variable whose value was the Window, and then when the browsing context was navigated, the browser went around and found all the variables labeled WindowProxy that held a pointer to the old Window and replaced the pointers with pointers to the new Window.
Comment 28 Ian 'Hixie' Hickson 2015-01-08 18:54:10 UTC
Comment 25 was intended for bug 27090.
Comment 29 Anne 2016-01-20 15:01:47 UTC
I filed bug 29386 on IDL needing to handle WindowProxy.

https://github.com/annevk/html-cross-origin-objects attempts to define WindowProxy in detail (modulo open issues).

I suggest we close this bug as RESOLVED MOVED since the issues it raises are now being tackled elsewhere. None of this has landed in HTML yet of course, but hopefully we'll get there soonish.