Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
parent
93e3a48004
commit
b38dea0597
25901 changed files with 9982925 additions and 369 deletions
228
gaia/apps/settings/js/modules/mvvm/observable_array.js
Executable file
228
gaia/apps/settings/js/modules/mvvm/observable_array.js
Executable file
|
|
@ -0,0 +1,228 @@
|
|||
/**
|
||||
* ObservableArray is able to notify its change through events of four basic
|
||||
* operations including 'insert', 'remove', 'replace', 'reset'.
|
||||
* ObservableArray implements most used methods including 'push', 'pop', and
|
||||
* 'splice'. Due to the syntax limitation it provides 'get' and 'set' for
|
||||
* manuplication values stored in the array. 'reset' is also provided for
|
||||
* replacing te entire array with another one. In addition to these methods,
|
||||
* methods including 'forEach', 'map', 'every', 'some', 'indexOf',
|
||||
* 'lastIndexOf', 'reduce', and 'reduceRight'.
|
||||
*
|
||||
* ObservableArray creation:
|
||||
* It can be initialized by an ordinary array. If the array is not given, an
|
||||
* empty is used by default.
|
||||
*
|
||||
* @example
|
||||
* var observableArray = ObservableArray([1, 2, 3]);
|
||||
*
|
||||
* Events:
|
||||
* Information regarding the operation is provided in the event detail. Please
|
||||
* check the following example:
|
||||
*
|
||||
* @example
|
||||
* var observableArray = ObservableArray([1, 2, 3]);
|
||||
* var handler = {
|
||||
* handleEvent: function(event) { console.log(JSON.stringify(event)); }
|
||||
* }
|
||||
* observableArray.addEventListener('insert', handler);
|
||||
* observableArray.addEventListener('remove', handler);
|
||||
* observableArray.addEventListener('replace', handler);
|
||||
* observableArray.addEventListener('reset', handler);
|
||||
*
|
||||
* observableArray.push(4);
|
||||
* // observableArray is [1, 2, 3, 4]
|
||||
* // event.type is 'insert'
|
||||
* // event.detail is {index: 3, count: 1, items: [4]}
|
||||
*
|
||||
* observableArray.pop();
|
||||
* // observableArray is [1, 2, 3]
|
||||
* // event.type is 'remove'
|
||||
* // event.detail is {index: 3, count: 1, items: [4]}
|
||||
*
|
||||
* observableArray.set(2, 4);
|
||||
* // observableArray is [1, 2, 4]
|
||||
* // event.type is 'replace'
|
||||
* // event.detail is {index: 2, oldValue: 3, newValue: 4}
|
||||
*
|
||||
* observableArray.reset([1, 2, 3]);
|
||||
* // observableArray is [1, 2, 3]
|
||||
* // event.type is 'reset'
|
||||
* // event.detail is {items: [1, 2, 3]}
|
||||
*
|
||||
* observableArray.splice(2, 1, [4, 5, 6]);
|
||||
* // observableArray is [1, 2, 4, 5, 6]
|
||||
* // First event:
|
||||
* // event.type is 'remove'
|
||||
* // event.detail is {index: 2, count: 1, items: [3]}
|
||||
* // Second event:
|
||||
* // event.type is 'insert'
|
||||
* // event.detail is {index: 2, count: 3, items: [4, 5, 6]}
|
||||
*
|
||||
* @module modules/mvvm/observable_array
|
||||
*/
|
||||
define(function(require) {
|
||||
'use strict';
|
||||
|
||||
var Module = require('modules/base/module');
|
||||
var EventEmitter = require('modules/base/event_emitter');
|
||||
var Observable = require('modules/mvvm/observable');
|
||||
|
||||
var Events = ['insert', 'remove', 'replace', 'reset'];
|
||||
var ReadOnlyMethods = ['forEach', 'map', 'every', 'some', 'indexOf',
|
||||
'lastIndexOf', 'reduce', 'reduceRight'];
|
||||
|
||||
/**
|
||||
* @class ObservableArray
|
||||
* @requires module:modules/base/module
|
||||
* @requires module:modules/base/event_emitter
|
||||
* @requires module:modules/mvvm/observable
|
||||
* @returns {ObservableArray}
|
||||
*/
|
||||
var ObservableArray = Module.create(function ObservableArray(array) {
|
||||
this.super(Observable).call(this);
|
||||
this.super(EventEmitter).call(this, Events);
|
||||
|
||||
this._array = array || [];
|
||||
this._length = this._array.length;
|
||||
}).extend(Observable, EventEmitter);
|
||||
|
||||
/**
|
||||
* An observable property indicating the length of the array.
|
||||
*
|
||||
* @access public
|
||||
* @type {Number}
|
||||
*/
|
||||
Observable.defineObservableProperty(ObservableArray.prototype, 'length', {
|
||||
readonly: true
|
||||
});
|
||||
|
||||
/**
|
||||
* An observable property representing the inner array.
|
||||
*
|
||||
* @access public
|
||||
* @type {Array}
|
||||
*/
|
||||
Observable.defineObservableProperty(ObservableArray.prototype, 'array', {
|
||||
readonly: true
|
||||
});
|
||||
|
||||
ReadOnlyMethods.forEach(function(op) {
|
||||
ObservableArray.prototype[op] = function() {
|
||||
return this._array[op].apply(this._array, arguments);
|
||||
};
|
||||
});
|
||||
|
||||
ObservableArray.prototype.push = function(item) {
|
||||
this._array.push(item);
|
||||
this._length = this._array.length;
|
||||
|
||||
this._emitEvent('insert', {
|
||||
index: this._array.length - 1,
|
||||
count: 1,
|
||||
items: [item]
|
||||
});
|
||||
};
|
||||
|
||||
ObservableArray.prototype.pop = function() {
|
||||
if (!this._array.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var item = this._array.pop();
|
||||
this._length = this._array.length;
|
||||
|
||||
this._emitEvent('remove', {
|
||||
index: this._array.length,
|
||||
count: 1,
|
||||
items: [item]
|
||||
});
|
||||
|
||||
return item;
|
||||
};
|
||||
|
||||
ObservableArray.prototype.splice = function(index, count) {
|
||||
if (arguments.length < 2) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Fix the arguments based on the behavior of the real spice function.
|
||||
if (index >= this._length) {
|
||||
index = this._length - 1;
|
||||
} else if (index < 0) {
|
||||
index = this._length + index;
|
||||
}
|
||||
if (count < 0) {
|
||||
count = 0;
|
||||
}
|
||||
|
||||
var addedItems = Array.prototype.slice.call(arguments, 2);
|
||||
var removedItems = this._array.splice.apply(this._array, arguments);
|
||||
this._length = this._array.length;
|
||||
|
||||
if (removedItems.length) {
|
||||
this._emitEvent('remove', {
|
||||
index: index,
|
||||
count: count,
|
||||
items: removedItems
|
||||
});
|
||||
}
|
||||
|
||||
if (addedItems.length) {
|
||||
this._emitEvent('insert', {
|
||||
index: index,
|
||||
count: addedItems.length,
|
||||
items: addedItems
|
||||
});
|
||||
}
|
||||
|
||||
return removedItems;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set a value to the field of a specfied index.
|
||||
*
|
||||
* @access public
|
||||
* @param {Number} index
|
||||
* @param {Object} value
|
||||
*/
|
||||
ObservableArray.prototype.set = function(index, value) {
|
||||
if (index < 0 || index >= this._array.length) {
|
||||
this.throw('set: out of range');
|
||||
}
|
||||
|
||||
var oldValue = this._array[index];
|
||||
this._array[index] = value;
|
||||
this._emitEvent('replace', {
|
||||
index: index,
|
||||
oldValue: oldValue,
|
||||
newValue: value
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the value from the field of a specfied index.
|
||||
*
|
||||
* @access public
|
||||
* @param {Number} index
|
||||
* @returns {Object}
|
||||
*/
|
||||
ObservableArray.prototype.get = function(index) {
|
||||
return this._array[index];
|
||||
};
|
||||
|
||||
/**
|
||||
* Replace the entire array with another one.
|
||||
*
|
||||
* @access public
|
||||
* @param {Array} array
|
||||
*/
|
||||
ObservableArray.prototype.reset = function(array) {
|
||||
this._array = array || [];
|
||||
this._length = this._array.length;
|
||||
this._emitEvent('reset', {
|
||||
items: this._array
|
||||
});
|
||||
};
|
||||
|
||||
return ObservableArray;
|
||||
});
|
||||
Loading…
Reference in a new issue