614 lines
18 KiB
JavaScript
614 lines
18 KiB
JavaScript
|
|
var utils = require('cordova/utils'),
|
||
|
|
BaseClass = require('./BaseClass');
|
||
|
|
|
||
|
|
var ARRAY_FIELD = typeof Symbol === 'undefined' ? '__array' + Date.now() : Symbol('array');
|
||
|
|
|
||
|
|
var nextTick = function(fn) { Promise.resolve().then(fn); };
|
||
|
|
/**
|
||
|
|
* Create a BaseArrayClass.
|
||
|
|
* @class
|
||
|
|
*/
|
||
|
|
function BaseArrayClass(array) {
|
||
|
|
BaseClass.apply(this);
|
||
|
|
var self = this;
|
||
|
|
self[ARRAY_FIELD] = [];
|
||
|
|
|
||
|
|
if (array && (array instanceof Array || Array.isArray(array))) {
|
||
|
|
for (var i = 0; i < array.length; i++) {
|
||
|
|
self[ARRAY_FIELD].push(array[i]);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
utils.extend(BaseArrayClass, BaseClass);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* The same as `Array.map` but runs a single async operation at a time.
|
||
|
|
*
|
||
|
|
* @name mapSeries
|
||
|
|
* @param {Function} iteratee - An async function to apply to each item in array.
|
||
|
|
* @param {Function} [callback] - A callback which is called when all `iteratee` functions
|
||
|
|
* have finished. Results is an array of the transformed items from holding array.
|
||
|
|
* Invoked with (results);
|
||
|
|
* @return {Promise} a promise, if no calback if passed.
|
||
|
|
*/
|
||
|
|
BaseArrayClass.prototype.mapSeries = function(iteratee, callback) {
|
||
|
|
if (typeof iteratee !== 'function') {
|
||
|
|
var error = new Error('iteratee must be a function');
|
||
|
|
if (typeof callback === 'function') {
|
||
|
|
throw error;
|
||
|
|
} else {
|
||
|
|
return Promise.reject(error);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
var self = this;
|
||
|
|
|
||
|
|
var results = [];
|
||
|
|
var _arrayLength = self[ARRAY_FIELD].length;
|
||
|
|
var currentCnt = 0;
|
||
|
|
if (_arrayLength === 0) {
|
||
|
|
if (typeof callback === 'function') {
|
||
|
|
callback.call(self, []);
|
||
|
|
return;
|
||
|
|
} else {
|
||
|
|
return Promise.resolve([]);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
var _looper = function(currentIdx, resolve) {
|
||
|
|
|
||
|
|
iteratee.call(self, self[ARRAY_FIELD][currentIdx], function(value) {
|
||
|
|
results[currentIdx] = value;
|
||
|
|
currentCnt++;
|
||
|
|
if (_arrayLength === currentCnt) {
|
||
|
|
resolve(results);
|
||
|
|
} else {
|
||
|
|
nextTick(function() {
|
||
|
|
_looper(currentIdx + 1, resolve);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
});
|
||
|
|
};
|
||
|
|
|
||
|
|
return new Promise(function(resolve) {
|
||
|
|
nextTick(function() {
|
||
|
|
_looper(0, resolve);
|
||
|
|
});
|
||
|
|
}).then(function(results) {
|
||
|
|
if (typeof callback === 'function') {
|
||
|
|
return callback.call(self, results);
|
||
|
|
} else {
|
||
|
|
return Promise.resolve(results);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* The same as `Array.map` but runs async all `iteratee` function at the same time.
|
||
|
|
*
|
||
|
|
* ```
|
||
|
|
* baseArray.mapAsync(function(item, idx, callback) {
|
||
|
|
* ...
|
||
|
|
* callback(value);
|
||
|
|
* }).then(function(values) {
|
||
|
|
*
|
||
|
|
* });
|
||
|
|
* ```
|
||
|
|
*
|
||
|
|
* @name mapAsync
|
||
|
|
* @param {Function} iteratee - An async function to apply to each item in array.
|
||
|
|
* @param {Function} [callback] - A callback which is called when all `iteratee` functions
|
||
|
|
* have finished. Results is an array of the transformed items from holding array.
|
||
|
|
* Invoked with (results);
|
||
|
|
* @return {Promise} a promise, if no calback if passed.
|
||
|
|
*/
|
||
|
|
BaseArrayClass.prototype.mapAsync = function(iteratee, callback) {
|
||
|
|
if (typeof iteratee !== 'function') {
|
||
|
|
var error = new Error('iteratee must be a function');
|
||
|
|
if (typeof callback === 'function') {
|
||
|
|
throw error;
|
||
|
|
} else {
|
||
|
|
return Promise.reject(error);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
var self = this;
|
||
|
|
var results = [];
|
||
|
|
for (var i = 0; i < self[ARRAY_FIELD].length; i++) {
|
||
|
|
results.push(null);
|
||
|
|
}
|
||
|
|
var _arrayLength = self[ARRAY_FIELD].length;
|
||
|
|
var finishCnt = 0;
|
||
|
|
if (_arrayLength === 0) {
|
||
|
|
if (typeof callback === 'function') {
|
||
|
|
callback.call(self, []);
|
||
|
|
return;
|
||
|
|
} else {
|
||
|
|
return Promise.resolve([]);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return new Promise(function(resolve) {
|
||
|
|
for (i = 0; i < self[ARRAY_FIELD].length; i++) {
|
||
|
|
(function(item, idx) {
|
||
|
|
nextTick(function() {
|
||
|
|
iteratee.call(self, item, function(value) {
|
||
|
|
results[idx] = value;
|
||
|
|
finishCnt++;
|
||
|
|
if (finishCnt === _arrayLength) {
|
||
|
|
resolve(results);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
});
|
||
|
|
})(self[ARRAY_FIELD][i], i);
|
||
|
|
}
|
||
|
|
}).then(function(results) {
|
||
|
|
if (typeof callback === 'function') {
|
||
|
|
return callback.call(self, results);
|
||
|
|
} else {
|
||
|
|
return Promise.resolve(results);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* If you provide `iteratee` and `callback`, work as `mapAsync()`.
|
||
|
|
* If you provide `iteratee`, but omit `callback`, work as `Array.map()`.
|
||
|
|
*
|
||
|
|
* @deprecated
|
||
|
|
* @name map
|
||
|
|
* @param {Function} iteratee - An async function to apply to each item in array.
|
||
|
|
* @param {Function} [callback] - A callback which is called when all `iteratee` functions
|
||
|
|
* have finished. Results is an array of the transformed items from holding array.
|
||
|
|
* Invoked with (results);
|
||
|
|
* @return {Promise|any[]} a promise, if no calback if passed. If you omit `callback`, return transformed items.
|
||
|
|
*/
|
||
|
|
BaseArrayClass.prototype.map = function(iteratee, callback) {
|
||
|
|
var self = this;
|
||
|
|
|
||
|
|
if (typeof iteratee !== 'function') {
|
||
|
|
var error = new Error('iteratee must be a function');
|
||
|
|
if (typeof callback === 'function') {
|
||
|
|
throw error;
|
||
|
|
} else {
|
||
|
|
return Promise.reject(error);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (typeof callback !== 'function') {
|
||
|
|
//------------------------
|
||
|
|
// example:
|
||
|
|
// var values = baseArray.map(function(item, idx) {
|
||
|
|
// ...
|
||
|
|
// return someValue;
|
||
|
|
// });
|
||
|
|
//------------------------
|
||
|
|
return self[ARRAY_FIELD].map(iteratee.bind(self));
|
||
|
|
}
|
||
|
|
return self.mapAsync(iteratee, callback);
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* The same as `Array.forEach` but runs async all `iteratee` function at the same time.
|
||
|
|
*
|
||
|
|
* @name forEachAsync
|
||
|
|
* @param {Function} iteratee - An async function to apply to each item in array.
|
||
|
|
* @param {Function} [callback] - A callback which is called when all `iteratee` functions
|
||
|
|
* have finished.
|
||
|
|
* @return {Promise} a promise, if no calback if passed.
|
||
|
|
*/
|
||
|
|
BaseArrayClass.prototype.forEachAsync = function(iteratee, callback) {
|
||
|
|
if (typeof iteratee !== 'function') {
|
||
|
|
var error = new Error('iteratee must be a function');
|
||
|
|
if (typeof callback === 'function') {
|
||
|
|
throw error;
|
||
|
|
} else {
|
||
|
|
return Promise.reject(error);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
var self = this;
|
||
|
|
//------------------------
|
||
|
|
// example:
|
||
|
|
// baseArray.forEach(function(item, callback) {
|
||
|
|
// ...
|
||
|
|
// callback();
|
||
|
|
// }, function() {
|
||
|
|
//
|
||
|
|
// });
|
||
|
|
//------------------------
|
||
|
|
var finishCnt = 0;
|
||
|
|
var _arrayLength = self[ARRAY_FIELD].length;
|
||
|
|
if (_arrayLength === 0) {
|
||
|
|
if (typeof callback === 'function') {
|
||
|
|
callback.call(self);
|
||
|
|
return;
|
||
|
|
} else {
|
||
|
|
return Promise.resolve();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return new Promise(function(resolve) {
|
||
|
|
|
||
|
|
self[ARRAY_FIELD].forEach(function(item) {
|
||
|
|
iteratee.call(self, item, function() {
|
||
|
|
finishCnt++;
|
||
|
|
if (finishCnt === _arrayLength) {
|
||
|
|
resolve(self);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
})
|
||
|
|
.then(function() {
|
||
|
|
if (typeof callback === 'function') {
|
||
|
|
callback.call(self);
|
||
|
|
return;
|
||
|
|
} else {
|
||
|
|
return Promise.resolve();
|
||
|
|
}
|
||
|
|
});
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* If you provide `iteratee` and `callback`, work as `forEachAsync()`.
|
||
|
|
* If you provide `iteratee`, but you omit `callback`, work as `Array.forEach()`
|
||
|
|
*
|
||
|
|
* @deprecated
|
||
|
|
* @name forEach
|
||
|
|
* @param {Function} iteratee - An async function to apply to each item in array.
|
||
|
|
* @param {Function} [callback] - A callback which is called when all `iteratee` functions
|
||
|
|
* have finished.
|
||
|
|
* Invoked with (results);
|
||
|
|
* @return {Promise} a promise, if no calback if passed.
|
||
|
|
*/
|
||
|
|
BaseArrayClass.prototype.forEach = function(iteratee, callback) {
|
||
|
|
var self = this;
|
||
|
|
if (typeof iteratee !== 'function') {
|
||
|
|
var error = new Error('iteratee must be a function');
|
||
|
|
if (typeof callback === 'function') {
|
||
|
|
throw error;
|
||
|
|
} else {
|
||
|
|
return Promise.reject(error);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (typeof callback !== 'function') {
|
||
|
|
//------------------------
|
||
|
|
// example:
|
||
|
|
// baseArray.forEach(function(item, idx) {
|
||
|
|
// ...
|
||
|
|
// });
|
||
|
|
//------------------------
|
||
|
|
self[ARRAY_FIELD].forEach(iteratee.bind(self));
|
||
|
|
return Promise.resolve();
|
||
|
|
}
|
||
|
|
return self.forEachAsync(iteratee, callback);
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* The same as `Array.filter` but runs async all `iteratee` function at the same time.
|
||
|
|
*
|
||
|
|
* @name filterAsync
|
||
|
|
* @param {Function} iteratee - An async function to apply to each item in array.
|
||
|
|
* @param {Function} [callback] - A callback which is called when all `iteratee` functions
|
||
|
|
* have finished. Results is an array of the filtered items from holding array.
|
||
|
|
* Invoked with (results);
|
||
|
|
* @return {Promise} a promise, if no calback if passed.
|
||
|
|
*/
|
||
|
|
BaseArrayClass.prototype.filterAsync = function(iteratee, callback) {
|
||
|
|
var self = this;
|
||
|
|
if (typeof iteratee !== 'function') {
|
||
|
|
var error = new Error('iteratee must be a function');
|
||
|
|
if (typeof callback === 'function') {
|
||
|
|
throw error;
|
||
|
|
} else {
|
||
|
|
return Promise.reject(error);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
//------------------------
|
||
|
|
// example:
|
||
|
|
// baseArray.filter(function(item, callback) {
|
||
|
|
// ...
|
||
|
|
// callback(true or false);
|
||
|
|
// }, function(filteredItems) {
|
||
|
|
//
|
||
|
|
// });
|
||
|
|
//------------------------
|
||
|
|
var finishCnt = 0;
|
||
|
|
var _arrayLength = self[ARRAY_FIELD].length;
|
||
|
|
if (_arrayLength === 0) {
|
||
|
|
if (typeof callback === 'function') {
|
||
|
|
callback.call(self, []);
|
||
|
|
return;
|
||
|
|
} else {
|
||
|
|
return Promise.resolve([]);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return (new Promise(function(resolve) {
|
||
|
|
var results = [];
|
||
|
|
self[ARRAY_FIELD].forEach(function(item, idx) {
|
||
|
|
iteratee.call(self, item, function(isOk) {
|
||
|
|
results[idx] = isOk;
|
||
|
|
finishCnt++;
|
||
|
|
if (finishCnt === _arrayLength) {
|
||
|
|
resolve(self[ARRAY_FIELD].filter(function(item, j) {
|
||
|
|
return results[j];
|
||
|
|
}));
|
||
|
|
}
|
||
|
|
});
|
||
|
|
});
|
||
|
|
}))
|
||
|
|
.then(function(results) {
|
||
|
|
if (typeof callback === 'function') {
|
||
|
|
callback.call(self, results);
|
||
|
|
return;
|
||
|
|
} else {
|
||
|
|
return Promise.resolve(results);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* If you provide `iteratee` and `callback`, work as `filterAsync()`.
|
||
|
|
* If you provide `iteratee`, but you omit `callback`, work as `Array.filter()`
|
||
|
|
*
|
||
|
|
* @deprecated
|
||
|
|
* @name filter
|
||
|
|
* @param {Function} iteratee - An async function to apply to each item in array.
|
||
|
|
* @param {Function} [callback] - A callback which is called when all `iteratee` functions
|
||
|
|
* have finished.
|
||
|
|
* @return {Promise} a promise, if no calback if passed.
|
||
|
|
*/
|
||
|
|
BaseArrayClass.prototype.filter = function(iteratee, callback) {
|
||
|
|
var self = this;
|
||
|
|
if (typeof iteratee !== 'function') {
|
||
|
|
var error = new Error('iteratee must be a function');
|
||
|
|
if (typeof callback === 'function') {
|
||
|
|
throw error;
|
||
|
|
} else {
|
||
|
|
return Promise.reject(error);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (typeof callback !== 'function') {
|
||
|
|
//------------------------
|
||
|
|
// example:
|
||
|
|
// baseArray.filter(function(item, idx) {
|
||
|
|
// ...
|
||
|
|
// return true or false
|
||
|
|
// });
|
||
|
|
//------------------------
|
||
|
|
return self[ARRAY_FIELD].filter(iteratee);
|
||
|
|
}
|
||
|
|
return self.filterAsync(iteratee, callback);
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the first index at which a given element can be found in the array, or -1 if it is not present.
|
||
|
|
*
|
||
|
|
* @name indexOf
|
||
|
|
* @param {any} searchElement - Element to locate in the array.
|
||
|
|
* @param {number} [searchElement] - The index to start the search at.
|
||
|
|
* If the index is greater than or equal to the array's length, -1 is returned,
|
||
|
|
* which means the array will not be searched.
|
||
|
|
* If the provided index value is a negative number,
|
||
|
|
* it is taken as the offset from the end of the array.
|
||
|
|
* Note: if the provided index is negative, the array is still searched from front to back.
|
||
|
|
* If the provided index is 0, then the whole array will be searched. Default: 0 (entire array is searched).
|
||
|
|
* @return The first index of the element in the array; -1 if not found.
|
||
|
|
*/
|
||
|
|
BaseArrayClass.prototype.indexOf = function(item, searchElement) {
|
||
|
|
searchElement = searchElement === undefined || searchElement === null ? 0 : searchElement;
|
||
|
|
if (typeof searchElement !== 'number') {
|
||
|
|
throw new Error('searchElement must be a number');
|
||
|
|
}
|
||
|
|
if (searchElement < 0) {
|
||
|
|
throw new Error('searchElement must be over number than 0');
|
||
|
|
}
|
||
|
|
|
||
|
|
return this[ARRAY_FIELD].indexOf(item, searchElement);
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Removes all elements. Fire `remove_at` event for each element.
|
||
|
|
*
|
||
|
|
* @name empty
|
||
|
|
* @param {boolean} [noNotify] - Sets `true` if you don't want to fire `remove_at` event.
|
||
|
|
*/
|
||
|
|
BaseArrayClass.prototype.empty = function(noNotify) {
|
||
|
|
var self = this;
|
||
|
|
var cnt = self[ARRAY_FIELD].length;
|
||
|
|
for (var i = cnt - 1; i >= 0; i--) {
|
||
|
|
self.removeAt(i, noNotify);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Adds one element to the end of an array and returns the new length of the array.
|
||
|
|
* Fire `insert_at` event if `noNotify` is `false`.
|
||
|
|
*
|
||
|
|
* @name push
|
||
|
|
* @param {any} value - The element to add to the end of the array.
|
||
|
|
* @param {boolean} [noNotify] - Sets `true` if you don't want to fire `insert_at` event.
|
||
|
|
* @return {number} The new length property of the object upon which the method was called.
|
||
|
|
*/
|
||
|
|
BaseArrayClass.prototype.push = function(value, noNotify) {
|
||
|
|
var self = this;
|
||
|
|
self[ARRAY_FIELD].push(value);
|
||
|
|
if (noNotify !== true) {
|
||
|
|
self.trigger('insert_at', self[ARRAY_FIELD].length - 1);
|
||
|
|
}
|
||
|
|
return self[ARRAY_FIELD].length;
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Adds one element to the end of an array and returns the new length of the array.
|
||
|
|
* Fire `insert_at` event if `noNotify` is `false`.
|
||
|
|
*
|
||
|
|
* @name insertAt
|
||
|
|
* @param {number} index - The position of the array you want to insert new element.
|
||
|
|
* @param {any} value - The element to add to the end of the array.
|
||
|
|
* @param {boolean} [noNotify] - Sets `true` if you don't want to fire `insert_at` event.
|
||
|
|
* @return {number} The new length property of the object upon which the method was called.
|
||
|
|
*/
|
||
|
|
BaseArrayClass.prototype.insertAt = function(index, value, noNotify) {
|
||
|
|
var self = this;
|
||
|
|
if (typeof index !== 'number') {
|
||
|
|
throw new Error('index must be a number');
|
||
|
|
}
|
||
|
|
if (index < 0) {
|
||
|
|
throw new Error('index must be over number than 0');
|
||
|
|
}
|
||
|
|
self[ARRAY_FIELD].splice(index, 0, value);
|
||
|
|
if (noNotify !== true) {
|
||
|
|
self.trigger('insert_at', index);
|
||
|
|
}
|
||
|
|
return self[ARRAY_FIELD].length;
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns a new array that is the clone of internal array.
|
||
|
|
*
|
||
|
|
* @name getArray
|
||
|
|
* @return {Array<any>} New array
|
||
|
|
*/
|
||
|
|
BaseArrayClass.prototype.getArray = function() {
|
||
|
|
//return _array.slice(0); <-- Android browser keeps the same instance of original array
|
||
|
|
return JSON.parse(JSON.stringify(this[ARRAY_FIELD]));
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns item of specified position.
|
||
|
|
*
|
||
|
|
* @name getAt
|
||
|
|
* @param {number} index - The position of the array you want to get.
|
||
|
|
* @return {any} item
|
||
|
|
*/
|
||
|
|
BaseArrayClass.prototype.getAt = function(index) {
|
||
|
|
var self = this;
|
||
|
|
if (typeof index !== 'number') {
|
||
|
|
throw new Error('index must be a number');
|
||
|
|
}
|
||
|
|
if (index < 0) {
|
||
|
|
throw new Error('index must be over number than 0');
|
||
|
|
}
|
||
|
|
if (index >= self[ARRAY_FIELD].length) {
|
||
|
|
throw new Error('index must be lower number than ' + self[ARRAY_FIELD].length);
|
||
|
|
}
|
||
|
|
return this[ARRAY_FIELD][index];
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Replaces item of specified position.
|
||
|
|
*
|
||
|
|
* @name setAt
|
||
|
|
* @param {number} index - The position of the array you want to get.
|
||
|
|
* @param {any} value - New element
|
||
|
|
* @param {boolean} [noNotify] - Sets `true` if you don't want to fire `set_at` event.
|
||
|
|
* @return {any} previous item
|
||
|
|
*/
|
||
|
|
BaseArrayClass.prototype.setAt = function(index, value, noNotify) {
|
||
|
|
var self = this;
|
||
|
|
if (typeof index !== 'number') {
|
||
|
|
throw new Error('index must be a number');
|
||
|
|
}
|
||
|
|
if (index < 0) {
|
||
|
|
throw new Error('index must be over number than 0');
|
||
|
|
}
|
||
|
|
if (index > self[ARRAY_FIELD].length) {
|
||
|
|
for (var i = self[ARRAY_FIELD].length; i <= index; i++) {
|
||
|
|
self[ARRAY_FIELD][i] = undefined;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
var prev = self[ARRAY_FIELD][index];
|
||
|
|
self[ARRAY_FIELD][index] = value;
|
||
|
|
if (noNotify !== true) {
|
||
|
|
self.trigger('set_at', index, prev);
|
||
|
|
}
|
||
|
|
return prev;
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Removes item of specified position.
|
||
|
|
*
|
||
|
|
* @name removeAt
|
||
|
|
* @param {number} index - The position of the array you want to get.
|
||
|
|
* @param {boolean} [noNotify] - Sets `true` if you don't want to fire `remove_at` event.
|
||
|
|
* @return {any} removed item
|
||
|
|
*/
|
||
|
|
BaseArrayClass.prototype.removeAt = function(index, noNotify) {
|
||
|
|
var self = this;
|
||
|
|
if (typeof index !== 'number') {
|
||
|
|
throw new Error('index must be a number');
|
||
|
|
}
|
||
|
|
if (index < 0) {
|
||
|
|
throw new Error('index must be over number than 0');
|
||
|
|
}
|
||
|
|
if (index >= self[ARRAY_FIELD].length) {
|
||
|
|
throw new Error('index must be lower number than ' + self[ARRAY_FIELD].length);
|
||
|
|
}
|
||
|
|
var value = self[ARRAY_FIELD][index];
|
||
|
|
self[ARRAY_FIELD].splice(index, 1);
|
||
|
|
if (noNotify !== true) {
|
||
|
|
self.trigger('remove_at', index, value);
|
||
|
|
}
|
||
|
|
return value;
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Removes item of the last array item.
|
||
|
|
*
|
||
|
|
* @name pop
|
||
|
|
* @param {boolean} [noNotify] - Sets `true` if you don't want to fire `remove_at` event.
|
||
|
|
* @return {any} removed item
|
||
|
|
*/
|
||
|
|
BaseArrayClass.prototype.pop = function(noNotify) {
|
||
|
|
var self = this;
|
||
|
|
var index = self[ARRAY_FIELD].length - 1;
|
||
|
|
var value = self[ARRAY_FIELD].pop();
|
||
|
|
if (noNotify !== true) {
|
||
|
|
self.trigger('remove_at', index, value);
|
||
|
|
}
|
||
|
|
return value;
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the length of array.
|
||
|
|
*
|
||
|
|
* @name getLength
|
||
|
|
* @return {any} Number of items
|
||
|
|
*/
|
||
|
|
BaseArrayClass.prototype.getLength = function() {
|
||
|
|
return parseInt(this[ARRAY_FIELD].length, 10); // In order to prevent manupulating through `length` property, conver to number mandatory using `parseInt`.
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Reverses an array in place. The first array element becomes the last, and the last array element becomes the first.
|
||
|
|
*
|
||
|
|
* @name reverse
|
||
|
|
*/
|
||
|
|
BaseArrayClass.prototype.reverse = function() {
|
||
|
|
this[ARRAY_FIELD].reverse();
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* The `sort()` method sorts the elements of an array in place and returns the array.
|
||
|
|
* The same as `array.sort()`.
|
||
|
|
*
|
||
|
|
* @name sort
|
||
|
|
* @param {Function} [compareFunction] - Specifies a function that defines the sort order.
|
||
|
|
* If omitted, the array is sorted according to each character's Unicode code point value,
|
||
|
|
* according to the string conversion of each element.
|
||
|
|
*/
|
||
|
|
BaseArrayClass.prototype.sort = function(compareFunction) {
|
||
|
|
if (typeof compareFunction === 'function') {
|
||
|
|
this[ARRAY_FIELD].sort(compareFunction);
|
||
|
|
} else {
|
||
|
|
this[ARRAY_FIELD].sort();
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
module.exports = BaseArrayClass;
|