- 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