Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

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