1 if (!Array.prototype.indexOf) { 2 Array.prototype.indexOf = function(value, from) { 3 var len = this.length >>> 0; 4 from = Number(from) || 0; 5 from = Math[from < 0 ? 'ceil' : 'floor'](from); 6 if (from < 0) { 7 from += len; 8 } 9 for (; from < len; from++) { 10 if (from in this && this[from] === value) { 11 return from; 12 } 13 } 14 return -1; 15 }; 16 } 17 18 if (!Array.prototype.forEach) { 19 Array.prototype.forEach = function(fn, context) { 20 for (var i = 0, len = this.length >>> 0; i < len; i++) { 21 if (i in this) { 22 fn.call(context, this[i], i, this); 23 } 24 } 25 }; 26 } 27 28 if (!Array.prototype.map) { 29 Array.prototype.map = function(fn, context) { 30 var result = [ ]; 31 for (var i = 0, len = this.length >>> 0; i < len; i++) { 32 if (i in this) { 33 result[i] = fn.call(context, this[i], i, this); 34 } 35 } 36 return result; 37 }; 38 } 39 40 if (!Array.prototype.every) { 41 Array.prototype.every = function(fn, context) { 42 for (var i = 0, len = this.length >>> 0; i < len; i++) { 43 if (i in this && !fn.call(context, this[i], i, this)) { 44 return false; 45 } 46 } 47 return true; 48 }; 49 } 50 51 if (!Array.prototype.some) { 52 Array.prototype.some = function(fn, context) { 53 for (var i = 0, len = this.length >>> 0; i < len; i++) { 54 if (i in this && fn.call(context, this[i], i, this)) { 55 return true; 56 } 57 } 58 return false; 59 }; 60 } 61 62 if (!Array.prototype.filter) { 63 Array.prototype.filter = function(fn, context) { 64 var result = [ ], val; 65 for (var i = 0, len = this.length >>> 0; i < len; i++) { 66 if (i in this) { 67 val = this[i]; // in case fn mutates this 68 if (fn.call(context, val, i, this)) { 69 result.push(val); 70 } 71 } 72 } 73 return result; 74 }; 75 } 76 77 if (!Array.prototype.reduce) { 78 Array.prototype.reduce = function(fn /*, initial*/) { 79 var len = this.length >>> 0, 80 i = 0, 81 rv; 82 83 if (arguments.length > 1) { 84 rv = arguments[1]; 85 } 86 else { 87 do { 88 if (i in this) { 89 rv = this[i++]; 90 break; 91 } 92 // if array contains no values, no initial value to return 93 if (++i >= len) { 94 throw new TypeError(); 95 } 96 } 97 while (true); 98 } 99 for (; i < len; i++) { 100 if (i in this) { 101 rv = fn.call(null, rv, this[i], i, this); 102 } 103 } 104 return rv; 105 }; 106 } 107 108 /** 109 * Invokes method on all items in a given array 110 * @method invoke 111 * @memberOf fabric.util.array 112 * @param {Array} array Array to iterate over 113 * @param {String} method Name of a method to invoke 114 */ 115 function invoke(array, method) { 116 var args = slice.call(arguments, 2), result = [ ]; 117 for (var i = 0, len = array.length; i < len; i++) { 118 result[i] = args.length ? array[i][method].apply(array[i], args) : array[i][method].call(array[i]); 119 } 120 return result; 121 } 122 123 /** 124 * Finds maximum value in array (not necessarily "first" one) 125 * @method max 126 * @memberOf fabric.util.array 127 * @param {Array} array Array to iterate over 128 * @param {String} byProperty 129 */ 130 function max(array, byProperty) { 131 var i = array.length - 1, 132 result = byProperty ? array[i][byProperty] : array[i]; 133 if (byProperty) { 134 while (i--) { 135 if (array[i][byProperty] >= result) { 136 result = array[i][byProperty]; 137 } 138 } 139 } 140 else { 141 while (i--) { 142 if (array[i] >= result) { 143 result = array[i]; 144 } 145 } 146 } 147 return result; 148 } 149 150 /** 151 * Finds minimum value in array (not necessarily "first" one) 152 * @method min 153 * @memberOf fabric.util.array 154 * @param {Array} array Array to iterate over 155 * @param {String} byProperty 156 */ 157 function min(array, byProperty) { 158 var i = array.length - 1, 159 result = byProperty ? array[i][byProperty] : array[i]; 160 161 if (byProperty) { 162 while (i--) { 163 if (array[i][byProperty] < result) { 164 result = array[i][byProperty]; 165 } 166 } 167 } 168 else { 169 while (i--) { 170 if (array[i] < result) { 171 result = array[i]; 172 } 173 } 174 } 175 return result; 176 } 177 178 /** @namespace */ 179 fabric.util.array = { 180 invoke: invoke, 181 min: min, 182 max: max 183 };