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 Oliver Hunt

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

 On 8/4/10, Oliver Hunt oli...@apple.com wrote:
 
 On Aug 4, 2010, at 3:32 PM, Garrett Smith wrote:
 
 On 8/4/10, Garrett Smith dhtmlkitc...@gmail.com 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-05 Thread Garrett Smith
On 8/5/10, Oliver Hunt oli...@apple.com wrote:

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

 On 8/4/10, Oliver Hunt oli...@apple.com wrote:

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

 On 8/4/10, Garrett Smith dhtmlkitc...@gmail.com 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 Garrett Smith
On 8/5/10, Garrett Smith dhtmlkitc...@gmail.com wrote:
 On 8/5/10, Oliver Hunt oli...@apple.com wrote:

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

 On 8/4/10, Oliver Hunt oli...@apple.com wrote:

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

 On 8/4/10, Garrett Smith dhtmlkitc...@gmail.com 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-04 Thread Alex Russell
Sorry for the lagged response,

On Fri, Jul 30, 2010 at 2:56 PM, Oliver Hunt oli...@apple.com wrote:

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

 On Fri, Jul 30, 2010 at 4:18 AM, Jonas Sicking jo...@sicking.cc wrote:
 On Thu, Jul 29, 2010 at 5:45 PM, Ian Hickson i...@hixie.ch 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-08-04 Thread Jonas Sicking
On Wed, Aug 4, 2010 at 11:10 AM, Alex Russell slightly...@google.com wrote:
 Sorry for the lagged response,

 On Fri, Jul 30, 2010 at 2:56 PM, Oliver Hunt oli...@apple.com wrote:

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

 On Fri, Jul 30, 2010 at 4:18 AM, Jonas Sicking jo...@sicking.cc wrote:
 On Thu, Jul 29, 2010 at 5:45 PM, Ian Hickson i...@hixie.ch 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 

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 slightly...@google.com wrote:
 Sorry for the lagged response,
 
 On Fri, Jul 30, 2010 at 2:56 PM, Oliver Hunt oli...@apple.com 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 Garrett Smith
On 8/4/10, Jonas Sicking jo...@sicking.cc wrote:
 On Wed, Aug 4, 2010 at 11:10 AM, Alex Russell slightly...@google.com
 wrote:
 Sorry for the lagged response,

 On Fri, Jul 30, 2010 at 2:56 PM, Oliver Hunt oli...@apple.com wrote:

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

 On Fri, Jul 30, 2010 at 4:18 AM, Jonas Sicking jo...@sicking.cc wrote:
 On Thu, Jul 29, 2010 at 5:45 PM, Ian Hickson i...@hixie.ch 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 have done that. It would not be immutable. How much
interoperability issue would changing it now cause? Array could be an
ECMA binding as a potential consideration as an idea for alternative
to non-live static nodelist.

Changing live collections to be Arrays would cause severe
interoperability problems. It would be very complicated.

Then if you're going to get an array, it should be possible to set an
array. I suppose in this sort of situation a setItems method could be
useful:

  var cells = Array.prototype.slice.call(row.cells).sort( comparator );
  row.childNodes.setItems( cells );

The first line is a bit ugly and so it would be nice to have it a more
succinct, not to save typing, 

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

2010-08-04 Thread Garrett Smith
On 8/4/10, Garrett Smith dhtmlkitc...@gmail.com 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 Oliver Hunt

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

 On 8/4/10, Garrett Smith dhtmlkitc...@gmail.com 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, Oliver Hunt oli...@apple.com wrote:

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

 On 8/4/10, Garrett Smith dhtmlkitc...@gmail.com 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:
http://jibbering.com/faq/names/extra_props.html

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-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-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 Garrett Smith
On 8/2/10, Oliver Hunt oli...@apple.com 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:
https://mail.mozilla.org/pipermail/es-discuss/2010-July/thread.html#11501

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 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 Jonas Sicking
On Fri, Jul 30, 2010 at 2:46 PM, Alex Russell slightly...@google.com wrote:
 On Fri, Jul 30, 2010 at 4:18 AM, Jonas Sicking jo...@sicking.cc wrote:
 On Thu, Jul 29, 2010 at 5:45 PM, Ian Hickson i...@hixie.ch 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 arrays?

 I don't think this makes sense given the immutability 

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 
(132)-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 Garrett Smith
On 8/2/10, And Clover and...@doxdesk.com 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
 (132)-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:
http://www.jibbering.com/faq/names/

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 Garrett Smith
On 8/2/10, Garrett Smith dhtmlkitc...@gmail.com wrote:
 On 8/2/10, And Clover and...@doxdesk.com 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-07-30 Thread Jonas Sicking
On Thu, Jul 29, 2010 at 5:45 PM, Ian Hickson i...@hixie.ch 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 arrays?

I don't think this makes sense given the immutability of NodeLists.

  - provide a toArray() method or equivalent?

I think this would make sense, though I think it's also worth
supplying functions that 

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 oli...@apple.com 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 Garrett Smith
On 7/29/10, Garrett Smith dhtmlkitc...@gmail.com wrote:
 On 7/29/10, Ian Hickson i...@hixie.ch 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 Alex Russell
On Fri, Jul 30, 2010 at 4:18 AM, Jonas Sicking jo...@sicking.cc wrote:
 On Thu, Jul 29, 2010 at 5:45 PM, Ian Hickson i...@hixie.ch 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 arrays?

 I don't think this makes sense given the immutability of NodeLists.

Wait...what? Shouldn't some sort of NodeList be mutable? And 

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 jo...@sicking.cc wrote:
 On Thu, Jul 29, 2010 at 5:45 PM, Ian Hickson i...@hixie.ch 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 arrays?
 
 I don't think this makes sense given the immutability of NodeLists.
 
 

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   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  

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
da...@davidflanagan.com 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 Oliver Hunt

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

 On Mon, Apr 26, 2010 at 10:04 AM, David Flanagan
 da...@davidflanagan.com 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 Garrett Smith
On 7/29/10, Ian Hickson i...@hixie.ch 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 (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 Grahamjgra...@opera.com  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
http://gsnedders.com/
http://www.opera.com/


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 gsned...@opera.com wrote:
 On 28/04/10 23:28, Garrett Smith wrote:

 On Wed, Apr 28, 2010 at 2:12 AM, James Grahamjgra...@opera.com  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-28 Thread Garrett Smith
On Mon, Apr 26, 2010 at 10:04 AM, David Flanagan
da...@davidflanagan.com 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 (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
da...@davidflanagan.com  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

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
http://gsnedders.com/
http://www.opera.com/


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 (ATTN IE TEAM - TRAVIS LEITHEAD)

2010-04-28 Thread Garrett Smith
On Wed, Apr 28, 2010 at 2:12 AM, James Graham jgra...@opera.com 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 (JZ and David Bruant)

2010-04-27 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-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
http://gsnedders.com/
http://www.opera.com/


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-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 Garrett Smith
On Mon, Apr 26, 2010 at 9:49 AM, Erik Arvidsson a...@chromium.org wrote:
 On Sun, Apr 25, 2010 at 01:07, David Bruant bru...@enseirb-matmeca.fr 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 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 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 (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 David Bruant

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

On Mon, Apr 26, 2010 at 9:49 AM, Erik Arvidssona...@chromium.org  wrote:
   

On Sun, Apr 25, 2010 at 01:07, David Bruantbru...@enseirb-matmeca.fr  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 

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

2010-04-25 Thread Garrett Smith
On Sat, Apr 24, 2010 at 10:50 PM, J Z kangax@gmail.com wrote:
 On Fri, Apr 23, 2010 at 10:30 PM, David Bruant 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++)


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-25 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-25 Thread J Z
On Sun, Apr 25, 2010 at 2:33 AM, David Bruant bru...@enseirb-matmeca.frwrote:

  Le 24/04/2010 22:50, J Z a écrit :

 On Fri, Apr 23, 2010 at 10:30 PM, David Bruant 
 bru...@enseirb-matmeca.frwrote:

 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.body.childNodes.push(document.createTextNode('foo'))` append text
node to a body element? Or 

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