underscore-deep-extend
Advanced tools
Comparing version
{ | ||
"name": "underscore-deep-extend", | ||
"version": "1.1.4", | ||
"version": "1.1.5", | ||
"main": "index.js", | ||
@@ -5,0 +5,0 @@ "repository": { |
{ | ||
"name": "underscore-deep-extend", | ||
"version": "1.1.4", | ||
"version": "1.1.5", | ||
"repo": "kurtmilam/underscoreDeepExtend", | ||
@@ -5,0 +5,0 @@ "description": "A deepExtend implementation for underscore, lodash and friends.", |
114
index.js
@@ -17,34 +17,91 @@ /* implementation: Copyright (C) 2012-2013 Kurt Milam - http://xioup.com | Source: https://gist.github.com/1868955 | ||
return function underscoreDeepExtend(obj) { | ||
var parentRE = /#{\s*?_\s*?}/; | ||
var parentRE = /#{\s*?_\s*?}/, | ||
source, | ||
isAssign = function (oProp, sProp) { | ||
return (_.isUndefined(oProp) || _.isNull(oProp) || _.isFunction(oProp) || _.isNull(sProp) || _.isDate(sProp)); | ||
}, | ||
procAssign = function (oProp, sProp, propName) { | ||
// Perform a straight assignment | ||
// Assign for object properties & return for array members | ||
return obj[propName] = _.clone(sProp); | ||
}, | ||
hasRegex = function (oProp, sProp) { | ||
return ( _.isString(sProp) && parentRE.test(sProp) ); | ||
}, | ||
procRegex = function (oProp, sProp, propName) { | ||
// Perform a string.replace using parentRE if oProp is a string | ||
if (!_.isString(oProp)) { | ||
// We're being optimistic at the moment | ||
// throw new Error('Trying to combine a string with a non-string (' + propName + ')'); | ||
} | ||
// Assign for object properties & return for array members | ||
return obj[propName] = sProp.replace(parentRE, oProp); | ||
}, | ||
hasArray = function (oProp, sProp) { | ||
return (_.isArray(oProp) || _.isArray(sProp)); | ||
}, | ||
procArray = function (oProp, sProp, propName) { | ||
// extend oProp if both properties are arrays | ||
if (!_.isArray(oProp) || !_.isArray(sProp)){ | ||
throw new Error('Trying to combine an array with a non-array (' + propName + ')'); | ||
} | ||
var tmp = _.deepExtend(obj[propName], sProp); | ||
// Assign for object properties & return for array members | ||
return obj[propName] = _.reject(tmp, _.isNull); | ||
}, | ||
hasObject = function (oProp, sProp) { | ||
return (_.isObject(oProp) || _.isObject(sProp)); | ||
}, | ||
procObject = function (oProp, sProp, propName) { | ||
// extend oProp if both properties are objects | ||
if (!_.isObject(oProp) || !_.isObject(sProp)){ | ||
throw new Error('Trying to combine an object with a non-object (' + propName + ')'); | ||
} | ||
// Assign for object properties & return for array members | ||
return obj[propName] = _.deepExtend(oProp, sProp); | ||
}, | ||
var extendProperty = function(source) { | ||
for (var prop in source) { | ||
if (_.isUndefined(obj[prop]) || _.isNull(obj[prop]) ||_.isFunction(obj[prop]) || _.isNull(source[prop]) || _.isDate(source[prop])) { | ||
obj[prop] = _.clone(source[prop]); | ||
} | ||
else if (_.isString(source[prop]) && parentRE.test(source[prop])) { | ||
if (_.isString(obj[prop])) { | ||
obj[prop] = source[prop].replace(parentRE, obj[prop]); | ||
procMain = function(propName) { | ||
var oProp = obj[propName], | ||
sProp = source[propName]; | ||
// The order of the 'if' statements is critical | ||
// Cases in which we want to perform a straight assignment | ||
if ( isAssign(oProp, sProp) ) { | ||
procAssign(oProp, sProp, propName); | ||
} | ||
} | ||
else if (_.isArray(obj[prop]) || _.isArray(source[prop])){ | ||
if (!_.isArray(obj[prop]) || !_.isArray(source[prop])){ | ||
throw new Error('Trying to combine an array with a non-array (' + prop + ')'); | ||
} else { | ||
obj[prop] = _.reject(_.deepExtend(_.clone(obj[prop]), source[prop]), _.isNull); | ||
// sProp is a string that contains parentRE | ||
else if ( hasRegex(oProp, sProp) ) { | ||
procRegex(oProp, sProp, propName); | ||
} | ||
} | ||
else if (_.isObject(obj[prop]) || _.isObject(source[prop])){ | ||
if (!_.isObject(obj[prop]) || !_.isObject(source[prop])){ | ||
throw new Error('Trying to combine an object with a non-object (' + prop + ')'); | ||
} else { | ||
obj[prop] = _.deepExtend(_.clone(obj[prop]), source[prop]); | ||
// At least one property is an array | ||
else if ( hasArray(oProp, sProp) ){ | ||
procArray(oProp, sProp, propName); | ||
} | ||
} else { | ||
obj[prop] = source[prop]; | ||
} | ||
} | ||
}; | ||
// At least one property is an object | ||
else if ( hasObject(oProp, sProp) ){ | ||
procObject(oProp, sProp, propName); | ||
} | ||
// Everything else (I don't think we ever reach this else) | ||
else { | ||
// Let's be optimistic and perform a straight assignment | ||
obj[propName] = procAssign(oProp, sProp, propName); | ||
} | ||
}, | ||
extendObject = function(src) { | ||
source = src; | ||
Object.keys(source).forEach(procMain); | ||
}; | ||
_.each(Array.prototype.slice.call(arguments, 1), extendProperty); | ||
_.each(Array.prototype.slice.call(arguments, 1), extendObject); | ||
@@ -54,2 +111,3 @@ return obj; | ||
};}); | ||
}; | ||
}); |
@@ -28,3 +28,3 @@ { | ||
"license": "MIT", | ||
"version": "1.1.4", | ||
"version": "1.1.5", | ||
"repository": { | ||
@@ -31,0 +31,0 @@ "type": "git", |
10999
23.31%118
66.2%