[whatwg] Adding ECMAScript 5 array extras to HTMLCollection

Garrett Smith dhtmlkitchen at gmail.com
Thu Jul 29 22:15:18 PDT 2010


On 7/29/10, Ian Hickson <ian at 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


More information about the whatwg mailing list