Add ol.MVCArray
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
goog.provide('ol');
|
goog.provide('ol');
|
||||||
|
|
||||||
goog.require('ol.MVCObject');
|
goog.require('ol.MVCObject');
|
||||||
|
goog.require('ol.MVCArray');
|
||||||
|
|||||||
218
src/ol/mvcarray.js
Normal file
218
src/ol/mvcarray.js
Normal file
@@ -0,0 +1,218 @@
|
|||||||
|
|
||||||
|
/**
|
||||||
|
* @fileoverview An implementation of Google Maps' MVCArray.
|
||||||
|
* @see https://developers.google.com/maps/documentation/javascript/reference
|
||||||
|
*/
|
||||||
|
|
||||||
|
goog.provide('ol.MVCArray');
|
||||||
|
goog.provide('ol.MVCArrayEvent');
|
||||||
|
goog.provide('ol.MVCArrayEventType');
|
||||||
|
|
||||||
|
goog.require('goog.array');
|
||||||
|
goog.require('goog.asserts');
|
||||||
|
goog.require('goog.events.Event');
|
||||||
|
goog.require('ol.MVCObject');
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @enum {string}
|
||||||
|
*/
|
||||||
|
ol.MVCArrayEventType = {
|
||||||
|
INSERT_AT: 'insert_at',
|
||||||
|
REMOVE_AT: 'remove_at',
|
||||||
|
SET_AT: 'set_at'
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @extends {goog.events.Event}
|
||||||
|
* @param {ol.MVCArrayEventType} type Type.
|
||||||
|
* @param {number} index Index.
|
||||||
|
* @param {*=} opt_prev Value.
|
||||||
|
* @param {Object=} opt_target Target.
|
||||||
|
*/
|
||||||
|
ol.MVCArrayEvent = function(type, index, opt_prev, opt_target) {
|
||||||
|
|
||||||
|
goog.base(this, type, opt_target);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
this.index = index;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {*}
|
||||||
|
*/
|
||||||
|
this.prev = opt_prev;
|
||||||
|
|
||||||
|
};
|
||||||
|
goog.inherits(ol.MVCArrayEvent, goog.events.Event);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @extends {ol.MVCObject}
|
||||||
|
* @param {Array=} opt_array Array.
|
||||||
|
*/
|
||||||
|
ol.MVCArray = function(opt_array) {
|
||||||
|
|
||||||
|
goog.base(this);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {Array}
|
||||||
|
*/
|
||||||
|
this.array_ = goog.isDefAndNotNull(opt_array) ? opt_array : [];
|
||||||
|
|
||||||
|
this.updateLength_();
|
||||||
|
|
||||||
|
};
|
||||||
|
goog.inherits(ol.MVCArray, ol.MVCObject);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
ol.MVCArray.LENGTH = 'length';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {ol.MVCArray|Array} arg Argument.
|
||||||
|
* @return {ol.MVCArray} MVCArray.
|
||||||
|
*/
|
||||||
|
ol.MVCArray.create = function(arg) {
|
||||||
|
if (arg instanceof ol.MVCArray) {
|
||||||
|
return arg;
|
||||||
|
} else {
|
||||||
|
return new ol.MVCArray(arg);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
ol.MVCArray.prototype.clear = function() {
|
||||||
|
while (this[ol.MVCArray.LENGTH]) {
|
||||||
|
this.pop();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {function(*, number)} callback Callback.
|
||||||
|
*/
|
||||||
|
ol.MVCArray.prototype.forEach = function(callback) {
|
||||||
|
goog.array.forEach(this.array_, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {Array} Array.
|
||||||
|
*/
|
||||||
|
ol.MVCArray.prototype.getArray = function() {
|
||||||
|
return this.array_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} index Index.
|
||||||
|
* @return {*} Element.
|
||||||
|
*/
|
||||||
|
ol.MVCArray.prototype.getAt = function(index) {
|
||||||
|
return this.array_[index];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {number} Length.
|
||||||
|
*/
|
||||||
|
ol.MVCArray.prototype.getLength = function() {
|
||||||
|
return /** @type {number} */ (this.get(ol.MVCArray.LENGTH));
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} index Index.
|
||||||
|
* @param {*} elem Element.
|
||||||
|
*/
|
||||||
|
ol.MVCArray.prototype.insertAt = function(index, elem) {
|
||||||
|
goog.array.insertAt(this.array_, elem, index);
|
||||||
|
this.updateLength_();
|
||||||
|
this.dispatchEvent(new ol.MVCArrayEvent(
|
||||||
|
ol.MVCArrayEventType.INSERT_AT, index, undefined, this));
|
||||||
|
if (this[ol.MVCArrayEventType.INSERT_AT]) {
|
||||||
|
this[ol.MVCArrayEventType.INSERT_AT](index);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {*} Element.
|
||||||
|
*/
|
||||||
|
ol.MVCArray.prototype.pop = function() {
|
||||||
|
return this.removeAt(this.getLength() - 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {*} elem Element.
|
||||||
|
* @return {number} Length.
|
||||||
|
*/
|
||||||
|
ol.MVCArray.prototype.push = function(elem) {
|
||||||
|
var n = this.array_.length;
|
||||||
|
this.insertAt(n, elem);
|
||||||
|
return n;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} index Index.
|
||||||
|
* @return {*} Value.
|
||||||
|
*/
|
||||||
|
ol.MVCArray.prototype.removeAt = function(index) {
|
||||||
|
var prev = this.array_[index];
|
||||||
|
goog.array.removeAt(this.array_, index);
|
||||||
|
this.updateLength_();
|
||||||
|
this.dispatchEvent(new ol.MVCArrayEvent(ol.MVCArrayEventType.REMOVE_AT,
|
||||||
|
index, prev, this));
|
||||||
|
if (this[ol.MVCArrayEventType.REMOVE_AT]) {
|
||||||
|
this[ol.MVCArrayEventType.REMOVE_AT](index);
|
||||||
|
}
|
||||||
|
return prev;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} index Index.
|
||||||
|
* @param {*} elem Element.
|
||||||
|
*/
|
||||||
|
ol.MVCArray.prototype.setAt = function(index, elem) {
|
||||||
|
var n = this[ol.MVCArray.LENGTH];
|
||||||
|
if (index < n) {
|
||||||
|
var prev = this.array_[index];
|
||||||
|
this.array_[index] = elem;
|
||||||
|
this.dispatchEvent(new ol.MVCArrayEvent(ol.MVCArrayEventType.SET_AT,
|
||||||
|
index, prev, this));
|
||||||
|
if (this[ol.MVCArrayEventType.SET_AT]) {
|
||||||
|
this[ol.MVCArrayEventType.SET_AT](index, prev);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var j;
|
||||||
|
for (j = n; j < index; ++j) {
|
||||||
|
this.insertAt(j, undefined);
|
||||||
|
}
|
||||||
|
this.insertAt(index, elem);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ol.MVCArray.prototype.updateLength_ = function() {
|
||||||
|
this.set('length', this.array_.length);
|
||||||
|
};
|
||||||
162
src/ol/mvcarray_test.js
Normal file
162
src/ol/mvcarray_test.js
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
goog.require('goog.array');
|
||||||
|
goog.require('goog.testing.jsunit');
|
||||||
|
goog.require('ol.MVCArray');
|
||||||
|
goog.require('ol.MVCArrayEventType');
|
||||||
|
|
||||||
|
|
||||||
|
function testEmpty() {
|
||||||
|
var a = new ol.MVCArray();
|
||||||
|
assertEquals(0, a.getLength());
|
||||||
|
assertTrue(goog.array.equals(a.getArray(), []));
|
||||||
|
assertUndefined(a.getAt(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function testConstruct() {
|
||||||
|
var array = [0, 1, 2];
|
||||||
|
var a = new ol.MVCArray(array);
|
||||||
|
assertEquals(0, a.getAt(0));
|
||||||
|
assertEquals(1, a.getAt(1));
|
||||||
|
assertEquals(2, a.getAt(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function testPush() {
|
||||||
|
var a = new ol.MVCArray();
|
||||||
|
a.push(1);
|
||||||
|
assertEquals(1, a.getLength());
|
||||||
|
assertTrue(goog.array.equals(a.getArray(), [1]));
|
||||||
|
assertEquals(1, a.getAt(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function testPushPop() {
|
||||||
|
var a = new ol.MVCArray();
|
||||||
|
a.push(1);
|
||||||
|
a.pop();
|
||||||
|
assertEquals(0, a.getLength());
|
||||||
|
assertTrue(goog.array.equals(a.getArray(), []));
|
||||||
|
assertUndefined(a.getAt(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function testInsertAt() {
|
||||||
|
var a = new ol.MVCArray([0, 2]);
|
||||||
|
a.insertAt(1, 1);
|
||||||
|
assertEquals(0, a.getAt(0));
|
||||||
|
assertEquals(1, a.getAt(1));
|
||||||
|
assertEquals(2, a.getAt(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function testSetAt() {
|
||||||
|
var a = new ol.MVCArray();
|
||||||
|
a.setAt(1, 1);
|
||||||
|
assertEquals(2, a.getLength());
|
||||||
|
assertUndefined(a.getAt(0));
|
||||||
|
assertEquals(1, a.getAt(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function testRemoveAt() {
|
||||||
|
var a = new ol.MVCArray([0, 1, 2]);
|
||||||
|
a.removeAt(1);
|
||||||
|
assertEquals(0, a.getAt(0));
|
||||||
|
assertEquals(2, a.getAt(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function testForEachEmpty() {
|
||||||
|
var a = new ol.MVCArray();
|
||||||
|
var forEachCalled = false;
|
||||||
|
a.forEach(function() {
|
||||||
|
forEachCalled = true;
|
||||||
|
});
|
||||||
|
assertFalse(forEachCalled);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function testForEachPopulated() {
|
||||||
|
var a = new ol.MVCArray();
|
||||||
|
a.push(1);
|
||||||
|
a.push(2);
|
||||||
|
var forEachCount = 0;
|
||||||
|
a.forEach(function() {
|
||||||
|
++forEachCount;
|
||||||
|
});
|
||||||
|
assertEquals(2, forEachCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function testSetAtEvent() {
|
||||||
|
var a = new ol.MVCArray(['a', 'b']);
|
||||||
|
var index, prev;
|
||||||
|
goog.events.listen(a, ol.MVCArrayEventType.SET_AT, function(e) {
|
||||||
|
index = e.index;
|
||||||
|
prev = e.prev;
|
||||||
|
});
|
||||||
|
a.setAt(1, 1);
|
||||||
|
assertEquals(1, index);
|
||||||
|
assertEquals('b', prev);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function testRemoveAtEvent() {
|
||||||
|
var a = new ol.MVCArray(['a']);
|
||||||
|
var index, prev;
|
||||||
|
goog.events.listen(a, ol.MVCArrayEventType.REMOVE_AT, function(e) {
|
||||||
|
index = e.index;
|
||||||
|
prev = e.prev;
|
||||||
|
});
|
||||||
|
a.pop();
|
||||||
|
assertEquals(0, index);
|
||||||
|
assertEquals('a', prev);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function testInsertAtEvent() {
|
||||||
|
var a = new ol.MVCArray([0, 2]);
|
||||||
|
var index;
|
||||||
|
goog.events.listen(a, ol.MVCArrayEventType.INSERT_AT, function(e) {
|
||||||
|
index = e.index;
|
||||||
|
});
|
||||||
|
a.insertAt(1, 1);
|
||||||
|
assertEquals(1, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function testSetAtBeyondEnd() {
|
||||||
|
var a = new ol.MVCArray();
|
||||||
|
var inserts = [];
|
||||||
|
a.insert_at = function(index) {
|
||||||
|
inserts.push(index);
|
||||||
|
};
|
||||||
|
a.setAt(2, 0);
|
||||||
|
assertEquals(3, a.getLength());
|
||||||
|
assertUndefined(a.getAt(0));
|
||||||
|
assertUndefined(a.getAt(1));
|
||||||
|
assertEquals(0, a.getAt(2));
|
||||||
|
assertEquals(3, inserts.length);
|
||||||
|
assertEquals(0, inserts[0]);
|
||||||
|
assertEquals(1, inserts[1]);
|
||||||
|
assertEquals(2, inserts[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function testCreateFromArray() {
|
||||||
|
var a = [0, 1, 2];
|
||||||
|
var mvcArray = ol.MVCArray.create(a);
|
||||||
|
assertTrue(mvcArray instanceof ol.MVCArray);
|
||||||
|
assertEquals(3, mvcArray.getLength());
|
||||||
|
assertEquals(0, mvcArray.getAt(0));
|
||||||
|
assertEquals(1, mvcArray.getAt(1));
|
||||||
|
assertEquals(2, mvcArray.getAt(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function testCreateFromMVCArray() {
|
||||||
|
var mvcArray1 = new ol.MVCArray();
|
||||||
|
var mvcArray2 = ol.MVCArray.create(mvcArray1);
|
||||||
|
assertTrue(mvcArray1 === mvcArray2);
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user