From 94dfccc6dbb2dbf7b91e01622ff746c9c9f447d6 Mon Sep 17 00:00:00 2001 From: Corey Jewett Date: Mon, 23 Apr 2007 15:29:57 +0000 Subject: [PATCH] Add hook for modifying the merge behavior of $.extend. Specifically, and time there is a collision between the target and mergee this function is called to resolve it. --- src/jquery/jquery.js | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/src/jquery/jquery.js b/src/jquery/jquery.js index 715fbf1..5347c92 100644 --- a/src/jquery/jquery.js +++ b/src/jquery/jquery.js @@ -1177,6 +1177,10 @@ jQuery.fn = jQuery.prototype = { /** * Extend one object with one or more others, returning the original, * modified, object. This is a great utility for simple inheritance. + * + * There is also an optional collision resolution function. Any time the target and + * merged object both contain a key this function is called. This may be used to create + * a recursive merge. (See example) Unless you know what this is, you probably don't care. * * @example var settings = { validate: false, limit: 5, name: "foo" }; * var options = { validate: true, name: "bar" }; @@ -1190,8 +1194,19 @@ jQuery.fn = jQuery.prototype = { * @result settings == { validate: true, limit: 5, name: "bar" } * @desc Merge defaults and options, without modifying the defaults * + * @example var defaults = { validate: false, limit: 5, name: "foo", nested: {depth: false} }; + * var options = { validate: true, name: "bar", nested: {depth: true} }; + * var collision_resolver_fn = function(target, mergee) { + * // combine nested Objects, in this case the object being merged takes priority + * return jQuery.extend({}, target, mergee); + * } + * var settings = jQuery.extend({}, collision_resolver_fn, defaults, options); + * @result settings == { validate: true, limit: 5, name: "bar" } + * @desc Recursively merge defaults and options, without modifying the defaults + * * @name $.extend * @param Object target The object to extend + * @param Function (optional) collision resolution function. Hook to extend the merging behavior of $.extend(). See example. * @param Object prop1 The object that will be merged into the first. * @param Object propN (optional) More objects to merge into the first * @type Object @@ -1199,18 +1214,26 @@ jQuery.fn = jQuery.prototype = { */ jQuery.extend = jQuery.fn.extend = function() { // copy reference to target object - var target = arguments[0], + var resolver, prop, target = arguments[0], a = 1; - + // extend jQuery itself if only one argument is passed if ( arguments.length == 1 ) { target = this; a = 0; + } else if (jQuery.isFunction(arguments[a])) { + resolver = arguments[a++]; } - var prop; + while (prop = arguments[a++]) // Extend the base object - for ( var i in prop ) target[i] = prop[i]; + for ( var i in prop ) { + if (resolver && target[i] && prop[i]) { + target[i] = resolver(target[i], prop[i]); + } else { + target[i] = prop[i]; + } + } // Return the modified object return target; -- 1.7.10.4