/**
* ObservableArray.js
*
* Released under LGPL License.
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
*
* License: http://www.tinymce.com/license
* Contributing: http://www.tinymce.com/contributing
*/
/**
* This class is an array that emmits events when mutation occurs.
*
* @private
* @class tinymce.data.ObservableArray
*/
define(
'tinymce.core.data.ObservableArray',
[
"tinymce.core.util.Observable",
"tinymce.core.util.Class"
],
function (Observable, Class) {
var push = Array.prototype.push, slice = Array.prototype.slice, splice = Array.prototype.splice;
var ObservableArray = Class.extend({
Mixins: [Observable],
/**
* Number of items in array.
*
* @field length
* @type Number
*/
length: 0,
/**
* Constructs a new observable object instance.
*
* @constructor
* @param {Object} data Optional initial data for the object.
*/
init: function (data) {
if (data) {
this.push.apply(this, data);
}
},
/**
* Adds items to the end of array.
*
* @method push
* @param {Object} item... Item or items to add to the end of array.
* @return {Number} Number of items that got added.
*/
push: function () {
var args, index = this.length;
args = Array.prototype.slice.call(arguments);
push.apply(this, args);
this.fire('add', {
items: args,
index: index
});
return args.length;
},
/**
* Pops the last item off the array.
*
* @method pop
* @return {Object} Item that got popped out.
*/
pop: function () {
return this.splice(this.length - 1, 1)[0];
},
/**
* Slices out a portion of the array as a new array.
*
* @method slice
* @param {Number} begin Beginning of slice.
* @param {Number} end End of slice.
* @return {Array} Native array instance with items.
*/
slice: function (begin, end) {
return slice.call(this, begin, end);
},
/**
* Removes/replaces/inserts items in the array.
*
* @method splice
* @param {Number} index Index to splice at.
* @param {Number} howMany Optional number of items to splice away.
* @param {Object} item ... Item or items to insert at the specified index.
*/
splice: function (index) {
var added, removed, args = slice.call(arguments);
if (args.length === 1) {
args[1] = this.length;
}
removed = splice.apply(this, args);
added = args.slice(2);
if (removed.length > 0) {
this.fire('remove', { items: removed, index: index });
}
if (added.length > 0) {
this.fire('add', { items: added, index: index });
}
return removed;
},
/**
* Removes and returns the first item of the array.
*
* @method shift
* @return {Object} First item of the array.
*/
shift: function () {
return this.splice(0, 1)[0];
},
/**
* Appends an item to the top of array.
*
* @method unshift
* @param {Object} item... Item or items to prepend to array.
* @return {Number} Number of items that got added.
*/
unshift: function () {
var args = slice.call(arguments);
this.splice.apply(this, [0, 0].concat(args));
return args.length;
},
/**
* Executes the callback for each item in the array.
*
* @method forEach
* @param {function} callback Callback to execute for each item in array.
* @param {Object} scope Optional scope for this when executing the callback.
*/
forEach: function (callback, scope) {
var i;
scope = scope || this;
for (i = 0; i < this.length; i++) {
callback.call(scope, this[i], i, this);
}
},
/**
* Returns the index of the specified item or -1 if it wasn't found.
*
* @method indexOf
* @return {Number} Index of item or null if it wasn't found.
*/
indexOf: function (item) {
for (var i = 0; i < this.length; i++) {
if (this[i] === item) {
return i;
}
}
return -1;
},
/**
* Filters the observable array into a new observable array
* based on the true/false return value of the specified callback.
*
* @method filter
* @param {function} callback Callback function to execute for each item and filter by.
* @param {Object} thisArg Optional scope for this when executing the callback.
* @return {tinymce.data.ObservableArray} Filtered observable array instance.
*/
filter: function (callback, thisArg) {
var self = this, out = new ObservableArray();
this.forEach(function (item, index) {
if (callback.call(thisArg || self, item, index, self)) {
out.push(item);
}
});
return out;
}
});
return ObservableArray;
}
);
|