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