123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- define([
- 'underscore',
- 'mage/utils/objects'
- ], function (_, utils) {
- 'use strict';
- var result = [];
- /**
- * Checks if all of the provided arrays contains equal values.
- *
- * @param {(Boolean|Array)} [keepOrder=false]
- * @param {Array} target
- * @returns {Boolean}
- */
- function equalArrays(keepOrder, target) {
- var args = _.toArray(arguments),
- arrays;
- if (!Array.isArray(keepOrder)) {
- arrays = args.slice(2);
- } else {
- target = keepOrder;
- keepOrder = false;
- arrays = args.slice(1);
- }
- if (!arrays.length) {
- return true;
- }
- return arrays.every(function (array) {
- if (array === target) {
- return true;
- } else if (array.length !== target.length) {
- return false;
- } else if (!keepOrder) {
- return !_.difference(target, array).length;
- }
- return array.every(function (value, index) {
- return target.indexOf(value) === index;
- });
- });
- }
- /**
- * Checks if two values are different.
- *
- * @param {*} a - First value.
- * @param {*} b - Second value.
- * @returns {Boolean}
- */
- function isDifferent(a, b) {
- var oldIsPrimitive = utils.isPrimitive(a);
- if (Array.isArray(a) && Array.isArray(b)) {
- return !equalArrays(true, a, b);
- }
- return oldIsPrimitive ? a !== b : true;
- }
- /**
- * @param {String} prefix
- * @param {String} part
- */
- function getPath(prefix, part) {
- return prefix ? prefix + '.' + part : part;
- }
- /**
- * Checks if object has own specified property.
- *
- * @param {*} obj - Value to be checked.
- * @param {String} key - Key of the property.
- * @returns {Boolean}
- */
- function hasOwn(obj, key) {
- return Object.prototype.hasOwnProperty.call(obj, key);
- }
- /**
- * @param {Array} changes
- */
- function getContainers(changes) {
- var containers = {},
- indexed = _.indexBy(changes, 'path');
- _.each(indexed, function (change, name) {
- var path;
- name.split('.').forEach(function (part) {
- path = getPath(path, part);
- if (path in indexed) {
- return;
- }
- (containers[path] = containers[path] || []).push(change);
- });
- });
- return containers;
- }
- /**
- * @param {String} path
- * @param {String} name
- * @param {String} type
- * @param {String} newValue
- * @param {String} oldValue
- */
- function addChange(path, name, type, newValue, oldValue) {
- var data;
- data = {
- path: path,
- name: name,
- type: type
- };
- if (type !== 'remove') {
- data.value = newValue;
- data.oldValue = oldValue;
- } else {
- data.oldValue = newValue;
- }
- result.push(data);
- }
- /**
- * @param {String} ns
- * @param {String} name
- * @param {String} type
- * @param {String} iterator
- * @param {String} placeholder
- */
- function setAll(ns, name, type, iterator, placeholder) {
- var key;
- if (arguments.length > 4) {
- type === 'add' ?
- addChange(ns, name, 'update', iterator, placeholder) :
- addChange(ns, name, 'update', placeholder, iterator);
- } else {
- addChange(ns, name, type, iterator);
- }
- if (!utils.isObject(iterator)) {
- return;
- }
- for (key in iterator) {
- if (hasOwn(iterator, key)) {
- setAll(getPath(ns, key), key, type, iterator[key]);
- }
- }
- }
- /*eslint-disable max-depth*/
- /**
- * @param {Object} old
- * @param {Object} current
- * @param {String} ns
- * @param {String} name
- */
- function compare(old, current, ns, name) {
- var key,
- oldIsObj = utils.isObject(old),
- newIsObj = utils.isObject(current);
- if (oldIsObj && newIsObj) {
- for (key in old) {
- if (hasOwn(old, key) && !hasOwn(current, key)) {
- setAll(getPath(ns, key), key, 'remove', old[key]);
- }
- }
- for (key in current) {
- if (hasOwn(current, key)) {
- hasOwn(old, key) ?
- compare(old[key], current[key], getPath(ns, key), key) :
- setAll(getPath(ns, key), key, 'add', current[key]);
- }
- }
- } else if (oldIsObj) {
- setAll(ns, name, 'remove', old, current);
- } else if (newIsObj) {
- setAll(ns, name, 'add', current, old);
- } else if (isDifferent(old, current)) {
- addChange(ns, name, 'update', current, old);
- }
- }
- /*eslint-enable max-depth*/
- return {
- /**
- *
- * @returns {Object}
- */
- compare: function () {
- var changes;
- compare.apply(null, arguments);
- changes = result.splice(0);
- return {
- containers: getContainers(changes),
- changes: changes,
- equal: !changes.length
- };
- },
- equalArrays: equalArrays
- };
- });
|