From: John Resig <jeresig@gmail.com>
Date: Sat, 10 Jan 2009 19:57:07 +0000 (+0000)
Subject: Landed a fix for when a DOM element gets accidentally removed by another live event... 
X-Git-Url: http://git.asbjorn.biz/?a=commitdiff_plain;h=b1018cad1256a7b9cc47e675b2a9e22c409b7aed;p=jquery.git

Landed a fix for when a DOM element gets accidentally removed by another live event handler. Thanks to Irae for the patches. Fixed #3820.
---

diff --git a/src/event.js b/src/event.js
index 1ba0357..08deb8b 100644
--- a/src/event.js
+++ b/src/event.js
@@ -560,15 +560,23 @@ jQuery.fn.extend({
 
 function liveHandler( event ){
 	var check = RegExp("(^|\\.)" + event.type + "(\\.|$)"),
-		stop = true;
+		stop = true,
+		elems = [];
 
 	jQuery.each(jQuery.data(this, "events").live || [], function(i, fn){
-		if ( !event.isImmediatePropagationStopped() && check.test(fn.type) ) {
+		if ( check.test(fn.type) ) {
 			var elem = jQuery(event.target).closest(fn.data)[0];
-			if ( elem && fn.call(elem, event, fn.data) === false )
-				stop = false;
+			if ( elem )
+				elems.push({ elem: elem, fn: fn });
 		}
 	});
+
+	jQuery.each(elems, function(){
+		if ( !event.isImmediatePropagationStopped() &&
+			this.fn.call(this.elem, event, this.fn.data) === false )
+				stop = false;
+	});
+
 	return stop;
 }
 
diff --git a/test/unit/event.js b/test/unit/event.js
index e12f3b7..83a0797 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(36);
+	expect(38);
 
 	var submit = 0, div = 0, livea = 0, liveb = 0;
 
@@ -588,6 +588,20 @@ test(".live()/.die()", function() {
 
 	// Cleanup
 	jQuery("#nothiddendiv").die("foo", callback);
+	
+	// Make sure we don't loose the target by DOM modifications
+	// after the bubble already reached the liveHandler
+	var livec = 0, elemDiv = jQuery("#nothiddendivchild").html('<span></span>').get(0);
+	
+	jQuery("#nothiddendivchild").live("click", function(e){ jQuery("#nothiddendivchild").html(''); });
+	jQuery("#nothiddendivchild").live("click", function(e){ if(e.target) {livec++;} });
+	
+	jQuery("#nothiddendiv span").click();
+	equals( jQuery("#nothiddendiv span").length, 0, "Verify that first handler occurred and modified the DOM." );
+	equals( livec, 1, "Verify that second handler occurred even with nuked target." );
+	
+	// Cleanup
+	jQuery("#nothiddendivchild").die("click");
 });
 
 /*