aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorScott González <scott.gonzalez@gmail.com>2012-06-14 12:33:16 -0400
committerScott González <scott.gonzalez@gmail.com>2012-06-14 12:33:16 -0400
commitff39bed57a05ca060033187b8aecebafab357f78 (patch)
treee82f4c3faa3b5269f0f86e3f186a6f3024ad7466
parent00d4beb0ca4a99933bb7e786a1dd50618c180a0b (diff)
downloadjquery-ui-ff39bed57a05ca060033187b8aecebafab357f78.tar.gz
jquery-ui-ff39bed57a05ca060033187b8aecebafab357f78.zip
Widget: Added _off() for removing event handlers. Fixes #7795 - Widget: _on and _off.
-rw-r--r--tests/unit/widget/widget_core.js77
-rw-r--r--ui/jquery.ui.accordion.js3
-rw-r--r--ui/jquery.ui.button.js32
-rw-r--r--ui/jquery.ui.dialog.js6
-rw-r--r--ui/jquery.ui.menu.js4
-rw-r--r--ui/jquery.ui.tabs.js6
-rw-r--r--ui/jquery.ui.tooltip.js2
-rw-r--r--ui/jquery.ui.widget.js5
8 files changed, 108 insertions, 27 deletions
diff --git a/tests/unit/widget/widget_core.js b/tests/unit/widget/widget_core.js
index 24ae9c567..abfb0d9de 100644
--- a/tests/unit/widget/widget_core.js
+++ b/tests/unit/widget/widget_core.js
@@ -767,6 +767,83 @@ test( "_on() to common element", function() {
$( document ).trigger( "customevent" );
});
+test( "_off() - single event", function() {
+ expect( 3 );
+
+ $.widget( "ui.testWidget", {} );
+ var shouldTriggerWidget, shouldTriggerOther,
+ element = $( "#widget" ),
+ widget = element.testWidget().data( "testWidget" );
+ widget._on( element, { foo: function() {
+ ok( shouldTriggerWidget, "foo called from _on" );
+ }});
+ element.bind( "foo", function() {
+ ok( shouldTriggerOther, "foo called from bind" );
+ });
+ shouldTriggerWidget = true;
+ shouldTriggerOther = true;
+ element.trigger( "foo" );
+ shouldTriggerWidget = false;
+ widget._off( element, "foo" );
+ element.trigger( "foo" );
+});
+
+test( "_off() - multiple events", function() {
+ expect( 6 );
+
+ $.widget( "ui.testWidget", {} );
+ var shouldTriggerWidget, shouldTriggerOther,
+ element = $( "#widget" ),
+ widget = element.testWidget().data( "testWidget" );
+ widget._on( element, {
+ foo: function() {
+ ok( shouldTriggerWidget, "foo called from _on" );
+ },
+ bar: function() {
+ ok( shouldTriggerWidget, "bar called from _on" );
+ }
+ });
+ element.bind( "foo bar", function( event ) {
+ ok( shouldTriggerOther, event.type + " called from bind" );
+ });
+ shouldTriggerWidget = true;
+ shouldTriggerOther = true;
+ element.trigger( "foo" );
+ element.trigger( "bar" );
+ shouldTriggerWidget = false;
+ widget._off( element, "foo bar" );
+ element.trigger( "foo" );
+ element.trigger( "bar" );
+});
+
+test( "_off() - all events", function() {
+ expect( 6 );
+
+ $.widget( "ui.testWidget", {} );
+ var shouldTriggerWidget, shouldTriggerOther,
+ element = $( "#widget" ),
+ widget = element.testWidget().data( "testWidget" );
+ widget._on( element, {
+ foo: function() {
+ ok( shouldTriggerWidget, "foo called from _on" );
+ },
+ bar: function() {
+ ok( shouldTriggerWidget, "bar called from _on" );
+ }
+ });
+ element.bind( "foo bar", function( event ) {
+ ok( shouldTriggerOther, event.type + " called from bind" );
+ });
+ shouldTriggerWidget = true;
+ shouldTriggerOther = true;
+ element.trigger( "foo" );
+ element.trigger( "bar" );
+ shouldTriggerWidget = false;
+ widget._off( element );
+ element.trigger( "foo" );
+ element.trigger( "bar" );
+});
+
test( "._hoverable()", function() {
$.widget( "ui.testWidget", {
_create: function() {
diff --git a/ui/jquery.ui.accordion.js b/ui/jquery.ui.accordion.js
index 4cfc265a3..e8a10b746 100644
--- a/ui/jquery.ui.accordion.js
+++ b/ui/jquery.ui.accordion.js
@@ -219,8 +219,7 @@ $.widget( "ui.accordion", {
if ( key === "event" ) {
if ( this.options.event ) {
- this.headers.unbind(
- this.options.event.split( " " ).join( ".accordion " ) + ".accordion" );
+ this._off( this.headers, this.options.event );
}
this._setupEvents( value );
}
diff --git a/ui/jquery.ui.button.js b/ui/jquery.ui.button.js
index 810191775..0c72e9c4b 100644
--- a/ui/jquery.ui.button.js
+++ b/ui/jquery.ui.button.js
@@ -54,8 +54,8 @@ $.widget( "ui.button", {
},
_create: function() {
this.element.closest( "form" )
- .unbind( "reset.button" )
- .bind( "reset.button", formResetHandler );
+ .unbind( "reset" + this.eventNamespace )
+ .bind( "reset" + this.eventNamespace, formResetHandler );
if ( typeof this.options.disabled !== "boolean" ) {
this.options.disabled = !!this.element.prop( "disabled" );
@@ -79,7 +79,7 @@ $.widget( "ui.button", {
this.buttonElement
.addClass( baseClasses )
.attr( "role", "button" )
- .bind( "mouseenter.button", function() {
+ .bind( "mouseenter" + this.eventNamespace, function() {
if ( options.disabled ) {
return;
}
@@ -88,13 +88,13 @@ $.widget( "ui.button", {
$( this ).addClass( "ui-state-active" );
}
})
- .bind( "mouseleave.button", function() {
+ .bind( "mouseleave" + this.eventNamespace, function() {
if ( options.disabled ) {
return;
}
$( this ).removeClass( hoverClass );
})
- .bind( "click.button", function( event ) {
+ .bind( "click" + this.eventNamespace, function( event ) {
if ( options.disabled ) {
event.preventDefault();
event.stopImmediatePropagation();
@@ -102,16 +102,16 @@ $.widget( "ui.button", {
});
this.element
- .bind( "focus.button", function() {
+ .bind( "focus" + this.eventNamespace, function() {
// no need to check disabled, focus won't be triggered anyway
that.buttonElement.addClass( focusClass );
})
- .bind( "blur.button", function() {
+ .bind( "blur" + this.eventNamespace, function() {
that.buttonElement.removeClass( focusClass );
});
if ( toggleButton ) {
- this.element.bind( "change.button", function() {
+ this.element.bind( "change" + this.eventNamespace, function() {
if ( clickDragged ) {
return;
}
@@ -121,7 +121,7 @@ $.widget( "ui.button", {
// prevents issue where button state changes but checkbox/radio checked state
// does not in Firefox (see ticket #6970)
this.buttonElement
- .bind( "mousedown.button", function( event ) {
+ .bind( "mousedown" + this.eventNamespace, function( event ) {
if ( options.disabled ) {
return;
}
@@ -129,7 +129,7 @@ $.widget( "ui.button", {
startXPos = event.pageX;
startYPos = event.pageY;
})
- .bind( "mouseup.button", function( event ) {
+ .bind( "mouseup" + this.eventNamespace, function( event ) {
if ( options.disabled ) {
return;
}
@@ -140,7 +140,7 @@ $.widget( "ui.button", {
}
if ( this.type === "checkbox" ) {
- this.buttonElement.bind( "click.button", function() {
+ this.buttonElement.bind( "click" + this.eventNamespace, function() {
if ( options.disabled || clickDragged ) {
return false;
}
@@ -148,7 +148,7 @@ $.widget( "ui.button", {
that.buttonElement.attr( "aria-pressed", that.element[0].checked );
});
} else if ( this.type === "radio" ) {
- this.buttonElement.bind( "click.button", function() {
+ this.buttonElement.bind( "click" + this.eventNamespace, function() {
if ( options.disabled || clickDragged ) {
return false;
}
@@ -166,7 +166,7 @@ $.widget( "ui.button", {
});
} else {
this.buttonElement
- .bind( "mousedown.button", function() {
+ .bind( "mousedown" + this.eventNamespace, function() {
if ( options.disabled ) {
return false;
}
@@ -176,13 +176,13 @@ $.widget( "ui.button", {
lastActive = null;
});
})
- .bind( "mouseup.button", function() {
+ .bind( "mouseup" + this.eventNamespace, function() {
if ( options.disabled ) {
return false;
}
$( this ).removeClass( "ui-state-active" );
})
- .bind( "keydown.button", function(event) {
+ .bind( "keydown" + this.eventNamespace, function(event) {
if ( options.disabled ) {
return false;
}
@@ -190,7 +190,7 @@ $.widget( "ui.button", {
$( this ).addClass( "ui-state-active" );
}
})
- .bind( "keyup.button", function() {
+ .bind( "keyup" + this.eventNamespace, function() {
$( this ).removeClass( "ui-state-active" );
});
diff --git a/ui/jquery.ui.dialog.js b/ui/jquery.ui.dialog.js
index 4ef8a20cb..a22eef806 100644
--- a/ui/jquery.ui.dialog.js
+++ b/ui/jquery.ui.dialog.js
@@ -224,7 +224,7 @@ $.widget("ui.dialog", {
if ( this.overlay ) {
this.overlay.destroy();
}
- this.uiDialog.unbind( "keypress.ui-dialog" );
+ this._off( this.uiDialog, "keypress" );
if ( this.options.hide ) {
this.uiDialog.hide( this.options.hide, function() {
@@ -310,7 +310,7 @@ $.widget("ui.dialog", {
// prevent tabbing out of modal dialogs
if ( options.modal ) {
- uiDialog.bind( "keydown.ui-dialog", function( event ) {
+ this._on( uiDialog, { keydown: function( event ) {
if ( event.keyCode !== $.ui.keyCode.TAB ) {
return;
}
@@ -326,7 +326,7 @@ $.widget("ui.dialog", {
last.focus( 1 );
return false;
}
- });
+ }});
}
// set focus to the first tabbable element in the content area or the first button
diff --git a/ui/jquery.ui.menu.js b/ui/jquery.ui.menu.js
index eb0be494c..616389ba2 100644
--- a/ui/jquery.ui.menu.js
+++ b/ui/jquery.ui.menu.js
@@ -44,7 +44,7 @@ $.widget( "ui.menu", {
})
// need to catch all clicks on disabled menu
// not possible through _on
- .bind( "click.menu", $.proxy(function( event ) {
+ .bind( "click" + this.eventNamespace, $.proxy(function( event ) {
if ( this.options.disabled ) {
event.preventDefault();
}
@@ -168,7 +168,7 @@ $.widget( "ui.menu", {
this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
// unbind currentEventTarget click event handler
- $( currentEventTarget ).unbind( "click.menu" );
+ this._off( $( currentEventTarget ), "click" );
},
_keydown: function( event ) {
diff --git a/ui/jquery.ui.tabs.js b/ui/jquery.ui.tabs.js
index 21736641f..aed4ba8fb 100644
--- a/ui/jquery.ui.tabs.js
+++ b/ui/jquery.ui.tabs.js
@@ -58,7 +58,7 @@ $.widget( "ui.tabs", {
.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
.toggleClass( "ui-tabs-collapsible", options.collapsible )
// Prevent users from focusing disabled tabs via click
- .delegate( ".ui-tabs-nav > li", "mousedown.tabs", function( event ) {
+ .delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) {
if ( $( this ).is( ".ui-state-disabled" ) ) {
event.preventDefault();
}
@@ -69,7 +69,7 @@ $.widget( "ui.tabs", {
// We don't have to worry about focusing the previously focused
// element since clicking on a non-focusable element should focus
// the body anyway.
- .delegate( ".ui-tabs-anchor", "focus.tabs", function() {
+ .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
this.blur();
}
@@ -480,7 +480,7 @@ $.widget( "ui.tabs", {
});
}
- this.anchors.add( this.tabs ).add( this.panels ).unbind( ".tabs" );
+ this._off( this.anchors.add( this.tabs ).add( this.panels ) );
this._on( this.anchors, events );
this._on( this.tabs, { keydown: "_tabKeydown" } );
this._on( this.panels, { keydown: "_panelKeydown" } );
diff --git a/ui/jquery.ui.tooltip.js b/ui/jquery.ui.tooltip.js
index 6a7aab706..c4bdbb0d7 100644
--- a/ui/jquery.ui.tooltip.js
+++ b/ui/jquery.ui.tooltip.js
@@ -233,7 +233,7 @@ $.widget( "ui.tooltip", {
});
target.removeData( "tooltip-open" );
- target.unbind( "mouseleave.tooltip focusout.tooltip keyup.tooltip" );
+ this._off( target, "mouseleave focusout keyup" );
this.closing = true;
this._trigger( "close", event, { tooltip: tooltip } );
diff --git a/ui/jquery.ui.widget.js b/ui/jquery.ui.widget.js
index 22049cbb8..5366beefe 100644
--- a/ui/jquery.ui.widget.js
+++ b/ui/jquery.ui.widget.js
@@ -387,6 +387,11 @@ $.Widget.prototype = {
});
},
+ _off: function( element, eventName ) {
+ eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
+ element.unbind( eventName ).undelegate( eventName );
+ },
+
_delay: function( handler, delay ) {
function handlerProxy() {
return ( typeof handler === "string" ? instance[ handler ] : handler )