1// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5/** 6 * @fileoverview This is a data model representin 7 */ 8 9cr.define('cr.ui', function() { 10 const EventTarget = cr.EventTarget; 11 const Event = cr.Event; 12 13 /** 14 * A data model that wraps a simple array. 15 * @param {!Array} array The underlying array. 16 * @constructor 17 * @extends {EventTarget} 18 */ 19 function ArrayDataModel(array) { 20 this.array_ = array; 21 } 22 23 ArrayDataModel.prototype = { 24 __proto__: EventTarget.prototype, 25 26 /** 27 * The length of the data model. 28 * @type {number} 29 */ 30 get length() { 31 return this.array_.length; 32 }, 33 34 /** 35 * Returns the item at the given index. 36 * @param {number} index The index of the element to get. 37 * @return {*} The element at the given index. 38 */ 39 item: function(index) { 40 return this.array_[index]; 41 }, 42 43 /** 44 * Returns the first matching item. 45 * @param {*} item The item to find. 46 * @param {number=} opt_fromIndex If provided, then the searching start at 47 * the {@code opt_fromIndex}. 48 * @return {number} The index of the first found element or -1 if not found. 49 */ 50 indexOf: function(item, opt_fromIndex) { 51 return this.array_.indexOf(item, opt_fromIndex); 52 }, 53 54 /** 55 * Returns an array of elements in a selected range. 56 * @param {number=} opt_from The starting index of the selected range. 57 * @param {number=} opt_to The ending index of selected range. 58 * @return {Array} An array of elements in the selected range. 59 */ 60 slice: function(opt_from, opt_to) { 61 return this.array_.slice.apply(this.array_, arguments); 62 }, 63 64 /** 65 * This removes and adds items to the model. 66 * 67 * This dispatches a splice event. 68 * 69 * @param {number} index The index of the item to update. 70 * @param {number} deleteCount The number of items to remove. 71 * @param {...*} The items to add. 72 * @return {!Array} An array with the removed items. 73 */ 74 splice: function(index, deleteCount, var_args) { 75 var arr = this.array_; 76 77 // TODO(arv): Maybe unify splice and change events? 78 var e = new Event('splice'); 79 e.index = index; 80 e.removed = arr.slice(index, index + deleteCount); 81 e.added = Array.prototype.slice.call(arguments, 2); 82 83 var rv = arr.splice.apply(arr, arguments); 84 85 this.dispatchEvent(e); 86 87 return rv; 88 }, 89 90 /** 91 * Appends items to the end of the model. 92 * 93 * This dispatches a splice event. 94 * 95 * @param {...*} The items to append. 96 * @return {number} The new length of the model. 97 */ 98 push: function(var_args) { 99 var args = Array.prototype.slice.call(arguments); 100 args.unshift(this.length, 0); 101 this.splice.apply(this, args); 102 return this.length; 103 }, 104 105 /** 106 * Use this to update a given item in the array. This does not remove and 107 * reinsert a new item. 108 * 109 * This dispatches a change event. 110 * 111 * @param {number} index The index of the item to update. 112 */ 113 updateIndex: function(index) { 114 if (index < 0 || index >= this.length) 115 throw Error('Invalid index, ' + index); 116 117 // TODO(arv): Maybe unify splice and change events? 118 var e = new Event('change'); 119 e.index = index; 120 this.dispatchEvent(e); 121 } 122 }; 123 124 return { 125 ArrayDataModel: ArrayDataModel 126 }; 127}); 128