- From: Boris Zbarsky <bzbarsky@MIT.EDU>
- Date: Sun, 22 Dec 2013 01:31:51 -0500
- To: "public-script-coord@w3.org" <public-script-coord@w3.org>
The current specification for [Global] says that all IDL attributes are
defined on the object itself, not its proto, to prevent accidental
shadowing of things by vars in situations like this:
var performance = window.mozPerformance ||
window.webkitPerforamnce ||
window.oPerforamnce ||
window.msPerformance ||
window.performance;
However when we tried implementing this in Gecko, we encountered a
problem with the Dell website due to the use of the following pattern
(spread over multiple JS files, actually, but I'm condensing it for
clarity):
var onload;
(function() {
onload = { foo: "bar"; };
doSomething(onload);
})();
Some instances of this pattern have a "var onload" inside the function,
but some do not, and it's the latter that are problematic.
In the current Gecko implementation, the "onload" property lives on
Window.prototype, so the global var declaration shadows it and
everything works. But if we follow the current spec and move the
property to the global object directly, then the var does nothing (since
the property is already defined), and the assignment invokes the setter
for the property. The property is marked as only accepting
EventHandler, which is a callback type that treats non-callables as
null. The upshot is that doSomething is called with null as the
argument instead of the actual object it expects.
I tested what other UAs do with this situation, and it goes like this:
Chrome: Seems to put on* properties on Window.prototype, even though
other Window properties (e.g. "performance") go directly on the global
object. It's not clear to me how Chrome decides where to place which
properties; I would love an explanation of how that's decided.
Safari: Puts the "onload" property directly on the global, but allows
assigning _any_ object to it (and in fact to all event handler
properties), not just callables, which makes the above code work.
Opera (Presto-based): Has the same behavior as current Gecko: just puts
the IDL properties on Window.prototype.
IE9 and IE11: Puts the IDL properties on Window.prototype like
Gecko/Presto _and_ allows assigning arbitrary non-callable objects like
Safari.
The obvious question here is what the spec should say.
Do we want to move some but not all of the global's properties back to
the proto chain? If so, which ones? Should it be a whitelist (i.e.
annotate the properties that go on the proto) or a blacklist (annotate
the properties that go on the object)? Or should we just give up
putting things on the object directly and simply spec on Window that all
UAs must support all prefixed variants of the properties that need to be
supported with prefixes to avoid the var problem described at the
beginning of this mail?
Any other bright ideas?
-Boris
Received on Sunday, 22 December 2013 06:34:01 UTC