- From: David Bruant <bruant@enseirb-matmeca.fr>
- Date: Mon, 26 Apr 2010 21:56:29 -0700
Le 26/04/2010 10:33, Garrett Smith a ?crit : > On Mon, Apr 26, 2010 at 9:49 AM, Erik Arvidsson<arv at chromium.org> wrote: > >> On Sun, Apr 25, 2010 at 01:07, David Bruant<bruant at 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 prototype would be needed to deal with live (dynamic) objects. Maybe this constructor could be : *LiveCollection* with method(s) : * toStaticArray (I think that expliciting "static" is a good thing. It can be discussed) I have tried to separate the notion of "immutable" and "live/dynamic", because these are different concepts. It makes sense to say that live implies immutable, but the contrary is not obvious. I have not investigated, but I know that NodeLists returned by querySelectorAll are not live. I think that they are likely to be immutable (it would make sense in my opinion). I don't know any example for HTMLCollection. I'd be interested to know if there is any. For the moment, NodeList are out of the scope of this proposal since NodeList is out of the scope of HTML5 (NodeList is defined in DOM core level 3 as well as its ES 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? There are a lot of examples where adding or modifying an object/prototype you don't own ended to be harmful : http://www.nczonline.net/blog/2010/03/02/maintainable-javascript-dont-modify-objects-you-down-own/ http://perfectionkills.com/whats-wrong-with-extending-the-dom/ As such, my first reaction is to be cautious about this. For instance, if authors decide to do the following : HTMLCollection.prototype.filter = Array.prototype.filter; Then the filter method on HTMLCollection is expected to return an Array. If some day, the W3C or WHATWG decides that HTMLCollection are freely instanciable (var hcol = new HTMLCollection()) and contain a filter methods that MUST return an HTMLCollection, then calls to .filter will break because Array and HTMLCollection are different. Defining in the ES binding what methods the HTMLCollection implements in ES has the advantage of making sure that the same method will always have the same behavior. If some day, the W3C or WHATWG decides that HTMLCollection are freely instanciable (var hcol = new HTMLCollection()) and contain a filter methods that MUST return an HTMLCollection, then in the ES binding, it can be decided that the ES method that implements the HTMLCollection interface filter method can be called .filterCollection. This decision won't break any existing code. David
Received on Monday, 26 April 2010 21:56:29 UTC