with and scope chain augmentation

# Mike Wilson (16 years ago)

Watching the "Changes to JavaScript, Part 1: EcmaScript 5" www.youtube.com/watch?v=Kq4FpMe6cRs I came to think of augmented scope chains for DOM0 event handlers.

I sympathize with the slide "Problem: Can't emulate platform objects" (which is addressed by e g getter/setter properties), but the removal of with(){} in ES5 strict mode would mean it gets harder to emulate the scope chain augmentation done by browsers?

Best Mike Wilson

# Jason Orendorff (16 years ago)

On Mon, Jun 22, 2009 at 2:43 PM, Mike Wilson<mikewse at hotmail.com> wrote:

I sympathize with the slide "Problem: Can't emulate platform objects" (which is addressed by e g getter/setter properties), but the removal of with(){} in ES5 strict mode would mean it gets harder to emulate the scope chain augmentation done by browsers?

Actually, I think we do this by wrapping event handlers in something like

(function (event) { ... })

so "with" is not involved. In fact, surely everyone does something like this, as event handlers have to support stuff like "return false;".

# Juriy Zaytsev (16 years ago)

On Jun 23, 2009, at 5:18 PM, Jason Orendorff wrote:

On Mon, Jun 22, 2009 at 2:43 PM, Mike Wilson<mikewse at hotmail.com>
wrote:

I sympathize with the slide "Problem: Can't emulate platform objects" (which is addressed by e g getter/setter properties), but the removal of with(){} in ES5 strict mode would mean it gets harder to emulate the scope chain augmentation done by browsers?

Actually, I think we do this by wrapping event handlers in something
like

(function (event) { ... })

so "with" is not involved. In fact, surely everyone does something like this, as event handlers have to support stuff like "return false;".

Last time I checked, most of the browsers actually still were
augmenting scope
of event handlers as if by using "with". There's
been some research on this subject first by Cornford, then by Garrett
Smith. Most of it is documented at <jibbering.com/faq/names/event_handler.html

In a nutshell, if one wanted to create a function object out of a
string value of intrinsic event attribute, something along these lines
would need to be used (for a more or less complete emulation):

function eventHandlerFromAttr(element, attrValue){ return function(e){ with(document){ with(element){ var fn = eval('(function(event){' + attrValue + '})'); return fn.call(element, e); } } } }

[...]

# Jason Orendorff (16 years ago)

On Tue, Jun 23, 2009 at 5:13 PM, Juriy Zaytsev<kangax at gmail.com> wrote:

Last time I checked, most of the browsers actually still were augmenting scope of event handlers as if by using "with". There's been some research on this subject first by Cornford, then by Garrett Smith. Most of it is documented at jibbering.com/faq/names/event_handler.html

Eeuuurgh. In that case, what David-Sarah said.

# Mike Wilson (16 years ago)

Jason Orendorff wrote:

Eeuuurgh. In that case, what David-Sarah said.

What did he say?

Best Mike

# Brendan Eich (16 years ago)

On Jun 24, 2009, at 11:38 AM, Mike Wilson wrote:

Jason Orendorff wrote:

Eeuuurgh. In that case, what David-Sarah said.

What did he say?

He said "don't do that", to paraphrase. Full quote:

"The 'with' can be in non-strict code, which is perfectly adequate for implementing a backward-compatible misfeature (the peculiar scope chain of a DOM0 event handler)."

The nested DOM object scopes for event handlers was something I did to
allow brevity in inline event handler code. On balance it was a
mistake, but it was so popular that the VXML spec actually goes nuts
and reifies nested XML tags as objects on the scope chain for its ES
scripting model!

This makes for a confusing tower of scopes. You can't always see the
bindings, since an XML or HTML doc can be large. With the DOM, pieces
of the namespace can be bound implicitly or in obscure ways. And
"unobtrusive JavaScript" favors no event handler code bodies at all.

So yeah: "don't do that" (don't use strict mode for any with hacks
that emulate bad old web APIs such as event handler scope).

Or to shorten it further a la jorendorff: Eeuuurgh.

# Mike Wilson (16 years ago)

Brendan Eich wrote:

On Jun 24, 2009, at 11:38 AM, Mike Wilson wrote:

Jason Orendorff wrote:

Eeuuurgh. In that case, what David-Sarah said.

What did he say?

He said "don't do that", to paraphrase. Full quote:

"The 'with' can be in non-strict code, which is perfectly adequate for implementing a backward-compatible misfeature (the peculiar scope chain of a DOM0 event handler)."

Thanks. I seem to have missed this reply. Where did it appear?

The nested DOM object scopes for event handlers was something I did to allow brevity in inline event handler code. On balance it was a mistake, but it was so popular that the VXML spec actually goes nuts and reifies nested XML tags as objects on the scope chain for its ES scripting model!

:-) I'm sure many agree it is a confusing feature that is best not depended upon, but well the topic here was emulating the browser in pure JS. Anyway, if |with| will always be available in non-strict code, well, I guess it's no problem.

BTW, the DOM0 scope chain augmentation is now finally being specified for all time, as of HTML5: dev.w3.org/html5/spec/Overview.html#event-handler-attributes

Best Mike

# Garrett Smith (16 years ago)

On Wed, Jun 24, 2009 at 12:02 PM, Brendan Eich<brendan at mozilla.com> wrote:

On Jun 24, 2009, at 11:38 AM, Mike Wilson wrote:

Jason Orendorff wrote:

Eeuuurgh.  In that case, what David-Sarah said.

What did he say?

He said "don't do that", to paraphrase. Full quote:

"The 'with' can be in non-strict code, which is perfectly adequate for implementing a backward-compatible misfeature (the peculiar scope chain of a DOM0 event handler)."

Isn't it funny how something that seems small can have such a large effect? This misfeature doesn't seem to have a good role or use cases. It seems a bit like the callable collections that MSIE started.

If HTML 5 author(s) only had the hindsight to see the problems with their inventions. I don't expect much at this point.

The nested DOM object scopes for event handlers was something I did to allow brevity in inline event handler code. On balance it was a mistake, but it was so popular that the VXML spec actually goes nuts and reifies nested XML tags as objects on the scope chain for its ES scripting model!

Chrome actually shows the source code for the onclick using "with".

Taking that document linked, javascript:document.write("<xmp onclick="foo()">",(Function.prototype.toString.call(document.getElementsByTagName("xmp")[0].onclick),"</xmp>");

results:

function onclick(evt) { with (this.ownerDocument ? this.ownerDocument : {}) { with (this.form ? this.form : {}) { with (this) { return (function(evt){ self.alert([window.tagName, document.tagName]) }).call(this, evt); } } } }

This makes for a confusing tower of scopes. You can't always see the bindings, since an XML or HTML doc can be large. With the DOM, pieces of the namespace can be bound implicitly or in obscure ways. And "unobtrusive JavaScript" favors no event handler code bodies at all.

So yeah: "don't do that" (don't use strict mode for any with hacks that emulate bad old web APIs such as event handler scope).

Not using bad old web APIs is also an alternative.

Garrett

# Garrett Smith (16 years ago)

On Wed, Jun 24, 2009 at 2:42 PM, Garrett Smith<dhtmlkitchen at gmail.com> wrote:

On Wed, Jun 24, 2009 at 12:02 PM, Brendan Eich<brendan at mozilla.com> wrote:

On Jun 24, 2009, at 11:38 AM, Mike Wilson wrote:

Jason Orendorff wrote:

Eeuuurgh.  In that case, what David-Sarah said.

What did he say?

He said "don't do that", to paraphrase. Full quote:

"The 'with' can be in non-strict code, which is perfectly adequate for implementing a backward-compatible misfeature (the peculiar scope chain of a DOM0 event handler)."

Isn't it funny how something that seems small can have such a large effect? This misfeature doesn't seem to have a good role or use cases. It seems a bit like the callable collections that MSIE started.

If HTML 5 author(s) only had the hindsight to see the problems with their inventions. I don't expect much at this point.

The nested DOM object scopes for event handlers was something I did to allow brevity in inline event handler code. On balance it was a mistake, but it was so popular that the VXML spec actually goes nuts and reifies nested XML tags as objects on the scope chain for its ES scripting model!

Chrome actually shows the source code for the onclick using "with".

Taking that document linked,

[snip]

No, that was the wrong code. Example bookmarklet: javascript:document.write("<xmp>",

Function.prototype.toString.call(document.getElementsByTagName("input")[1].onclick),"</xmp>");

Produces in chrome:

function onclick(evt) { with (this.ownerDocument ? this.ownerDocument : {}) { with (this.form ? this.form : {}) { with (this) { return (function(evt){ self.alert([title, files, focus == window.focus]); var e = event||window.event; if(e && e.preventDefault) e.preventDefault();e.returnValue = false; }).call(this, evt); } } } }

Garrett

# Brendan Eich (16 years ago)

On Jun 24, 2009, at 2:42 PM, Garrett Smith wrote:

Isn't it funny how something that seems small can have such a large effect? This misfeature doesn't seem to have a good role or use cases. It seems a bit like the callable collections that MSIE started.

Agreed, at a gut-feel (churning, I mean) level.

If HTML 5 author(s) only had the hindsight to see the problems with their inventions. I don't expect much at this point.

Careful with pronouns -- HTML 5 spec writers did not create nested
scopes for event handlers, I did. They are just paving this particular
cowpath, droppings and all. :-)

# Garrett Smith (16 years ago)

On Wed, Jun 24, 2009 at 2:57 PM, Brendan Eich<brendan at mozilla.com> wrote:

On Jun 24, 2009, at 2:42 PM, Garrett Smith wrote:

Isn't it funny how something that seems small can have such a large effect? This misfeature doesn't seem to have a good role or use cases. It seems a bit like the callable collections that MSIE started.

Agreed, at a gut-feel (churning, I mean) level.

If HTML 5 author(s) only had the hindsight to see the problems with their inventions. I don't expect much at this point.

Careful with pronouns -- HTML 5 spec writers did not create nested scopes for event handlers, I did. They are just paving this particular cowpath, droppings and all. :-)

Of course, obviously the feature came long before HTML 5. I'm frustrated by what I see happening with HTML 5 in general. At a gut level, you know, some of the other things in HTML 5, new things, feels the same. To me.

Garrett

# David-Sarah Hopwood (16 years ago)

Juriy Zaytsev wrote:

In a nutshell, if one wanted to create a function object out of a string value of intrinsic event attribute, something along these lines would need to be used (for a more or less complete emulation):

function eventHandlerFromAttr(element, attrValue){ return function(e){ with(document){ with(element){ var fn = eval('(function(event){' + attrValue + '})');

This is eval'ing in the current lexical context. You want a global eval. In ES5:

      var evil = eval;
      var fn = evil('(function(event){' + attrValue + '})');