Support for unique collections
This commit is contained in:
@@ -8,6 +8,21 @@ var olx;
|
||||
/* typedefs for object literals provided by applications */
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{unique: (boolean|undefined)}}
|
||||
*/
|
||||
olx.CollectionOptions;
|
||||
|
||||
|
||||
/**
|
||||
* Disallow the same item from being added to the collection twice. Default is
|
||||
* false.
|
||||
* @type {boolean|undefined}
|
||||
* @api
|
||||
*/
|
||||
olx.CollectionOptions.prototype.unique;
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{html: string,
|
||||
* tileRanges: (Object.<string, Array.<ol.TileRange>>|undefined)}}
|
||||
|
||||
@@ -23,19 +23,34 @@ goog.require('ol.events.Event');
|
||||
* @extends {ol.Object}
|
||||
* @fires ol.Collection.Event
|
||||
* @param {!Array.<T>=} opt_array Array.
|
||||
* @param {olx.CollectionOptions=} opt_options Collection options.
|
||||
* @template T
|
||||
* @api
|
||||
*/
|
||||
ol.Collection = function(opt_array) {
|
||||
ol.Collection = function(opt_array, opt_options) {
|
||||
|
||||
ol.Object.call(this);
|
||||
|
||||
var options = opt_options || {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.unique_ = !!options.unique;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {!Array.<T>}
|
||||
*/
|
||||
this.array_ = opt_array ? opt_array : [];
|
||||
|
||||
if (this.unique_) {
|
||||
for (var i = 0, ii = this.array_.length; i < ii; ++i) {
|
||||
this.assertUnique_(this.array_[i], i);
|
||||
}
|
||||
}
|
||||
|
||||
this.updateLength_();
|
||||
|
||||
};
|
||||
@@ -125,6 +140,9 @@ ol.Collection.prototype.getLength = function() {
|
||||
* @api
|
||||
*/
|
||||
ol.Collection.prototype.insertAt = function(index, elem) {
|
||||
if (this.unique_) {
|
||||
this.assertUnique_(elem);
|
||||
}
|
||||
this.array_.splice(index, 0, elem);
|
||||
this.updateLength_();
|
||||
this.dispatchEvent(
|
||||
@@ -150,6 +168,9 @@ ol.Collection.prototype.pop = function() {
|
||||
* @api
|
||||
*/
|
||||
ol.Collection.prototype.push = function(elem) {
|
||||
if (this.unique_) {
|
||||
this.assertUnique_(elem);
|
||||
}
|
||||
var n = this.getLength();
|
||||
this.insertAt(n, elem);
|
||||
return this.getLength();
|
||||
@@ -200,6 +221,9 @@ ol.Collection.prototype.removeAt = function(index) {
|
||||
ol.Collection.prototype.setAt = function(index, elem) {
|
||||
var n = this.getLength();
|
||||
if (index < n) {
|
||||
if (this.unique_) {
|
||||
this.assertUnique_(elem, index);
|
||||
}
|
||||
var prev = this.array_[index];
|
||||
this.array_[index] = elem;
|
||||
this.dispatchEvent(
|
||||
@@ -224,6 +248,20 @@ ol.Collection.prototype.updateLength_ = function() {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {T} elem Element.
|
||||
* @param {number=} opt_except Optional index to ignore.
|
||||
*/
|
||||
ol.Collection.prototype.assertUnique_ = function(elem, opt_except) {
|
||||
for (var i = 0, ii = this.array_.length; i < ii; ++i) {
|
||||
if (this.array_[i] === elem && i !== opt_except) {
|
||||
throw new Error('Duplicate item added to a unique collection');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
* @private
|
||||
|
||||
@@ -298,4 +298,67 @@ describe('ol.collection', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('unique collection', function() {
|
||||
it('allows unique items in the constructor', function() {
|
||||
new ol.Collection([{}, {}, {}], {unique: true});
|
||||
});
|
||||
|
||||
it('throws if duplicate items are passed to the contructor', function() {
|
||||
var item = {};
|
||||
var call = function() {
|
||||
new ol.Collection([item, item], {unique: true});
|
||||
};
|
||||
expect(call).to.throwException();
|
||||
});
|
||||
|
||||
it('allows unique items to be added via push', function() {
|
||||
var unique = new ol.Collection(undefined, {unique: true});
|
||||
unique.push({});
|
||||
unique.push({});
|
||||
});
|
||||
|
||||
it('throws if duplicate items are added via push', function() {
|
||||
var unique = new ol.Collection(undefined, {unique: true});
|
||||
var item = {};
|
||||
unique.push(item);
|
||||
var call = function() {
|
||||
unique.push(item);
|
||||
};
|
||||
expect(call).to.throwException();
|
||||
});
|
||||
|
||||
it('allows unique items to be added via insertAt', function() {
|
||||
var unique = new ol.Collection(undefined, {unique: true});
|
||||
unique.insertAt(0, {});
|
||||
unique.insertAt(0, {});
|
||||
});
|
||||
|
||||
it('throws if duplicate items are added via insertAt', function() {
|
||||
var unique = new ol.Collection(undefined, {unique: true});
|
||||
var item = {};
|
||||
unique.insertAt(0, item);
|
||||
var call = function() {
|
||||
unique.insertAt(0, item);
|
||||
};
|
||||
expect(call).to.throwException();
|
||||
});
|
||||
|
||||
it('allows unique items to be added via setAt', function() {
|
||||
var unique = new ol.Collection(undefined, {unique: true});
|
||||
unique.setAt(0, {});
|
||||
unique.setAt(1, {});
|
||||
});
|
||||
|
||||
it('throws if duplicate items are added via setAt', function() {
|
||||
var unique = new ol.Collection(undefined, {unique: true});
|
||||
var item = {};
|
||||
unique.setAt(0, item);
|
||||
var call = function() {
|
||||
unique.setAt(1, item);
|
||||
};
|
||||
expect(call).to.throwException();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user