var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); /** * @module ol/Collection */ import AssertionError from './AssertionError.js'; import BaseObject from './Object.js'; import CollectionEventType from './CollectionEventType.js'; import Event from './events/Event.js'; /** * @enum {string} * @private */ var Property = { LENGTH: 'length', }; /** * @classdesc * Events emitted by {@link module:ol/Collection~Collection} instances are instances of this * type. */ var CollectionEvent = /** @class */ (function (_super) { __extends(CollectionEvent, _super); /** * @param {import("./CollectionEventType.js").default} type Type. * @param {*} [opt_element] Element. * @param {number} [opt_index] The index of the added or removed element. */ function CollectionEvent(type, opt_element, opt_index) { var _this = _super.call(this, type) || this; /** * The element that is added to or removed from the collection. * @type {*} * @api */ _this.element = opt_element; /** * The index of the added or removed element. * @type {number} * @api */ _this.index = opt_index; return _this; } return CollectionEvent; }(Event)); export { CollectionEvent }; /*** * @template Return * @typedef {import("./Observable").OnSignature & * import("./Observable").OnSignature & * import("./Observable").OnSignature<'add'|'remove', CollectionEvent, Return> & * import("./Observable").CombinedOnSignature} CollectionOnSignature */ /** * @typedef {Object} Options * @property {boolean} [unique=false] Disallow the same item from being added to * the collection twice. */ /** * @classdesc * An expanded version of standard JS Array, adding convenience methods for * manipulation. Add and remove changes to the Collection trigger a Collection * event. Note that this does not cover changes to the objects _within_ the * Collection; they trigger events on the appropriate object, not on the * Collection as a whole. * * @fires CollectionEvent * * @template T * @api */ var Collection = /** @class */ (function (_super) { __extends(Collection, _super); /** * @param {Array} [opt_array] Array. * @param {Options} [opt_options] Collection options. */ function Collection(opt_array, opt_options) { var _this = _super.call(this) || this; /*** * @type {CollectionOnSignature} */ _this.on; /*** * @type {CollectionOnSignature} */ _this.once; /*** * @type {CollectionOnSignature} */ _this.un; var options = opt_options || {}; /** * @private * @type {boolean} */ _this.unique_ = !!options.unique; /** * @private * @type {!Array} */ _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_(); return _this; } /** * Remove all elements from the collection. * @api */ Collection.prototype.clear = function () { while (this.getLength() > 0) { this.pop(); } }; /** * Add elements to the collection. This pushes each item in the provided array * to the end of the collection. * @param {!Array} arr Array. * @return {Collection} This collection. * @api */ Collection.prototype.extend = function (arr) { for (var i = 0, ii = arr.length; i < ii; ++i) { this.push(arr[i]); } return this; }; /** * Iterate over each element, calling the provided callback. * @param {function(T, number, Array): *} f The function to call * for every element. This function takes 3 arguments (the element, the * index and the array). The return value is ignored. * @api */ Collection.prototype.forEach = function (f) { var array = this.array_; for (var i = 0, ii = array.length; i < ii; ++i) { f(array[i], i, array); } }; /** * Get a reference to the underlying Array object. Warning: if the array * is mutated, no events will be dispatched by the collection, and the * collection's "length" property won't be in sync with the actual length * of the array. * @return {!Array} Array. * @api */ Collection.prototype.getArray = function () { return this.array_; }; /** * Get the element at the provided index. * @param {number} index Index. * @return {T} Element. * @api */ Collection.prototype.item = function (index) { return this.array_[index]; }; /** * Get the length of this collection. * @return {number} The length of the array. * @observable * @api */ Collection.prototype.getLength = function () { return this.get(Property.LENGTH); }; /** * Insert an element at the provided index. * @param {number} index Index. * @param {T} elem Element. * @api */ Collection.prototype.insertAt = function (index, elem) { if (this.unique_) { this.assertUnique_(elem); } this.array_.splice(index, 0, elem); this.updateLength_(); this.dispatchEvent(new CollectionEvent(CollectionEventType.ADD, elem, index)); }; /** * Remove the last element of the collection and return it. * Return `undefined` if the collection is empty. * @return {T|undefined} Element. * @api */ Collection.prototype.pop = function () { return this.removeAt(this.getLength() - 1); }; /** * Insert the provided element at the end of the collection. * @param {T} elem Element. * @return {number} New length of the collection. * @api */ Collection.prototype.push = function (elem) { if (this.unique_) { this.assertUnique_(elem); } var n = this.getLength(); this.insertAt(n, elem); return this.getLength(); }; /** * Remove the first occurrence of an element from the collection. * @param {T} elem Element. * @return {T|undefined} The removed element or undefined if none found. * @api */ Collection.prototype.remove = function (elem) { var arr = this.array_; for (var i = 0, ii = arr.length; i < ii; ++i) { if (arr[i] === elem) { return this.removeAt(i); } } return undefined; }; /** * Remove the element at the provided index and return it. * Return `undefined` if the collection does not contain this index. * @param {number} index Index. * @return {T|undefined} Value. * @api */ Collection.prototype.removeAt = function (index) { var prev = this.array_[index]; this.array_.splice(index, 1); this.updateLength_(); this.dispatchEvent(new CollectionEvent(CollectionEventType.REMOVE, prev, index)); return prev; }; /** * Set the element at the provided index. * @param {number} index Index. * @param {T} elem Element. * @api */ 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(new CollectionEvent(CollectionEventType.REMOVE, prev, index)); this.dispatchEvent(new CollectionEvent(CollectionEventType.ADD, elem, index)); } else { for (var j = n; j < index; ++j) { this.insertAt(j, undefined); } this.insertAt(index, elem); } }; /** * @private */ Collection.prototype.updateLength_ = function () { this.set(Property.LENGTH, this.array_.length); }; /** * @private * @param {T} elem Element. * @param {number} [opt_except] Optional index to ignore. */ 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 AssertionError(58); } } }; return Collection; }(BaseObject)); export default Collection; //# sourceMappingURL=Collection.js.map