Skip to content
Browse files

Avoid collateral damage when removing bindType/delegateType special e…

…vents.
  • Loading branch information...
1 parent 5ba7f60 commit 774eba33881093efa592d350a831ca1a812428a8 @dmethvin dmethvin committed Nov 10, 2011
Showing with 56 additions and 22 deletions.
  1. +14 −15 src/event.js
  2. +42 −7 test/unit/event.js
View
29 src/event.js
@@ -151,7 +151,7 @@ jQuery.event = {
remove: function( elem, types, handler, selector ) {
var elemData = jQuery.hasData( elem ) && jQuery._data( elem ),
- t, tns, type, namespaces, origCount,
+ t, tns, type, origType, namespaces, origCount,
j, events, special, handle, eventType, handleObj;
if ( !elemData || !(events = elemData.events) ) {
@@ -162,7 +162,7 @@ jQuery.event = {
types = jQuery.trim( hoverHack( types || "" ) ).split(" ");
for ( t = 0; t < types.length; t++ ) {
tns = rtypenamespace.exec( types[t] ) || [];
- type = tns[1];
+ type = origType = tns[1];
namespaces = tns[2];
// Unbind all events (on this namespace, if provided) for the element
@@ -181,22 +181,21 @@ jQuery.event = {
namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.)?") + "(\\.|$)") : null;
// Only need to loop for special events or selective removal
- if ( handler || namespaces || selector || special.remove ) {
+ if ( handler || namespaces || selector || special.remove || origType !== type ) {
for ( j = 0; j < eventType.length; j++ ) {
handleObj = eventType[ j ];
- if ( !handler || handler.guid === handleObj.guid ) {
- if ( !namespaces || namespaces.test( handleObj.namespace ) ) {
- if ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) {
- eventType.splice( j--, 1 );
-
- if ( handleObj.selector ) {
- eventType.delegateCount--;
- }
- if ( special.remove ) {
- special.remove.call( elem, handleObj );
- }
- }
+ if ( origType === handleObj.origType &&
+ ( !handler || handler.guid === handleObj.guid ) &&
+ ( !namespaces || namespaces.test( handleObj.namespace ) ) &&
+ ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
+ eventType.splice( j--, 1 );
+
+ if ( handleObj.selector ) {
+ eventType.delegateCount--;
+ }
+ if ( special.remove ) {
+ special.remove.call( elem, handleObj );
}
}
}
View
49 test/unit/event.js
@@ -1146,7 +1146,7 @@ test(".trigger() bubbling on disconnected elements (#10489)", function() {
ok( true, "click fired on div" );
})
.find( "p" )
- .on( "click", function() {
+ .on( "click", function() {
ok( true, "click fired on p" );
})
.click()
@@ -1203,7 +1203,7 @@ test("jQuery.Event( type, props )", function() {
test("jQuery.Event.currentTarget", function(){
expect(2);
-
+
jQuery('<div><p><button>shiny</button></p></div>')
.on( "click", "p", function( e ){
equal( e.currentTarget, this, "Check delegated currentTarget on event" );
@@ -2101,7 +2101,7 @@ test(".delegate()/.undelegate()", function() {
test("jQuery.off using dispatched jQuery.Event", function() {
expect(1);
-
+
var markup = jQuery( '<p><a href="#">target</a></p>' ),
count = 0;
markup
@@ -2115,7 +2115,7 @@ test("jQuery.off using dispatched jQuery.Event", function() {
test("stopPropagation() stops directly-bound events on delegated target", function() {
expect(1);
-
+
var markup = jQuery( '<div><p><a href="#">target</a></p></div>' );
markup
.on( "click", function() {
@@ -2296,7 +2296,7 @@ test("Non DOM element events", function() {
test("inline handler returning false stops default", function() {
expect(1);
-
+
var markup = jQuery('<div><a href="#" onclick="return false">x</a></div>');
markup.click(function(e) {
ok( e.isDefaultPrevented(), "inline handler prevented default");
@@ -2461,15 +2461,50 @@ test(".on and .off", function() {
jQuery("#onandoff").remove();
});
+test("special bind/delegate name mapping", function() {
+ expect( 7 );
+
+ jQuery.event.special.slap = {
+ bindType: "click",
+ delegateType: "swing",
+ handle: function( event ) {
+ equal( event.handleObj.origType, "slap", "event type is correct for " + event.type );
+ equal( event.target.id, "mammy", "slapped your mammy" );
+ }
+ };
+
+ var comeback = function( event ) {
+ ok( true, "event " + event.type + " triggered" );
+ };
+
+ jQuery( '<div><button id="mammy">Are We Not Men?</button></div>' )
+ .on( "slap", "button", jQuery.noop )
+ .on( "swing", "button", comeback )
+ .find( "button" )
+ .on( "slap", jQuery.noop )
+ .on( "click", comeback )
+ .trigger( "click" ) // bindType-slap and click
+ .off( "slap" )
+ .trigger( "click" ) // click
+ .off( "click" )
+ .trigger( "swing" ) // delegateType-slap and swing
+ .end()
+ .off( "slap swing" )
+ .find( "button " ) // everything should be gone
+ .trigger( "slap" )
+ .trigger( "click" )
+ .trigger( "swing" )
+ .end();
+});
test(".on and .off, selective mixed removal (#10705)", function() {
expect(7);
var clockout = 0,
- timingx = function( e ) {
+ timingx = function( e ) {
ok( true, "triggered " + e.type );
};
-
+
jQuery( '<p>Strange Pursuit</p>' )
.on( "click", timingx )
.on( "click.duty", timingx )

0 comments on commit 774eba3

Please sign in to comment.
Something went wrong with that request. Please try again.