Cameron McCormack wrote:
Brendan Eich:
As bz and others point out, the object detection w/ var pattern can
arise for operations, e.g. for requestAnimationFrame, using the same
var requestAnimationFrame = window.mozRequestAnimationFrame || ... ||
window.requestAnimationFrame;
pattern. So WebIDL operations (JS methods) on the global would be
promoted to "own" too. They'd be configurable, if I recall correctly,
and either writable or replaceable. Do I have that right?
OK. So one thing that I think has been pointed out is that moving
properties for operations on to window makes it harder to monkeypatch
addEventListener and friends.
This is a recent feature, right? I can't even find EventTarget in Opera
12, e.g.
It's plausible the global object exception breaks symmetry here. Could
we live with the inability to monkey-patch? As Jonas points out, playing
deep prototype chain games with the global object when var (and
function) shadow as in ES6 or ES5.1+erratum-fix is just bug-making and
confusing.
We *could*, if we thought it was important, have the properties on
window forward on to the ones from the prototype.
Less magic if we can avoid it.
Some other questions on specifics:
1. If we don't do that auto-forwarding, does Window.prototype still
need to exist? What should window.__proto__ be?
There's no need to over-invent for uniformity, if the global object is
exceptional. The simpler the exception, the better.
However, implementations (at least Gecko) give window a proto chain that
is "interesting":
--
[19:29:57.405] Object.prototype.toString.call(window.__proto__).slice(8,-1)
[19:29:57.408] "XPC_WN_ModsAllowed_NoCall_Proto_JSClass"
--
[19:30:06.143]
Object.prototype.toString.call(window.__proto__.__proto__).slice(8,-1)
[19:30:06.145] "Global Scope Polluter"
--
[19:30:11.629]
Object.prototype.toString.call(window.__proto__.__proto__.__proto__).slice(8,-1)
[19:30:11.631] "Object"
--
[19:30:18.373]
Object.prototype.toString.call(window.__proto__.__proto__.__proto__.__proto__).slice(8,-1)
[19:30:18.375] "Null"
This is from a stable-release Firefox Web Console. I believe it matches
a real DOM content window. I don't see EventTarget, because its methods
get flattened into the direct proto, Window.prototype:
[19:33:30.076] Window.prototype === this.__proto__
[19:33:30.077] true
--
[19:33:50.323] Object.getOwnPropertyNames(this.__proto__)
[19:33:50.325] ["addEventListener", "removeEventListener",
"dispatchEvent", "dump", "name", "parent", "top", "self",
"sessionStorage", "localStorage", "onmouseenter", "onmouseleave",
"getSelection", "scrollByLines", "getComputedStyle", "__lookupGetter__",
"__lookupSetter__", "__defineGetter__", "__defineSetter__", "toString",
"QueryInterface", "window", "document", "location", "history",
"locationbar", "menubar", "personalbar", "scrollbars", "statusbar",
"toolbar", "status", "close", "stop", "focus", "blur", "length",
"opener", "frameElement", "navigator", "applicationCache", "alert",
"confirm", "prompt", "print", "showModalDialog", "postMessage", "atob",
"btoa", "matchMedia", "screen", "innerWidth", "innerHeight", "scrollX",
"pageXOffset", "scrollY", "pageYOffset", "scroll", "scrollTo",
"scrollBy", "screenX", "screenY", "outerWidth", "outerHeight",
"scrollByPages", "sizeToContent", "content", "closed", "crypto",
"pkcs11", "controllers", "defaultStatus", "mozInnerScreenX",
"mozInnerScreenY", "scrollMaxX", "scrollMaxY", "fullScreen", "back",
"forward", "home", "moveTo", "moveBy", "resizeTo", "resizeBy",
"updateCommands", "find", "mozPaintCount", "mozRequestAnimationFrame",
"mozCancelAnimationFrame", "mozCancelRequestAnimationFrame",
"mozAnimationStartTime", "URL", "onafterprint", "onbeforeprint",
"onbeforeunload", "onhashchange", "onmessage", "onoffline", "ononline",
"onpopstate", "onpagehide", "onpageshow", "onresize", "onunload",
"ondevicemotion", "ondeviceorientation", "ondeviceproximity",
"onuserproximity", "ondevicelight", "setTimeout", "setInterval",
"clearTimeout", "clearInterval", "setResizable", "captureEvents",
"releaseEvents", "routeEvent", "enableExternalCapture",
"disableExternalCapture", "open", "openDialog", "frames", "onabort",
"onblur", "oncanplay", "oncanplaythrough", "onchange", "onclick",
"oncontextmenu", "ondblclick", "ondrag", "ondragend", "ondragenter",
"ondragleave", "ondragover", "ondragstart", "ondrop",
"ondurationchange", "onemptied", "onended", "onerror", "onfocus",
"oninput", "oninvalid", "onkeydown", "onkeypress", "onkeyup", "onload",
"onloadeddata", "onloadedmetadata", "onloadstart", "onmousedown",
"onmousemove", "onmouseout", "onmouseover", "onmouseup",
"onmozfullscreenchange", "onmozfullscreenerror",
"onmozpointerlockchange", "onmozpointerlockerror", "onpause", "onplay",
"onplaying", "onprogress", "onratechange", "onreset", "onscroll",
"onseeked", "onseeking", "onselect", "onshow", "onstalled", "onsubmit",
"onsuspend", "ontimeupdate", "onvolumechange", "onwaiting", "oncopy",
"oncut", "onpaste", "onbeforescriptexecute", "onafterscriptexecute",
"indexedDB", "performance"]
The global object's prototype chain must end with Object.prototype (ES5
says so, IIRC). But the exact chain is not something that should be
standardized in detail.
2. If Window.prototype still does exist, should it be empty?
Rather have no Window.prototype if everything currently there becomes
"own" in each window object, than have an empty proto as an attractive
nuisance. You can't patch if shadowed by an own property, but it might
seem like you ought to be able to.
3. The only writable IDL attributes on Window are:
attribute DOMString name;
attribute DOMString status;
attribute WindowProxy? opener;
and all of the event handler attributes like "onclick". How do these
need to behave if script blithely tries to use variables of the same
name? With this:
<script>
alert([window.status, typeof window.status]);
window.status = "hello";
alert([window.status, typeof window.status]);
</script>
<script>
var status;
alert([window.status, typeof window.status]);
status = 1;
alert([window.status, typeof window.status]);
</script>
Gecko and Opera alert:
,string
hello,string
,undefined
1,number
Yes, this is more lossage compared to historical norms that WebKit-based
browsers still uphold.
The lack of a var initialiser means that the (historically own) status
accessor must have its getter or setter invoked. 'var' doesn't replace
an existing own property in any scenario, historical or ES5+erratum-fix.
while Chrome and Safari alert:
,string
hello,string
hello,string
1,string
which seems to indicate that they're setting the IDL attribute.
Did you try IE8, 9 and 10? I suspect they match but can't test.
I guess this is related to whether we want "function onclick(){}" to
invoke the setter.
We decided (as Allen points out; related to the var issue but distinct
from it) we do not.
But function onmessage(){} in a worker script then doesn't do what some
devs seem to like (or at least expect) from Chrome and Safari.
With this:
<body onerror="alert('exception')">
<script>
alert([String(window.onclick), typeof window.onclick)]);
</script>
<script>
var onclick = 1;
alert([String(window.onclick), typeof window.onclick]);
</script>
Gecko, Opera and Chrome alert:
null,object
1,number
which could mean shadowing or treating "onclick" as IDL type "any" and
treating non-Function values as null, while Safari alerts:
null,object
null,object
which looks like it's invoking the setter but ignoring the assignment
of a non-Function value.
Seems a Safari deviation.
/be
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss