- From: Garrett Smith <dhtmlkitchen@gmail.com>
- Date: Thu, 28 Jul 2011 20:23:59 -0700
- To: Jonas Sicking <jonas@sicking.cc>
- Cc: Allen Wirfs-Brock <allen@wirfs-brock.com>, Alex Russell <slightlyoff@google.com>, public-script-coord@w3.org, Brendan Eich <brendan@mozilla.com>, Cameron McCormack <cam@mcc.id.au>
On 7/28/11, Jonas Sicking <jonas@sicking.cc> wrote: > On Thu, Jul 28, 2011 at 7:12 PM, Allen Wirfs-Brock > <allen@wirfs-brock.com> wrote: >> >> On Jul 28, 2011, at 5:04 PM, Jonas Sicking wrote: >> >>> As I asked above, what would the mutating functions do to "live" >>> NodeList? And IMHO only APIs that want to return "live" objects should >>> return NodeLists. Others should simply return arrays. >>> >>> >> >> In ES5 all of the Array.prototype functions are defined to operate upon >> generic objects with "array indexed" (ie, integer string values) >> properties. The objects they operate upon do not need to be Array >> instances. The functions are specified in terms of the basic ES5 internal >> operations such as [[Get]], [[Put]], etc. Such generic objects (or even >> Array instances for that matter) may, in ES5, have non-writable and >> non-deletable properties and the objects may be non-extensible. For that >> reason, the array algorithms all explicitly define how to deal with such >> situations. Generally, they throw when they try to modify a property in a >> manner that is forbidden for that object. >> >> If a DOM implementation provides reasonable implementations of [[Get]], >> [[Put]] and friends then the Array functions should just work on its DOM >> objects. Trying to reverse a read-only DOM object may not do anything >> useful, but its unuseful behavior would still be fully specified. > Yeah. > I'm very aware how the Array functions are defined. The problem is > that there aren't any reasonable defaults we could provide for > NodeList's [[Put]] operations simply due to what a NodeList > represents. > Well you could do like this: For [[Put]](I, N), if `I` is between 0 and nodeList.length, call replaceChild. If `I` == nodeList.length, call appendChild, otherwise, `I` is out of range so throw a RangeError. That makes NodeList work like an array. It's easier to let programs use an Array instead. I don't know if this is Alex' gripe but to me, NodeList -> Array (do operation) -> NodeList results in inelegant code. Alex proposes to make NodeList become an array but there's another way to improve the situation. I remember suggesting before a method `element.setChildNodes(nodeArray)`. I think this is the direction to go in; so using arrays to replaceChildNodes(nodeArray), appendChildNodes(nodeArray), insertChildNodes(ref, nodeArray), removeChildren(). A nodeArray coud be either a NodeList or an Array, but if any property < length is not a node, a TypeError would be thrown. That would make a lot of things a lot easier. Like sorting lists, for example, it would be used as: var kids = ul.children; arraySort(kids, byLastName); ul.replaceChildNodes(kids); Or for the one line wonderers: ul.replaceChildNodes(arraySort(ul.children, byLastName)); Otherwise you have to remove childNodes and then use a loop to append them in order. > The only reasonable thing we could do is to make all mutating > operations throw, which frankly would be a pretty strange API. I.e. > all NodeLists would have whole host of operations like .push and > .shift which always would throw. It would seem much better if those > operations weren't there. > Making mutable nodelist would be weird. Using an Array there makes sense. -- Garrett
Received on Friday, 29 July 2011 03:24:27 UTC