diff --git a/src/zepto.js b/src/zepto.js
index ae9858f40..a29a4d469 100644
--- a/src/zepto.js
+++ b/src/zepto.js
@@ -177,14 +177,24 @@ var Zepto = (function() {
return zepto.init(selector, context)
}
+ function extend(target, source, deep) {
+ for (key in source)
+ if (deep && isPlainObject(source[key])) {
+ if (!isPlainObject(target[key])) target[key] = {}
+ extend(target[key], source[key], deep)
+ }
+ else if (source[key] !== undefined) target[key] = source[key]
+ }
+
// Copy all but undefined properties from one or more
// objects to the `target` object.
$.extend = function(target){
- slice.call(arguments, 1).forEach(function(source) {
- for (key in source)
- if (source[key] !== undefined)
- target[key] = source[key]
- })
+ var deep, args = slice.call(arguments, 1)
+ if (typeof target == 'boolean') {
+ deep = target
+ target = args.shift()
+ }
+ args.forEach(function(arg){ extend(target, arg, deep) })
return target
}
diff --git a/test/zepto.html b/test/zepto.html
index d86bf96a9..08ecd267e 100644
--- a/test/zepto.html
+++ b/test/zepto.html
@@ -368,6 +368,39 @@
Zepto DOM unit tests
// undefined values are not copied over
t.assertSame({a:1}, $.extend({a:1}, {b:undefined}))
+
+ // shallow by default
+ obj = $.extend({ a:{b:"c"} }, { a:{d:"e"} })
+ t.assertSame({d:"e"}, obj.a)
+ },
+
+ testExtendDeep: function(t){
+ var obj = { a:{b:"c", x:{y:"z"}} }
+ $.extend(true, obj, { a:{d:"e"} }, { a:{b:"B", f:"g", x:{q:"x"}} })
+
+ t.assertEqual('a', Object.keys(obj).join(','))
+ t.assertEqual('b,d,f,x', Object.keys(obj.a).sort().join(','))
+ t.assertEqual('B', obj.a.b)
+ t.assertEqual('e', obj.a.d)
+ t.assertEqual('g', obj.a.f)
+ t.assertEqual('z', obj.a.x.y)
+ t.assertEqual('x', obj.a.x.q)
+
+ // creates non-existing keys on target object
+ obj = {}
+ $.extend(true, obj, { a:{b:"c"} })
+ t.assertEqual('a', Object.keys(obj).join(','))
+ t.assertEqual('c', obj.a.b)
+
+ // skips iterating over DOM elements
+ obj = {}
+ var dom = $('#some_element').get(0)
+ $.extend(true, obj, { element: dom })
+ t.assertIdentical(dom, obj.element)
+
+ // can override DOM element
+ $.extend(true, obj, { element:{a:'b'} })
+ t.assertEqual('b', obj.element.a)
},
testExtensionAPI: function(t) {