HTML5 spec. seems to unnecessarily ban strict mode event handlers
On Thu, 3 Feb 2011, Allen Wirfs-Brock wrote:
To be sure, I checked the event handler section of the HTML5 spec (dev.w3.org/html5/spec/Overview.html#event-handler-attributes) and to my surprise I discovered that it specifies the creation of the handler function in a manner that, at first glance, seems to explicitly cause the presence of a use strict directive to be ignored.
This wasn't intentional.
I'm happy to change the spec to more correctly interface with the ES spec. Let me know what it should say!
On 02/03/2011 05:00 PM, Allen Wirfs-Brock wrote:
I was browsing Kangax's strict mode test result page (kangax.github.com/es5-compat-table/strict-mode ) and I noticed that he listed the recognition of a use strict directive of a event handler as a "non-standard" feature that he tests for. This spiked my curiosity as my recollection was the HTML5 event handler content attribute was specified to be text that is an ECMAScript FunctionBody. FunctionBody may contain a Directive Prologue that includes a use strict directive so, from an ECMAScript perspective, there shouldn't be anything non-standard about a strict mode event handler.
To be sure, I checked the event handler section of the HTML5 spec (dev.w3.org/html5/spec/Overview.html#event-handler-attributes) and to my surprise I discovered that it specifies the creation of the handler function in a manner that, at first glance, seems to explicitly cause the presence of a use strict directive to be ignored. Essentially it seems to specify that event handlers specified using the event handler attribute are never executed in ECMAScript 5 strict mode. I don't know whether or not this was intentional, but it certainly seems wrong. The "strictness" of an ECMAScript function is an internal and local characteristic of the function. For a ECMAScript host to say that a use strict directive is ignored is really no different from saying that IfStatements or any other syntactically valid element of a FunctionBody will be ignored.
The HTML5 spec. get into this trouble because of the way it uses the abstract operation for creating function objects defined by section 13.2 of the ES5 specification (www.ecma-international.org/publications/standards/Ecma-262.htm). In step 2 of the algorithm in HTML5 6.1.6.1 it unconditionally uses False as the Strict parameter to the ES5 13.2 algorithm. That might seem to exclude the function from strict mode, however that isn't actually the case. All the Strict parameter to 13.2 controls is whether or not "poison-pill" properties for 'caller' and 'arguments' are created for the function object. The semantics of strict mode are specified throughout the ES5 specification and are control by the actual lexical occurrence of a use strict directive. The Strict parameter to 13.2 does not alter this semantics.
The HTML5 spec. also contains another related bug. Step three says "If the previous steps failed to compile the script, then ..." where the "previous steps" pretty clearly references the use of ES5 13.2 in the immediately preceding step 2. However, there is nothing in ES5 13.2 that concerns the compilation of ECMAScript source text. Instead 13.2 expects to be passed an valid FunctionBody. That validation ("compilation") must occur somewhere else.
It appears to me that these problem are probably the result of the HTML5 algorithm being patterned after the wrong parts of the ES5 spec. The appropriate part of the ES5 spec. to use as a model is steps 8-11 of ES5 15.3.2.1. This is the definition of the Function constructor. These steps correctly take care of parsing the FunctionBody and handling any resulting syntax errors. It also calls 13.2 with a correct Strict parameter. Replacing HTML5 6.1.6.1 steps 2-3 with steps modeled after ES5 15.3.2.1 steps, 8, 9, and 11 (step 10 is not applicable) should correct these issues.
Finally, Kangax also lists as a "non-standard" feature the recognition of strict coder as the string argument to setTimeout. I couldn't find anything the HTML5 spec. that could be interpreted as excluding strict ECMAScript code in this context.
Any chance you could open one or more bugs on this?
Doing it via the bugzilla interface gives you an increased ability to be notified and participate, but you can also use the form directly on the W3C spec itself:
dev.w3.org/html5/spec/#status-of-this-document
Or the form at the bottom of every page on the WHATWG spec:
www.whatwg.org/specs/web-apps/current-work/multipage
Whichever way you enter it, it ends up in the same place.
- Sam Ruby
On 2/3/11, Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:
I was browsing Kangax's strict mode test result page (kangax.github.com/es5-compat-table/strict-mode ) and I noticed that he listed the recognition of a use strict directive of a event handler as a "non-standard" feature that he tests for.
javascript: void(document.body.setAttribute("onclick", "'use strict;'\nalert(this);")); alert(document.body.onclick);
To be sure, I checked the event handler section of the HTML5 spec (dev.w3.org/html5/spec/Overview.html#event-handler-attributes) and to my surprise I discovered that it specifies the creation of the handler function in a manner that, at first glance, seems to explicitly cause the presence of a use strict directive to be ignored. Essentially it seems to specify that event handlers specified using the event handler attribute are never executed in ECMAScript 5 strict mode. I don't know whether or not this was intentional, but it certainly seems wrong. The "strictness" of an ECMAScript function is an internal and local characteristic of the function. For a ECMAScript host to say that a use strict directive is ignored is really no different from saying that IfStatements or any other syntactically valid element of a FunctionBody will be ignored.
The HTML5 spec. get into this trouble because of the way it uses the abstract operation for creating function objects defined by section 13.2 of the ES5 specification
HTML 5 also specifies that the function's call
callback is called
when in fact that does not happen at all.
dev.w3.org/html5/spec/Overview.html#event-handler-content-attributes
"When an event handler's Function object is invoked, its call() callback must be invoked with one argument, set to the Event object of the event in question."
Instead, it should say something like when the event handler is invoked, the callback function is called.
And to add to that D3E should say (and it has been agreed upon) that
the this
value (cntext) for callbacks oef event handlers is set to
be the current target object.
Sprruy, I have only scanned and skimmed cause I'm too damn lazy :-D. But would there be any problems with doing things like that, Allen?
(oops, resend: typo in original to line for public-script-coord)
I was browsing Kangax's strict mode test result page (kangax.github.com/es5-compat-table/strict-mode ) and I noticed that he listed the recognition of a use strict directive of a event handler as a "non-standard" feature that he tests for. This spiked my curiosity as my recollection was the HTML5 event handler content attribute was specified to be text that is an ECMAScript FunctionBody. FunctionBody may contain a Directive Prologue that includes a use strict directive so, from an ECMAScript perspective, there shouldn't be anything non-standard about a strict mode event handler.
To be sure, I checked the event handler section of the HTML5 spec (dev.w3.org/html5/spec/Overview.html#event-handler-attributes) and to my surprise I discovered that it specifies the creation of the handler function in a manner that, at first glance, seems to explicitly cause the presence of a use strict directive to be ignored. Essentially it seems to specify that event handlers specified using the event handler attribute are never executed in ECMAScript 5 strict mode. I don't know whether or not this was intentional, but it certainly seems wrong. The "strictness" of an ECMAScript function is an internal and local characteristic of the function. For a ECMAScript host to say that a use strict directive is ignored is really no different from saying that IfStatements or any other syntactically valid element of a FunctionBody will be ignored.
The HTML5 spec. get into this trouble because of the way it uses the abstract operation for creating function objects defined by section 13.2 of the ES5 specification (www.ecma-international.org/publications/standards/Ecma-262.htm). In step 2 of the algorithm in HTML5 6.1.6.1 it unconditionally uses False as the Strict parameter to the ES5 13.2 algorithm. That might seem to exclude the function from strict mode, however that isn't actually the case. All the Strict parameter to 13.2 controls is whether or not "poison-pill" properties for 'caller' and 'arguments' are created for the function object. The semantics of strict mode are specified throughout the ES5 specification and are control by the actual lexical occurrence of a use strict directive. The Strict parameter to 13.2 does not alter this semantics.
The HTML5 spec. also contains another related bug. Step three says "If the previous steps failed to compile the script, then ..." where the "previous steps" pretty clearly references the use of ES5 13.2 in the immediately preceding step 2. However, there is nothing in ES5 13.2 that concerns the compilation of ECMAScript source text. Instead 13.2 expects to be passed an valid FunctionBody. That validation ("compilation") must occur somewhere else.
It appears to me that these problem are probably the result of the HTML5 algorithm being patterned after the wrong parts of the ES5 spec. The appropriate part of the ES5 spec. to use as a model is steps 8-11 of ES5 15.3.2.1. This is the definition of the Function constructor. These steps correctly take care of parsing the FunctionBody and handling any resulting syntax errors. It also calls 13.2 with a correct Strict parameter. Replacing HTML5 6.1.6.1 steps 2-3 with steps modeled after ES5 15.3.2.1 steps, 8, 9, and 11 (step 10 is not applicable) should correct these issues.
Finally, Kangax also lists as a "non-standard" feature the recognition of strict coder as the string argument to setTimeout. I couldn't find anything the HTML5 spec. that could be interpreted as excluding strict ECMAScript code in this context.
I included suggested language in bug www.w3.org/Bugs/Public/show_bug.cgi?id=11977
On Thu, 3 Feb 2011, Allen Wirfs-Brock wrote:
I included suggested language in bug www.w3.org/Bugs/Public/show_bug.cgi?id=11977
Cool, thanks. I'l follow up on the bug once I get to that one (I'm dealing with them first-come-first-served). Let me know if it's more urgent.
Regarding the call language, it would probably be best if it was described in terms of invoking the [[Call]] internal method of the handler's function object. However, that might be unnecessary if if the WebIDL ECMASCript binding makes it clear that the effect of invoking the call method of the Function interface is defined in terms of [[Call]].
We may have clashing spec. terminology here but I think the intent seems clear enough.
On 2/3/11, Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:
Regarding the call language, it would probably be best if it was described in terms of invoking the [[Call]] internal method of the handler's function object. However, that might be unnecessary if if the WebIDL ECMASCript binding makes it clear that the effect of invoking the call method of the Function interface is defined in terms of [[Call]].
But browsers don't call the call
property of the function object.
It's easy to test that: Create a function and give it an own "call" property on a function or by replacing Function.prototype.call.
function x() { alert(1); } x.call = function() { alert('call()'); };
We may have clashing spec. terminology here but I think the intent seems clear enough.
Uh uh.
It would seem to depend upon exactly how the WebIDL ECMAScript binding defines the meaning of: The Function interface represents a function in the scripting language being used. It is represented in IDL as follows:
[Callback=FunctionOnly, NoInterfaceObject] interface Function { any call(in any... arguments); }; The call(...) method is the object's callback.
However, I agree that it must be in terms of [[Call]] and not access to the 'call' property. what does "is the object's callback" actually mean?
Thanks for bringing this quirk to the surface. I remember being puzzled by the presence of this wording in HTML5 spec but never got a chance to do anything about it.
By "non-standard" I meant "not part of ECMA-262 standard" (not that it's not part of any other standard, such as HTML5... which — to be precise — is not yet a standard, as far as I understand). I changed the wording of the test to make it clearer — kangax.github.com/es5-compat-table/strict-mode
And while we're on this subject, I've been tinkering with compat. table of non-standard ES features across various (modern and not so modern) implementations — kangax.github.com/es5-compat-table/non-standard
Might be useful in assessing the risk of dropping/introducing certain extensions in future versions of ES.
The issue has been address in the HTML spec as www.w3.org/Bugs/Public/show_bug.cgi?id=11977
On 3/17/11, Juriy Zaytsev <kangax at gmail.com> wrote:
Thanks for bringing this quirk to the surface. I remember being puzzled by the presence of this wording in HTML5 spec but never got a chance to do anything about it.
By "non-standard" I meant "not part of ECMA-262 standard" (not that it's not part of any other standard, such as HTML5... which — to be precise — is not yet a standard, as far as I understand). I changed the wording of the test to make it clearer — kangax.github.com/es5-compat-table/strict-mode
HTML5 is modular and granular. Each part can have a status.
And while we're on this subject, I've been tinkering with compat. table of non-standard ES features across various (modern and not so modern) implementations — kangax.github.com/es5-compat-table/non-standard
The table indicates FF as the only browser supporting Array generics. Array generics are standard and work in Webki, Opera and Chrome .
I think you meant what I call static Array Generics, though I think I may have coined that term. That is, Array.push( a, "f" ); can be used in just Firefox.
// Array Generic var a = {}; Array.prototype.push.call( a, "f" ); a[0]; // "f"
// Static Array Generic var a = {}; Array.push( a, "f" ); a[0]; // "f"
Some IE versions have bugs with using Array.prototype built-ins
generically. For example, where obj
is anything other than an Array,
Array.prototype.push.call( obj );
won't update obj.length
.
On Thu, Mar 17, 2011 at 10:24 PM, Garrett Smith <dhtmlkitchen at gmail.com>wrote:
On 3/17/11, Juriy Zaytsev <kangax at gmail.com> wrote:
Thanks for bringing this quirk to the surface. I remember being puzzled by the presence of this wording in HTML5 spec but never got a chance to do anything about it.
By "non-standard" I meant "not part of ECMA-262 standard" (not that it's not part of any other standard, such as HTML5... which — to be precise — is not yet a standard, as far as I understand). I changed the wording of the test to make it clearer — kangax.github.com/es5-compat-table/strict-mode
HTML5 is modular and granular. Each part can have a status.
Ok.
And while we're on this subject, I've been tinkering with compat. table of non-standard ES features across various (modern and not so modern) implementations — kangax.github.com/es5-compat-table/non-standard
The table indicates FF as the only browser supporting Array generics. Array generics are standard and work in Webki, Opera and Chrome .
I think you meant what I call static Array Generics, though I think I may have coined that term.
Yep, that's what I meant. I actually thought that "Array Generics" are what you call "Static Array Generics". MDN docs are vague — developer.mozilla.org/en/new_in_javascript_1.6#Array_and_String_generics
That is, Array.push( a, "f" ); can be used in just Firefox.
Yeah. Well, any Gecko-based implementation (that implements JS 1.6), to be more precise ;)
// Array Generic var a = {}; Array.prototype.push.call( a, "f" ); a[0]; // "f"
// Static Array Generic var a = {}; Array.push( a, "f" ); a[0]; // "f"
The table lists non-standard extensions only, which Array.*
and
String.*
are, so those are the methods presence of which I'm testing.
[...]
I need to show code that's associated with each test, to avoid this ambiguity.
I was browsing Kangax's strict mode test result page (kangax.github.com/es5-compat-table/strict-mode ) and I noticed that he listed the recognition of a use strict directive of a event handler as a "non-standard" feature that he tests for. This spiked my curiosity as my recollection was the HTML5 event handler content attribute was specified to be text that is an ECMAScript FunctionBody. FunctionBody may contain a Directive Prologue that includes a use strict directive so, from an ECMAScript perspective, there shouldn't be anything non-standard about a strict mode event handler.
To be sure, I checked the event handler section of the HTML5 spec (dev.w3.org/html5/spec/Overview.html#event-handler-attributes) and to my surprise I discovered that it specifies the creation of the handler function in a manner that, at first glance, seems to explicitly cause the presence of a use strict directive to be ignored. Essentially it seems to specify that event handlers specified using the event handler attribute are never executed in ECMAScript 5 strict mode. I don't know whether or not this was intentional, but it certainly seems wrong. The "strictness" of an ECMAScript function is an internal and local characteristic of the function. For a ECMAScript host to say that a use strict directive is ignored is really no different from saying that IfStatements or any other syntactically valid element of a FunctionBody will be ignored.
The HTML5 spec. get into this trouble because of the way it uses the abstract operation for creating function objects defined by section 13.2 of the ES5 specification (www.ecma-international.org/publications/standards/Ecma-262.htm). In step 2 of the algorithm in HTML5 6.1.6.1 it unconditionally uses False as the Strict parameter to the ES5 13.2 algorithm. That might seem to exclude the function from strict mode, however that isn't actually the case. All the Strict parameter to 13.2 controls is whether or not "poison-pill" properties for 'caller' and 'arguments' are created for the function object. The semantics of strict mode are specified throughout the ES5 specification and are control by the actual lexical occurrence of a use strict directive. The Strict parameter to 13.2 does not alter this semantics.
The HTML5 spec. also contains another related bug. Step three says "If the previous steps failed to compile the script, then ..." where the "previous steps" pretty clearly references the use of ES5 13.2 in the immediately preceding step 2. However, there is nothing in ES5 13.2 that concerns the compilation of ECMAScript source text. Instead 13.2 expects to be passed an valid FunctionBody. That validation ("compilation") must occur somewhere else.
It appears to me that these problem are probably the result of the HTML5 algorithm being patterned after the wrong parts of the ES5 spec. The appropriate part of the ES5 spec. to use as a model is steps 8-11 of ES5 15.3.2.1. This is the definition of the Function constructor. These steps correctly take care of parsing the FunctionBody and handling any resulting syntax errors. It also calls 13.2 with a correct Strict parameter. Replacing HTML5 6.1.6.1 steps 2-3 with steps modeled after ES5 15.3.2.1 steps, 8, 9, and 11 (step 10 is not applicable) should correct these issues.
Finally, Kangax also lists as a "non-standard" feature the recognition of strict coder as the string argument to setTimeout. I couldn't find anything the HTML5 spec. that could be interpreted as excluding strict ECMAScript code in this context.