Radarr/UI/Mixins/underscore.mixin.deepExtend.js

123 lines
4.3 KiB
JavaScript

/**
* Underscore mixins for deep objects
*
* Based on https://gist.github.com/echong/3861963
*/
define(
[
'underscore'
], function (_) {
var arrays, basicObjects, deepClone, deepExtend, deepExtendCouple, isBasicObject, __slice =
[
].slice;
deepClone = function (obj) {
var func, isArr;
if (!_.isObject(obj) || _.isFunction(obj)) {
return obj;
}
if (obj instanceof Backbone.Collection || obj instanceof Backbone.Model) {
return obj;
}
if (_.isDate(obj)) {
return new Date(obj.getTime());
}
if (_.isRegExp(obj)) {
return new RegExp(obj.source, obj.toString().replace(/.*\//, ''));
}
isArr = _.isArray(obj || _.isArguments(obj));
func = function (memo, value, key) {
if (isArr) {
memo.push(deepClone(value));
}
else {
memo[key] = deepClone(value);
}
return memo;
};
return _.reduce(obj, func, isArr ?
[
] :{});
};
isBasicObject = function (object) {
if (object == null) {
return false;
}
return (object.prototype === {}.prototype || object.prototype === Object.prototype) && _.isObject(object) && !_.isArray(object) && !_.isFunction(object) && !_.isDate(object) && !_.isRegExp(object) && !_.isArguments(object);
};
basicObjects = function (object) {
return _.filter(_.keys(object), function (key) {
return isBasicObject(object[key]);
});
};
arrays = function (object) {
return _.filter(_.keys(object), function (key) {
return _.isArray(object[key]);
});
};
deepExtendCouple = function (destination, source, maxDepth) {
var combine, recurse, sharedArrayKey, sharedArrayKeys, sharedObjectKey, sharedObjectKeys, _i, _j, _len, _len1;
if (maxDepth == null) {
maxDepth = 20;
}
if (maxDepth <= 0) {
console.warn('_.deepExtend(): Maximum depth of recursion hit.');
return _.extend(destination, source);
}
sharedObjectKeys = _.intersection(basicObjects(destination), basicObjects(source));
recurse = function (key) {
return source[key] = deepExtendCouple(destination[key], source[key], maxDepth - 1);
};
for (_i = 0, _len = sharedObjectKeys.length; _i < _len; _i++) {
sharedObjectKey = sharedObjectKeys[_i];
recurse(sharedObjectKey);
}
sharedArrayKeys = _.intersection(arrays(destination), arrays(source));
combine = function (key) {
return source[key] = _.union(destination[key], source[key]);
};
for (_j = 0, _len1 = sharedArrayKeys.length; _j < _len1; _j++) {
sharedArrayKey = sharedArrayKeys[_j];
combine(sharedArrayKey);
}
return _.extend(destination, source);
};
deepExtend = function () {
var finalObj, maxDepth, objects, _i;
objects = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) :(_i = 0,
[
]), maxDepth = arguments[_i++];
if (!_.isNumber(maxDepth)) {
objects.push(maxDepth);
maxDepth = 20;
}
if (objects.length <= 1) {
return objects[0];
}
if (maxDepth <= 0) {
return _.extend.apply(this, objects);
}
finalObj = objects.shift();
while (objects.length > 0) {
finalObj = deepExtendCouple(finalObj, deepClone(objects.shift()), maxDepth);
}
return finalObj;
};
_.mixin({
deepClone : deepClone,
isBasicObject: isBasicObject,
basicObjects : basicObjects,
arrays : arrays,
deepExtend : deepExtend
});
});