| 1 | efrain | 1 | YUI.add('recordset-base', function (Y, NAME) {
 | 
        
           |  |  | 2 |   | 
        
           |  |  | 3 | /**
 | 
        
           |  |  | 4 |  * Provides a wrapper around a standard javascript object. Can be inserted into a Recordset instance.
 | 
        
           |  |  | 5 |  *
 | 
        
           |  |  | 6 |  * @class Record
 | 
        
           |  |  | 7 |  */
 | 
        
           |  |  | 8 | var Record = Y.Base.create('record', Y.Base, [], {
 | 
        
           |  |  | 9 |     _setId: function() {
 | 
        
           |  |  | 10 |         return Y.guid();
 | 
        
           |  |  | 11 |     },
 | 
        
           |  |  | 12 |   | 
        
           |  |  | 13 |     initializer: function() {
 | 
        
           |  |  | 14 |     },
 | 
        
           |  |  | 15 |   | 
        
           |  |  | 16 |     destructor: function() {
 | 
        
           |  |  | 17 |     },
 | 
        
           |  |  | 18 |   | 
        
           |  |  | 19 |     /**
 | 
        
           |  |  | 20 |      * Retrieve a particular (or all) values from the object
 | 
        
           |  |  | 21 |      *
 | 
        
           |  |  | 22 |      * @param field {string} (optional) The key to retrieve the value from. If not supplied, the entire object is returned.
 | 
        
           |  |  | 23 |      * @method getValue
 | 
        
           |  |  | 24 |      * @public
 | 
        
           |  |  | 25 |      */
 | 
        
           |  |  | 26 |     getValue: function(field) {
 | 
        
           |  |  | 27 |         if (field === undefined) {
 | 
        
           |  |  | 28 |             return this.get("data");
 | 
        
           |  |  | 29 |         }
 | 
        
           |  |  | 30 |         else {
 | 
        
           |  |  | 31 |             return this.get("data")[field];
 | 
        
           |  |  | 32 |         }
 | 
        
           |  |  | 33 |         return null;
 | 
        
           |  |  | 34 |     }
 | 
        
           |  |  | 35 | },
 | 
        
           |  |  | 36 | {
 | 
        
           |  |  | 37 |     ATTRS: {
 | 
        
           |  |  | 38 |   | 
        
           |  |  | 39 |         /**
 | 
        
           |  |  | 40 |         * @description Unique ID of the record instance
 | 
        
           |  |  | 41 |         * @attribute id
 | 
        
           |  |  | 42 |         * @type string
 | 
        
           |  |  | 43 |         */
 | 
        
           |  |  | 44 |         id: {
 | 
        
           |  |  | 45 |             valueFn: "_setId"
 | 
        
           |  |  | 46 |         },
 | 
        
           |  |  | 47 |   | 
        
           |  |  | 48 |         /**
 | 
        
           |  |  | 49 |         * @description The object stored within the record instance
 | 
        
           |  |  | 50 |         * @attribute data
 | 
        
           |  |  | 51 |         * @type object
 | 
        
           |  |  | 52 |         */
 | 
        
           |  |  | 53 |         data: {
 | 
        
           |  |  | 54 |             value: null
 | 
        
           |  |  | 55 |         }
 | 
        
           |  |  | 56 |     }
 | 
        
           |  |  | 57 | });
 | 
        
           |  |  | 58 |   | 
        
           |  |  | 59 | Y.Record = Record;
 | 
        
           |  |  | 60 | /**
 | 
        
           |  |  | 61 | The Recordset utility provides a standard way for dealing with
 | 
        
           |  |  | 62 | a collection of similar objects.
 | 
        
           |  |  | 63 | @module recordset
 | 
        
           |  |  | 64 | @main recordset
 | 
        
           |  |  | 65 | @submodule recordset-base
 | 
        
           |  |  | 66 | **/
 | 
        
           |  |  | 67 |   | 
        
           |  |  | 68 |   | 
        
           |  |  | 69 | var ArrayList = Y.ArrayList,
 | 
        
           |  |  | 70 | Lang = Y.Lang,
 | 
        
           |  |  | 71 |   | 
        
           |  |  | 72 | /**
 | 
        
           |  |  | 73 | The Recordset utility provides a standard way for dealing with
 | 
        
           |  |  | 74 | a collection of similar objects.
 | 
        
           |  |  | 75 |   | 
        
           |  |  | 76 | Provides the base Recordset implementation, which can be extended to add
 | 
        
           |  |  | 77 | additional functionality, such as custom indexing. sorting, and filtering.
 | 
        
           |  |  | 78 |   | 
        
           |  |  | 79 | @class Recordset
 | 
        
           |  |  | 80 | @extends Base
 | 
        
           |  |  | 81 | @uses ArrayList
 | 
        
           |  |  | 82 | @param config {Object} Configuration object with initial attribute values
 | 
        
           |  |  | 83 | @constructor
 | 
        
           |  |  | 84 | **/
 | 
        
           |  |  | 85 | Recordset = Y.Base.create('recordset', Y.Base, [], {
 | 
        
           |  |  | 86 |   | 
        
           |  |  | 87 |   | 
        
           |  |  | 88 |     /**
 | 
        
           |  |  | 89 |      * Publish default functions for events. Create the initial hash table.
 | 
        
           |  |  | 90 |      *
 | 
        
           |  |  | 91 |      * @method initializer
 | 
        
           |  |  | 92 |      * @protected
 | 
        
           |  |  | 93 |      */
 | 
        
           |  |  | 94 |     initializer: function() {
 | 
        
           |  |  | 95 |         // The reason the conditional is needed is because of two scenarios:
 | 
        
           |  |  | 96 |         // 1. Instantiating new Y.Recordset() will not go into the setter of "records", and so it is necessary to create this._items in the initializer.
 | 
        
           |  |  | 97 |         // 2. Instantiating new Y.Recordset({records: [{...}]}) will call the setter of "records" and create this._items. In this case, we don't want that to be overwritten by [].
 | 
        
           |  |  | 98 |         if (!this._items) {
 | 
        
           |  |  | 99 |             this._items = [];
 | 
        
           |  |  | 100 |         }
 | 
        
           |  |  | 101 |   | 
        
           |  |  | 102 |         //set up event listener to fire events when recordset is modified in anyway
 | 
        
           |  |  | 103 |         this.publish({
 | 
        
           |  |  | 104 |             /**
 | 
        
           |  |  | 105 |              * <p>At least one record is being added. Additional properties of
 | 
        
           |  |  | 106 |              * the event are:</p>
 | 
        
           |  |  | 107 |              * <dl>
 | 
        
           |  |  | 108 |              *     <dt>added</dt>
 | 
        
           |  |  | 109 |              *         <dd>Array of new records to be added</dd>
 | 
        
           |  |  | 110 |              *     <dt>index</dt>
 | 
        
           |  |  | 111 |              *         <dd>The insertion index in the Recordset's internal
 | 
        
           |  |  | 112 |              *         array</dd>
 | 
        
           |  |  | 113 |              * </dl>
 | 
        
           |  |  | 114 |              *
 | 
        
           |  |  | 115 |              * <p>Preventing this event will cause the new records NOT to be
 | 
        
           |  |  | 116 |              * added to the Recordset's internal collection.</p>
 | 
        
           |  |  | 117 |              *
 | 
        
           |  |  | 118 |              * @event add
 | 
        
           |  |  | 119 |              * @preventable _defAddFn
 | 
        
           |  |  | 120 |              */
 | 
        
           |  |  | 121 |             add: { defaultFn: this._defAddFn },
 | 
        
           |  |  | 122 |   | 
        
           |  |  | 123 |             /**
 | 
        
           |  |  | 124 |              * <p>At least one record is being removed. Additional properties of
 | 
        
           |  |  | 125 |              * the event are:</p>
 | 
        
           |  |  | 126 |              * <dl>
 | 
        
           |  |  | 127 |              *     <dt>removed</dt>
 | 
        
           |  |  | 128 |              *         <dd>Array of records to be removed</dd>
 | 
        
           |  |  | 129 |              *     <dt>range</dt>
 | 
        
           |  |  | 130 |              *         <dd>Number of records to be removed</dd>
 | 
        
           |  |  | 131 |              *     <dt>index</dt>
 | 
        
           |  |  | 132 |              *         <dd>The starting index in the Recordset's internal
 | 
        
           |  |  | 133 |              *         array from which to remove records</dd>
 | 
        
           |  |  | 134 |              * </dl>
 | 
        
           |  |  | 135 |              *
 | 
        
           |  |  | 136 |              * <p>Preventing this event will cause the records NOT to be
 | 
        
           |  |  | 137 |              * removed from the Recordset's internal collection.</p>
 | 
        
           |  |  | 138 |              *
 | 
        
           |  |  | 139 |              * @event remove
 | 
        
           |  |  | 140 |              * @preventable _defRemoveFn
 | 
        
           |  |  | 141 |              */
 | 
        
           |  |  | 142 |             remove: { defaultFn: this._defRemoveFn },
 | 
        
           |  |  | 143 |   | 
        
           |  |  | 144 |             /**
 | 
        
           |  |  | 145 |              * The Recordset is being flushed of all records.
 | 
        
           |  |  | 146 |              *
 | 
        
           |  |  | 147 |              * @event empty
 | 
        
           |  |  | 148 |              * @preventable _defEmptyFn
 | 
        
           |  |  | 149 |              */
 | 
        
           |  |  | 150 |             empty: { defaultFn: this._defEmptyFn },
 | 
        
           |  |  | 151 |   | 
        
           |  |  | 152 |             /**
 | 
        
           |  |  | 153 |              * <p>At least one record is being updated. Additional properties of
 | 
        
           |  |  | 154 |              * the event are:</p>
 | 
        
           |  |  | 155 |              * <dl>
 | 
        
           |  |  | 156 |              *     <dt>updated</dt>
 | 
        
           |  |  | 157 |              *         <dd>Array of records with updated values</dd>
 | 
        
           |  |  | 158 |              *     <dt>overwritten</dt>
 | 
        
           |  |  | 159 |              *         <dd>Array of current records that will be replaced</dd>
 | 
        
           |  |  | 160 |              *     <dt>index</dt>
 | 
        
           |  |  | 161 |              *         <dd>The starting index in the Recordset's internal
 | 
        
           |  |  | 162 |              *         array from which to update will apply</dd>
 | 
        
           |  |  | 163 |              * </dl>
 | 
        
           |  |  | 164 |              *
 | 
        
           |  |  | 165 |              * <p>Preventing this event will cause the records NOT to be
 | 
        
           |  |  | 166 |              * updated in the Recordset's internal collection.</p>
 | 
        
           |  |  | 167 |              *
 | 
        
           |  |  | 168 |              * @event update
 | 
        
           |  |  | 169 |              * @preventable _defUpdateFn
 | 
        
           |  |  | 170 |              */
 | 
        
           |  |  | 171 |             update: { defaultFn: this._defUpdateFn }
 | 
        
           |  |  | 172 |         });
 | 
        
           |  |  | 173 |   | 
        
           |  |  | 174 |         this._buildHashTable(this.get('key'));
 | 
        
           |  |  | 175 |   | 
        
           |  |  | 176 |         this.after([
 | 
        
           |  |  | 177 |             'recordsChange',
 | 
        
           |  |  | 178 |             'add',
 | 
        
           |  |  | 179 |             'remove',
 | 
        
           |  |  | 180 |             'update',
 | 
        
           |  |  | 181 |             'empty'], this._updateHash);
 | 
        
           |  |  | 182 |     },
 | 
        
           |  |  | 183 |   | 
        
           |  |  | 184 |     /**
 | 
        
           |  |  | 185 |      * Returns the record with particular ID or index
 | 
        
           |  |  | 186 |      *
 | 
        
           |  |  | 187 |      * @method getRecord
 | 
        
           |  |  | 188 |      * @param i {String, Number} The ID of the record if a string, or the index if a number.
 | 
        
           |  |  | 189 |      * @return {Record} A Y.Record instance
 | 
        
           |  |  | 190 |      */
 | 
        
           |  |  | 191 |     getRecord: function(i) {
 | 
        
           |  |  | 192 |   | 
        
           |  |  | 193 |         if (Lang.isString(i)) {
 | 
        
           |  |  | 194 |             return this.get('table')[i];
 | 
        
           |  |  | 195 |         }
 | 
        
           |  |  | 196 |         else if (Lang.isNumber(i)) {
 | 
        
           |  |  | 197 |             return this._items[i];
 | 
        
           |  |  | 198 |         }
 | 
        
           |  |  | 199 |         return null;
 | 
        
           |  |  | 200 |     },
 | 
        
           |  |  | 201 |   | 
        
           |  |  | 202 |   | 
        
           |  |  | 203 |     /**
 | 
        
           |  |  | 204 |      * Returns the record at a particular index
 | 
        
           |  |  | 205 |      *
 | 
        
           |  |  | 206 |      * @method getRecordByIndex
 | 
        
           |  |  | 207 |      * @param i {Number} Index at which the required record resides
 | 
        
           |  |  | 208 |      * @return {Record} A Y.Record instance
 | 
        
           |  |  | 209 |      */
 | 
        
           |  |  | 210 |     getRecordByIndex: function(i) {
 | 
        
           |  |  | 211 |         return this._items[i];
 | 
        
           |  |  | 212 |     },
 | 
        
           |  |  | 213 |   | 
        
           |  |  | 214 |     /**
 | 
        
           |  |  | 215 |      * Returns a range of records beginning at particular index
 | 
        
           |  |  | 216 |      *
 | 
        
           |  |  | 217 |      * @method getRecordsByIndex
 | 
        
           |  |  | 218 |      * @param index {Number} Index at which the required record resides
 | 
        
           |  |  | 219 |      * @param range {Number} (Optional) Number of records to retrieve. The default is 1
 | 
        
           |  |  | 220 |      * @return {Array} An array of Y.Record instances
 | 
        
           |  |  | 221 |      */
 | 
        
           |  |  | 222 |     getRecordsByIndex: function(index, range) {
 | 
        
           |  |  | 223 |         var i = 0,
 | 
        
           |  |  | 224 |         returnedRecords = [];
 | 
        
           |  |  | 225 |         //Range cannot take on negative values
 | 
        
           |  |  | 226 |         range = (Lang.isNumber(range) && (range > 0)) ? range: 1;
 | 
        
           |  |  | 227 |   | 
        
           |  |  | 228 |         for (; i < range; i++) {
 | 
        
           |  |  | 229 |             returnedRecords.push(this._items[index + i]);
 | 
        
           |  |  | 230 |         }
 | 
        
           |  |  | 231 |         return returnedRecords;
 | 
        
           |  |  | 232 |     },
 | 
        
           |  |  | 233 |   | 
        
           |  |  | 234 |     /**
 | 
        
           |  |  | 235 |      * Returns the length of the recordset
 | 
        
           |  |  | 236 |      *
 | 
        
           |  |  | 237 |      * @method getLength
 | 
        
           |  |  | 238 |      * @return {Number} Number of records in the recordset
 | 
        
           |  |  | 239 |      */
 | 
        
           |  |  | 240 |     getLength: function() {
 | 
        
           |  |  | 241 |         return this.size();
 | 
        
           |  |  | 242 |     },
 | 
        
           |  |  | 243 |   | 
        
           |  |  | 244 |     /**
 | 
        
           |  |  | 245 |     Gets an array of values for a data _key_ in the set's records.  If no _key_
 | 
        
           |  |  | 246 |     is supplied, the returned array will contain the full data object for each
 | 
        
           |  |  | 247 |     record.
 | 
        
           |  |  | 248 |   | 
        
           |  |  | 249 |     @method getValuesByKey
 | 
        
           |  |  | 250 |     @param {String} [key] Data property to get from all records
 | 
        
           |  |  | 251 |     @return {Array} An array of values for the given _key_ if supplied.
 | 
        
           |  |  | 252 |         Otherwise, an array of each record's data hash.
 | 
        
           |  |  | 253 |     **/
 | 
        
           |  |  | 254 |     getValuesByKey: function(key) {
 | 
        
           |  |  | 255 |         var i = 0,
 | 
        
           |  |  | 256 |         len = this._items.length,
 | 
        
           |  |  | 257 |         retVals = [];
 | 
        
           |  |  | 258 |         for (; i < len; i++) {
 | 
        
           |  |  | 259 |             retVals.push(this._items[i].getValue(key));
 | 
        
           |  |  | 260 |         }
 | 
        
           |  |  | 261 |         return retVals;
 | 
        
           |  |  | 262 |     },
 | 
        
           |  |  | 263 |   | 
        
           |  |  | 264 |   | 
        
           |  |  | 265 |     /**
 | 
        
           |  |  | 266 |      * Adds one or more Records to the RecordSet at the given index. If index is null, then adds the Records to the end of the RecordSet.
 | 
        
           |  |  | 267 |      *
 | 
        
           |  |  | 268 |      * @method add
 | 
        
           |  |  | 269 |      * @param {Record|Object|Array} oData A Y.Record instance, An object literal of data or an array of object literals
 | 
        
           |  |  | 270 |      * @param [index] {Number} [index] Index at which to add the record(s)
 | 
        
           |  |  | 271 |      * @return {Recordset} The updated recordset instance
 | 
        
           |  |  | 272 |      */
 | 
        
           |  |  | 273 |     add: function(oData, index) {
 | 
        
           |  |  | 274 |   | 
        
           |  |  | 275 |         var newRecords = [],
 | 
        
           |  |  | 276 |         idx,
 | 
        
           |  |  | 277 |         i = 0;
 | 
        
           |  |  | 278 |   | 
        
           |  |  | 279 |         idx = (Lang.isNumber(index) && (index > -1)) ? index: this._items.length;
 | 
        
           |  |  | 280 |   | 
        
           |  |  | 281 |         //Passing in array of object literals for oData
 | 
        
           |  |  | 282 |         if (Lang.isArray(oData)) {
 | 
        
           |  |  | 283 |             for (; i < oData.length; i++) {
 | 
        
           |  |  | 284 |                 newRecords[i] = this._changeToRecord(oData[i]);
 | 
        
           |  |  | 285 |             }
 | 
        
           |  |  | 286 |         } else if (Lang.isObject(oData)) {
 | 
        
           |  |  | 287 |             newRecords[0] = this._changeToRecord(oData);
 | 
        
           |  |  | 288 |         }
 | 
        
           |  |  | 289 |   | 
        
           |  |  | 290 |         this.fire('add', {
 | 
        
           |  |  | 291 |             added: newRecords,
 | 
        
           |  |  | 292 |             index: idx
 | 
        
           |  |  | 293 |         });
 | 
        
           |  |  | 294 |         return this;
 | 
        
           |  |  | 295 |     },
 | 
        
           |  |  | 296 |   | 
        
           |  |  | 297 |     /**
 | 
        
           |  |  | 298 |     Removes one or more Records to the RecordSet at the given index. If index
 | 
        
           |  |  | 299 |     is null, then removes a single Record from the end of the RecordSet.
 | 
        
           |  |  | 300 |   | 
        
           |  |  | 301 |     @method remove
 | 
        
           |  |  | 302 |     @param {Number} [index] Index at which to remove the record(s) from
 | 
        
           |  |  | 303 |     @param {Number} [range] Number of records to remove (including the one
 | 
        
           |  |  | 304 |         at the index)
 | 
        
           |  |  | 305 |     @return {Recordset} The updated recordset instance
 | 
        
           |  |  | 306 |     **/
 | 
        
           |  |  | 307 |     remove: function(index, range) {
 | 
        
           |  |  | 308 |         var remRecords = [];
 | 
        
           |  |  | 309 |   | 
        
           |  |  | 310 |         //Default is to only remove the last record - the length is always 1 greater than the last index
 | 
        
           |  |  | 311 |         index = (index > -1) ? index: (this._items.length - 1);
 | 
        
           |  |  | 312 |         range = (range > 0) ? range: 1;
 | 
        
           |  |  | 313 |   | 
        
           |  |  | 314 |         remRecords = this._items.slice(index, (index + range));
 | 
        
           |  |  | 315 |         this.fire('remove', {
 | 
        
           |  |  | 316 |             removed: remRecords,
 | 
        
           |  |  | 317 |             range: range,
 | 
        
           |  |  | 318 |             index: index
 | 
        
           |  |  | 319 |         });
 | 
        
           |  |  | 320 |         //this._recordRemoved(remRecords, index);
 | 
        
           |  |  | 321 |         //return ({data: remRecords, index:index});
 | 
        
           |  |  | 322 |         return this;
 | 
        
           |  |  | 323 |     },
 | 
        
           |  |  | 324 |   | 
        
           |  |  | 325 |     /**
 | 
        
           |  |  | 326 |      * Empties the recordset
 | 
        
           |  |  | 327 |      *
 | 
        
           |  |  | 328 |      * @method empty
 | 
        
           |  |  | 329 |      * @return {Recordset} The updated recordset instance
 | 
        
           |  |  | 330 |      */
 | 
        
           |  |  | 331 |     empty: function() {
 | 
        
           |  |  | 332 |         this.fire('empty', {});
 | 
        
           |  |  | 333 |         return this;
 | 
        
           |  |  | 334 |     },
 | 
        
           |  |  | 335 |   | 
        
           |  |  | 336 |     /**
 | 
        
           |  |  | 337 |     Updates the recordset with the new records passed in. Overwrites existing
 | 
        
           |  |  | 338 |     records when updating the index with the new records.
 | 
        
           |  |  | 339 |   | 
        
           |  |  | 340 |     @method update
 | 
        
           |  |  | 341 |     @param {Record|Object|Array} data A Y.Record instance, An object literal of
 | 
        
           |  |  | 342 |         data or an array of object literals
 | 
        
           |  |  | 343 |     @param {Number} [index] The index to start updating from.
 | 
        
           |  |  | 344 |     @return {Recordset} The updated recordset instance
 | 
        
           |  |  | 345 |     **/
 | 
        
           |  |  | 346 |     update: function(data, index) {
 | 
        
           |  |  | 347 |         var rec,
 | 
        
           |  |  | 348 |             arr,
 | 
        
           |  |  | 349 |             i = 0;
 | 
        
           |  |  | 350 |   | 
        
           |  |  | 351 |         // Whatever is passed in, we are changing it to an array so that it can
 | 
        
           |  |  | 352 |         // be easily iterated in the _defUpdateFn method
 | 
        
           |  |  | 353 |         arr = (!(Lang.isArray(data))) ? [data] : data;
 | 
        
           |  |  | 354 |         rec = this._items.slice(index, index + arr.length);
 | 
        
           |  |  | 355 |   | 
        
           |  |  | 356 |         for (; i < arr.length; i++) {
 | 
        
           |  |  | 357 |             arr[i] = this._changeToRecord(arr[i]);
 | 
        
           |  |  | 358 |         }
 | 
        
           |  |  | 359 |   | 
        
           |  |  | 360 |         this.fire('update', {
 | 
        
           |  |  | 361 |             updated: arr,
 | 
        
           |  |  | 362 |             overwritten: rec,
 | 
        
           |  |  | 363 |             index: index
 | 
        
           |  |  | 364 |         });
 | 
        
           |  |  | 365 |   | 
        
           |  |  | 366 |         return this;
 | 
        
           |  |  | 367 |     },
 | 
        
           |  |  | 368 |   | 
        
           |  |  | 369 |     /**
 | 
        
           |  |  | 370 |      * Default behavior for the "add" event. Adds Record instances starting from
 | 
        
           |  |  | 371 |      * the index specified in `e.index`.
 | 
        
           |  |  | 372 |      *
 | 
        
           |  |  | 373 |      * @method _defAddFn
 | 
        
           |  |  | 374 |      * @param {EventFacade} e The add event
 | 
        
           |  |  | 375 |      * @private
 | 
        
           |  |  | 376 |      */
 | 
        
           |  |  | 377 |     _defAddFn: function(e) {
 | 
        
           |  |  | 378 |         this._items.splice.apply(this._items, [e.index, 0].concat(e.added));
 | 
        
           |  |  | 379 |     },
 | 
        
           |  |  | 380 |   | 
        
           |  |  | 381 |     /**
 | 
        
           |  |  | 382 |      * Default behavior for the "remove" event. Removes Records from the
 | 
        
           |  |  | 383 |      * internal array starting from `e.index`.  By default, it will remove one
 | 
        
           |  |  | 384 |      * Record. But if `e.range` is set, it will remove that many Records.
 | 
        
           |  |  | 385 |      *
 | 
        
           |  |  | 386 |      * @method _defRemoveFn
 | 
        
           |  |  | 387 |      * @param {EventFacade} e The remove event
 | 
        
           |  |  | 388 |      * @private
 | 
        
           |  |  | 389 |      */
 | 
        
           |  |  | 390 |     _defRemoveFn: function(e) {
 | 
        
           |  |  | 391 |         this._items.splice(e.index, e.range || 1);
 | 
        
           |  |  | 392 |     },
 | 
        
           |  |  | 393 |   | 
        
           |  |  | 394 |     /**
 | 
        
           |  |  | 395 |      * Default behavior for the "update" event. Sets Record instances for each
 | 
        
           |  |  | 396 |      * item in `e.updated` at indexes starting from `e.index`.
 | 
        
           |  |  | 397 |      *
 | 
        
           |  |  | 398 |      * @method _defUpdateFn
 | 
        
           |  |  | 399 |      * @param {EventFacade} e The update event
 | 
        
           |  |  | 400 |      * @private
 | 
        
           |  |  | 401 |      */
 | 
        
           |  |  | 402 |     _defUpdateFn: function(e) {
 | 
        
           |  |  | 403 |         for (var i = 0; i < e.updated.length; i++) {
 | 
        
           |  |  | 404 |             this._items[e.index + i] = this._changeToRecord(e.updated[i]);
 | 
        
           |  |  | 405 |         }
 | 
        
           |  |  | 406 |     },
 | 
        
           |  |  | 407 |   | 
        
           |  |  | 408 |     /**
 | 
        
           |  |  | 409 |      * Default behavior for the "empty" event. Clears the internal array of
 | 
        
           |  |  | 410 |      * Records.
 | 
        
           |  |  | 411 |      *
 | 
        
           |  |  | 412 |      * @method _defEmptyFn
 | 
        
           |  |  | 413 |      * @param {EventFacade} e The empty event
 | 
        
           |  |  | 414 |      * @private
 | 
        
           |  |  | 415 |      */
 | 
        
           |  |  | 416 |     _defEmptyFn: function(e) {
 | 
        
           |  |  | 417 |         this._items = [];
 | 
        
           |  |  | 418 |     },
 | 
        
           |  |  | 419 |   | 
        
           |  |  | 420 |     /**
 | 
        
           |  |  | 421 |     Updates the internal hash table.
 | 
        
           |  |  | 422 |   | 
        
           |  |  | 423 |     @method _defUpdateHash
 | 
        
           |  |  | 424 |     @param {EventFacade} e Event triggering the hash table update
 | 
        
           |  |  | 425 |     @private
 | 
        
           |  |  | 426 |     **/
 | 
        
           |  |  | 427 |     _updateHash: function (e) {
 | 
        
           |  |  | 428 |         var handler = "_hash",
 | 
        
           |  |  | 429 |             type = e.type.replace(/.*:/,''),
 | 
        
           |  |  | 430 |             newHash;
 | 
        
           |  |  | 431 |   | 
        
           |  |  | 432 |         // _hashAdd, _hashRemove, _hashEmpty, etc
 | 
        
           |  |  | 433 |         // Not a switch or else if setup to allow for external expansion.
 | 
        
           |  |  | 434 |         handler += type.charAt(0).toUpperCase() + type.slice(1);
 | 
        
           |  |  | 435 |   | 
        
           |  |  | 436 |         newHash = this[handler] &&
 | 
        
           |  |  | 437 |                     this[handler](this.get('table'), this.get('key'), e);
 | 
        
           |  |  | 438 |   | 
        
           |  |  | 439 |         if (newHash) {
 | 
        
           |  |  | 440 |             this.set('table', newHash);
 | 
        
           |  |  | 441 |         }
 | 
        
           |  |  | 442 |     },
 | 
        
           |  |  | 443 |   | 
        
           |  |  | 444 |     /**
 | 
        
           |  |  | 445 |     Regenerates the hash table from the current internal array of Records.
 | 
        
           |  |  | 446 |   | 
        
           |  |  | 447 |     @method _hashRecordsChange
 | 
        
           |  |  | 448 |     @param {Object} hash The hash map before replacement
 | 
        
           |  |  | 449 |     @param {String} key The key by which to add items to the hash
 | 
        
           |  |  | 450 |     @param {Object} e The event or object containing the items to be added.
 | 
        
           |  |  | 451 |                       Items are expected to be stored in an array assigned to
 | 
        
           |  |  | 452 |                       the `added` property.
 | 
        
           |  |  | 453 |     @return {Object} The updated hash map
 | 
        
           |  |  | 454 |     @private
 | 
        
           |  |  | 455 |     **/
 | 
        
           |  |  | 456 |     _hashRecordsChange: function (hash, key, e) {
 | 
        
           |  |  | 457 |         return this._buildHashTable(key);
 | 
        
           |  |  | 458 |     },
 | 
        
           |  |  | 459 |   | 
        
           |  |  | 460 |     /**
 | 
        
           |  |  | 461 |     Builds a hash table from the current internal array of Records.
 | 
        
           |  |  | 462 |   | 
        
           |  |  | 463 |     @method _buildHashTable
 | 
        
           |  |  | 464 |     @param {String} key The Record key to hash the items by
 | 
        
           |  |  | 465 |     @return {Object} A new hash map of Records keyed by each Records' key
 | 
        
           |  |  | 466 |     @private
 | 
        
           |  |  | 467 |     **/
 | 
        
           |  |  | 468 |     _buildHashTable: function (key) {
 | 
        
           |  |  | 469 |         return this._hashAdd({}, key, { added: this._items });
 | 
        
           |  |  | 470 |     },
 | 
        
           |  |  | 471 |   | 
        
           |  |  | 472 |     /**
 | 
        
           |  |  | 473 |     Adds items to the hash table.  Items are the values, and the keys are the
 | 
        
           |  |  | 474 |     values of the item's attribute named in the `key` parameter.
 | 
        
           |  |  | 475 |   | 
        
           |  |  | 476 |     @method _hashAdd
 | 
        
           |  |  | 477 |     @param {Object} hash The hash map before adding items
 | 
        
           |  |  | 478 |     @param {String} key The key by which to add the items to the hash
 | 
        
           |  |  | 479 |     @param {Object} e The event or object containing the items to be added.
 | 
        
           |  |  | 480 |                       Items are expected to be stored in an array assigned to
 | 
        
           |  |  | 481 |                       the `added` property.
 | 
        
           |  |  | 482 |     @return {Object} The updated hash map
 | 
        
           |  |  | 483 |     @private
 | 
        
           |  |  | 484 |     **/
 | 
        
           |  |  | 485 |     _hashAdd: function(hash, key, e) {
 | 
        
           |  |  | 486 |         var items = e.added,
 | 
        
           |  |  | 487 |             i, len;
 | 
        
           |  |  | 488 |   | 
        
           |  |  | 489 |         for (i = 0, len = e.added.length; i < len; ++i) {
 | 
        
           |  |  | 490 |             hash[items[i].get(key)] = items[i];
 | 
        
           |  |  | 491 |         }
 | 
        
           |  |  | 492 |   | 
        
           |  |  | 493 |         return hash;
 | 
        
           |  |  | 494 |     },
 | 
        
           |  |  | 495 |   | 
        
           |  |  | 496 |     /**
 | 
        
           |  |  | 497 |     Removes items from the hash table.
 | 
        
           |  |  | 498 |   | 
        
           |  |  | 499 |     @method _hashRemove
 | 
        
           |  |  | 500 |     @param {Object} hash The hash map before removing items
 | 
        
           |  |  | 501 |     @param {String} key The key by which to remove the items from the hash
 | 
        
           |  |  | 502 |     @param {Object} e The event or object containing the items to be removed.
 | 
        
           |  |  | 503 |                       Items are expected to be stored in an array assigned to
 | 
        
           |  |  | 504 |                       the `removed` property.
 | 
        
           |  |  | 505 |     @return {Object} The updated hash map
 | 
        
           |  |  | 506 |     @private
 | 
        
           |  |  | 507 |     **/
 | 
        
           |  |  | 508 |     _hashRemove: function(hash, key, e) {
 | 
        
           |  |  | 509 |         for (var i = e.removed.length - 1; i >= 0; --i) {
 | 
        
           |  |  | 510 |             delete hash[e.removed[i].get(key)];
 | 
        
           |  |  | 511 |         }
 | 
        
           |  |  | 512 |   | 
        
           |  |  | 513 |         return hash;
 | 
        
           |  |  | 514 |     },
 | 
        
           |  |  | 515 |   | 
        
           |  |  | 516 |     /**
 | 
        
           |  |  | 517 |     Updates items in the hash table.
 | 
        
           |  |  | 518 |   | 
        
           |  |  | 519 |     @method _hashUpdate
 | 
        
           |  |  | 520 |     @param {Object} hash The hash map before updating items
 | 
        
           |  |  | 521 |     @param {String} key The key by which to update the items to the hash
 | 
        
           |  |  | 522 |     @param {Object} e The event or object containing the items to be updated.
 | 
        
           |  |  | 523 |                       Items are expected to be stored in an array assigned to
 | 
        
           |  |  | 524 |                       the `updated` property. Optionally, items can be
 | 
        
           |  |  | 525 |                       identified for being overwritten by including them in an
 | 
        
           |  |  | 526 |                       array assigned to the `overwritten` property.
 | 
        
           |  |  | 527 |     @return {Object} The updated hash map
 | 
        
           |  |  | 528 |     @private
 | 
        
           |  |  | 529 |     **/
 | 
        
           |  |  | 530 |     _hashUpdate: function (hash, key, e) {
 | 
        
           |  |  | 531 |         if (e.overwritten && e.overwritten.length) {
 | 
        
           |  |  | 532 |             hash = this._hashRemove(hash, key, { removed: e.overwritten });
 | 
        
           |  |  | 533 |         }
 | 
        
           |  |  | 534 |   | 
        
           |  |  | 535 |         return this._hashAdd(hash, key, { added: e.updated });
 | 
        
           |  |  | 536 |     },
 | 
        
           |  |  | 537 |   | 
        
           |  |  | 538 |     /**
 | 
        
           |  |  | 539 |     Clears the hash table.
 | 
        
           |  |  | 540 |   | 
        
           |  |  | 541 |     @method _hashEmpty
 | 
        
           |  |  | 542 |     @param {Object} hash The hash map before adding items
 | 
        
           |  |  | 543 |     @param {String} key The key by which to remove the items from the hash
 | 
        
           |  |  | 544 |     @param {Object} e The event or object containing the items to be removed.
 | 
        
           |  |  | 545 |                       Items are expected to be stored in an array assigned to
 | 
        
           |  |  | 546 |                       the `removed` property.
 | 
        
           |  |  | 547 |     @return {Object} An empty hash
 | 
        
           |  |  | 548 |     @private
 | 
        
           |  |  | 549 |     **/
 | 
        
           |  |  | 550 |     _hashEmpty: function() {
 | 
        
           |  |  | 551 |         return {};
 | 
        
           |  |  | 552 |     },
 | 
        
           |  |  | 553 |   | 
        
           |  |  | 554 |     /**
 | 
        
           |  |  | 555 |      * Sets up the hashtable with all the records currently in the recordset
 | 
        
           |  |  | 556 |      *
 | 
        
           |  |  | 557 |      * @method _initHashTable
 | 
        
           |  |  | 558 |      * @private
 | 
        
           |  |  | 559 |      */
 | 
        
           |  |  | 560 |     _initHashTable: function() {
 | 
        
           |  |  | 561 |         return this._hashAdd({}, this.get('key'), { added: this._items || [] });
 | 
        
           |  |  | 562 |     },
 | 
        
           |  |  | 563 |   | 
        
           |  |  | 564 |     /**
 | 
        
           |  |  | 565 |      * Helper method - it takes an object bag and converts it to a Y.Record
 | 
        
           |  |  | 566 |      *
 | 
        
           |  |  | 567 |      * @method _changeToRecord
 | 
        
           |  |  | 568 |      * @param obj {Object|Record} Any objet literal or Y.Record instance
 | 
        
           |  |  | 569 |      * @return {Record} A Record instance.
 | 
        
           |  |  | 570 |      * @private
 | 
        
           |  |  | 571 |      */
 | 
        
           |  |  | 572 |     _changeToRecord: function(obj) {
 | 
        
           |  |  | 573 |         return (obj instanceof Y.Record) ? obj : new Y.Record({ data: obj });
 | 
        
           |  |  | 574 |     },
 | 
        
           |  |  | 575 |   | 
        
           |  |  | 576 |     /**
 | 
        
           |  |  | 577 |     Ensures the value being set is an array of Record instances. If array items
 | 
        
           |  |  | 578 |     are raw object data, they are turned into Records.
 | 
        
           |  |  | 579 |   | 
        
           |  |  | 580 |     @method _setRecords
 | 
        
           |  |  | 581 |     @param {Record[]|Object[]} items The Records or data Objects to store as
 | 
        
           |  |  | 582 |                                      Records.
 | 
        
           |  |  | 583 |     @return {Record[]}
 | 
        
           |  |  | 584 |     **/
 | 
        
           |  |  | 585 |     _setRecords: function (items) {
 | 
        
           |  |  | 586 |         if (!Y.Lang.isArray(items)) {
 | 
        
           |  |  | 587 |             return Y.Attribute.INVALID_VALUE;
 | 
        
           |  |  | 588 |         }
 | 
        
           |  |  | 589 |   | 
        
           |  |  | 590 |         var records = [],
 | 
        
           |  |  | 591 |             i, len;
 | 
        
           |  |  | 592 |   | 
        
           |  |  | 593 |         // FIXME: This should use the flyweight pattern if possible
 | 
        
           |  |  | 594 |         for (i = 0, len = items.length; i < len; ++i) {
 | 
        
           |  |  | 595 |             records[i] = this._changeToRecord(items[i]);
 | 
        
           |  |  | 596 |         }
 | 
        
           |  |  | 597 |   | 
        
           |  |  | 598 |         return (this._items = records);
 | 
        
           |  |  | 599 |     }
 | 
        
           |  |  | 600 | }, {
 | 
        
           |  |  | 601 |     ATTRS: {
 | 
        
           |  |  | 602 |   | 
        
           |  |  | 603 |         /**
 | 
        
           |  |  | 604 |         * An array of Records that the Recordset is storing.  Passing an array
 | 
        
           |  |  | 605 |         * of raw record data is also accepted.  The data for each item will be
 | 
        
           |  |  | 606 |         * wrapped in a Record instance.
 | 
        
           |  |  | 607 |         *
 | 
        
           |  |  | 608 |         * @attribute records
 | 
        
           |  |  | 609 |         * @type {Record[]}
 | 
        
           |  |  | 610 |         */
 | 
        
           |  |  | 611 |         records: {
 | 
        
           |  |  | 612 |             // TODO: necessary? valueFn?
 | 
        
           |  |  | 613 |             lazyAdd: false,
 | 
        
           |  |  | 614 |             getter: function() {
 | 
        
           |  |  | 615 |                 // give them a copy, not the internal object
 | 
        
           |  |  | 616 |                 return Y.Array(this._items);
 | 
        
           |  |  | 617 |             },
 | 
        
           |  |  | 618 |             setter: "_setRecords"
 | 
        
           |  |  | 619 |         },
 | 
        
           |  |  | 620 |   | 
        
           |  |  | 621 |         /**
 | 
        
           |  |  | 622 |         A hash table where the ID of the record is the key, and the record
 | 
        
           |  |  | 623 |         instance is the value.
 | 
        
           |  |  | 624 |   | 
        
           |  |  | 625 |         @attribute table
 | 
        
           |  |  | 626 |         @type object
 | 
        
           |  |  | 627 |         **/
 | 
        
           |  |  | 628 |         table: {
 | 
        
           |  |  | 629 |             valueFn: '_initHashTable'
 | 
        
           |  |  | 630 |         },
 | 
        
           |  |  | 631 |   | 
        
           |  |  | 632 |         /**
 | 
        
           |  |  | 633 |         The ID to use as the key in the hash table.
 | 
        
           |  |  | 634 |   | 
        
           |  |  | 635 |         @attribute key
 | 
        
           |  |  | 636 |         @type string
 | 
        
           |  |  | 637 |         **/
 | 
        
           |  |  | 638 |         key: {
 | 
        
           |  |  | 639 |             value: 'id',
 | 
        
           |  |  | 640 |             readOnly: true
 | 
        
           |  |  | 641 |         }
 | 
        
           |  |  | 642 |   | 
        
           |  |  | 643 |     }
 | 
        
           |  |  | 644 | });
 | 
        
           |  |  | 645 | Y.augment(Recordset, ArrayList);
 | 
        
           |  |  | 646 | Y.Recordset = Recordset;
 | 
        
           |  |  | 647 |   | 
        
           |  |  | 648 |   | 
        
           |  |  | 649 |   | 
        
           |  |  | 650 | }, '3.18.1', {"requires": ["base", "arraylist"]});
 |