From: John Resig <jeresig@gmail.com>
Date: Fri, 9 Jan 2009 22:10:42 +0000 (+0000)
Subject: Made it so that you can bind a single function to multiple .live() selectors. Additio... 
X-Git-Url: http://git.asbjorn.biz/?a=commitdiff_plain;h=d12e8a34e6d96f98ac4f9408a0d61a9ed373f917;p=jquery.git

Made it so that you can bind a single function to multiple .live() selectors. Additionally, simplified the proxy code to provide a default proxy function.
Fixes #3787.
---

diff --git a/src/event.js b/src/event.js
index 06a6d83..405e19f 100644
--- a/src/event.js
+++ b/src/event.js
@@ -26,10 +26,7 @@ jQuery.event = {
 			var fn = handler;
 
 			// Create unique handler function, wrapped around original handler
-			handler = this.proxy( fn, function() {
-				// Pass arguments and context to original handler
-				return fn.apply(this, arguments);
-			});
+			handler = this.proxy( fn );
 
 			// Store data in unique handler
 			handler.data = data;
@@ -334,6 +331,7 @@ jQuery.event = {
 	},
 
 	proxy: function( fn, proxy ){
+		proxy = proxy || function(){ return fn.apply(this, arguments); };
 		// Set the guid of unique handler to the same of original handler, so it can be removed
 		proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++;
 		// So proxy can be declared as an argument
@@ -362,7 +360,7 @@ jQuery.event = {
 							remove++;
 					});
 					
-					if ( remove <= 1 )
+					if ( remove < 1 )
 						jQuery.event.remove( this, namespaces[0], liveHandler );
 				}
 			}
@@ -546,12 +544,16 @@ jQuery.fn.extend({
 	},
 	
 	live: function( type, fn ){
-		jQuery(document).bind( liveConvert(type, this.selector), this.selector, fn );
+		var proxy = jQuery.event.proxy( fn );
+		proxy.guid += this.selector;
+
+		jQuery(document).bind( liveConvert(type, this.selector), this.selector, proxy );
+
 		return this;
 	},
 	
 	die: function( type, fn ){
-		jQuery(document).unbind( liveConvert(type, this.selector), fn );
+		jQuery(document).unbind( liveConvert(type, this.selector), fn ? { guid: fn.guid + this.selector } : null );
 		return this;
 	}
 });
diff --git a/test/unit/event.js b/test/unit/event.js
index fb08a2e..cbeb9ff 100644
--- a/test/unit/event.js
+++ b/test/unit/event.js
@@ -474,7 +474,7 @@ test("toggle(Function, Function, ...)", function() {
 });
 
 test(".live()/.die()", function() {
-	expect(30);
+	expect(34);
 
 	var submit = 0, div = 0, livea = 0, liveb = 0;
 
@@ -550,6 +550,31 @@ test(".live()/.die()", function() {
 	jQuery("#anchor2").trigger("click");
 	equals( window.location.hash, hash, "e.preventDefault() worked" );
 	jQuery("#anchor2").die("click");
+
+	// Test binding the same handler to multiple points
+	var called = 0;
+	function callback(){ called++; return false; }
+
+	jQuery("#nothiddendiv").live("click", callback);
+	jQuery("#anchor2").live("click", callback);
+
+	jQuery("#nothiddendiv").trigger("click");
+	equals( called, 1, "Verify that only one click occurred." );
+
+	jQuery("#anchor2").trigger("click");
+	equals( called, 2, "Verify that only one click occurred." );
+
+	// Make sure that only one callback is removed
+	jQuery("#anchor2").die("click", callback);
+
+	jQuery("#nothiddendiv").trigger("click");
+	equals( called, 3, "Verify that only one click occurred." );
+
+	jQuery("#anchor2").trigger("click");
+	equals( called, 3, "Verify that only one click occurred." );
+
+	// Cleanup
+	jQuery("#nothiddendiv").die("click", callback);
 });
 
 /*