Hey folks, Weighing in briefly (being hammered at work and at home, and not in that fun way). Great stuff so far! Thoughts/opinions/questions:
1. IMHO, $$() should _always_ return a list/array/whatever, even if there's only one element; it should never return the NodeWrapper itself. Two reasons: A) Having a function that returns a list in some situations and a single element in another situations just means that every use of it has to check what it got back, leading to unnecessarily-verbose code and confusion on the part of users. If people are doing things like $$("#thingy"), tell them to use $(), that's what it's for. :-) If there's a really really good reason they're using $$() (for instance, they don't know what the selector is, it's supplied from elsewhere), well, then they should always be expecting to get back a list. B) That's what it does now. > > I don't think there would be confusion with things like $$ > > (..).getValue() here. > > > Keep in mind users do use the equiv of $$('#myId') and that in those > > cases you are expecting 1 result > > so the desired behavior of a readAttribute, or getValue or anything > > getting a property > > is to return from the only matched item. > > True. > We could reduce ambiguity by having some kind of a generic rule - e.g. > "all accessor methods always act on the first item". This should be > fine, as long as there are no (or not many) exceptions. 2. FWIW, it seems to me that calling an accessor on a list should return a list of the accessor results for each list element. Always. Similarly, calling a setter on the list [e.g., $$ ('.blarg').update('yada')] should call the setter on all list elements. > 1) NodeWrapper always exposes a public `source` property, which is a > reference to a wrapped element: 3. Still don't like "source". That word is just way too overloaded, and again, it's as much a target (e.g., of an update() call) as a source. "raw" is the best general term I've thought of, but I'm not married to it. Whatever we use should be *short* (so not "wrappedThingamajig") and as clear as feasible. Maybe we should give up on the generic term (I *know* it was my idea, but...) and just use something meaningful for each wrapper, e.g. NodeWrapper.node, ListWrapper.list, etc. Keep 'em short, document 'em, and if people forget what the property for the wrapped thingy inside a NodeListWrapper is, too bad, at least the terms are short and clear. 4. get() and set() methods: Great to have them, but I think it's important that we not expect/require that people _use_ them. We're not, right? I don't want to make a function call to access tagName, I'll want to use "wrapper.source.tagName" (or "wrapper.raw.tagName") without the wrapper getting confused somehow. 5. How will the list wrapper handle indexing into the list? E.g.: var items; var n; items = $$('div.item'); for (n = 0; n < items.length; ++n) { items[n].update('This is item ' + n); } I'm not aware of a standard, widely-supported JavaScript feature that lets us define the subscript operator, so I'm guessing the above is out. Again I hate to introduce a function call for simple access [e.g., list.item(n), a'la Microsoft collections], so would I go to the underlying "raw/source"? 6. Question on $$(): I think the idea so far is that it returns a NodeListWrapper. I'm guessing that that's a list of NodeWrappers around the results of the query, right? So I could reliably rewrite my code above like this (I'll use 'source' rather than 'raw' here): var items; var list; var n; items = $$('div.item'); list = items.source; for (n = 0; n < list.length; ++n) { list[n].update('This is item ' + n); } ...because although I'm accessing the raw list, it contains wrapped nodes. Is that the idea? -- T.J. Crowder tj / crowder software / com On Aug 21, 6:37 am, kangax <[EMAIL PROTECTED]> wrote: > On Aug 21, 12:15 am, "Ken Snyder" <[EMAIL PROTECTED]> wrote: > > > > > ...> I forked prototype, and started working on NodeWrapper/NodeListWrapper > > > -http://github.com/kangax/prototype/tree/master/src/element.js > > > Accompanying tests are there as well (although the test suite is far > > > from being complete). > > > > -- > > > kangax > > > Exciting to see in code! What about adding caching instances and maybe even > > using a double-duty constructor instead of Class.create? See what I mean > > below. > > - Ken Snyder > > Prototype.Element = function(element) { > > if (this instanceof Prototype.Element) { > > // constructor > > element.__prototypeWrapper = this; > > this.raw = element; > > } else { > > // "getInstance" function > > // allow element to be string, dom node, or Prototype.Element instance > > element = (typeof element === 'string' ? > > document.getElementById(element) : element); > > if (element instanceof Prototype.Element) { > > return element; > > } > > if (element && element.__prototypeWrapper) { > > return element.__prototypeWrapper; > > } else { > > return new Prototype.Element(element) > > } > > } > > > }; > > > $W = Prototype.Element; > > > var myDiv = document.getElementById('someDiv'); > > var myWrappedDiv = $W('someDiv'); > > myWrappedDiv === $W(myDiv); // true > > myWrappedDiv === $W(myWrappedDiv); // true > > // although $W() is called 3 times, only one instance is created > > Ken, > > I wanted to keep $W consistent with the rest of the library - be a > simple shortcut for creating a new instance of NodeWrapper. Just like ` > $H` returns `new Hash` and $R returns `new ObjectRange`, $W should > probably return `new NodeWrapper`. $W is also responsible for > "transforming" string parameter into an actual element (via > `document.getElementById`): > > ... > this.$W = function(element) { > if (typeof element == 'string') { > element = document.getElementById(element); > } > return new Prototype.Node(element);}; > > ... > > Using such "proxy" helper ($W) also ensures NodeWrapper is always > called as a constructor. There are less chances that a user will > mistakenly call `NodeWrapper` as a function and pollute the global > scope. It, therefore, allows us to get rid of "this instanceof > Prototype.Node" check: > > new Prototype.Node('foo'); // returns a wrapper > Prototype.Node('foo'); // boom! returns undefined and creates a global > `source`/`raw` property > > Good point about passing a wrapper into a wrapper : ) Would it make > sense to return a wrapper itself or a "clone" of it? Would there ever > be a need for a cloned wrapper? > > As far as caching, I'm afraid that storing reference to a wrapper on a > node itself could lead to circular references (which as we know "leak" > in IE's JScript). Having a separate cache-table and map elements to > wrappers by an element's id (or a custom property of an element) seems > more appropriate. > > I also think that #update, #insert, #replace, etc. should allow to > accept a wrapper (besides an element or a string): > > $W('foo').insert($W('bar')); > > This should be as easy as giving wrapper `toElement`/`toHTML` methods > (since `update`/`insert` delegate to those when available) > > -- > kangax --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Prototype: Core" group. To post to this group, send email to prototype-core@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/prototype-core?hl=en -~----------~----~----~----~------~----~------~--~---