Honor stopImmediatePropagation for live/delegate event handlers. Fixes #7217.
[jquery.git] / src / event.js
index 8a40d00..959e89c 100644 (file)
@@ -7,7 +7,8 @@ var rnamespaces = /\.(.*)$/,
        rescape = /[^\w\s.|`]/g,
        fcleanup = function( nm ) {
                return nm.replace(rescape, "\\$&");
-       };
+       },
+       focusCounts = { focusin: 0, focusout: 0 };
 
 /*
  * A number of helper functions used for managing events.
@@ -31,6 +32,9 @@ jQuery.event = {
 
                if ( handler === false ) {
                        handler = returnFalse;
+               } else if ( !handler ) {
+                 // Fixes bug #7229. Fix recommended by jdalton
+                 return;
                }
 
                var handleObjIn, handleObj;
@@ -282,7 +286,7 @@ jQuery.event = {
                                handle.elem = null;
                        }
 
-                       delete elemData[ eventKey ];
+                       delete elemData.events;
                        delete elemData.handle;
 
                        if ( typeof elemData === "function" ) {
@@ -791,6 +795,8 @@ if ( !jQuery.support.changeBubbles ) {
                filters: {
                        focusout: testChange, 
 
+                       beforedeactivate: testChange,
+
                        click: function( e ) {
                                var elem = e.target, type = elem.type;
 
@@ -855,17 +861,21 @@ if ( document.addEventListener ) {
        jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
                jQuery.event.special[ fix ] = {
                        setup: function() {
-                               this.addEventListener( orig, handler, true );
+                               if ( focusCounts[fix]++ === 0 ) {
+                                       document.addEventListener( orig, handler, true );
+                               }
                        }, 
                        teardown: function() { 
-                               this.removeEventListener( orig, handler, true );
+                               if ( --focusCounts[fix] === 0 ) {
+                                       document.removeEventListener( orig, handler, true );
+                               }
                        }
                };
 
                function handler( e ) { 
                        e = jQuery.event.fix( e );
                        e.type = fix;
-                       return jQuery.event.handle.call( this, e );
+                       return jQuery.event.trigger( e, null, e.target );
                }
        });
 }
@@ -1122,6 +1132,9 @@ function liveHandler( event ) {
                        if ( ret === false ) {
                                stop = false;
                        }
+                       if ( event.isImmediatePropagationStopped() ) {
+                               break;
+                       }
                }
        }