[whatwg] [html5] scope chain for event handlers specified via content attributes

David Flanagan dflanagan at mozilla.com
Fri Sep 9 08:57:08 PDT 2011

On 9/8/11 6:30 PM, Boris Zbarsky wrote:
> On 9/8/11 8:23 PM, David Flanagan wrote:
>> function(event) {
>> with(event.target.ownerDocument) {
>> with(event.target.form || {}) {
>> with(event.target) {
>> alert(x);
>> }
>> }
>> }
>> }
> This is almost exactly how Chrome implements it.  It's all sorts of 
> buggy.  See http://code.google.com/p/chromium/issues/detail?id=80911
So Chrome's but has to do with the fact that the form property is 
spoofable.  That seems easy enough to fix even with this kind of dynamic 
scope chain that allows the scope to match the current position of the 
element in the document, rather that a static scope that matches the 
position the element had when the event handler attribute was set.

On the other hand, I suppose I could see a lexical scoping argument: 
when event handler content attributes are set in an HTML document, we 
might want them to have consistent lexical scope based on where they 
appear in the document, even if they are later moved.  In the same way 
that closures retain their lexical scope even when returned or passed 
into another scope.

I don't think I'm really persuaded by that argument, but on further 
testing I see that Opera uses static scope, just as Firefox and Safari 
do (my test doesn't work in IE, and I don't care enough to figure out 
why).  So Chrome is the outlier here: the spec matches the majority of 
the browsers, and I'll just accept that it is correct.

Thanks for helping to clarify this, Boris.


>> But § says that the scope chain should be initialized statically
>> when the content attribute string is converted to a function. I'd like
>> to check that that is intentional
> It's what most UAs implement, I believe... and doesn't suffer from the 
> sorts of issues mentioned in the bug report above.
>> since it causes counter-intiuitive
>> (to me) behavior if an element moves between forms or moves between
>> documents after the event handler attribute is set.
> So it does.  Of course people should ideally not be using this syntax 
> to start with, so it's mostly there for legacy pages that don't often 
> do this sort of thing.
>> My results: Firefox and Safari create the scope chain statically: when
>> an element moves between forms, the scope chain remains the same.
>> Chrome's scope chain is dynamic and resolves identifiers against the
>> element's new form. Chrome's behavior seems more sensible to me. Is it
>> correct?
> As implemented, no, in my opinion.  See above.
>> (When an element moves from one document to another (via adoptNode())
>> firefox uses dynamic scope (perhaps because it is re-creating the
>> function?)
> What actually happens in this case in Firefox internally is that the 
> parent (in the JS_GetParent) sense of the element's JS reflection is 
> changed.  This was done because origin determination for JS objects 
> depended on the scope chain, since Spidermonkey didn't offer any other 
> good way to do it.
> With ongoing changes to Spidermonkey, this implementation detail may 
> change, and then we may be able to preserve static scope in general, 
> maybe.
> In any case, the behavior there is definitely an artifact of 
> implementation details, and not intentional.
>> In Chrome and Safari, the event handler stops working when
>> the element is moved from one document to another, so the test doesn't
>> succeed there.)
> It's worth testing Opera and various IE versions here too.
> -Boris

More information about the whatwg mailing list