Merge branch 'MDL-32509' of git://github.com/danpoltawski/moodle
[moodle.git] / lib / yui / 3.5.0 / build / arraylist / arraylist.js
blobc8248a164ccae21d33882833bedc932f60a10860
1 /*
2 YUI 3.5.0 (build 5089)
3 Copyright 2012 Yahoo! Inc. All rights reserved.
4 Licensed under the BSD License.
5 http://yuilibrary.com/license/
6 */
7 YUI.add('arraylist', function(Y) {
9 /**
10  * Collection utilities beyond what is provided in the YUI core
11  * @module collection
12  * @submodule arraylist
13  */
15 var YArray      = Y.Array,
16     YArray_each = YArray.each,
17     ArrayListProto;
19 /**
20  * Generic ArrayList class for managing lists of items and iterating operations
21  * over them.  The targeted use for this class is for augmentation onto a
22  * class that is responsible for managing multiple instances of another class
23  * (e.g. NodeList for Nodes).  The recommended use is to augment your class with
24  * ArrayList, then use ArrayList.addMethod to mirror the API of the constituent
25  * items on the list's API.
26  *
27  * The default implementation creates immutable lists, but mutability can be
28  * provided via the arraylist-add submodule or by implementing mutation methods
29  * directly on the augmented class's prototype.
30  *
31  * @class ArrayList
32  * @constructor
33  * @param items { Array } array of items this list will be responsible for
34  */
35 function ArrayList( items ) {
36     if ( items !== undefined ) {
37         this._items = Y.Lang.isArray( items ) ? items : YArray( items );
38     } else {
39         // ||= to support lazy initialization from augment
40         this._items = this._items || [];
41     }
44 ArrayListProto = {
45     /**
46      * Get an item by index from the list.  Override this method if managing a
47      * list of objects that have a different public representation (e.g. Node
48      * instances vs DOM nodes).  The iteration methods that accept a user
49      * function will use this method for access list items for operation.
50      *
51      * @method item
52      * @param i { Integer } index to fetch
53      * @return { mixed } the item at the requested index
54      */
55     item: function ( i ) {
56         return this._items[i];
57     },
59     /**
60      * <p>Execute a function on each item of the list, optionally providing a
61      * custom execution context.  Default context is the item.</p>
62      *
63      * <p>The callback signature is <code>callback( item, index )</code>.</p>
64      *
65      * @method each
66      * @param fn { Function } the function to execute
67      * @param context { mixed } optional override 'this' in the function
68      * @return { ArrayList } this instance
69      * @chainable
70      */
71     each: function ( fn, context ) {
72         YArray_each( this._items, function ( item, i ) {
73             item = this.item( i );
75             fn.call( context || item, item, i, this );
76         }, this);
78         return this;
79     },
81     /**
82      * <p>Execute a function on each item of the list, optionally providing a
83      * custom execution context.  Default context is the item.</p>
84      *
85      * <p>The callback signature is <code>callback( item, index )</code>.</p>
86      *
87      * <p>Unlike <code>each</code>, if the callback returns true, the
88      * iteratation will stop.</p>
89      *
90      * @method some
91      * @param fn { Function } the function to execute
92      * @param context { mixed } optional override 'this' in the function
93      * @return { Boolean } True if the function returned true on an item
94      */
95     some: function ( fn, context ) {
96         return YArray.some( this._items, function ( item, i ) {
97             item = this.item( i );
99             return fn.call( context || item, item, i, this );
100         }, this);
101     },
103     /**
104      * Finds the first index of the needle in the managed array of items.
105      *
106      * @method indexOf
107      * @param needle { mixed } The item to search for
108      * @return { Integer } Array index if found.  Otherwise -1
109      */
110     indexOf: function ( needle ) {
111         return YArray.indexOf( this._items, needle );
112     },
114     /**
115      * How many items are in this list?
116      *
117      * @method size
118      * @return { Integer } Number of items in the list
119      */
120     size: function () {
121         return this._items.length;
122     },
124     /**
125      * Is this instance managing any items?
126      *
127      * @method isEmpty
128      * @return { Boolean } true if 1 or more items are being managed
129      */
130     isEmpty: function () {
131         return !this.size();
132     },
134     /**
135      * Provides an array-like representation for JSON.stringify.
136      *
137      * @method toJSON
138      * @return { Array } an array representation of the ArrayList
139      */
140     toJSON: function () {
141         return this._items;
142     }
144 // Default implementation does not distinguish between public and private
145 // item getter
147  * Protected method for optimizations that may be appropriate for API
148  * mirroring. Similar in functionality to <code>item</code>, but is used by
149  * methods added with <code>ArrayList.addMethod()</code>.
151  * @method _item
152  * @protected
153  * @param i { Integer } Index of item to fetch
154  * @return { mixed } The item appropriate for pass through API methods
155  */
156 ArrayListProto._item = ArrayListProto.item;
158 // Mixed onto existing proto to preserve constructor NOT being an own property.
159 // This has bitten me when composing classes by enumerating, copying prototypes.
160 Y.mix(ArrayList.prototype, ArrayListProto);
162 Y.mix( ArrayList, {
164     /**
165      * <p>Adds a pass through method to dest (typically the prototype of a list
166      * class) that calls the named method on each item in the list with
167      * whatever parameters are passed in.  Allows for API indirection via list
168      * instances.</p>
169      *
170      * <p>Accepts a single string name or an array of string names.</p>
171      *
172      * <pre><code>list.each( function ( item ) {
173      *     item.methodName( 1, 2, 3 );
174      * } );
175      * // becomes
176      * list.methodName( 1, 2, 3 );</code></pre>
177      *
178      * <p>Additionally, the pass through methods use the item retrieved by the
179      * <code>_item</code> method in case there is any special behavior that is
180      * appropriate for API mirroring.</p>
181      *
182      * <p>If the iterated method returns a value, the return value from the
183      * added method will be an array of values with each value being at the
184      * corresponding index for that item.  If the iterated method does not
185      * return a value, the added method will be chainable.
186      *
187      * @method addMethod
188      * @static
189      * @param dest {Object} Object or prototype to receive the iterator method
190      * @param name {String|String[]} Name of method of methods to create
191      */
192     addMethod: function ( dest, names ) {
194         names = YArray( names );
196         YArray_each( names, function ( name ) {
197             dest[ name ] = function () {
198                 var args = YArray( arguments, 0, true ),
199                     ret  = [];
201                 YArray_each( this._items, function ( item, i ) {
202                     item = this._item( i );
204                     var result = item[ name ].apply( item, args );
206                     if ( result !== undefined && result !== item ) {
207                         ret[i] = result;
208                     }
209                 }, this);
211                 return ret.length ? ret : this;
212             };
213         } );
214     }
215 } );
217 Y.ArrayList = ArrayList;
220 }, '3.5.0' ,{requires:['yui-base']});