- From: Maciej Stachowiak <mjs@apple.com>
- Date: Mon, 13 Mar 2006 03:57:20 -0800
- To: "Web APIs WG (public)" <public-webapi@w3.org>
Hi everyone,
This action item was assigned to me while I wasn't present, so I'm
not sure what it means. I could imagine the following possible things
intended to be covered:
1) Define scope chain for event listeners attached via HTML event
attributes, e.g. <img onclick="handleClick(event)">.
2) Define `this' binding behavior for #1.
3) Define scope chain for events attached via HTML DOM properties,
e.g. myImage.onclick = handleClick
4) Define `this' binding behavior for #3.
5) Define scope chain for events attached via addEventListener().
6) Define `this' binding for #5 (already done).
7) Define scope chain for event listeners attached via SVG 1.1 event
attributes, e.g. <image onclick="handleClick(event)">.
8) Define `this' binding behavior for #1.
I do not feel like I have the relevant expertise to answer 7 and 8,
but I can try to do some research if it is desirable to define those.
Here's brief outlines of the behavior I would propose. I have not
tested thoroughly or written any of this up in formal language, so
please let me know which ones need testing and formal language.
1) The attribute text is coverted to a function as if it were the
result of the following expression evaluated in global scope, where
ELT is the DOM object representing the element:
(function() { with(ELT) { return function(event) { ...contents of
attribute here... } } })()
The behavior is then as if resulting function F were added with
addEventListener(event, F, false).
The upshot of this is that a function is made with ELT at the head of
its [[Scope]] internal property, and "event" is bound to the event in
the function body.
I think describing this in terms of the language beats trying to
write prose about the [[Scope]] property though.
Also this is subtly incompatible with Win IE, since I believe it has
only window.event, not an actual event parameter to attribute handlers.
Also, some event listener properties on the <body> element actually
create event listeners on the window object, not the body, and so do
not include the body in their scope chain.
2) See above - no special considerations for "this" beyond the effect
of addEventListener of a function.
3) Event handler DOM properties have a function value. Getting the
property retrieves any event listener function previously set using
the property or corresponding markup attribute. Setting the property
removes any previous event listener set via that property or the
corresponding attribute, and adds the newly set function as if with
addEventListener. There is no change made to the scope chain of a
function set this way.
The slightly odd implication of this is that you can retrieve an
event listener created via attribute and attach it to another
element, and its scope chain continues to include the original
element, not the new element.
4) See above - no special considerations for "this" beyond the effect
of addEventListener of a function.
5) addEventListener does not alter any function parameters passed to
it. In particular it does not alter the scope chain.
6) I already came up with language for this. In brief my proposal was
to define this as equivalent to adding an EventListener created by
the expression { handleEvent: function(event) { F.applyTo
(event.currentTarget, [event]); } } where F is the function.
The upshot of this is that the event's current target will be the
"this" object for any function event listener. But if you add an
object with a handleEvent method, then its handleEvent method is
invoked as normal, with the EventListener as the "this" object. Here
again I think it is better to explain the behavior in terms of
ECMAScript expressions than to try to explain in terms of ECMA-262
spec-internal concepts. It is more obvious how to test this way, and
is more likely to be compatible with future revisions of ECMA-262.
Let me know if you need more detail or more formal language on any of
these.
Regards,
Maciej
Received on Monday, 13 March 2006 23:56:44 UTC