Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-08-24 Thread Ian Hickson
On Fri, 30 Jul 2010, Jonas Sicking wrote:
> >
> > Before changing something this substantial, I'd like to have implementor
> > feedback regarding what the best way to address this is [...]
> 
> Given how often this comes up, I think it's worth addressing this.

Based on the discussions, it really doesn't seem like this is an area 
where how to proceed is especially clear. I would like to recommend that 
browser vendors experiment in this space and report back with concrete 
experience and suggestions on how to move forward on this.

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-08-05 Thread Garrett Smith
On 8/5/10, Garrett Smith  wrote:
> On 8/5/10, Oliver Hunt  wrote:
>>
>> On Aug 4, 2010, at 6:26 PM, Garrett Smith wrote:
>>
>>> On 8/4/10, Oliver Hunt  wrote:

 On Aug 4, 2010, at 3:32 PM, Garrett Smith wrote:

> On 8/4/10, Garrett Smith  wrote:
>
> [...]

[...]

>
> I'm not proposing ES remove the text "whether or not the xxx
> method..." if that's what you meant. Rather, I'm proposing that
> NodeList be specified by the DOM ECMAScript bindings to be a native
> ECMAScript object. That way, it will not be possible for any ES method
> to discriminate against a host object.
>
Correction:
 "...to discriminate against those objects."

(ES methods ([].concat, et al) would still be able to discriminate
against any other host object that is not implemented as a native
object).

[...]

Garrett


Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-08-05 Thread Garrett Smith
On 8/5/10, Oliver Hunt  wrote:
>
> On Aug 4, 2010, at 6:26 PM, Garrett Smith wrote:
>
>> On 8/4/10, Oliver Hunt  wrote:
>>>
>>> On Aug 4, 2010, at 3:32 PM, Garrett Smith wrote:
>>>
 On 8/4/10, Garrett Smith  wrote:

 [...]
> "submitButton" in form.elements
>
> Existing implementations vary on when they use catchalls. I'd like to
> see standardization for this behavior and codification so that
> implementations behave similarly -- either use a catchall for a
> particular type of collection or use a native object. If a catchall is

 Native object either way, but either with a new ES catchall behavior
 or with a native ES object, as specified today.

 Garrett
>>> As a question, if the node lists were implemented as catchalls, how would
>>> the behaviour differ from current NodeLists?
>>


I'll tell you, I took another peek at WebIDL and see now "getter".

The DOM, web IDL, etc should not be specifying how catchalls work;
that's an ECMAScript language feature and so it is the job for the ES
committee.

In particular, WebIDL should not use terminology "getter" because that
may be confused with the ECMAScript language construct of the same
name.

>
> So your only desire is to have NodeLists lose the host object issues?
>

That isn't very precise; I can't acknowledge that as being correct.

In this thread, I want:
 * NodeList spec'd as native ES object (DOM)
 * Static Array generics (ES)
 * Consolidate collections (DOM) to:
  -  allow [[Get]] to return undefined (not require null)
  -  use more specific terminology than "integer index" (unsigned long)
  - resolve "has" checks for collections (DOM and ES)

* Array from a NodeList can be guaranteed with [].prototype.slice.call
if NodeList is specified as a native ES object in a DOM specification
(perhaps WebIDL, as that effort seems to be continuing).

* Array Generics, as JavaScriptTM has, for a while, had Array.slice,
et al to simplify from Array.prototype.slice.call. This is something
that should be done by ES committee.

Regarding indexed collections in general, the behavior of an indexed
collection should be consolidated where possible.

"has" checks should work as expected and should not fall apart as
shown in the article.

  var form = document.forms[0];
  "0" in form; // false in Gecko
  Array.prototype.indexOf.call(form, form[0]);

Firefox: -1
Safari: 0

[...]

I have many other desires, none of them having anything to do with
this thread or programming at all.

>>  [].slice.call( ho )
>
> It sounds like all you want is for the array (and other similar) methods to
> work on NodeLists, etc but currently some implementations make use of the
> ES5 text saying the they don't need to support host objects, correct?
>
> An ES definition for the type would merely be for the purpose of removing
> the ability for an implementation to make use of the "we don't need to
> support operation X on host objects"?
>

Sorry, but I didn't understand what you meant by "the type".

I'm not proposing ES remove the text "whether or not the xxx
method..." if that's what you meant. Rather, I'm proposing that
NodeList be specified by the DOM ECMAScript bindings to be a native
ECMAScript object. That way, it will not be possible for any ES method
to discriminate against a host object.

Does that answer your question? Are there any criticism or concerns
with that proposal?

Garrett


Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-08-05 Thread Oliver Hunt

On Aug 4, 2010, at 6:26 PM, Garrett Smith wrote:

> On 8/4/10, Oliver Hunt  wrote:
>> 
>> On Aug 4, 2010, at 3:32 PM, Garrett Smith wrote:
>> 
>>> On 8/4/10, Garrett Smith  wrote:
>>> 
>>> [...]
 "submitButton" in form.elements
 
 Existing implementations vary on when they use catchalls. I'd like to
 see standardization for this behavior and codification so that
 implementations behave similarly -- either use a catchall for a
 particular type of collection or use a native object. If a catchall is
>>> 
>>> Native object either way, but either with a new ES catchall behavior
>>> or with a native ES object, as specified today.
>>> 
>>> Garrett
>> As a question, if the node lists were implemented as catchalls, how would
>> the behaviour differ from current NodeLists?
> 

So your only desire is to have NodeLists lose the host object issues?

> 
> The only change I can see
>> would be the loss of the host object exceptions in the ES spec, but that
>> just puts you in the position of having semantics that match the current
>> host object behavior in those implementations that already allow array
>> functions to operate on host objects.
>> 
> 
> The semantics for native object are defined by ECMA-262.
> 
> If collection is required to be implemented as a native ECMAScript
> object, then it would still be considered a host as a native object,
> would be indistinguishable from other native objects, both internally
> and externally, and so would not be subject to ES "whether or not the
> xxx method may be applied to a host object" loopholes. Thus,
> 
>  [].slice.call( ho )

It sounds like all you want is for the array (and other similar) methods to 
work on NodeLists, etc but currently some implementations make use of the ES5 
text saying the they don't need to support host objects, correct?

An ES definition for the type would merely be for the purpose of removing the 
ability for an implementation to make use of the "we don't need to support 
operation X on host objects"?

--Oliver




Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-08-04 Thread Garrett Smith
On 8/4/10, Oliver Hunt  wrote:
>
> On Aug 4, 2010, at 3:32 PM, Garrett Smith wrote:
>
>> On 8/4/10, Garrett Smith  wrote:
>>
>> [...]
>>>  "submitButton" in form.elements
>>>
>>> Existing implementations vary on when they use catchalls. I'd like to
>>> see standardization for this behavior and codification so that
>>> implementations behave similarly -- either use a catchall for a
>>> particular type of collection or use a native object. If a catchall is
>>
>> Native object either way, but either with a new ES catchall behavior
>> or with a native ES object, as specified today.
>>
>> Garrett
> As a question, if the node lists were implemented as catchalls, how would
> the behaviour differ from current NodeLists?

The externally observable behavior wouldn't have to change.

[[HasProperty]] checks (using `in`) with catchalls have sometimes
unexpected results, so I wouldn't want to see that kind of change.

Try some of the tests here:


The article needs a little updating but the examples I'm referring to
demonstrate disparity with `in` operator:
FF3.6
  'test' in this.form true
  'test' in this.form.elements false

A catchall should possible for a result of `null` for indexed access.
This probably isn't adding any value over returning `undefined`
because many implementations will result `undefined` for property
access and most programs won't care one way or the other (and if they
do, they're not interoperable with existing browsers).

I want the specs to codify behavior of existing various collections
and to do that, I want to figure out where and why catchall is used.

I can't answer as to why Gecko uses a catchall; perhaps some of the
Mozilla devs on this list can give further info. Perhaps there is
behavior for "past names map" that requires catchall (I don't think
anybody is a big fan of past names map).

The only change I can see
> would be the loss of the host object exceptions in the ES spec, but that
> just puts you in the position of having semantics that match the current
> host object behavior in those implementations that already allow array
> functions to operate on host objects.
>

The semantics for native object are defined by ECMA-262.

If collection is required to be implemented as a native ECMAScript
object, then it would still be considered a host as a native object,
would be indistinguishable from other native objects, both internally
and externally, and so would not be subject to ES "whether or not the
xxx method may be applied to a host object" loopholes. Thus,

  [].slice.call( ho )

could be expected work. It would have to work because
Array.prototype.slice would have no way of determining that `ho` is a
host object; it would simply see that it is passed in a native object.
It would not be able to differentiate or discriminate between that and
a user-defined object.

All that would be necessary to make that happen would be to state that
the collection -- NodeList, for example -- is implemented as a native
ECMAScript object. That alone would be enough to guarantee that any
native operation would have results that could be expected.

Again, from ES point of view, there are two types of host objects:
1) host object implemented as a native object
2) host object implemented with other semantics

Garrett


Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-08-04 Thread Oliver Hunt

On Aug 4, 2010, at 3:32 PM, Garrett Smith wrote:

> On 8/4/10, Garrett Smith  wrote:
> 
> [...]
>>  "submitButton" in form.elements
>> 
>> Existing implementations vary on when they use catchalls. I'd like to
>> see standardization for this behavior and codification so that
>> implementations behave similarly -- either use a catchall for a
>> particular type of collection or use a native object. If a catchall is
> 
> Native object either way, but either with a new ES catchall behavior
> or with a native ES object, as specified today.
> 
> Garrett
As a question, if the node lists were implemented as catchalls, how would the 
behaviour differ from current NodeLists?  The only change I can see would be 
the loss of the host object exceptions in the ES spec, but that just puts you 
in the position of having semantics that match the current host object behavior 
in those implementations that already allow array functions to operate on host 
objects.

--Oliver



Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-08-04 Thread Garrett Smith
On 8/4/10, Garrett Smith  wrote:

[...]
>   "submitButton" in form.elements
>
> Existing implementations vary on when they use catchalls. I'd like to
> see standardization for this behavior and codification so that
> implementations behave similarly -- either use a catchall for a
> particular type of collection or use a native object. If a catchall is

Native object either way, but either with a new ES catchall behavior
or with a native ES object, as specified today.

Garrett


Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-08-04 Thread Garrett Smith
On 8/4/10, Jonas Sicking  wrote:
> On Wed, Aug 4, 2010 at 11:10 AM, Alex Russell 
> wrote:
>> Sorry for the lagged response,
>>
>> On Fri, Jul 30, 2010 at 2:56 PM, Oliver Hunt  wrote:
>>>
>>> On Jul 30, 2010, at 2:46 PM, Alex Russell wrote:
>>>
 On Fri, Jul 30, 2010 at 4:18 AM, Jonas Sicking  wrote:
> On Thu, Jul 29, 2010 at 5:45 PM, Ian Hickson  wrote:
>>
>> The e-mails quoted below consist of the salient points of this thread:
>>
>> On Fri, 23 Apr 2010, David Bruant wrote:
>>>
>>> Make that HTMLCollection (and all HTML*Collection, as a consequence
>>> of
>>> inheritence of HTMLCollection) inherit from the ECMAScript Array
>>> prototype. This way, it will make available all Array extra methods
>>> (forEach, map, filter...) added in ECMAScript5 (and next versions
>>> which
>>> should go in the same direction).
>>>
>>> As far as I know, adding this won't break any existing code. The
>>> semantics of a Collection and the way it is used is very close from
>>> ECMAScript Arrays. I don't think that the notion of "live object" and
>>> ECMAScript Array are incompatible either. Once again, I am talking
>>> about
>>> ECMAScript binding. I have no intention to touch the HTMLCollection
>>> interface or other languages bindings.
>>
>> On Sun, 25 Apr 2010, J Z wrote:
>>>
>>> If HTMLCollection was inheriting from Array, and methods like
>>> `forEach`,
>>> `map`, etc. were to operate on a live object, there would definitely
>>> be
>>> undesired consequences. We can see this in, say, Firefox (which
>>> allows to
>>> set [[Prototype]] of `HTMLCollection` to `Array.prototype`):
>>>
>>> HTMLCollection.prototype.__proto__ = Array.prototype;
>>>
>>> document.getElementsByTagName('div').forEach(function(el) {
>>>   el.parentNode.removeChild(el); // doesn't work as expected
>>> });
>>>
>>> // turning live collection into static array fixes this
>>> Array.slice(document.getElementsByTagName('div')).forEach(function(el)
>>> {
>>>   el.parentNode.removeChild(el);
>>> });
>>
>> On Sat, 24 Apr 2010, David Bruant wrote:
>>>
>>> I think I can take your point as a "pro" more than a "con", because
>>> in
>>> ES5, right before the definition of each array extra method, a
>>> paragraph
>>> like the following can be found :
>>>
>>> "The range of elements processed by forEach is set before the first
>>> call
>>> to callbackfn. Elements which are appended to the array after the
>>> call
>>> to forEach begins will not be visited by callbackfn. If existing
>>> elements of the array are changed, their value as passed to callback
>>> will be the value at the time forEach visits them; elements that are
>>> deleted after the call to forEach begins and before being visited are
>>> not visited."
>>>
>>> This point is confirmed by every algorithm where the length is
>>> "saved"
>>> once for all before the loop and not got from the .length property
>>> each
>>> time.
>>
>> On Mon, 26 Apr 2010, Erik Arvidsson wrote:
>>> On Sun, Apr 25, 2010 at 01:07, David Bruant wrote:
 Le 25/04/2010 00:39, J Z a écrit :
>
> I have thought a lot about weirdnesses that people could think
> about
> like trying to assign a value to the HTMLCollection (divs[14] =
> myOtherDiv), but once again, it wouldn't be more allowed than it
> currently is (I have no idea of what happens today, but if an error
> is thrown in a for-loop, it should throw an error as well in a call
> within a forEach).

 How would destructive methods like `push` or `sort` behave? Would
 `document.body.childNodes.push(document.createTextNode('foo'))`
 append
 text node to a body element? Or would it be a noop?

 That is actually a very good point. It think that the behavior
 should
 be exactly the same as "an equivalent without array methods". (this
 point of my proposal would need to be made completly explicit for
 each
 method)
>>>
>>> One way to solve this could be to split Array into two interfaces.
>>> One
>>> to be used with immutable array like objects and one to use to mutate
>>> objects. Then we could apply the immutable array like interface to
>>> NodeList and its related interfaces. The benefit of doing that is
>>> that
>>> NodeList.prototype.push would be undefined instead of failing when
>>> called.
>>
>> On Mon, 26 Apr 2010, David Flanagan wrote:
>>>

[snip]

To all, please trim quotes to a minimum - thanks.

>>> What would you expect a mutable NodeList to be?
>>
>> A good example would be the result of document.querySelectorAll().
>
> Why couldn't querySelectorAll return a normal Array?
>

It could ha

Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-08-04 Thread Maciej Stachowiak

On Aug 4, 2010, at 2:40 PM, Jonas Sicking wrote:

> On Wed, Aug 4, 2010 at 11:10 AM, Alex Russell  wrote:
>> Sorry for the lagged response,
>> 
>> On Fri, Jul 30, 2010 at 2:56 PM, Oliver Hunt  wrote:
>>> 
>>> On Jul 30, 2010, at 2:46 PM, Alex Russell wrote:
>>> 
 Wait...what? Shouldn't some sort of NodeList be mutable? And shouldn't
 JS support immutable Arrays? We need to fix both of these APIs, and we
 keep heaping back-pressure on JavaScript's Array without any
 reasonable resolution because we're not exploring how to make Array
 subtypes work as we want them to for all the use cases (like this)
 that we care to express.
>>> 
>>> What would you expect a mutable NodeList to be?
>> 
>> A good example would be the result of document.querySelectorAll().
> 
> Why couldn't querySelectorAll return a normal Array?

I think in principle it could, but it might be too much compat risk to do now.

Returning a fully mutable array would also remove the opportunities to cache 
and reuse the return value, since each result would really need to be distinct 
if they are mutable.

Regards,
Maciej


Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-08-04 Thread Jonas Sicking
On Wed, Aug 4, 2010 at 11:10 AM, Alex Russell  wrote:
> Sorry for the lagged response,
>
> On Fri, Jul 30, 2010 at 2:56 PM, Oliver Hunt  wrote:
>>
>> On Jul 30, 2010, at 2:46 PM, Alex Russell wrote:
>>
>>> On Fri, Jul 30, 2010 at 4:18 AM, Jonas Sicking  wrote:
 On Thu, Jul 29, 2010 at 5:45 PM, Ian Hickson  wrote:
>
> The e-mails quoted below consist of the salient points of this thread:
>
> On Fri, 23 Apr 2010, David Bruant wrote:
>>
>> Make that HTMLCollection (and all HTML*Collection, as a consequence of
>> inheritence of HTMLCollection) inherit from the ECMAScript Array
>> prototype. This way, it will make available all Array extra methods
>> (forEach, map, filter...) added in ECMAScript5 (and next versions which
>> should go in the same direction).
>>
>> As far as I know, adding this won't break any existing code. The
>> semantics of a Collection and the way it is used is very close from
>> ECMAScript Arrays. I don't think that the notion of "live object" and
>> ECMAScript Array are incompatible either. Once again, I am talking about
>> ECMAScript binding. I have no intention to touch the HTMLCollection
>> interface or other languages bindings.
>
> On Sun, 25 Apr 2010, J Z wrote:
>>
>> If HTMLCollection was inheriting from Array, and methods like `forEach`,
>> `map`, etc. were to operate on a live object, there would definitely be
>> undesired consequences. We can see this in, say, Firefox (which allows to
>> set [[Prototype]] of `HTMLCollection` to `Array.prototype`):
>>
>> HTMLCollection.prototype.__proto__ = Array.prototype;
>>
>> document.getElementsByTagName('div').forEach(function(el) {
>>   el.parentNode.removeChild(el); // doesn't work as expected
>> });
>>
>> // turning live collection into static array fixes this
>> Array.slice(document.getElementsByTagName('div')).forEach(function(el) {
>>   el.parentNode.removeChild(el);
>> });
>
> On Sat, 24 Apr 2010, David Bruant wrote:
>>
>> I think I can take your point as a "pro" more than a "con", because in
>> ES5, right before the definition of each array extra method, a paragraph
>> like the following can be found :
>>
>> "The range of elements processed by forEach is set before the first call
>> to callbackfn. Elements which are appended to the array after the call
>> to forEach begins will not be visited by callbackfn. If existing
>> elements of the array are changed, their value as passed to callback
>> will be the value at the time forEach visits them; elements that are
>> deleted after the call to forEach begins and before being visited are
>> not visited."
>>
>> This point is confirmed by every algorithm where the length is "saved"
>> once for all before the loop and not got from the .length property each
>> time.
>
> On Mon, 26 Apr 2010, Erik Arvidsson wrote:
>> On Sun, Apr 25, 2010 at 01:07, David Bruant wrote:
>>> Le 25/04/2010 00:39, J Z a écrit :

 I have thought a lot about weirdnesses that people could think about
 like trying to assign a value to the HTMLCollection (divs[14] =
 myOtherDiv), but once again, it wouldn't be more allowed than it
 currently is (I have no idea of what happens today, but if an error
 is thrown in a for-loop, it should throw an error as well in a call
 within a forEach).
>>>
>>> How would destructive methods like `push` or `sort` behave? Would
>>> `document.body.childNodes.push(document.createTextNode('foo'))` append
>>> text node to a body element? Or would it be a noop?
>>>
>>> That is actually a very good point. It think that the behavior should
>>> be exactly the same as "an equivalent without array methods". (this
>>> point of my proposal would need to be made completly explicit for each
>>> method)
>>
>> One way to solve this could be to split Array into two interfaces. One
>> to be used with immutable array like objects and one to use to mutate
>> objects. Then we could apply the immutable array like interface to
>> NodeList and its related interfaces. The benefit of doing that is that
>> NodeList.prototype.push would be undefined instead of failing when
>> called.
>
> On Mon, 26 Apr 2010, David Flanagan wrote:
>>
>> Rather that trying to make DOM collections feel like arrays, how about
>> just giving them a toArray() method?  This makes it clear that a
>> collection is not an array, but clearly defines a way to obtain an
>> array.  Clever implementors might even be able to optimize common
>> uses-cases using some kind of copy-on-write strategy so that toArray()
>> doesn't involve memory allocation and copying.
>>
>> Of course, trying to teach programmers when they ought to call toArray()
>> and when it is not

Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-08-04 Thread Alex Russell
Sorry for the lagged response,

On Fri, Jul 30, 2010 at 2:56 PM, Oliver Hunt  wrote:
>
> On Jul 30, 2010, at 2:46 PM, Alex Russell wrote:
>
>> On Fri, Jul 30, 2010 at 4:18 AM, Jonas Sicking  wrote:
>>> On Thu, Jul 29, 2010 at 5:45 PM, Ian Hickson  wrote:

 The e-mails quoted below consist of the salient points of this thread:

 On Fri, 23 Apr 2010, David Bruant wrote:
>
> Make that HTMLCollection (and all HTML*Collection, as a consequence of
> inheritence of HTMLCollection) inherit from the ECMAScript Array
> prototype. This way, it will make available all Array extra methods
> (forEach, map, filter...) added in ECMAScript5 (and next versions which
> should go in the same direction).
>
> As far as I know, adding this won't break any existing code. The
> semantics of a Collection and the way it is used is very close from
> ECMAScript Arrays. I don't think that the notion of "live object" and
> ECMAScript Array are incompatible either. Once again, I am talking about
> ECMAScript binding. I have no intention to touch the HTMLCollection
> interface or other languages bindings.

 On Sun, 25 Apr 2010, J Z wrote:
>
> If HTMLCollection was inheriting from Array, and methods like `forEach`,
> `map`, etc. were to operate on a live object, there would definitely be
> undesired consequences. We can see this in, say, Firefox (which allows to
> set [[Prototype]] of `HTMLCollection` to `Array.prototype`):
>
> HTMLCollection.prototype.__proto__ = Array.prototype;
>
> document.getElementsByTagName('div').forEach(function(el) {
>   el.parentNode.removeChild(el); // doesn't work as expected
> });
>
> // turning live collection into static array fixes this
> Array.slice(document.getElementsByTagName('div')).forEach(function(el) {
>   el.parentNode.removeChild(el);
> });

 On Sat, 24 Apr 2010, David Bruant wrote:
>
> I think I can take your point as a "pro" more than a "con", because in
> ES5, right before the definition of each array extra method, a paragraph
> like the following can be found :
>
> "The range of elements processed by forEach is set before the first call
> to callbackfn. Elements which are appended to the array after the call
> to forEach begins will not be visited by callbackfn. If existing
> elements of the array are changed, their value as passed to callback
> will be the value at the time forEach visits them; elements that are
> deleted after the call to forEach begins and before being visited are
> not visited."
>
> This point is confirmed by every algorithm where the length is "saved"
> once for all before the loop and not got from the .length property each
> time.

 On Mon, 26 Apr 2010, Erik Arvidsson wrote:
> On Sun, Apr 25, 2010 at 01:07, David Bruant wrote:
>> Le 25/04/2010 00:39, J Z a écrit :
>>>
>>> I have thought a lot about weirdnesses that people could think about
>>> like trying to assign a value to the HTMLCollection (divs[14] =
>>> myOtherDiv), but once again, it wouldn't be more allowed than it
>>> currently is (I have no idea of what happens today, but if an error
>>> is thrown in a for-loop, it should throw an error as well in a call
>>> within a forEach).
>>
>> How would destructive methods like `push` or `sort` behave? Would
>> `document.body.childNodes.push(document.createTextNode('foo'))` append
>> text node to a body element? Or would it be a noop?
>>
>> That is actually a very good point. It think that the behavior should
>> be exactly the same as "an equivalent without array methods". (this
>> point of my proposal would need to be made completly explicit for each
>> method)
>
> One way to solve this could be to split Array into two interfaces. One
> to be used with immutable array like objects and one to use to mutate
> objects. Then we could apply the immutable array like interface to
> NodeList and its related interfaces. The benefit of doing that is that
> NodeList.prototype.push would be undefined instead of failing when
> called.

 On Mon, 26 Apr 2010, David Flanagan wrote:
>
> Rather that trying to make DOM collections feel like arrays, how about
> just giving them a toArray() method?  This makes it clear that a
> collection is not an array, but clearly defines a way to obtain an
> array.  Clever implementors might even be able to optimize common
> uses-cases using some kind of copy-on-write strategy so that toArray()
> doesn't involve memory allocation and copying.
>
> Of course, trying to teach programmers when they ought to call toArray()
> and when it is not necessary is another matter.  Perhaps calling the
> method snapshot() and focusing on the live vs. static distinction
> instead of the fake array v

Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-08-02 Thread Garrett Smith
On 8/2/10, Garrett Smith  wrote:
> On 8/2/10, And Clover  wrote:
>> On 08/02/2010 09:57 PM, Garrett Smith wrote:
>>
[...]

> ({}).hasOwnProperty.call(document.links, "0");
>
> - and resulting true in IE.
>
> However, that hasOwnProperty check does not always true for

...does not always result `true for...

> collections. As seen in the previous example I posted, for property P,
> [[HasProperty]] resulted false when there is a property P. Once again,
> this time with hasOwnProperty, I see a result in Firefox 3.6: [false,
> object]
>

That was not clear, I meant that [[HasProperty]] resulted false and
[[Get]], via property accessors. resulted in the element being
retrieved.

Garrett


Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-08-02 Thread Garrett Smith
On 8/2/10, And Clover  wrote:
> On 08/02/2010 09:57 PM, Garrett Smith wrote:
>
>> Can it be argued as to what "integer index" means? And what is a "string
>> index"?
>
> Good catch, that's pretty ambiguous language. Browsers implement this as
> if "integer index" were equal to the term "array index" defined section
> 15.4 of ECMA262 (that is an unsigned 32-bit integer other than
> (1<<32)-1, expressed in simplest-possible decimal form), and "string
> index" meaning any other index.
>

Not exactly.

An array's `length` is 1 greater than the largest index in the array;
represented as uint internally. The largest possible array index is
2^32 - 2. ES5 specification says this a bit differently:


| A property name P (in the form of a String value) is
| an array index if and only if ToString(ToUint32(P)) is
| equal to P and ToUint32(P) is not equal to 232-1

That could cover "integer index", but the remaining undefined is
"string index", which seems a paradoxical name, even for Java
programmers.

Suppose string index could be any other index. Or it could be any
index matching production for NAME.

But then, does that mean property access on an HTMLCollection can
never return undefined? Seems so; must be either `null` or an object.

If the a collection is spec'd to use specialized [[Get]] access, then
it may need to use catchalls. Again, browsers do use these in some
cases and they aren't specified.

> The paragraph should be updated to explicitly reference this; probably
> the language about square brackets should be dropped too, as it seems to
> represent a misunderstanding of exactly how the ECMAScript
> square-bracket and dot operators actually work.
>


> Whether a property name is an "array index" or not is an unrelated issue

Depends. If a specialized [[Get]] implemented as a catchall, then the
browsers do some checking.

A specialized [[Get]] may be interfering with array generics working
with IE host object collections. It may have been that it was too
complicated and that the developers decided that it was easier to fail
fast by throwing "JScript object expected'.

Again, on that error, if `ho` is a host object, then the behavior in
IE <= 8 for `[].slice.call( ho )` is "JScript object expected." IE
operation sees that the context -- the `this`value -- is not a JScript
object and then aborts prematurely, without trying. It could be that
the attempt to slice the object could actually succeed, as: -
  "0" in ho && "length" in ho

- is true.

> to the matter of how the property value is retrieved. OK, you can't use
> the direct dot syntax on an array index purely as a grammatical manner,
> but . and [] aren't the only way to access properties. (eg.
> document.links.hasOwnProperty('0').)
>

That shows that `hasOwnProperty` is present on the object and that
calling it returns true where there.

For compatibility with IE, a layer of indirection may be used:

({}).hasOwnProperty.call(document.links, "0");

- and resulting true in IE.

However, that hasOwnProperty check does not always true for
collections. As seen in the previous example I posted, for property P,
[[HasProperty]] resulted false when there is a property P. Once again,
this time with hasOwnProperty, I see a result in Firefox 3.6: [false,
object]

javascript: var result =
  [
  ({}).hasOwnProperty.call(document.forms[0], "0"),
  typeof document.forms[0][0]
  ];

 alert( result )

HTML5 also codifies a common form memory leak as "past names map".

Both of those oddities were explained more here:


However, AFAIK, HTML5 does not specify the catchall behavior for the
approach for specialized property access seen there.

Does a collection have element properties?  (and by "element", I do
not mean Element, but indexed/keyed item that represents an object in
the collection.

If it does, then that's a lot easier. Spec'd specialized behavior for
property accessors can be removed; as that behavior is already defined
by ECMA-262. The only change could be to allow for "integer index"
access to return `undefined`, as it currently does in most browsers.

If any collection does not have element properties, then it is
necessary to define "integer index" and "string access", at least for
that collection.

Most collections appear to have element properties and so I can't see
any reason for not specifying that. I recall raising discussion of
property access on collections over a year ago, before writing the
article I've linked above.

Garrett


Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-08-02 Thread And Clover

On 08/02/2010 09:57 PM, Garrett Smith wrote:


Can it be argued as to what "integer index" means? And what is a "string index"?


Good catch, that's pretty ambiguous language. Browsers implement this as 
if "integer index" were equal to the term "array index" defined section 
15.4 of ECMA262 (that is an unsigned 32-bit integer other than 
(1<<32)-1, expressed in simplest-possible decimal form), and "string 
index" meaning any other index.


The paragraph should be updated to explicitly reference this; probably 
the language about square brackets should be dropped too, as it seems to 
represent a misunderstanding of exactly how the ECMAScript 
square-bracket and dot operators actually work.


Whether a property name is an "array index" or not is an unrelated issue 
to the matter of how the property value is retrieved. OK, you can't use 
the direct dot syntax on an array index purely as a grammatical manner, 
but . and [] aren't the only way to access properties. (eg. 
document.links.hasOwnProperty('0').)


--
And Clover
mailto:a...@doxdesk.com
http://www.doxdesk.com/


Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-08-02 Thread Jonas Sicking
On Fri, Jul 30, 2010 at 2:46 PM, Alex Russell  wrote:
> On Fri, Jul 30, 2010 at 4:18 AM, Jonas Sicking  wrote:
>> On Thu, Jul 29, 2010 at 5:45 PM, Ian Hickson  wrote:
>>>
>>> The e-mails quoted below consist of the salient points of this thread:
>>>
>>> On Fri, 23 Apr 2010, David Bruant wrote:

 Make that HTMLCollection (and all HTML*Collection, as a consequence of
 inheritence of HTMLCollection) inherit from the ECMAScript Array
 prototype. This way, it will make available all Array extra methods
 (forEach, map, filter...) added in ECMAScript5 (and next versions which
 should go in the same direction).

 As far as I know, adding this won't break any existing code. The
 semantics of a Collection and the way it is used is very close from
 ECMAScript Arrays. I don't think that the notion of "live object" and
 ECMAScript Array are incompatible either. Once again, I am talking about
 ECMAScript binding. I have no intention to touch the HTMLCollection
 interface or other languages bindings.
>>>
>>> On Sun, 25 Apr 2010, J Z wrote:

 If HTMLCollection was inheriting from Array, and methods like `forEach`,
 `map`, etc. were to operate on a live object, there would definitely be
 undesired consequences. We can see this in, say, Firefox (which allows to
 set [[Prototype]] of `HTMLCollection` to `Array.prototype`):

 HTMLCollection.prototype.__proto__ = Array.prototype;

 document.getElementsByTagName('div').forEach(function(el) {
   el.parentNode.removeChild(el); // doesn't work as expected
 });

 // turning live collection into static array fixes this
 Array.slice(document.getElementsByTagName('div')).forEach(function(el) {
   el.parentNode.removeChild(el);
 });
>>>
>>> On Sat, 24 Apr 2010, David Bruant wrote:

 I think I can take your point as a "pro" more than a "con", because in
 ES5, right before the definition of each array extra method, a paragraph
 like the following can be found :

 "The range of elements processed by forEach is set before the first call
 to callbackfn. Elements which are appended to the array after the call
 to forEach begins will not be visited by callbackfn. If existing
 elements of the array are changed, their value as passed to callback
 will be the value at the time forEach visits them; elements that are
 deleted after the call to forEach begins and before being visited are
 not visited."

 This point is confirmed by every algorithm where the length is "saved"
 once for all before the loop and not got from the .length property each
 time.
>>>
>>> On Mon, 26 Apr 2010, Erik Arvidsson wrote:
 On Sun, Apr 25, 2010 at 01:07, David Bruant wrote:
 > Le 25/04/2010 00:39, J Z a écrit :
 >>
 >> I have thought a lot about weirdnesses that people could think about
 >> like trying to assign a value to the HTMLCollection (divs[14] =
 >> myOtherDiv), but once again, it wouldn't be more allowed than it
 >> currently is (I have no idea of what happens today, but if an error
 >> is thrown in a for-loop, it should throw an error as well in a call
 >> within a forEach).
 >
 > How would destructive methods like `push` or `sort` behave? Would
 > `document.body.childNodes.push(document.createTextNode('foo'))` append
 > text node to a body element? Or would it be a noop?
 >
 > That is actually a very good point. It think that the behavior should
 > be exactly the same as "an equivalent without array methods". (this
 > point of my proposal would need to be made completly explicit for each
 > method)

 One way to solve this could be to split Array into two interfaces. One
 to be used with immutable array like objects and one to use to mutate
 objects. Then we could apply the immutable array like interface to
 NodeList and its related interfaces. The benefit of doing that is that
 NodeList.prototype.push would be undefined instead of failing when
 called.
>>>
>>> On Mon, 26 Apr 2010, David Flanagan wrote:

 Rather that trying to make DOM collections feel like arrays, how about
 just giving them a toArray() method?  This makes it clear that a
 collection is not an array, but clearly defines a way to obtain an
 array.  Clever implementors might even be able to optimize common
 uses-cases using some kind of copy-on-write strategy so that toArray()
 doesn't involve memory allocation and copying.

 Of course, trying to teach programmers when they ought to call toArray()
 and when it is not necessary is another matter.  Perhaps calling the
 method snapshot() and focusing on the live vs. static distinction
 instead of the fake array vs. true array distinction would invite less
 misuse.

 Or we can just leave the DOM as it is and get used to calling the
 equivalent of Prototype's $

Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-08-02 Thread Oliver Hunt

On Aug 2, 2010, at 12:57 PM, Garrett Smith wrote:
> I also linked to the old "catchalls" proposal earlier in the thread.
> That is because the host objects mentioned here have a specialized
> "catchall" behavior that isn't yet defined by any specification, so
> when the code has property access with an integer index, as: anObj[2]
> - then it's supposed to be the same as a  call to the `item` method.
> That mostly works, but isn't specified isn't completely and isn't
> completely interoperable due to variance in undefined vs null.
> 
> I noticed that rather than define catchall, HTML5 copied the old DOM text:
> 
> | In the ECMAScript DOM binding, objects implementing the
> | HTMLFormControlsCollection  interface must support being
> | dereferenced using the square bracket notation, such that dereferencing
> | with an integer index is equivalent to invoking the item() method with that
> | index, and such that dereferencing with a string index is equivalent to
> | invoking the namedItem() method with that index.
> 
> The problem with that is that property access doesn't do any
> typechecking, and so
>  obj[2]
> - is equivalent to:-
>  obj["2"]
> 
> Can it be argued as to what "integer index" means? And what is a "string 
> index"?

It does seem a little weird as EcmaScript does not distinguish between string 
and non-string property names, the special handling of "numeric" indices inside 
the [[GetOwnProperty]]/[[PutOwnProperty]] methods of those types that have 
special handling, in those types the special "numeric index" path is hit if the 
property name is an "Array index", which is defined as (pseudo code)

bool isArrayIndex(String property)
{
unsigned index = ToUint32(property);
return ToString(index) == property && index >= 0 && index < 0x; 
}

> Garrett

--Oliver



Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-08-02 Thread Garrett Smith
On 8/2/10, Garrett Smith  wrote:
> On 8/2/10, Oliver Hunt  wrote:
>>
>> On Aug 2, 2010, at 7:36 AM, And Clover wrote:
>>
>>> On 07/30/2010 06:43 AM, Oliver Hunt wrote:
 all array functions defined in ES5 are "generic" in that they work
 over any array-like object.
>>>
>>> They're guaranteed to work over any array-like native JavaScript object.
>>> They're *not* guaranteed to work on host objects like the various node
>>> lists.
>>
>> Uhhh, I have no idea what you're talking about -- there are no type
>> checks
>> in any of the array prototype functions, they all operate in terms of
>> property access alone, all the methods we're talking about basically
>> start
>> out like this:
>>
>
> [..]
>
> And they continue like this:
>
> "Whether the [something] function can be applied successfully to a
> host object is implementation-dependent."
>
> Where "[something]" is replaced by "slice" in this case.
>
>> Eg. "array-like" in the context of ES5 should be interpreted as "has a
>> property named 'length', the array methods will work on any type.
>>
>
> That is not true. ECMAScript has what is called "host object". A host
> is any ecmascript object that is not defined by the specification; it

Should be:
any object that is not defined by the specification.

I also linked to the old "catchalls" proposal earlier in the thread.
That is because the host objects mentioned here have a specialized
"catchall" behavior that isn't yet defined by any specification, so
when the code has property access with an integer index, as: anObj[2]
- then it's supposed to be the same as a  call to the `item` method.
That mostly works, but isn't specified isn't completely and isn't
completely interoperable due to variance in undefined vs null.

I noticed that rather than define catchall, HTML5 copied the old DOM text:

| In the ECMAScript DOM binding, objects implementing the
| HTMLFormControlsCollection  interface must support being
| dereferenced using the square bracket notation, such that dereferencing
| with an integer index is equivalent to invoking the item() method with that
| index, and such that dereferencing with a string index is equivalent to
| invoking the namedItem() method with that index.

The problem with that is that property access doesn't do any
typechecking, and so
  obj[2]
 - is equivalent to:-
  obj["2"]

Can it be argued as to what "integer index" means? And what is a "string index"?

Garrett


Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-08-02 Thread Oliver Hunt

On Aug 2, 2010, at 12:25 PM, Garrett Smith wrote:

> On 8/2/10, Oliver Hunt  wrote:
>> 
>> On Aug 2, 2010, at 7:36 AM, And Clover wrote:
>> 
>>> On 07/30/2010 06:43 AM, Oliver Hunt wrote:
 all array functions defined in ES5 are "generic" in that they work
 over any array-like object.
>>> 
>>> They're guaranteed to work over any array-like native JavaScript object.
>>> They're *not* guaranteed to work on host objects like the various node
>>> lists.
>> 
>> Uhhh, I have no idea what you're talking about -- there are no type checks
>> in any of the array prototype functions, they all operate in terms of
>> property access alone, all the methods we're talking about basically start
>> out like this:
>> 
> 
> [..]
> 
> And they continue like this:
> 
> "Whether the [something] function can be applied successfully to a
> host object is implementation-dependent."
> 
> Where "[something]" is replaced by "slice" in this case.
> 
>> Eg. "array-like" in the context of ES5 should be interpreted as "has a
>> property named 'length', the array methods will work on any type.
>> 
> 
> That is not true. ECMAScript has what is called "host object". A host
> is any ecmascript object that is not defined by the specification; it
> is not a user-defined object (because that explicitly defined to be a
> native object).
> 
> A host object may or may not be implemented as a native ECMAScript
> object. That leaves two types of host objects:
> 1) native
> 2) non-native
> 
> More on that:
> 
> 
> Nothing says that any of the various dom "collection" objects must be
> native object.
> 
> The W3C does not define an interface "collection"; The term itself
> comes from Microsoft IE 4, which predates the w3c DOM; hence the
> quotes around the term "collection".

I didn't say that Host Objects don't exist, i said that "array like" is 
equivalent basically "has a property named length"

Things like Array.prototype.splice not working "as expected" on a NodeList is 
because the numeric properties on the nodelist are essentially DontDelete(or 
configurable=false in es5)

If I define an Object with:
var o = {length:1};
Object.defineProperty(o, "0", {value: "foo", configurable: false});

Then do:
var result = Array.prototype.splice.call(o, 0)

result will be ["foo"], but the property will not have been removed from object 
o.

There is no part of the spec that performs a type check, being a Host Object 
does not get you out of the required behaviour of the Array methods.

The reason the behaviour of Host Objects is considered magic is not so that you 
can say a function doesn't need to work on them, it is _specifically_ to allow 
the behaviour shown by the DOM where you can have properties that are have the 
attributes writable=false, configurable=false, and yet can still change.  This 
is the basis of the Host Object exception.  No property on a non-Host Object 
can change if it is not writable, yet the DOM requires that there be objects 
that do just that.

That said there is also no way in which you can implement any of the live 
collection types using EcmaScript.

Re: IE + Array methods, for whatever reason the ES5 spec does have an addendum 
that allows an implementation to disallow array methods on host objects -- i 
think this was foolish as the specification of the array methods should behave 
exactly as they would with a object with equivalent properties and attributes.

--Oliver



Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-08-02 Thread Garrett Smith
On 8/2/10, Oliver Hunt  wrote:
>
> On Aug 2, 2010, at 7:36 AM, And Clover wrote:
>
>> On 07/30/2010 06:43 AM, Oliver Hunt wrote:
>>> all array functions defined in ES5 are "generic" in that they work
>>> over any array-like object.
>>
>> They're guaranteed to work over any array-like native JavaScript object.
>> They're *not* guaranteed to work on host objects like the various node
>> lists.
>
> Uhhh, I have no idea what you're talking about -- there are no type checks
> in any of the array prototype functions, they all operate in terms of
> property access alone, all the methods we're talking about basically start
> out like this:
>

[..]

And they continue like this:

"Whether the [something] function can be applied successfully to a
host object is implementation-dependent."

Where "[something]" is replaced by "slice" in this case.

> Eg. "array-like" in the context of ES5 should be interpreted as "has a
> property named 'length', the array methods will work on any type.
>

That is not true. ECMAScript has what is called "host object". A host
is any ecmascript object that is not defined by the specification; it
is not a user-defined object (because that explicitly defined to be a
native object).

A host object may or may not be implemented as a native ECMAScript
object. That leaves two types of host objects:
 1) native
 2) non-native

More on that:


Nothing says that any of the various dom "collection" objects must be
native object.

The W3C does not define an interface "collection"; The term itself
comes from Microsoft IE 4, which predates the w3c DOM; hence the
quotes around the term "collection".

>>
>> FWIW in practice `Array.prototype.*.call(htmlcollection)` does work on the
>> modern desktop browsers except for IE.
>>
>> It would be possible to specify that the native-JS object guarantee should
>> also extend to node lists. This would allow fast browser implementations
>> of the array-like methods to be used without having to copy to a new
>> Array. However this would still leave the method of calling them a little
>> ugly.
>
> As above there is no question of it being possible -- the spec behaviour
> makes no exceptions for host vs. native object types.  If IE has a bug, then
> IE has a bug, that doesn't change the spec.
>

IE does not have a bug. IE does not implement its host objects as
native ES objects. I proposed to change that by defining an interface
that would require that, as well as putting a definition of [[Get]]
property access on such objects in one place; not scattered through
various interfaces as they currently are and will continue to be
otherwise, with the proliferation of new indexed "collection" type
interfaces.

Garrett


Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-08-02 Thread Oliver Hunt

On Aug 2, 2010, at 7:36 AM, And Clover wrote:

> On 07/30/2010 06:43 AM, Oliver Hunt wrote:
>> all array functions defined in ES5 are "generic" in that they work
>> over any array-like object.
> 
> They're guaranteed to work over any array-like native JavaScript object. 
> They're *not* guaranteed to work on host objects like the various node lists.

Uhhh, I have no idea what you're talking about -- there are no type checks in 
any of the array prototype functions, they all operate in terms of property 
access alone, all the methods we're talking about basically start out like this:

1.  Let O be the result of calling ToObject passing the this value as the 
argument. 
2.  Let lenValue be the result of calling the [[Get]] internal method of O 
with the argument "length". 
3.  Let len be ToUint32(lenValue). 
4.  If IsCallable(callbackfn) is false, throw a TypeError exception. 
5.  If thisArg was supplied, let T be thisArg; else let T be undefined. 
6.  Let k be 0.
7.  Repeat, while k < len
 

Eg. "array-like" in the context of ES5 should be interpreted as "has a property 
named 'length', the array methods will work on any type.

> 
> FWIW in practice `Array.prototype.*.call(htmlcollection)` does work on the 
> modern desktop browsers except for IE.
> 
> It would be possible to specify that the native-JS object guarantee should 
> also extend to node lists. This would allow fast browser implementations of 
> the array-like methods to be used without having to copy to a new Array. 
> However this would still leave the method of calling them a little ugly.

As above there is no question of it being possible -- the spec behaviour makes 
no exceptions for host vs. native object types.  If IE has a bug, then IE has a 
bug, that doesn't change the spec.

--Oliver



Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-08-02 Thread And Clover

On 07/30/2010 06:43 AM, Oliver Hunt wrote:

all array functions defined in ES5 are "generic" in that they work
over any array-like object.


They're guaranteed to work over any array-like native JavaScript object. 
They're *not* guaranteed to work on host objects like the various node 
lists.


FWIW in practice `Array.prototype.*.call(htmlcollection)` does work on 
the modern desktop browsers except for IE.


It would be possible to specify that the native-JS object guarantee 
should also extend to node lists. This would allow fast browser 
implementations of the array-like methods to be used without having to 
copy to a new Array. However this would still leave the method of 
calling them a little ugly.


--
And Clover
mailto:a...@doxdesk.com
http://www.doxdesk.com/


Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-07-30 Thread Oliver Hunt

On Jul 30, 2010, at 2:46 PM, Alex Russell wrote:

> On Fri, Jul 30, 2010 at 4:18 AM, Jonas Sicking  wrote:
>> On Thu, Jul 29, 2010 at 5:45 PM, Ian Hickson  wrote:
>>> 
>>> The e-mails quoted below consist of the salient points of this thread:
>>> 
>>> On Fri, 23 Apr 2010, David Bruant wrote:
 
 Make that HTMLCollection (and all HTML*Collection, as a consequence of
 inheritence of HTMLCollection) inherit from the ECMAScript Array
 prototype. This way, it will make available all Array extra methods
 (forEach, map, filter...) added in ECMAScript5 (and next versions which
 should go in the same direction).
 
 As far as I know, adding this won't break any existing code. The
 semantics of a Collection and the way it is used is very close from
 ECMAScript Arrays. I don't think that the notion of "live object" and
 ECMAScript Array are incompatible either. Once again, I am talking about
 ECMAScript binding. I have no intention to touch the HTMLCollection
 interface or other languages bindings.
>>> 
>>> On Sun, 25 Apr 2010, J Z wrote:
 
 If HTMLCollection was inheriting from Array, and methods like `forEach`,
 `map`, etc. were to operate on a live object, there would definitely be
 undesired consequences. We can see this in, say, Firefox (which allows to
 set [[Prototype]] of `HTMLCollection` to `Array.prototype`):
 
 HTMLCollection.prototype.__proto__ = Array.prototype;
 
 document.getElementsByTagName('div').forEach(function(el) {
   el.parentNode.removeChild(el); // doesn't work as expected
 });
 
 // turning live collection into static array fixes this
 Array.slice(document.getElementsByTagName('div')).forEach(function(el) {
   el.parentNode.removeChild(el);
 });
>>> 
>>> On Sat, 24 Apr 2010, David Bruant wrote:
 
 I think I can take your point as a "pro" more than a "con", because in
 ES5, right before the definition of each array extra method, a paragraph
 like the following can be found :
 
 "The range of elements processed by forEach is set before the first call
 to callbackfn. Elements which are appended to the array after the call
 to forEach begins will not be visited by callbackfn. If existing
 elements of the array are changed, their value as passed to callback
 will be the value at the time forEach visits them; elements that are
 deleted after the call to forEach begins and before being visited are
 not visited."
 
 This point is confirmed by every algorithm where the length is "saved"
 once for all before the loop and not got from the .length property each
 time.
>>> 
>>> On Mon, 26 Apr 2010, Erik Arvidsson wrote:
 On Sun, Apr 25, 2010 at 01:07, David Bruant wrote:
> Le 25/04/2010 00:39, J Z a écrit :
>> 
>> I have thought a lot about weirdnesses that people could think about
>> like trying to assign a value to the HTMLCollection (divs[14] =
>> myOtherDiv), but once again, it wouldn't be more allowed than it
>> currently is (I have no idea of what happens today, but if an error
>> is thrown in a for-loop, it should throw an error as well in a call
>> within a forEach).
> 
> How would destructive methods like `push` or `sort` behave? Would
> `document.body.childNodes.push(document.createTextNode('foo'))` append
> text node to a body element? Or would it be a noop?
> 
> That is actually a very good point. It think that the behavior should
> be exactly the same as "an equivalent without array methods". (this
> point of my proposal would need to be made completly explicit for each
> method)
 
 One way to solve this could be to split Array into two interfaces. One
 to be used with immutable array like objects and one to use to mutate
 objects. Then we could apply the immutable array like interface to
 NodeList and its related interfaces. The benefit of doing that is that
 NodeList.prototype.push would be undefined instead of failing when
 called.
>>> 
>>> On Mon, 26 Apr 2010, David Flanagan wrote:
 
 Rather that trying to make DOM collections feel like arrays, how about
 just giving them a toArray() method?  This makes it clear that a
 collection is not an array, but clearly defines a way to obtain an
 array.  Clever implementors might even be able to optimize common
 uses-cases using some kind of copy-on-write strategy so that toArray()
 doesn't involve memory allocation and copying.
 
 Of course, trying to teach programmers when they ought to call toArray()
 and when it is not necessary is another matter.  Perhaps calling the
 method snapshot() and focusing on the live vs. static distinction
 instead of the fake array vs. true array distinction would invite less
 misuse.
 
 Or we can just leave the DOM as it is and get used to calling the
 equivalent of Prototype's

Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-07-30 Thread Alex Russell
On Fri, Jul 30, 2010 at 4:18 AM, Jonas Sicking  wrote:
> On Thu, Jul 29, 2010 at 5:45 PM, Ian Hickson  wrote:
>>
>> The e-mails quoted below consist of the salient points of this thread:
>>
>> On Fri, 23 Apr 2010, David Bruant wrote:
>>>
>>> Make that HTMLCollection (and all HTML*Collection, as a consequence of
>>> inheritence of HTMLCollection) inherit from the ECMAScript Array
>>> prototype. This way, it will make available all Array extra methods
>>> (forEach, map, filter...) added in ECMAScript5 (and next versions which
>>> should go in the same direction).
>>>
>>> As far as I know, adding this won't break any existing code. The
>>> semantics of a Collection and the way it is used is very close from
>>> ECMAScript Arrays. I don't think that the notion of "live object" and
>>> ECMAScript Array are incompatible either. Once again, I am talking about
>>> ECMAScript binding. I have no intention to touch the HTMLCollection
>>> interface or other languages bindings.
>>
>> On Sun, 25 Apr 2010, J Z wrote:
>>>
>>> If HTMLCollection was inheriting from Array, and methods like `forEach`,
>>> `map`, etc. were to operate on a live object, there would definitely be
>>> undesired consequences. We can see this in, say, Firefox (which allows to
>>> set [[Prototype]] of `HTMLCollection` to `Array.prototype`):
>>>
>>> HTMLCollection.prototype.__proto__ = Array.prototype;
>>>
>>> document.getElementsByTagName('div').forEach(function(el) {
>>>   el.parentNode.removeChild(el); // doesn't work as expected
>>> });
>>>
>>> // turning live collection into static array fixes this
>>> Array.slice(document.getElementsByTagName('div')).forEach(function(el) {
>>>   el.parentNode.removeChild(el);
>>> });
>>
>> On Sat, 24 Apr 2010, David Bruant wrote:
>>>
>>> I think I can take your point as a "pro" more than a "con", because in
>>> ES5, right before the definition of each array extra method, a paragraph
>>> like the following can be found :
>>>
>>> "The range of elements processed by forEach is set before the first call
>>> to callbackfn. Elements which are appended to the array after the call
>>> to forEach begins will not be visited by callbackfn. If existing
>>> elements of the array are changed, their value as passed to callback
>>> will be the value at the time forEach visits them; elements that are
>>> deleted after the call to forEach begins and before being visited are
>>> not visited."
>>>
>>> This point is confirmed by every algorithm where the length is "saved"
>>> once for all before the loop and not got from the .length property each
>>> time.
>>
>> On Mon, 26 Apr 2010, Erik Arvidsson wrote:
>>> On Sun, Apr 25, 2010 at 01:07, David Bruant wrote:
>>> > Le 25/04/2010 00:39, J Z a écrit :
>>> >>
>>> >> I have thought a lot about weirdnesses that people could think about
>>> >> like trying to assign a value to the HTMLCollection (divs[14] =
>>> >> myOtherDiv), but once again, it wouldn't be more allowed than it
>>> >> currently is (I have no idea of what happens today, but if an error
>>> >> is thrown in a for-loop, it should throw an error as well in a call
>>> >> within a forEach).
>>> >
>>> > How would destructive methods like `push` or `sort` behave? Would
>>> > `document.body.childNodes.push(document.createTextNode('foo'))` append
>>> > text node to a body element? Or would it be a noop?
>>> >
>>> > That is actually a very good point. It think that the behavior should
>>> > be exactly the same as "an equivalent without array methods". (this
>>> > point of my proposal would need to be made completly explicit for each
>>> > method)
>>>
>>> One way to solve this could be to split Array into two interfaces. One
>>> to be used with immutable array like objects and one to use to mutate
>>> objects. Then we could apply the immutable array like interface to
>>> NodeList and its related interfaces. The benefit of doing that is that
>>> NodeList.prototype.push would be undefined instead of failing when
>>> called.
>>
>> On Mon, 26 Apr 2010, David Flanagan wrote:
>>>
>>> Rather that trying to make DOM collections feel like arrays, how about
>>> just giving them a toArray() method?  This makes it clear that a
>>> collection is not an array, but clearly defines a way to obtain an
>>> array.  Clever implementors might even be able to optimize common
>>> uses-cases using some kind of copy-on-write strategy so that toArray()
>>> doesn't involve memory allocation and copying.
>>>
>>> Of course, trying to teach programmers when they ought to call toArray()
>>> and when it is not necessary is another matter.  Perhaps calling the
>>> method snapshot() and focusing on the live vs. static distinction
>>> instead of the fake array vs. true array distinction would invite less
>>> misuse.
>>>
>>> Or we can just leave the DOM as it is and get used to calling the
>>> equivalent of Prototype's $A() function.
>>
>> Before changing something this substantial, I'd like to have implementor
>> feedback regarding what the best way to address this is:
>>

Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-07-30 Thread Garrett Smith
On 7/29/10, Garrett Smith  wrote:
> On 7/29/10, Ian Hickson  wrote:
>>
>> The e-mails quoted below consist of the salient points of this thread:
>>
>> On Fri, 23 Apr 2010, David Bruant wrote:
>>>
>
[...]
> The difficulty is getting the special behavior for [[Get]] which would
> seem to require some sort of catchall behavior that I linked to
> earlier and when it comes to [[HasProperty]] checks, that can be
> complicated (e.g. `"0" in document.forms` doesn't work).
>

It was the FORM element where [[HasProperty]] sometimes results false
where [[Get]] results in an object:

  var aForm = document.forms[0];
  [typeof aForm[0], "0" in aForm];

Result in FF: "object", false

[[Get]] access for various collections is defined for each collection
and doesn't work consistently as specified.


Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-07-30 Thread Mike Shaver
On Fri, Jul 30, 2010 at 12:43 AM, Oliver Hunt  wrote:
> The various html collections aren't fixed length, they're not assignable, so 
> they can't used interchangeably with arrays at the best of times.

Array generics work on arrays that aren't fixed-length, perhaps
obviously, and I believe they're still valid over arrays which have
had their indexed properties configured to be unwritable as well.  As
your later example shows, they can be used interchangeably with arrays
at exactly the best of times: when wanting to apply a non-mutating
extra to one!

We've got the array statics in Firefox (Array.forEach, etc.) and it's
made the make-collections-be-arrays cries from those working on
front-end JS subside dramatically.  I think they would probably solve
the problem quite effectively, and not require us to be on the lookout
for naming collisions between future Array.prototype and
HTMLCollection fields.

Mike


Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-07-30 Thread Jonas Sicking
On Thu, Jul 29, 2010 at 5:45 PM, Ian Hickson  wrote:
>
> The e-mails quoted below consist of the salient points of this thread:
>
> On Fri, 23 Apr 2010, David Bruant wrote:
>>
>> Make that HTMLCollection (and all HTML*Collection, as a consequence of
>> inheritence of HTMLCollection) inherit from the ECMAScript Array
>> prototype. This way, it will make available all Array extra methods
>> (forEach, map, filter...) added in ECMAScript5 (and next versions which
>> should go in the same direction).
>>
>> As far as I know, adding this won't break any existing code. The
>> semantics of a Collection and the way it is used is very close from
>> ECMAScript Arrays. I don't think that the notion of "live object" and
>> ECMAScript Array are incompatible either. Once again, I am talking about
>> ECMAScript binding. I have no intention to touch the HTMLCollection
>> interface or other languages bindings.
>
> On Sun, 25 Apr 2010, J Z wrote:
>>
>> If HTMLCollection was inheriting from Array, and methods like `forEach`,
>> `map`, etc. were to operate on a live object, there would definitely be
>> undesired consequences. We can see this in, say, Firefox (which allows to
>> set [[Prototype]] of `HTMLCollection` to `Array.prototype`):
>>
>> HTMLCollection.prototype.__proto__ = Array.prototype;
>>
>> document.getElementsByTagName('div').forEach(function(el) {
>>   el.parentNode.removeChild(el); // doesn't work as expected
>> });
>>
>> // turning live collection into static array fixes this
>> Array.slice(document.getElementsByTagName('div')).forEach(function(el) {
>>   el.parentNode.removeChild(el);
>> });
>
> On Sat, 24 Apr 2010, David Bruant wrote:
>>
>> I think I can take your point as a "pro" more than a "con", because in
>> ES5, right before the definition of each array extra method, a paragraph
>> like the following can be found :
>>
>> "The range of elements processed by forEach is set before the first call
>> to callbackfn. Elements which are appended to the array after the call
>> to forEach begins will not be visited by callbackfn. If existing
>> elements of the array are changed, their value as passed to callback
>> will be the value at the time forEach visits them; elements that are
>> deleted after the call to forEach begins and before being visited are
>> not visited."
>>
>> This point is confirmed by every algorithm where the length is "saved"
>> once for all before the loop and not got from the .length property each
>> time.
>
> On Mon, 26 Apr 2010, Erik Arvidsson wrote:
>> On Sun, Apr 25, 2010 at 01:07, David Bruant wrote:
>> > Le 25/04/2010 00:39, J Z a écrit :
>> >>
>> >> I have thought a lot about weirdnesses that people could think about
>> >> like trying to assign a value to the HTMLCollection (divs[14] =
>> >> myOtherDiv), but once again, it wouldn't be more allowed than it
>> >> currently is (I have no idea of what happens today, but if an error
>> >> is thrown in a for-loop, it should throw an error as well in a call
>> >> within a forEach).
>> >
>> > How would destructive methods like `push` or `sort` behave? Would
>> > `document.body.childNodes.push(document.createTextNode('foo'))` append
>> > text node to a body element? Or would it be a noop?
>> >
>> > That is actually a very good point. It think that the behavior should
>> > be exactly the same as "an equivalent without array methods". (this
>> > point of my proposal would need to be made completly explicit for each
>> > method)
>>
>> One way to solve this could be to split Array into two interfaces. One
>> to be used with immutable array like objects and one to use to mutate
>> objects. Then we could apply the immutable array like interface to
>> NodeList and its related interfaces. The benefit of doing that is that
>> NodeList.prototype.push would be undefined instead of failing when
>> called.
>
> On Mon, 26 Apr 2010, David Flanagan wrote:
>>
>> Rather that trying to make DOM collections feel like arrays, how about
>> just giving them a toArray() method?  This makes it clear that a
>> collection is not an array, but clearly defines a way to obtain an
>> array.  Clever implementors might even be able to optimize common
>> uses-cases using some kind of copy-on-write strategy so that toArray()
>> doesn't involve memory allocation and copying.
>>
>> Of course, trying to teach programmers when they ought to call toArray()
>> and when it is not necessary is another matter.  Perhaps calling the
>> method snapshot() and focusing on the live vs. static distinction
>> instead of the fake array vs. true array distinction would invite less
>> misuse.
>>
>> Or we can just leave the DOM as it is and get used to calling the
>> equivalent of Prototype's $A() function.
>
> Before changing something this substantial, I'd like to have implementor
> feedback regarding what the best way to address this is:
>
>  - somehow make HTMLCollections and NodeLists inherit from Array?
>
>  - define a bunch of feature on HTMLCollections and NodeLists so that
>   they're like

Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-07-29 Thread Garrett Smith
On 7/29/10, Ian Hickson  wrote:
>
> The e-mails quoted below consist of the salient points of this thread:
>
> On Fri, 23 Apr 2010, David Bruant wrote:
>>

[...]

>> Or we can just leave the DOM as it is and get used to calling the
>> equivalent of Prototype's $A() function.
>
> Before changing something this substantial, I'd like to have implementor
> feedback regarding what the best way to address this is:
>
>  - somehow make HTMLCollections and NodeLists inherit from Array?
>

Again, mutable operations including [[Put]] include reverse, sort,
push, pop won't make sense.

>  - define a bunch of feature on HTMLCollections and NodeLists so that
>they're like arrays?
>

What about StyleSheetList and CSSRuleList and HTMLOptionsCollection, et al?

Too generalized and too complicated. For example, the side effects of
cssRuleList.reverse() would be complicated and probably pointless. I'd
would not even consider trying to write a generalized fallback for
that, even if the implementations decided to implement it (I'm, pretty
sure they wont).

>  - provide a toArray() method or equivalent?
>

Isn't it duplicate functionality of Array.prototype.slice.call(obj),
so long as `obj` is a Native ECMAScript object?

Where do you define `toArray`? Do you define an interface with solely
a toArray method and then put that on each collection? Or do you
instead define a toArray individually for each indexed collection?

That's duplicate functionality repeated for each interface. If you're
going to do that, defining a toArray on its own interface and define
its functionality in one spot would avoid repetition and concomitant
problems associated (e.g. shotgun surgery).

>  - do nothing?
>

SImple for implementors and a simple fallback an be provided.

Scripts can use Array.prototype.slice.call(obj) where that works and a
`for` loop where it doesn't.  A problem with that is the various DOM
objects are not required to be implemented with native ECMAScript
object semantics.

>  - something else?
>

Could create a super interface that, for ES Binding, is required to be
a Native ECMAScript object.

If you're going to do that, you could define [[Get]] that finds the
property as the various `item()` method does. This is partially
specified in various places in the DOM, though is not implemented
consistently*.

Some interfaces that could implement this hypothetical interface (call
it "IndexedCollection" if you like), would be StyleSheetList,
CSSRuleList or NodeList or Collection or HTMLFormControlsCollection.

That way, there would be good safety from:

var sheet = document.styleSheets[0], rules;
if(sheet && sheet.cssRules) {
  rules = Array.prototype.slice.call(sheet.cssRules);
}

The difficulty is getting the special behavior for [[Get]] which would
seem to require some sort of catchall behavior that I linked to
earlier and when it comes to [[HasProperty]] checks, that can be
complicated (e.g. `"0" in document.forms` doesn't work).

http://wiki.ecmascript.org/doku.php?id=strawman:catchalls

* Invoking the `item` method and using property accessor are not
equivalent, though different w3c DOM specifications state, in various
places:
| Note: This object can also be dereferenced using square
| bracket notation (e.g. obj[1]). Dereferencing with an integer
| index is equivalent to invoking the item method with that index.

And we can see that sometimes browsers will return null for
`obj.item(888)` and undefined for `obj[888]`.

The main ideas of the proposed hypothetical interface are to 1)
consolidate that into one place and 2) define that whatever is a
collection is a Native ECMAScript Object.
-- 
Garrett


Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-07-29 Thread Oliver Hunt

On Jul 29, 2010, at 9:03 PM, Alex Russell wrote:

> On Mon, Apr 26, 2010 at 10:04 AM, David Flanagan
>  wrote:
>> Erik Arvidsson wrote:
> 
> for (var i = 0, length = collection.length; i < length; i++)
> // instead of:
> for (var i = 0; i < collection.length; i++)
> 
 Actually, the former is a problem when the nodelist is modified in the
 loop; it may result in collection[i] being undefined.
>>> 
>>> Even when checking the length in every iteration you can run into
>>> problems. If you remove something earlier in the collection you will
>>> *miss* one item unless you fix the loop iterator.
>>> 
>>> We should not let these edge cases get in the way of making the DOM
>>> collections feel less foreign to JavaScript.
>>> 
>>> --
>>> erik
>>> 
>> 
>> Rather that trying to make DOM collections feel like arrays, how about just
>> giving them a toArray() method?
> 
> This is pretty terrible. For lack of a way to subtype Arrays in the
> language, we're going to contort the entire DOM API (again) to do
> unnatural things? The right answer here is to make an immutable length
> Array type/trait/interface and just define the various flavors of HTML
> collection in those terms.

The various html collections aren't fixed length, they're not assignable, so 
they can't used interchangeably with arrays at the best of times.

> Support for doing this needs to be one of TC39's highest priority
> tasks, and indeed the work on proxies is going to make it possible in
> Harmony. No need to screw up the DOM any more than it already has
> been.

I'm not sure how you expect proxies to help here but for the record all array 
functions defined in ES5 are "generic" in that they work over any array-like 
object.  So Array.prototype.forEach.apply(myHTMLCollection, function(...){...}) 
will work.  This is obviously not as elegant as might be liked and TC39 is (or 
at least was) considering putting generic methods onto the Array constructor, 
eg. Array.forEach(arrayLike, callback)

--Oliver



Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-07-29 Thread Alex Russell
On Mon, Apr 26, 2010 at 10:04 AM, David Flanagan
 wrote:
> Erik Arvidsson wrote:

 for (var i = 0, length = collection.length; i < length; i++)
 // instead of:
 for (var i = 0; i < collection.length; i++)

>>> Actually, the former is a problem when the nodelist is modified in the
>>> loop; it may result in collection[i] being undefined.
>>
>> Even when checking the length in every iteration you can run into
>> problems. If you remove something earlier in the collection you will
>> *miss* one item unless you fix the loop iterator.
>>
>> We should not let these edge cases get in the way of making the DOM
>> collections feel less foreign to JavaScript.
>>
>> --
>> erik
>>
>
> Rather that trying to make DOM collections feel like arrays, how about just
> giving them a toArray() method?

This is pretty terrible. For lack of a way to subtype Arrays in the
language, we're going to contort the entire DOM API (again) to do
unnatural things? The right answer here is to make an immutable length
Array type/trait/interface and just define the various flavors of HTML
collection in those terms.

Support for doing this needs to be one of TC39's highest priority
tasks, and indeed the work on proxies is going to make it possible in
Harmony. No need to screw up the DOM any more than it already has
been.

> This makes it clear that a collection is
> not an array, but clearly defines a way to obtain an array.  Clever
> implementors might even be able to optimize common uses-cases using some
> kind of copy-on-write strategy so that toArray() doesn't involve memory
> allocation and copying.
>
> Of course, trying to teach programmers when they ought to call toArray() and
> when it is not necessary is another matter.  Perhaps calling the method
> snapshot() and focusing on the live vs. static distinction instead of the
> fake array vs. true array distinction would invite less misuse.
>
> Or we can just leave the DOM as it is and get used to calling the equivalent
> of Prototype's $A() function.
>
>        David
>


Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-07-29 Thread Ian Hickson

The e-mails quoted below consist of the salient points of this thread:

On Fri, 23 Apr 2010, David Bruant wrote:
> 
> Make that HTMLCollection (and all HTML*Collection, as a consequence of 
> inheritence of HTMLCollection) inherit from the ECMAScript Array 
> prototype. This way, it will make available all Array extra methods 
> (forEach, map, filter...) added in ECMAScript5 (and next versions which 
> should go in the same direction).
> 
> As far as I know, adding this won't break any existing code. The 
> semantics of a Collection and the way it is used is very close from 
> ECMAScript Arrays. I don't think that the notion of "live object" and 
> ECMAScript Array are incompatible either. Once again, I am talking about 
> ECMAScript binding. I have no intention to touch the HTMLCollection 
> interface or other languages bindings.

On Sun, 25 Apr 2010, J Z wrote:
> 
> If HTMLCollection was inheriting from Array, and methods like `forEach`,
> `map`, etc. were to operate on a live object, there would definitely be
> undesired consequences. We can see this in, say, Firefox (which allows to
> set [[Prototype]] of `HTMLCollection` to `Array.prototype`):
> 
> HTMLCollection.prototype.__proto__ = Array.prototype;
> 
> document.getElementsByTagName('div').forEach(function(el) {
>   el.parentNode.removeChild(el); // doesn't work as expected
> });
> 
> // turning live collection into static array fixes this
> Array.slice(document.getElementsByTagName('div')).forEach(function(el) {
>   el.parentNode.removeChild(el);
> });

On Sat, 24 Apr 2010, David Bruant wrote:
>
> I think I can take your point as a "pro" more than a "con", because in 
> ES5, right before the definition of each array extra method, a paragraph 
> like the following can be found :
>
> "The range of elements processed by forEach is set before the first call 
> to callbackfn. Elements which are appended to the array after the call 
> to forEach begins will not be visited by callbackfn. If existing 
> elements of the array are changed, their value as passed to callback 
> will be the value at the time forEach visits them; elements that are 
> deleted after the call to forEach begins and before being visited are 
> not visited."
> 
> This point is confirmed by every algorithm where the length is "saved" 
> once for all before the loop and not got from the .length property each 
> time.

On Mon, 26 Apr 2010, Erik Arvidsson wrote:
> On Sun, Apr 25, 2010 at 01:07, David Bruant wrote:
> > Le 25/04/2010 00:39, J Z a écrit :
> >>
> >> I have thought a lot about weirdnesses that people could think about 
> >> like trying to assign a value to the HTMLCollection (divs[14] = 
> >> myOtherDiv), but once again, it wouldn't be more allowed than it 
> >> currently is (I have no idea of what happens today, but if an error 
> >> is thrown in a for-loop, it should throw an error as well in a call 
> >> within a forEach).
> >
> > How would destructive methods like `push` or `sort` behave? Would 
> > `document.body.childNodes.push(document.createTextNode('foo'))` append 
> > text node to a body element? Or would it be a noop?
> >
> > That is actually a very good point. It think that the behavior should 
> > be exactly the same as "an equivalent without array methods". (this 
> > point of my proposal would need to be made completly explicit for each 
> > method)
> 
> One way to solve this could be to split Array into two interfaces. One 
> to be used with immutable array like objects and one to use to mutate 
> objects. Then we could apply the immutable array like interface to 
> NodeList and its related interfaces. The benefit of doing that is that 
> NodeList.prototype.push would be undefined instead of failing when 
> called.

On Mon, 26 Apr 2010, David Flanagan wrote:
> 
> Rather that trying to make DOM collections feel like arrays, how about 
> just giving them a toArray() method?  This makes it clear that a 
> collection is not an array, but clearly defines a way to obtain an 
> array.  Clever implementors might even be able to optimize common 
> uses-cases using some kind of copy-on-write strategy so that toArray() 
> doesn't involve memory allocation and copying.
> 
> Of course, trying to teach programmers when they ought to call toArray() 
> and when it is not necessary is another matter.  Perhaps calling the 
> method snapshot() and focusing on the live vs. static distinction 
> instead of the fake array vs. true array distinction would invite less 
> misuse.
> 
> Or we can just leave the DOM as it is and get used to calling the 
> equivalent of Prototype's $A() function.

Before changing something this substantial, I'd like to have implementor 
feedback regarding what the best way to address this is:

 - somehow make HTMLCollections and NodeLists inherit from Array?

 - define a bunch of feature on HTMLCollections and NodeLists so that 
   they're like arrays?

 - provide a toArray() method or equivalent?

 - do nothing?

 - something else?

-- 
Ian Hickson 

Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection (ATTN IE TEAM - TRAVIS LEITHEAD)

2010-04-29 Thread Garrett Smith
On Thu, Apr 29, 2010 at 6:59 AM, Geoffrey Sneddon  wrote:
> On 28/04/10 23:28, Garrett Smith wrote:
>>
>> On Wed, Apr 28, 2010 at 2:12 AM, James Graham  wrote:
>>>
>>> On 04/28/2010 10:27 AM, David Bruant wrote:
>>>
 When I started this thread, my point was to define a normalized way
 (through ECMAScript binding) to add array extras to array-like objects
 in the scope of HTML5 (HTMLCollection and inheriting interfaces).
 I don't see any reason yet to try to find a solution to problems that
 are in current web browsers.
 Of course, if/when a proposal emerges from this thread and some user
 agent accept to implement it, a workaround (probably, feature detection)
 will have to be found to use the feature in user agents that implement
 it and doing something equivalent in web browsers that don't.
>>>
>>> To be clear the proposals in this thread are pure syntactic sugar; they
>>> don't allow you do do anything that you can't already do like:
>>>
>>> Array.prototype.whatever.call(html_collection, arg1, arg2, ...)
>>>
>>> where "whatever" is the array method you are interested in.
>>>
>>
>> - and from that you can expect errors in Internet Explorer up to and
>> including version 8.
>
> Adding a toArray operation (for example) won't work in IE up to and
> including version 8 though either. There's no point in adding a toArray
> operation for the pure reason that they currently don't implement another
> part of the spec (through the WebIDL references) currently. toArray adds no
> extra usefulness once they implement other parts of the spec.
>

It's pretty hard to make out what you're getting at here. You "the
spec" to refer to something "here" that "they" don't implement.

It was also hard to understand your meaning in:

| To be clear the proposals in this thread are pure syntactic sugar;
| they don't allow you do do anything that you can't already do like:
|
|   Array.prototype.whatever.call(html_collection, arg1, arg2, ...)"

 Array.prototype.slice.call(html_collection) is not something that one
cannot already do; it *is* something that can be done, however one
cannot expect an Array to be returned from that operation in IE <= 8.
Whatever it is you meant to convey in that paragraph was lost.

If IE "dhtml collections" are implemented as native ECMAScript objects
in IE9, the case for the "toArray" proposal is weak.

The fact that IE implements "dhtml collections" as unwieldy
error-throwing objects poses an obstacle at a fundamental level. That
problem needs to be addressed by Microsoft.

[...]

>
> In IE8 document.styleSheets.toArray().slice(0, 1); also throws an error. How
> does adding toArray help for IE8, which you're giving as the reason for
> adding it?
>

What lead you to the assumption that I proposed "toArray" to address
problems in IE8? I would not publish something so ludicrous.

>> Travis Leithead and IE Team: Can you release Internet Explorer 9 with
>> all "dhtml collections" implemented as native EcmaScript objects?
>
> As far as I am aware, none of them are on this list.
>

He subscribes to the w3c-censored lists (dog-and-pony shows), but now
that you mention it, I don't see his name showing up here much.


Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection (ATTN IE TEAM - TRAVIS LEITHEAD)

2010-04-29 Thread Geoffrey Sneddon

On 28/04/10 23:28, Garrett Smith wrote:

On Wed, Apr 28, 2010 at 2:12 AM, James Graham  wrote:

On 04/28/2010 10:27 AM, David Bruant wrote:


When I started this thread, my point was to define a normalized way
(through ECMAScript binding) to add array extras to array-like objects
in the scope of HTML5 (HTMLCollection and inheriting interfaces).
I don't see any reason yet to try to find a solution to problems that
are in current web browsers.
Of course, if/when a proposal emerges from this thread and some user
agent accept to implement it, a workaround (probably, feature detection)
will have to be found to use the feature in user agents that implement
it and doing something equivalent in web browsers that don't.


To be clear the proposals in this thread are pure syntactic sugar; they
don't allow you do do anything that you can't already do like:

Array.prototype.whatever.call(html_collection, arg1, arg2, ...)

where "whatever" is the array method you are interested in.



- and from that you can expect errors in Internet Explorer up to and
including version 8.


Adding a toArray operation (for example) won't work in IE up to and 
including version 8 though either. There's no point in adding a toArray 
operation for the pure reason that they currently don't implement 
another part of the spec (through the WebIDL references) currently. 
toArray adds no extra usefulness once they implement other parts of the 
spec.





Of course there is nothing wrong with making the syntax more natural if it
can be done in a suitably web-compatible way. However it seems more sensible
to do this at a lower level e.g. as part of Web DOM Core. Sadly that spec is
in need of an editor.



The problem that has been well established is that Internet Explorer's
implementation of host object collections or "dhtml collection"[1]
objects is incompatible with JScript implementation of Array generics.

The result of attempting to supply an Internet Explorer "dhtml
collection" to an Array generic method, e.g. "slice", as the `this`
value, results in a jscript runtimer error: "JScript object expected".

IE8:
[].slice.call(document.styleSheets);

Result:
Error: "JScript object expected".


In IE8 document.styleSheets.toArray().slice(0, 1); also throws an error. 
How does adding toArray help for IE8, which you're giving as the reason 
for adding it?



Travis Leithead and IE Team: Can you release Internet Explorer 9 with
all "dhtml collections" implemented as native EcmaScript objects?


As far as I am aware, none of them are on this list.

--
Geoffrey Sneddon — Opera Software




Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection (ATTN IE TEAM - TRAVIS LEITHEAD)

2010-04-28 Thread Garrett Smith
On Wed, Apr 28, 2010 at 2:12 AM, James Graham  wrote:
> On 04/28/2010 10:27 AM, David Bruant wrote:
>
>> When I started this thread, my point was to define a normalized way
>> (through ECMAScript binding) to add array extras to array-like objects
>> in the scope of HTML5 (HTMLCollection and inheriting interfaces).
>> I don't see any reason yet to try to find a solution to problems that
>> are in current web browsers.
>> Of course, if/when a proposal emerges from this thread and some user
>> agent accept to implement it, a workaround (probably, feature detection)
>> will have to be found to use the feature in user agents that implement
>> it and doing something equivalent in web browsers that don't.
>
> To be clear the proposals in this thread are pure syntactic sugar; they
> don't allow you do do anything that you can't already do like:
>
> Array.prototype.whatever.call(html_collection, arg1, arg2, ...)
>
> where "whatever" is the array method you are interested in.
>

- and from that you can expect errors in Internet Explorer up to and
including version 8.

> Of course there is nothing wrong with making the syntax more natural if it
> can be done in a suitably web-compatible way. However it seems more sensible
> to do this at a lower level e.g. as part of Web DOM Core. Sadly that spec is
> in need of an editor.
>

The problem that has been well established is that Internet Explorer's
implementation of host object collections or "dhtml collection"[1]
objects is incompatible with JScript implementation of Array generics.

The result of attempting to supply an Internet Explorer "dhtml
collection" to an Array generic method, e.g. "slice", as the `this`
value, results in a jscript runtimer error: "JScript object expected".

IE8:
[].slice.call(document.styleSheets);

Result:
Error: "JScript object expected".

No other 21st century browsers exhibit such problems, to my knowledge.
The problem is with Internet Explorer.

A program cannot safely use such constructs without at least feature
testing with a try-catch.

If Microsoft will release Internet Explorer 9 with "dhtml collections"
implemented as native EcmaScript objects, then your proposal would not
be needed and would only add more complexity to the overly complicated
WebIDL (which should have been scrapped and restarted). The example
would do what is obviously wanted of it and create an array from the
StyleSheetList object.

I am asking for Microsoft to not Internet Explorer 9 with "dhtml
collections" as unwieldy error-throwing objects. I am asking Microsoft
to instead release Internet Explorer 9 with all "dhtml collections"
implemented as native EcmaScript objects.

Travis Leithead and IE Team: Can you release Internet Explorer 9 with
all "dhtml collections" implemented as native EcmaScript objects?

http://msdn.microsoft.com/en-us/library/ms533048%28VS.85%29.aspx


Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection (ATTN IE TEAM - TRAVIS LEITHEAD)

2010-04-28 Thread James Graham

On 04/28/2010 10:27 AM, David Bruant wrote:


When I started this thread, my point was to define a normalized way
(through ECMAScript binding) to add array extras to array-like objects
in the scope of HTML5 (HTMLCollection and inheriting interfaces).
I don't see any reason yet to try to find a solution to problems that
are in current web browsers.
Of course, if/when a proposal emerges from this thread and some user
agent accept to implement it, a workaround (probably, feature detection)
will have to be found to use the feature in user agents that implement
it and doing something equivalent in web browsers that don't.


To be clear the proposals in this thread are pure syntactic sugar; they 
don't allow you do do anything that you can't already do like:


Array.prototype.whatever.call(html_collection, arg1, arg2, ...)

where "whatever" is the array method you are interested in.

Of course there is nothing wrong with making the syntax more natural if 
it can be done in a suitably web-compatible way. However it seems more 
sensible to do this at a lower level e.g. as part of Web DOM Core. Sadly 
that spec is in need of an editor.


Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-04-28 Thread Geoffrey Sneddon

On 27/04/10 20:23, David Bruant wrote:

Le 27/04/2010 03:54, Geoffrey Sneddon a écrit :

On 26/04/10 19:50, And Clover wrote:

David Flanagan wrote:


Rather that trying to make DOM collections feel like arrays,
how about just giving them a toArray() method?


I like that, as a practical and explicit (JavaScript-specific)
binding.

In the longer term, what's the thinking on a more basic change:

- Require specific DOM interfaces like NodeList, HTMLCollection,
Element etc. to be available for prototype monkey-patching under
their interface names as properties of `window`?

Then we wouldn't have to worry about what Array-like methods need
to be provided on HTMLCollection, because application and
framework authors could choose whichever they liked to prototype
in.

IE8/Moz/Op/Saf/Chr already do this to a significant extent, but
there's no standard that says they have to. It would allow DOM
extension to be put on a much less shaky footing than the messy
hack Prototype 1.x uses.

Is this something that's a reasonable requirement for browsers in
 future?


HTML5 through WebIDL and its ECMAScript binding already does
require this.


I can see where interfaces are expected to be exposed
([NamedConstructor]) in the global object, but I don't see where it
is said that the prototype of the constructor must be extensible. I
don't even see this in the section which is the relevent one in my
opinion (Interface prototype object) I have read this version of
WebIDL : http://dev.w3.org/2006/webapi/WebIDL/


Section 4.1.1 Interface object:


The interface object MUST also have a property named "prototype" with
attributes { DontDelete, ReadOnly } whose value is an object called
the interface prototype object. This object provides access to the
functions that correspond to the operations defined on the interface,
and is described in more detail in section 4.4.3 below.


--
Geoffrey Sneddon — Opera Software




Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection (ATTN IE TEAM - TRAVIS LEITHEAD)

2010-04-28 Thread David Bruant

Le 28/04/2010 00:03, Garrett Smith a écrit :

On Mon, Apr 26, 2010 at 10:04 AM, David Flanagan
  wrote:
   

Erik Arvidsson wrote:
 
   

[snip]
   
   

Rather that trying to make DOM collections feel like arrays, how about just
giving them a toArray() method?  This makes it clear that a collection is
not an array, but clearly defines a way to obtain an array.  Clever
implementors might even be able to optimize common uses-cases using some
kind of copy-on-write strategy so that toArray() doesn't involve memory
allocation and copying.

 

That would solve the OP's problem, but what about other collections
like NodeList, StyleSheetList, and CSSStyleDeclaration?
   

I am sorry, I don't know what "OP" stands for.



An interface that has a toArray() method might be more suitable, as it
could be added arbitrarily to other interfaces mentioned already.
   

I agree with this idea and proposed something in that direction recently :
http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2010-April/026057.html



In any case, the problem is not going to go away in IE6. Nor IE7. Nor
IE8. IE9 might change to implement Host object collections as native
ECMAScript objects, but even then, then the problems will still need
to be addressed in all versions of IE prior.
   

In this case, what do you refer as "the problem" ?

When I started this thread, my point was to define a normalized way 
(through ECMAScript binding) to add array extras to array-like objects 
in the scope of HTML5 (HTMLCollection and inheriting interfaces).
I don't see any reason yet to try to find a solution to problems that 
are in current web browsers.
Of course, if/when a proposal emerges from this thread and some user 
agent accept to implement it, a workaround (probably, feature detection) 
will have to be found to use the feature in user agents that implement 
it and doing something equivalent in web browsers that don't.




MSIE's implementation of Host objects WRT Array generics is a
fundamental and significant and important problem that needs to be
addressed.

If Internet Explorer's problems with Host objects cannot be fixed,
then it would be a nice feature to have a way to get an array from a
collection.
   

The idea of getting an Array from a collection came out without IE in mind.
If we want to have it in a specification, it has to be a good idea 
regardless browsers specificities.



However, Microsoft should release an IE9 where host object collections
are implemented as native ECMAscript objects. If they can do that, the
problems would not be an issue.

What do you say, Travis Leithead and IE Team? Will you release IE9
with host object implemented as native EcmaScript objects?
   
I have not seen any Travis Leithead or IE Team in the recipients. Is 
that normal ?


David


Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection (ATTN IE TEAM - TRAVIS LEITHEAD)

2010-04-28 Thread Garrett Smith
On Mon, Apr 26, 2010 at 10:04 AM, David Flanagan
 wrote:
> Erik Arvidsson wrote:

[snip]
>>
>
> Rather that trying to make DOM collections feel like arrays, how about just
> giving them a toArray() method?  This makes it clear that a collection is
> not an array, but clearly defines a way to obtain an array.  Clever
> implementors might even be able to optimize common uses-cases using some
> kind of copy-on-write strategy so that toArray() doesn't involve memory
> allocation and copying.
>

That would solve the OP's problem, but what about other collections
like NodeList, StyleSheetList, and CSSStyleDeclaration?

An interface that has a toArray() method might be more suitable, as it
could be added arbitrarily to other interfaces mentioned already.

In any case, the problem is not going to go away in IE6. Nor IE7. Nor
IE8. IE9 might change to implement Host object collections as native
ECMAScript objects, but even then, then the problems will still need
to be addressed in all versions of IE prior.

MSIE's implementation of Host objects WRT Array generics is a
fundamental and significant and important problem that needs to be
addressed.

If Internet Explorer's problems with Host objects cannot be fixed,
then it would be a nice feature to have a way to get an array from a
collection.

However, Microsoft should release an IE9 where host object collections
are implemented as native ECMAscript objects. If they can do that, the
problems would not be an issue.

What do you say, Travis Leithead and IE Team? Will you release IE9
with host object implemented as native EcmaScript objects?

Garrett


Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-04-27 Thread David Bruant

Le 27/04/2010 03:54, Geoffrey Sneddon a écrit :

On 26/04/10 19:50, And Clover wrote:

David Flanagan wrote:


Rather that trying to make DOM collections feel like arrays, how about
just giving them a toArray() method?


I like that, as a practical and explicit (JavaScript-specific) binding.

In the longer term, what's the thinking on a more basic change:

- Require specific DOM interfaces like NodeList, HTMLCollection, Element
etc. to be available for prototype monkey-patching under their interface
names as properties of `window`?

Then we wouldn't have to worry about what Array-like methods need to be
provided on HTMLCollection, because application and framework authors
could choose whichever they liked to prototype in.

IE8/Moz/Op/Saf/Chr already do this to a significant extent, but there's
no standard that says they have to. It would allow DOM extension to be
put on a much less shaky footing than the messy hack Prototype 1.x uses.

Is this something that's a reasonable requirement for browsers in 
future?


HTML5 through WebIDL and its ECMAScript binding already does require 
this.


I can see where interfaces are expected to be exposed 
([NamedConstructor]) in the global object, but I don't see where it is 
said that the prototype of the constructor must be extensible. I don't 
even see this in the section which is the relevent one in my opinion 
(Interface prototype object)

I have read this version of WebIDL : http://dev.w3.org/2006/webapi/WebIDL/

David


Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-04-27 Thread Geoffrey Sneddon

On 26/04/10 19:50, And Clover wrote:

David Flanagan wrote:


Rather that trying to make DOM collections feel like arrays, how about
just giving them a toArray() method?


I like that, as a practical and explicit (JavaScript-specific) binding.

In the longer term, what's the thinking on a more basic change:

- Require specific DOM interfaces like NodeList, HTMLCollection, Element
etc. to be available for prototype monkey-patching under their interface
names as properties of `window`?

Then we wouldn't have to worry about what Array-like methods need to be
provided on HTMLCollection, because application and framework authors
could choose whichever they liked to prototype in.

IE8/Moz/Op/Saf/Chr already do this to a significant extent, but there's
no standard that says they have to. It would allow DOM extension to be
put on a much less shaky footing than the messy hack Prototype 1.x uses.

Is this something that's a reasonable requirement for browsers in future?


HTML5 through WebIDL and its ECMAScript binding already does require this.

--
Geoffrey Sneddon — Opera Software




Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection (JZ and David Bruant)

2010-04-26 Thread David Bruant

Le 26/04/2010 11:25, Frank Migacz a écrit :
  What is the implication of denying dynamic changes to the 
HTMLCollection in a CORS environment?  In some variant of Comet 
(or asynchronous UA polling), how can the UA implement change if it is 
regularly processing inside locked control blocks?
I am not sure I fully understand what you are saying. I don't have the 
impression that in the code samples we wrote we were locked in any 
control block.

Can you provide more details with your example ?

To answer one question (which may not be yours), if a JS code is stuck 
in a while(1), then, events are never handled. In that situation, 
XMLHttpRequest events or server-sent events are particular cases of 
events which won't be handled as well.


David


Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-04-26 Thread David Bruant

Le 26/04/2010 10:33, Garrett Smith a écrit :

On Mon, Apr 26, 2010 at 9:49 AM, Erik Arvidsson  wrote:
   

On Sun, Apr 25, 2010 at 01:07, David Bruant  wrote:
 

Le 25/04/2010 00:39, J Z a écrit :
   

I have thought a lot about weirdnesses that people could think about like
trying to assign a value to the HTMLCollection (divs[14] = myOtherDiv), but
once again, it wouldn't be more allowed than it currently is (I have no idea
of what happens today, but if an error is thrown in a for-loop, it should
throw an error as well in a call within a forEach).
 

How would destructive methods like `push` or `sort` behave? Would
`document.body.childNodes.push(document.createTextNode('foo'))` append text
node to a body element? Or would it be a noop?

That is actually a very good point.
It think that the behavior should be exactly the same as "an equivalent
without array methods". (this point of my proposal would need to be made
completly explicit for each method)
   

One way to solve this could be to split Array into two interfaces. One
to be used with immutable array like objects and one to use to mutate
objects. Then we could apply the immutable array like interface to
NodeList and its related interfaces. The benefit of doing that is that
NodeList.prototype.push would be undefined instead of failing when
called.
 

Yes, that was also discussed on es-discuss list.

The complaints that have been mentioned on this thread are also detailed:
https://mail.mozilla.org/pipermail/es-discuss/2009-May/009300.html
https://mail.mozilla.org/pipermail/es-discuss/2009-May/009323.html

- and the reply by Allen:
https://mail.mozilla.org/pipermail/es-discuss/2009-May/009323.html
   

I assume you meant :
https://mail.mozilla.org/pipermail/es-discuss/2009-May/009355.html

| I'm probably repeating myself here, but an new interface is not
| necessary to make this requirement explicit.  If you want (and
| can get agreement) for these objects to fully implement
| ECMAScript native object semantics then that is all you have to
| say in the WebIDL JavaScript binding specification.

Nobody argued with that post, which concluded the thread.
   
I assume Allen Wirfs-Brock meant "implement ECMAScript native object 
semantics" ... as host objects. And I agree with this idea or would 
suggest to say what we have to say either in the WebIDL ECMAScript 
binding or an independent rewriting of the DOM HTML ES binding.


In one of the email you refer to, you said :
>Host objects currently behave in implementation-dependent manner.
>Nobody likes it, but that's the way it is. I do not think such
>"implementation dependent" behavior should be arbitrary.

In my opinion, it's the role of the ECMAScript binding specification to 
determine what is implementation-dependent and what is not. Role that 
previous specifications didn't fill, allowing web browsers to choose, 
thus leading authors to do feature detection or browser sniffing.


I realize now that there is actually a lot that has never been said 
about ECMAScript bindings. WebIDL seems to be a good start. I will have 
a closer look at it.



Back to the main subject, I find interesting the idea of defining 
immutable arrays. To be more precise in the proposal, I would first 
suggest the following :
An *ImmutableCollection* constructor with a prototype containing the 
following methods :

* join
* slice (btw, .slice(0) would return an Array which is a static copy of 
the HTMLCollection)

* splice
* indexOf/lastIndexOf
* every/some
* forEach
* map
* filter
* reduce/reduceRight

Basically, it's all methods where no [[defineOwnProperty]] is used 
directly or indirectly (like through [[put]]).


The definition of each method is strictly the same definition than the 
corresponding method in Array.prototype.


Having this constructor and imposing that HTMLCollections inherit from 
it would make that it is not implementation-dependent anymore.


For the moment, this constructor would be created only for the 
ECMAScript binding purpose.


It would avoid to define methods which, we know, would systematically fail.


Rather that trying to make DOM collections feel like arrays, how about just
>  giving them a toArray() method?  This makes it clear that a collection is
>  not an array, but clearly defines a way to obtain an array.  Clever
>  implementors might even be able to optimize common uses-cases using some
>  kind of copy-on-write strategy so that toArray() doesn't involve memory
>  allocation and copying.
   
That might be better than nothing but why should a NodeList not have a

forEach method? It is pretty clear that people want to be able to
treat Arguments and NodeList as Arrays.
   
With my aforementionned proposal. HTMLCollections would have direclty a 
forEach method.


About the idea of clearly defining a way to obtain an Array (for its 
staticness), a method could be added, but no to 
ImmutableCollection.prototype.
Another constructor and prototype would be needed to deal w

Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection (JZ and David Bruant)

2010-04-26 Thread Frank Migacz
   What is the implication of denying dynamic changes to the HTMLCollection
in a CORS environment?  In some variant of Comet (or asynchronous UA
polling), how can the UA implement change if it is regularly processing
inside locked control blocks?

   Please pardon my ignorance of the details.

Frank Migacz, Technical Instructor
fmig...@gmail.com

excerpt:
>> As far as I can see, liveness of HTMLCollection actually does matter.
When
>> iterating over HTMLCollection, it's more or less a rule of thumb to
"save"
>> length, to avoid any kind of mismatch (in case code within loop modifies
>> document and so affects length of collection in question):
>>
>> for (var i = 0, length = collection.length; i < length; i++)
>> // instead of:
>> for (var i = 0; i < collection.length; i++)
>>

And another excerpt:
>> For push, I think that :
>>
>> collection.push(document.createTextNode('foo'));
>>
>> // should behave exactly as :
>>
>> collection.childNodes[collection.length] =
document.createTextNode('foo');
>>
>> I don't know what is the current behavior, but if it throws an error,
>> push should throw the same error. If it appends a text node to the body,
>> then push should do the same.
>> sort is a bunch of :
>>
>> "tmp = collection[i];
>> collection[i] = collection[j];
>> collection[j] = tmp"
>>
>> The first instruction is harmless, but if the second one would throw an
>> error, then let's throw the same error for .sort.
>>


Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-04-26 Thread And Clover

David Flanagan wrote:

Rather that trying to make DOM collections feel like arrays, how about 
just giving them a toArray() method?


I like that, as a practical and explicit (JavaScript-specific) binding.

In the longer term, what's the thinking on a more basic change:

- Require specific DOM interfaces like NodeList, HTMLCollection, Element 
etc. to be available for prototype monkey-patching under their interface 
names as properties of `window`?


Then we wouldn't have to worry about what Array-like methods need to be 
provided on HTMLCollection, because application and framework authors 
could choose whichever they liked to prototype in.


IE8/Moz/Op/Saf/Chr already do this to a significant extent, but there's 
no standard that says they have to. It would allow DOM extension to be 
put on a much less shaky footing than the messy hack Prototype 1.x uses.


Is this something that's a reasonable requirement for browsers in future?

--
And Clover
mailto:a...@doxdesk.com
http://www.doxdesk.com/



Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-04-26 Thread Erik Arvidsson
> Rather that trying to make DOM collections feel like arrays, how about just
> giving them a toArray() method?  This makes it clear that a collection is
> not an array, but clearly defines a way to obtain an array.  Clever
> implementors might even be able to optimize common uses-cases using some
> kind of copy-on-write strategy so that toArray() doesn't involve memory
> allocation and copying.

That might be better than nothing but why should a NodeList not have a
forEach method? It is pretty clear that people want to be able to
treat Arguments and NodeList as Arrays.

-- 
erik


Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-04-26 Thread Garrett Smith
On Mon, Apr 26, 2010 at 9:49 AM, Erik Arvidsson  wrote:
> On Sun, Apr 25, 2010 at 01:07, David Bruant  wrote:
>> Le 25/04/2010 00:39, J Z a écrit :
>>>
>>> I have thought a lot about weirdnesses that people could think about like
>>> trying to assign a value to the HTMLCollection (divs[14] = myOtherDiv), but
>>> once again, it wouldn't be more allowed than it currently is (I have no idea
>>> of what happens today, but if an error is thrown in a for-loop, it should
>>> throw an error as well in a call within a forEach).
>>
>> How would destructive methods like `push` or `sort` behave? Would
>> `document.body.childNodes.push(document.createTextNode('foo'))` append text
>> node to a body element? Or would it be a noop?
>>
>> That is actually a very good point.
>> It think that the behavior should be exactly the same as "an equivalent
>> without array methods". (this point of my proposal would need to be made
>> completly explicit for each method)
>
> One way to solve this could be to split Array into two interfaces. One
> to be used with immutable array like objects and one to use to mutate
> objects. Then we could apply the immutable array like interface to
> NodeList and its related interfaces. The benefit of doing that is that
> NodeList.prototype.push would be undefined instead of failing when
> called.
>

Yes, that was also discussed on es-discuss list.

The complaints that have been mentioned on this thread are also detailed:
https://mail.mozilla.org/pipermail/es-discuss/2009-May/009300.html
https://mail.mozilla.org/pipermail/es-discuss/2009-May/009323.html

- and the reply by Allen:
https://mail.mozilla.org/pipermail/es-discuss/2009-May/009323.html

| I'm probably repeating myself here, but an new interface is not
| necessary to make this requirement explicit.  If you want (and
| can get agreement) for these objects to fully implement
| ECMAScript native object semantics then that is all you have to
| say in the WebIDL JavaScript binding specification.

Nobody argued with that post, which concluded the thread.


Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-04-26 Thread David Flanagan

Erik Arvidsson wrote:

for (var i = 0, length = collection.length; i < length; i++)
// instead of:
for (var i = 0; i < collection.length; i++)


Actually, the former is a problem when the nodelist is modified in the
loop; it may result in collection[i] being undefined.


Even when checking the length in every iteration you can run into
problems. If you remove something earlier in the collection you will
*miss* one item unless you fix the loop iterator.

We should not let these edge cases get in the way of making the DOM
collections feel less foreign to JavaScript.

--
erik



Rather that trying to make DOM collections feel like arrays, how about 
just giving them a toArray() method?  This makes it clear that a 
collection is not an array, but clearly defines a way to obtain an 
array.  Clever implementors might even be able to optimize common 
uses-cases using some kind of copy-on-write strategy so that toArray() 
doesn't involve memory allocation and copying.


Of course, trying to teach programmers when they ought to call toArray() 
and when it is not necessary is another matter.  Perhaps calling the 
method snapshot() and focusing on the live vs. static distinction 
instead of the fake array vs. true array distinction would invite less 
misuse.


Or we can just leave the DOM as it is and get used to calling the 
equivalent of Prototype's $A() function.


David


Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-04-26 Thread Erik Arvidsson
On Sun, Apr 25, 2010 at 01:07, David Bruant  wrote:
> Le 25/04/2010 00:39, J Z a écrit :
>>
>> I have thought a lot about weirdnesses that people could think about like
>> trying to assign a value to the HTMLCollection (divs[14] = myOtherDiv), but
>> once again, it wouldn't be more allowed than it currently is (I have no idea
>> of what happens today, but if an error is thrown in a for-loop, it should
>> throw an error as well in a call within a forEach).
>
> How would destructive methods like `push` or `sort` behave? Would
> `document.body.childNodes.push(document.createTextNode('foo'))` append text
> node to a body element? Or would it be a noop?
>
> That is actually a very good point.
> It think that the behavior should be exactly the same as "an equivalent
> without array methods". (this point of my proposal would need to be made
> completly explicit for each method)

One way to solve this could be to split Array into two interfaces. One
to be used with immutable array like objects and one to use to mutate
objects. Then we could apply the immutable array like interface to
NodeList and its related interfaces. The benefit of doing that is that
NodeList.prototype.push would be undefined instead of failing when
called.

-- 
erik


Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-04-26 Thread Erik Arvidsson
>> for (var i = 0, length = collection.length; i < length; i++)
>> // instead of:
>> for (var i = 0; i < collection.length; i++)
>>
>
> Actually, the former is a problem when the nodelist is modified in the
> loop; it may result in collection[i] being undefined.

Even when checking the length in every iteration you can run into
problems. If you remove something earlier in the collection you will
*miss* one item unless you fix the loop iterator.

We should not let these edge cases get in the way of making the DOM
collections feel less foreign to JavaScript.

--
erik


Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-04-25 Thread David Bruant

Le 25/04/2010 00:39, J Z a écrit :



I have thought a lot about weirdnesses that people could think
about like trying to assign a value to the HTMLCollection
(divs[14] = myOtherDiv), but once again, it wouldn't be more
allowed than it currently is (I have no idea of what happens
today, but if an error is thrown in a for-loop, it should throw an
error as well in a call within a forEach).


How would destructive methods like `push` or `sort` behave? Would 
`document.body.childNodes.push(document.createTextNode('foo'))` append 
text node to a body element? Or would it be a noop?

That is actually a very good point.
It think that the behavior should be exactly the same as "an equivalent 
without array methods". (this point of my proposal would need to be made 
completly explicit for each method)

For push, I think that :

collection.push(document.createTextNode('foo'));

// should behave exactly as :

collection.childNodes[collection.length] = document.createTextNode('foo');

I don't know what is the current behavior, but if it throws an error, 
push should throw the same error. If it appends a text node to the body, 
then push should do the same.


sort is a bunch of :
"tmp = collection[i];
collection[i] = collection[j];
collection[j] = tmp"

The first instruction is harmless, but if the second one would throw an 
error, then let's throw the same error for .sort.


The array.prototype methods are actually "shortcuts" for usual coding 
patterns. I describe forEach here : 
http://longtermlaziness.wordpress.com/2010/04/19/array-foreach-introduction/ 
(by the way, you must be the same Kangax who did the ES5 compat table. 
Thank you very much for this work.)

And I have just described push and sort.

Of course, some patterns (like push, pop, sort, reduce...) may not be 
compatible with the fact that we are dealing with live objects. I think 
that it is fine. The way those patterns were working (throwing error, 
doing nothing, creating a new collection item, whatever) should work the 
same with the "shortcuts". There is no reason to change anything from 
the DOM point of view and behaviors that was happening on the DOM. Just 
"embed the behavior in the shortcut".


Once again, I only want to change the ECMAScript language binding, not 
the DOM interfaces or semantics.


Thank you for your answers,

David


Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-04-25 Thread J Z
On Sun, Apr 25, 2010 at 2:33 AM, David Bruant wrote:

>  Le 24/04/2010 22:50, J Z a écrit :
>
> On Fri, Apr 23, 2010 at 10:30 PM, David Bruant 
> wrote:
>
>> Hi,
>>
>> In the HTML5 "status of this document" section, one can read : "This
>> specification is intended to replace (be the new version of) what was
>> previously the [...] DOM2 HTML specifications."
>> This spec can be found here : http://www.w3.org/TR/DOM-Level-2-HTML/
>>
>> It defines ECMAScript language Binding (
>> http://www.w3.org/TR/DOM-Level-2-HTML/ecma-script-binding.html). This
>> document explains how to implement the DOM HTML interfaces in an
>> ECMAScript-compliant environment.
>>
>> Because HTML5 is intended to replace DOM2 HTML, it can "freely" change
>> ECMAScript bindings. My suggestion is the following :
>> Make that HTMLCollection (and all HTML*Collection, as a consequence of
>> inheritence of HTMLCollection) inherit from the ECMAScript Array prototype.
>> This way, it will make available all Array extra methods (forEach, map,
>> filter...) added in ECMAScript5 (and next versions which should go in the
>> same direction).
>>
>> As far as I know, adding this won't break any existing code. The semantics
>> of a Collection and the way it is used is very close from ECMAScript Arrays.
>> I don't think that the notion of "live object" and ECMAScript Array are
>> incompatible either.
>> Once again, I am talking about ECMAScript binding. I have no intention to
>> touch the HTMLCollection interface or other languages bindings.
>>
>> Would the WHATWG have the power to decide something similar regarding
>> NodeList ?
>>
>> Any thoughts ?
>>
>> Thanks,
>>
>> David
>>
>
> As far as I can see, liveness of HTMLCollection actually does matter. When
> iterating over HTMLCollection, it's more or less a rule of thumb to "save"
> length, to avoid any kind of mismatch (in case code within loop modifies
> document and so affects length of collection in question):
>
> for (var i = 0, length = collection.length; i < length; i++)
> // instead of:
> for (var i = 0; i < collection.length; i++)
>
> I think I can take your point as a "pro" more than a "con", because in ES5,
> right before the definition of each array extra method, a paragraph like the
> following can be found :
> "The range of elements processed by forEach is set before the first call to
> callbackfn. Elements which are appended to the array after the call to
> forEach begins will not be visited by callbackfn. If existing elements of
> the array are changed, their value as passed to callback will be the value
> at the time forEach visits them; elements that are deleted after the call to
> forEach begins and before being visited are not visited."
>
> This point is confirmed by every algorithm where the length is "saved" once
> for all before the loop and not got from the .length property each time.
>

Oh, perfect :)


If HTMLCollection was inheriting from Array, and methods like `forEach`,
`map`, etc. were to operate on a live object, there would definitely be
undesired consequences. We can see this in, say, Firefox (which allows to
set [[Prototype]] of `HTMLCollection` to `Array.prototype`):

HTMLCollection.prototype.__proto__ = Array.prototype;

document.getElementsByTagName('div').forEach(function(el) {
  el.parentNode.removeChild(el); // doesn't work as expected
});

This code doesn't work as expected as the following doesn't either :
> var divs = document.getElementsByTagName('div');
> for(var i=0, l = divs.length ; i < l ; i++){
> var el = divs[i]; // Due to the live-ness, this might not work as
> expected
> el.parentNode.removeChild(el);
> }
>
> This code written as a for-loop behave exactly the same way (in this case)
> as the .forEach one, so it's as buggy as the forEach one.
>

Sorry, that was a stupid example indeed. It should have been at least
something along the lines of:

var els = document.getElementsByTagName('span');

for (var i = 0; i < els.length; /* can't access length dynamically */ i++) {
  var spanEl = document.createElement('span');
  spanEl.appendChild(document.createTextNode('foo'));
  document.body.appendChild(spanEl);
}


> My point is that forEach doesn't create more bugs than before, which is
> what you seem to imply.
>

If it operates on "static" collection, then I don't see problems either.


> Adding .forEach and other Array extras wouldn't prevent programmers to
> remember that they are dealing with a live object even within a .forEach,
> the same way they are not supposed to forget it with a for-loop.
>

Sure.


>
> I have thought a lot about weirdnesses that people could think about like
> trying to assign a value to the HTMLCollection (divs[14] = myOtherDiv), but
> once again, it wouldn't be more allowed than it currently is (I have no idea
> of what happens today, but if an error is thrown in a for-loop, it should
> throw an error as well in a call within a forEach).
>

How would destructive methods like `push` or `sort` behave? Would
`document.

Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-04-24 Thread David Bruant



// turning live collection into static array fixes this

Array.slice(document.getElementsByTagName('div')).forEach(function(el) {
   el.parentNode.removeChild(el);
});

 

Where supported, though top level generics such as Array.slice are not
standard, so:

var divList = document.getElementsByTagName('div');
Array.prototype.slice.call( divList );

Elsewhere:
https://mail.mozilla.org/pipermail/es-discuss/2009-December/010241.html
   

Ok. I understand the "Array.slice" now. Sorry.
"Array.prototype.slice.call( divList );" is not standard either. In 
ECMAScript 5, it is stated that :
"The slice function is intentionally generic; it does not require that 
its this value be an Array object. Therefore it can be transferred to 
other kinds of objects for use as a method. Whether the slice function 
can be applied successfully to a host object is implementation-dependent."


Somehow, the reason why I am proposing that HTMLCollections inherit from 
Array.prototype is to get rid of the "implementation-dependant" for 
HTMLCollections which are clearly very good candidates for methods such 
as forEach, filter (returns a new array (which would be a convinient way 
to create static copies in one call)) or some/every.


David


Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-04-24 Thread Garrett Smith
On Sat, Apr 24, 2010 at 10:50 PM, J Z  wrote:
> On Fri, Apr 23, 2010 at 10:30 PM, David Bruant 
> wrote:
>>
>> Hi,
>>
>> In the HTML5 "status of this document" section, one can read : "This
>> specification is intended to replace (be the new version of) what was
>> previously the [...] DOM2 HTML specifications."
>> This spec can be found here : http://www.w3.org/TR/DOM-Level-2-HTML/
>>
>> It defines ECMAScript language Binding
>> (http://www.w3.org/TR/DOM-Level-2-HTML/ecma-script-binding.html). This
>> document explains how to implement the DOM HTML interfaces in an
>> ECMAScript-compliant environment.
>>
>> Because HTML5 is intended to replace DOM2 HTML, it can "freely" change
>> ECMAScript bindings. My suggestion is the following :
>> Make that HTMLCollection (and all HTML*Collection, as a consequence of
>> inheritence of HTMLCollection) inherit from the ECMAScript Array prototype.
>> This way, it will make available all Array extra methods (forEach, map,
>> filter...) added in ECMAScript5 (and next versions which should go in the
>> same direction).
>>
>> As far as I know, adding this won't break any existing code. The semantics
>> of a Collection and the way it is used is very close from ECMAScript Arrays.
>> I don't think that the notion of "live object" and ECMAScript Array are
>> incompatible either.
>> Once again, I am talking about ECMAScript binding. I have no intention to
>> touch the HTMLCollection interface or other languages bindings.
>>
>> Would the WHATWG have the power to decide something similar regarding
>> NodeList ?
>>
>> Any thoughts ?
>>
>> Thanks,
>>
>> David
>
> As far as I can see, liveness of HTMLCollection actually does matter. When
> iterating over HTMLCollection, it's more or less a rule of thumb to "save"
> length, to avoid any kind of mismatch (in case code within loop modifies
> document and so affects length of collection in question):
>
> for (var i = 0, length = collection.length; i < length; i++)
> // instead of:
> for (var i = 0; i < collection.length; i++)
>

Actually, the former is a problem when the nodelist is modified in the
loop; it may result in collection[i] being undefined.

The reason for storing length can only be to save a few milliseconds
in checking it each time i.e. "get the length property".

> If HTMLCollection was inheriting from Array, and methods like `forEach`,
> `map`, etc. were to operate on a live object, there would definitely be
> undesired consequences. We can see this in, say, Firefox (which allows to
> set [[Prototype]] of `HTMLCollection` to `Array.prototype`):
>
> HTMLCollection.prototype.__proto__ = Array.prototype;
>

Scary.

> document.getElementsByTagName('div').forEach(function(el) {
>   el.parentNode.removeChild(el); // doesn't work as expected
> });
>

Removing a child div of an already removed div seems a bit odd, but whatever.

> // turning live collection into static array fixes this
>
> Array.slice(document.getElementsByTagName('div')).forEach(function(el) {
>   el.parentNode.removeChild(el);
> });
>
Where supported, though top level generics such as Array.slice are not
standard, so:

var divList = document.getElementsByTagName('div');
Array.prototype.slice.call( divList );

Elsewhere:
https://mail.mozilla.org/pipermail/es-discuss/2009-December/010241.html


Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-04-24 Thread David Bruant

Le 24/04/2010 22:50, J Z a écrit :
On Fri, Apr 23, 2010 at 10:30 PM, David Bruant 
mailto:bru...@enseirb-matmeca.fr>> wrote:


Hi,

In the HTML5 "status of this document" section, one can read :
"This specification is intended to replace (be the new version of)
what was previously the [...] DOM2 HTML specifications."
This spec can be found here : http://www.w3.org/TR/DOM-Level-2-HTML/

It defines ECMAScript language Binding
(http://www.w3.org/TR/DOM-Level-2-HTML/ecma-script-binding.html).
This document explains how to implement the DOM HTML interfaces in
an ECMAScript-compliant environment.

Because HTML5 is intended to replace DOM2 HTML, it can "freely"
change ECMAScript bindings. My suggestion is the following :
Make that HTMLCollection (and all HTML*Collection, as a
consequence of inheritence of HTMLCollection) inherit from the
ECMAScript Array prototype. This way, it will make available all
Array extra methods (forEach, map, filter...) added in ECMAScript5
(and next versions which should go in the same direction).

As far as I know, adding this won't break any existing code. The
semantics of a Collection and the way it is used is very close
from ECMAScript Arrays.
I don't think that the notion of "live object" and ECMAScript
Array are incompatible either.
Once again, I am talking about ECMAScript binding. I have no
intention to touch the HTMLCollection interface or other languages
bindings.

Would the WHATWG have the power to decide something similar
regarding NodeList ?

Any thoughts ?

Thanks,

David


As far as I can see, liveness of HTMLCollection actually does matter. 
When iterating over HTMLCollection, it's more or less a rule of thumb 
to "save" length, to avoid any kind of mismatch (in case code within 
loop modifies document and so affects length of collection in question):


for (var i = 0, length = collection.length; i < length; i++)
// instead of:
for (var i = 0; i < collection.length; i++)
I think I can take your point as a "pro" more than a "con", because in 
ES5, right before the definition of each array extra method, a paragraph 
like the following can be found :
"The range of elements processed by forEach is set before the first call 
to callbackfn. Elements which are appended to the array after the call 
to forEach begins will not be visited by callbackfn. If existing elements of
the array are changed, their value as passed to callback will be the 
value at the time forEach visits them; elements that are deleted after 
the call to forEach begins and before being visited are not visited."


This point is confirmed by every algorithm where the length is "saved" 
once for all before the loop and not got from the .length property each 
time.





If HTMLCollection was inheriting from Array, and methods like 
`forEach`, `map`, etc. were to operate on a live object, there would 
definitely be undesired consequences. We can see this in, say, Firefox 
(which allows to set [[Prototype]] of `HTMLCollection` to 
`Array.prototype`):


HTMLCollection.prototype.__proto__ = Array.prototype;

document.getElementsByTagName('div').forEach(function(el) {
  el.parentNode.removeChild(el); // doesn't work as expected
});

This code doesn't work as expected as the following doesn't either :
var divs = document.getElementsByTagName('div');
for(var i=0, l = divs.length ; i < l ; i++){
var el = divs[i]; // Due to the live-ness, this might not work as 
expected

el.parentNode.removeChild(el);
}

This code written as a for-loop behave exactly the same way (in this 
case) as the .forEach one, so it's as buggy as the forEach one.
My point is that forEach doesn't create more bugs than before, which is 
what you seem to imply.
Adding .forEach and other Array extras wouldn't prevent programmers to 
remember that they are dealing with a live object even within a 
.forEach, the same way they are not supposed to forget it with a for-loop.


I have thought a lot about weirdnesses that people could think about 
like trying to assign a value to the HTMLCollection (divs[14] = 
myOtherDiv), but once again, it wouldn't be more allowed than it 
currently is (I have no idea of what happens today, but if an error is 
thrown in a for-loop, it should throw an error as well in a call within 
a forEach).



This has nothing to do with this thread, but 
document.getElementsByTagName('div') should return a NodeList 
(http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-A6C9094). Returning 
an HTMLCollection is a Firefox bug 
(https://bugzilla.mozilla.org/show_bug.cgi?id=14869).





// turning live collection into static array fixes this

Array.slice(document.getElementsByTagName('div')).forEach(function(el) {
  el.parentNode.removeChild(el);
});
I have not found anything about a Array.slice method and the ES5 .splice 
method doesn't seem to by usable in the way you describe. What did you 
mean ?


The idea of tu

Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-04-24 Thread J Z
On Fri, Apr 23, 2010 at 10:30 PM, David Bruant wrote:

> Hi,
>
> In the HTML5 "status of this document" section, one can read : "This
> specification is intended to replace (be the new version of) what was
> previously the [...] DOM2 HTML specifications."
> This spec can be found here : http://www.w3.org/TR/DOM-Level-2-HTML/
>
> It defines ECMAScript language Binding (
> http://www.w3.org/TR/DOM-Level-2-HTML/ecma-script-binding.html). This
> document explains how to implement the DOM HTML interfaces in an
> ECMAScript-compliant environment.
>
> Because HTML5 is intended to replace DOM2 HTML, it can "freely" change
> ECMAScript bindings. My suggestion is the following :
> Make that HTMLCollection (and all HTML*Collection, as a consequence of
> inheritence of HTMLCollection) inherit from the ECMAScript Array prototype.
> This way, it will make available all Array extra methods (forEach, map,
> filter...) added in ECMAScript5 (and next versions which should go in the
> same direction).
>
> As far as I know, adding this won't break any existing code. The semantics
> of a Collection and the way it is used is very close from ECMAScript Arrays.
> I don't think that the notion of "live object" and ECMAScript Array are
> incompatible either.
> Once again, I am talking about ECMAScript binding. I have no intention to
> touch the HTMLCollection interface or other languages bindings.
>
> Would the WHATWG have the power to decide something similar regarding
> NodeList ?
>
> Any thoughts ?
>
> Thanks,
>
> David
>

As far as I can see, liveness of HTMLCollection actually does matter. When
iterating over HTMLCollection, it's more or less a rule of thumb to "save"
length, to avoid any kind of mismatch (in case code within loop modifies
document and so affects length of collection in question):

for (var i = 0, length = collection.length; i < length; i++)
// instead of:
for (var i = 0; i < collection.length; i++)

If HTMLCollection was inheriting from Array, and methods like `forEach`,
`map`, etc. were to operate on a live object, there would definitely be
undesired consequences. We can see this in, say, Firefox (which allows to
set [[Prototype]] of `HTMLCollection` to `Array.prototype`):

HTMLCollection.prototype.__proto__ = Array.prototype;

document.getElementsByTagName('div').forEach(function(el) {
  el.parentNode.removeChild(el); // doesn't work as expected
});

// turning live collection into static array fixes this

Array.slice(document.getElementsByTagName('div')).forEach(function(el) {
  el.parentNode.removeChild(el);
});

-- 
kangax