162 lines
4.6 KiB
JavaScript
Executable File
162 lines
4.6 KiB
JavaScript
Executable File
/**
|
|
* Copyright © Magento, Inc. All rights reserved.
|
|
* See COPYING.txt for license details.
|
|
*/
|
|
|
|
define([
|
|
'underscore',
|
|
'./strings'
|
|
], function (_, utils) {
|
|
'use strict';
|
|
|
|
/**
|
|
* Defines index of an item in a specified container.
|
|
*
|
|
* @param {*} item - Item whose index should be defined.
|
|
* @param {Array} container - Container upon which to perform search.
|
|
* @returns {Number}
|
|
*/
|
|
function getIndex(item, container) {
|
|
var index = container.indexOf(item);
|
|
|
|
if (~index) {
|
|
return index;
|
|
}
|
|
|
|
return _.findIndex(container, function (value) {
|
|
return value && value.name === item;
|
|
});
|
|
}
|
|
|
|
return {
|
|
/**
|
|
* Facade method to remove/add value from/to array
|
|
* without creating a new instance.
|
|
*
|
|
* @param {Array} arr - Array to be modified.
|
|
* @param {*} value - Value to add/remove.
|
|
* @param {Boolean} add - Flag that specfies operation.
|
|
* @returns {Utils} Chainable.
|
|
*/
|
|
toggle: function (arr, value, add) {
|
|
return add ?
|
|
this.add(arr, value) :
|
|
this.remove(arr, value);
|
|
},
|
|
|
|
/**
|
|
* Removes the incoming value from array in case
|
|
* without creating a new instance of it.
|
|
*
|
|
* @param {Array} arr - Array to be modified.
|
|
* @param {*} value - Value to be removed.
|
|
* @returns {Utils} Chainable.
|
|
*/
|
|
remove: function (arr, value) {
|
|
var index = arr.indexOf(value);
|
|
|
|
if (~index) {
|
|
arr.splice(index, 1);
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Adds the incoming value to array if
|
|
* it's not alredy present in there.
|
|
*
|
|
* @param {Array} arr - Array to be modifed.
|
|
* @param {...*} arguments - Values to be added.
|
|
* @returns {Utils} Chainable.
|
|
*/
|
|
add: function (arr) {
|
|
var values = _.toArray(arguments).slice(1);
|
|
|
|
values.forEach(function (value) {
|
|
if (!~arr.indexOf(value)) {
|
|
arr.push(value);
|
|
}
|
|
});
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Inserts specified item into container at a specified position.
|
|
*
|
|
* @param {*} item - Item to be inserted into container.
|
|
* @param {Array} container - Container of items.
|
|
* @param {*} [position=-1] - Position at which item should be inserted.
|
|
* Position can represent:
|
|
* - specific index in container
|
|
* - item which might already be present in container
|
|
* - structure with one of these properties: after, before
|
|
* @returns {Boolean|*}
|
|
* - true if element has changed its' position
|
|
* - false if nothing has changed
|
|
* - inserted value if it wasn't present in container
|
|
*/
|
|
insert: function (item, container, position) {
|
|
var currentIndex = getIndex(item, container),
|
|
newIndex,
|
|
target;
|
|
|
|
if (typeof position === 'undefined') {
|
|
position = -1;
|
|
} else if (typeof position === 'string') {
|
|
position = isNaN(+position) ? position : +position;
|
|
}
|
|
|
|
newIndex = position;
|
|
|
|
if (~currentIndex) {
|
|
target = container.splice(currentIndex, 1)[0];
|
|
|
|
if (typeof item === 'string') {
|
|
item = target;
|
|
}
|
|
}
|
|
|
|
if (typeof position !== 'number') {
|
|
target = position.after || position.before || position;
|
|
|
|
newIndex = getIndex(target, container);
|
|
|
|
if (~newIndex && (position.after || newIndex >= currentIndex)) {
|
|
newIndex++;
|
|
}
|
|
}
|
|
|
|
if (newIndex < 0) {
|
|
newIndex += container.length + 1;
|
|
}
|
|
|
|
container[newIndex] ?
|
|
container.splice(newIndex, 0, item) :
|
|
container[newIndex] = item;
|
|
|
|
return !~currentIndex ? item : currentIndex !== newIndex;
|
|
},
|
|
|
|
/**
|
|
* @param {Array} elems
|
|
* @param {Number} offset
|
|
* @return {Number|*}
|
|
*/
|
|
formatOffset: function (elems, offset) {
|
|
if (utils.isEmpty(offset)) {
|
|
offset = -1;
|
|
}
|
|
|
|
offset = +offset;
|
|
|
|
if (offset < 0) {
|
|
offset += elems.length + 1;
|
|
}
|
|
|
|
return offset;
|
|
}
|
|
};
|
|
});
|