> $W('foo').wrap('div', { className: 'bar' }); // NodeWrapper around a
> newly created `div` element with class="bar"
Sorry to barge in the middle here, but could you clarify what 'foo'
means here? Is 'foo' the ID of the newly-created div.bar? Or is the
existing div#foo now wrapped with a div.bar?
Walter
>> I think $A should return a ListWrapper, maybe ListWrapper could be the
>> $super for NodeListWrapper.
>> ListWrapper would have methods of Array Additions and Enumerable
>> methods.
>
> Definitely a possibility if we stop extending Array.prototype.
> Otherwise, I don't see much usefulness in this. NodeListWrapper
> encapsulates an array of `NodeWrapper`s and its methods operate
> directly on those `NodeWrapper`. A custom `_each` and mixed-in
> Enumerable would take care of iteration. Am I missing something?
>
> --
> kangax
I think he means that it appears that the Enumerable mix-in concept is
necessitated the fact that native Array objects can't inherit from
Enumerable. Consider this hierarchy assuming we use a ListWrapper
instead of Array.prototype:
Enumerable (each, collect, inject, invoke, etc.)
+--ListWrapper (Enumerable + first, last, reduce, reverse, etc.)
+--NodeListWrapper (ListWrapper + addClassName, setAttribute, etc.)
+--ObjectRange (ListWrapper + overrides)
+--Ajax.Responders (ListWrapper + register, unregister, dispatch)
+--Hash (Enumerable + get, set, keys, toQueryString, etc.)
- Ken Snyder
In fact, I think it would be faster to have a ListWrapper#item method
instead of extending the ListWrapper with numbered indexes:
$$W('div p').item(5);
ListWrapper.prototype.item = function(index) {
// in this example, the element isn't even wrapped until it is accessed
return this.raw[index] ? $W(this.raw[index]) : undefined;
};
Length could be a property like a browser NodeList object, but we might
find more consistency with a ListWrapper#size method instead.
- Ken Snyder
$W('foo') instanceof Prototype.Node; // true
but seeing it written out like that does make sense.
> 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?
>
The only case I can think of is when there is an item in memory with the
same id as one on the page. I don't know how we would handle that case.
Maybe the caching system could handle that somehow.
> 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.
>
What about this caching idea: http://gist.github.com/6609
> 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)
>
Definitely.
> --
> kangax
Ken Snyder
Of course an argument /against/ lazy wrapping is that we would have to
make "this.raw" a private property because you wouldn't know if it
contains wrapped or unwrapped elements.
- Ken
initialize: function(array) {
this.raw = array;
this.length = this.raw.length;
}...
item: function(index) {
if (index < 0 || index >= this.length) return null;
// $W either instantiates a new wrapper, or returns the value
// if the value is already an instance of Prototype.ElementWrapper
this.raw[index] = $W(this.raw[index]);
return this.raw[index];
}...
_each: function(iterator) {
var index = 0;
while (index < this.length)
iterator(this.item(index), index++);
}
Any time I don't need the sugar.
-- T.J. :-)