Subversion Repositories JSX

Compare Revisions

Last modification

Ignore whitespace Rev 126 → Rev 127

/trunk/collection.js
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;
};