arraylist.js 6.8 KB

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