(function() {
/**
* @typedef {Help4.control2.container.Container.Params} Help4.control2.container.SortedContainer.Params
* @property {string[]} [itemOrder = []] - default type of the hosted controls
*/
/**
* Will provide a sorted container with a predefined well-known item order
* @augments Help4.control2.container.Container
* @property {string[]} itemOrder - order of the container items
*/
Help4.control2.container.SortedContainer = class extends Help4.control2.container.Container {
/**
* @override
* @param {Help4.control2.container.SortedContainer.Params} [params]
* @param {Help4.jscore.ControlBase.Params} [derived]
*/
constructor(params, derived) {
const {TYPES: T} = Help4.jscore.ControlBase;
super(params, {
params: {
// this defines the fixed order of all to-be-added items
// each item is identified by item.getOrder()
itemOrder: {type: T.array}
},
derived
});
}
/**
* adds controls in a sorted order
* @param {Help4.control2.Control.Params} params - parameters for the to-be-created controls
* @returns {?Help4.control2.Control|Array<?Help4.control2.Control>} the added control(s)
*/
addSorted(...params) {
const toAdd = params.length;
const added = new Array(toAdd);
for (const [index, item] of Help4.arrayEntries(params)) {
added[index] = _addSorted.call(this, item);
}
return toAdd === 1 ? added[0] : added;
}
}
/**
* @memberof Help4.control2.container.SortedContainer#
* @private
* @param {Help4.control2.Control.Params} params
* @returns {?Help4.control2.Control|Array<?Help4.control2.Control>}
*/
function _addSorted(params) {
const {itemOrder, _store} = this;
const {_order: id} = params;
const targetIndex = itemOrder.indexOf(id);
if (targetIndex < 0) throw new Error(`SortedContainer: unable to add an unknown item "${id}"`);
if (targetIndex === 0) {
// simple, insert at front
return this.insertAt(params, 0);
} else if (targetIndex === itemOrder.length - 1) {
// simple, insert at end
return this.insertAt(params, targetIndex);
}
// predecessors and successors exist
// attention: not all of them are already inserted
const predecessors = itemOrder.slice(0, targetIndex);
const successors = itemOrder.slice(targetIndex + 1);
// this is the list of already inserted items
const currentOrder = _store.map(control => control.getOrder());
let position = 0;
for (const [index, itemId] of Help4.arrayEntries(currentOrder)) {
if (predecessors.indexOf(itemId) >= 0) {
// insert position needs to be behind all predecessors
position = index + 1;
continue;
}
if (successors.indexOf(itemId) >= 0) {
// the first available successor was found; insert before
return this.insertAt(params, index);
}
}
// no successor was found; insert behind last predecessor
this.insertAt(params, position);
}
})();