5,7 → 5,7 |
* |
* @section Copyright & Disclaimer |
* |
* @author (C) 2002-2006 Thomas Lahn <collection.js@PointedEars.de> |
* @author (C) 2002-2008 Thomas Lahn <collection.js@PointedEars.de> |
* |
* This program is free software; you can redistribute it and/or |
* modify it under the terms of the GNU General Public License |
30,38 → 30,43 |
* for details. |
*/ |
|
/** |
/** |
* @section Abstract |
* |
* A collection in ECMAScript and its implementations is an |
* object which has indexed elements like an Array object. |
* Unlike an Array object, it also has named elements which |
* refer to the same data as the indexed elements do. Each |
* element receives a numeric index in order of assignment/ |
* addition, and if it is given, a name, too. Both indexes |
* and names become properties of the collection and are |
* thus accessible via the standard property accessor syntax: |
* `object["property"]' and, if property is an identifier, |
* `object.property'. By internal references it is ensured |
* that an operation on an element is performed on both the |
* indexed element and its named counterpart, and vice-versa. |
* A collection in ECMAScript and its implementations is an object |
* which has indexed items like an {@link Array} object. |
* Unlike an <code>Array</code> object, it also has named items |
* which refer to the same data as the indexed items. Each |
* item receives a numeric index in order of assignment/addition, |
* and if it is given, a name, too. Both indexes and names become |
* properties of the collection and are thus accessible via the |
* standard property accessor syntax: |
* <code><var>object</var>["<var>property</var>"]</code> |
* and, if <var>property</var> is an identifier, |
* <code><var>object</var>.<var>property</var></code>. |
* By internal references it is ensured that an operation on |
* an item is performed on both the indexed item and its named |
* counterpart. |
* |
* You could compare this behavior to an associative array |
* in PHP, only that ECMAScript has no built-in concept of |
* associative arrays. |
* You could compare this behavior to an associative array in PHP, |
* only that ECMAScript has no built-in concept of associative arrays. |
*/ |
|
/** |
* @param o: optional Object |
* Creates and initializes a <code>Collection</code> object. |
* |
* @param o : optional Object |
* reference used to fill the collection. |
* @constructor |
* @return undefined |
*/ |
function Collection(o) |
{ |
this.version = "0.1.2006073010"; |
this.version = "0.1.2008120823"; |
/** |
* @partof PointedEars JavaScript Extensions (JSX) |
*/ |
this.copyright = "Copyright \xA9 2002-2006"; |
this.copyright = "Copyright \xA9 2002-2008"; |
this.author = "Thomas Lahn"; |
this.email = "collection.js@PointedEars.de"; |
this.path = "http://pointedears.de/scripts/"; |
72,87 → 77,131 |
this.set(o); |
} |
|
/** |
* @param o: optional Object |
* reference used to append to the collection. |
*/ |
Collection.prototype.addItems = function collection_addItems(o) |
{ |
var result = null; |
Collection.prototype = { |
constructor: Collection, |
|
for (var i in o) |
{ |
// omit deleted items |
if (typeof o[i] != "undefined") |
/** |
* Adds an item to a {@link Collection}. |
* |
* @param val |
* @param name : optional string |
* Reference to an object used to fill the collection. |
* @return CollectionItem |
* the added item |
*/ |
add: function collection_add(val, name) { |
var index = this.items.length; |
this.items[index] = new CollectionItem(val); |
|
if (name && isNaN(name)) |
{ |
this.items[i] = new CollectionItem(o[i]); |
this.items[name] = this.items[index]; |
} |
|
return this.items[index]; |
}, |
|
// if the property name is not numeric |
if (isNaN(i)) |
/** |
* @param o: optional Object |
* reference used to append to the collection. |
*/ |
addItems: function collection_addItems(o) { |
var result = null; |
|
for (var i in o) |
{ |
// omit deleted items |
if (typeof o[i] != "undefined") |
{ |
this.items[this.items.length] = this.items[i]; |
result = this.add(o[i], i); |
} |
} |
|
return result; |
}, |
|
result = this.items[i]; |
/** |
* Removes all items from the {@link Collection}. |
* |
* @type Array |
*/ |
clear: function collection_clear() { |
this.items = []; |
|
if (typeof this.items.map != "function") |
{ |
this.items.map = function(callback, thisObj) { |
var a = this; |
|
if (typeof callback == "function") |
{ |
if (!thisObj) thisObj = this; |
|
a = []; |
for (var i = 0, len = this.length; i < len; i++) |
{ |
a[i] = callback.call(thisObj, this[i], i, this); |
} |
} |
else |
{ |
(function() { |
eval("throw new TypeError('Collection.prototype.items.map(callback, thisObj):'" |
+ "+ ' expected function, got ' + typeof thisObj)"); |
})() |
} |
|
return a; |
}; |
} |
|
return this.items; |
}, |
|
keys: function collection_keys() { |
var a = [], o = this.items; |
|
for (var k in o) |
{ |
a.push(o[k]); |
} |
} |
|
return a; |
}, |
|
return result; |
}; |
|
/** |
* @argument o: optional Object |
* reference used to fill the {@link Collection}. |
*/ |
Collection.prototype.set = function collection_set(o) |
{ |
// no real array, but Array.prototype.length is useful |
this.items = new Array(); |
values: function collection_values() { |
return this.items.map(function(v) { return v; }); |
}, |
|
return this.addItems(o); |
}; |
|
/** |
* Adds an item to a {@link Collection}. |
* |
* @argument val |
* @argument name: optional string |
* Reference to an object used to fill the collection. |
*/ |
Collection.prototype.add = function collection_add(val, name) |
{ |
var index = this.items.length; |
this.items[index] = new CollectionItem(val); |
|
if (name && isNaN(name)) |
{ |
this.items[name] = this.items[index]; |
/** |
* Returns a reference to a new {@link Iterator} for the {@link Collection}. |
* |
* @return Iterator |
*/ |
iterator: function collection_iterator() { |
return new Iterator(this.items); |
}, |
|
/** |
* @param o : optional Object |
* reference used to fill the {@link Collection}. |
*/ |
set: function collection_set(o) { |
this.clear(); |
return this.addItems(o); |
} |
|
return this.items[index]; |
}; |
|
/** |
* Removes all items from the {@link Collection}. |
* Creates and initializes a <code>ValueCollection</code> object, |
* which is a special {@link Collection} that can hold a value. |
* |
* @type Array |
* @param o : Object |
* reference used to fill the collection |
* @param val |
* Value that the object holds |
* @return undefined |
*/ |
Collection.prototype.clear = function collection_clear() |
{ |
this.items = new Array(); |
return !this.items; |
}; |
|
/** |
* Returns a reference to a new {@link Iterator} for the {@link Collection}. |
* |
* @type Iterator |
*/ |
Collection.prototype.iterator = function collection_iterator() |
{ |
return new Iterator(this.items); |
}; |
|
function ValueCollection(o, val) |
{ |
Collection.call(o); |
160,11 → 209,27 |
} |
ValueCollection.extend(Collection); |
|
/** |
* Creates and initializes a <code>CollectionItem</code> object. |
* |
* @param val |
* Value of the item |
* @return undefined |
*/ |
function CollectionItem(val) |
{ |
this.value = val; |
} |
|
/** |
* Creates an initializes an <code>Iterator</code> object. |
* An iterator iterates over a {@link Collection} such that |
* each item of that collection is visited only once. |
* |
* @param o : Collection |
* Iteration target |
* @return undefined |
*/ |
function Iterator(o) |
{ |
// properties |
175,8 → 240,12 |
} |
|
// prototype methods |
Iterator.prototype.prev = function iterator_prev() |
{ |
/** |
* Returns the item previously visited in the iteration. |
* |
* @return CollectionItem |
*/ |
Iterator.prototype.prev = function iterator_prev() { |
var result = result; // undefined |
var t = this.target; |
|
220,9 → 289,12 |
return result; |
}; |
|
Iterator.prototype.next = function iterator_next() |
{ |
|
/** |
* Returns the item that will next be visited in the iteration. |
* |
* @return CollectionItem |
*/ |
Iterator.prototype.next = function iterator_next() { |
var |
// undefined |
result = result, |
269,8 → 341,15 |
return result; |
}; |
|
Iterator.prototype.hasPrev = function iterator_hasPrev() |
{ |
/** |
* Returns <code>true</code> if there is a previous item |
* in the iteration, i.e. if the current item is not the |
* first item and the collection consists of more than |
* one item. Returns <code>false</code> otherwise. |
* |
* @return boolean |
*/ |
Iterator.prototype.hasPrev = function iterator_hasPrev() { |
var result = false; |
this.prevItem = -1; |
var t = this.target; |
305,8 → 384,15 |
return result; |
}; |
|
Iterator.prototype.hasNext = function iterator_hasNext() |
{ |
/** |
* Returns <code>true</code> if there is a next item |
* in the iteration, i.e. if the current item is not the |
* last item and the collection consists of more than |
* one item. Returns <code>false</code> otherwise. |
* |
* @return boolean |
*/ |
Iterator.prototype.hasNext = function iterator_hasNext() { |
var result = false; |
this.nextItem = -1; |
var t = this.target; |
341,8 → 427,13 |
return result; |
}; |
|
Iterator.prototype.remove = function iterator_remove() |
{ |
/** |
* Removes the current item from the collection. |
* |
* @type mixed |
* @return the next item, <code>undefined</code> if there is none. |
*/ |
Iterator.prototype.remove = function iterator_remove() { |
var undef = undef; |
delete this.target[this.currItem]; |
if (this.hasNext()) |
349,8 → 440,6 |
{ |
return this.next(); |
} |
else |
{ |
return undef; |
} |
|
return undef; |
}; |