jstd-web/node_modules/object-refs/lib/collection.js

120 lines
2.7 KiB
JavaScript
Raw Normal View History

2025-11-25 15:23:22 +08:00
'use strict';
/**
* An empty collection stub. Use {@link RefsCollection.extend} to extend a
* collection with ref semantics.
*
* @class RefsCollection
*/
/**
* Extends a collection with {@link Refs} aware methods
*
* @memberof RefsCollection
* @static
*
* @param {Array<Object>} collection
* @param {Refs} refs instance
* @param {Object} property represented by the collection
* @param {Object} target object the collection is attached to
*
* @return {RefsCollection<Object>} the extended array
*/
function extend(collection, refs, property, target) {
var inverseProperty = property.inverse;
/**
* Removes the given element from the array and returns it.
*
* @method RefsCollection#remove
*
* @param {Object} element the element to remove
*/
Object.defineProperty(collection, 'remove', {
value: function(element) {
var idx = this.indexOf(element);
if (idx !== -1) {
this.splice(idx, 1);
// unset inverse
refs.unset(element, inverseProperty, target);
}
return element;
}
});
/**
* Returns true if the collection contains the given element
*
* @method RefsCollection#contains
*
* @param {Object} element the element to check for
*/
Object.defineProperty(collection, 'contains', {
value: function(element) {
return this.indexOf(element) !== -1;
}
});
/**
* Adds an element to the array, unless it exists already (set semantics).
*
* @method RefsCollection#add
*
* @param {Object} element the element to add
* @param {Number} optional index to add element to
* (possibly moving other elements around)
*/
Object.defineProperty(collection, 'add', {
value: function(element, idx) {
var currentIdx = this.indexOf(element);
if (typeof idx === 'undefined') {
if (currentIdx !== -1) {
// element already in collection (!)
return;
}
// add to end of array, as no idx is specified
idx = this.length;
}
// handle already in collection
if (currentIdx !== -1) {
// remove element from currentIdx
this.splice(currentIdx, 1);
}
// add element at idx
this.splice(idx, 0, element);
if (currentIdx === -1) {
// set inverse, unless element was
// in collection already
refs.set(element, inverseProperty, target);
}
}
});
// a simple marker, identifying this element
// as being a refs collection
Object.defineProperty(collection, '__refs_collection', {
value: true
});
return collection;
}
function isExtended(collection) {
return collection.__refs_collection === true;
}
module.exports.extend = extend;
module.exports.isExtended = isExtended;