API Docs for: 3.13.0
Show:

File: collection/js/arraylist.js

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