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;
 | 
						|
        }
 | 
						|
    };
 | 
						|
});
 |