Tooltip: Properly track hiding and closing for delegated tooltips

Fixes #10602
Closes gh-1353
This commit is contained in:
Scott González 2014-09-30 09:44:34 -04:00
parent 6833a31697
commit 8825d93dc8
2 changed files with 84 additions and 26 deletions

View File

@ -174,4 +174,52 @@ asyncTest( "destroy during hide animation; only one close event", function() {
});
});
// http://bugs.jqueryui.com/ticket/10602
asyncTest( "multiple active delegated tooltips", function() {
expect( 1 );
var anchor = $( "#tooltipped1" ),
input = anchor.next(),
actions = [];
$( document ).tooltip({
show: false,
hide: false,
open: function( event, ui ) {
actions.push( "open:" + ui.tooltip.text() );
},
close: function( event, ui ) {
actions.push( "close:" + ui.tooltip.text() );
}
});
function step1() {
anchor.simulate( "mouseover" );
setTimeout( step2 );
}
function step2() {
input.simulate( "focus" );
setTimeout( step3 );
}
function step3() {
input.simulate( "blur" );
setTimeout( step4 );
}
function step4() {
anchor.simulate( "mouseout" );
deepEqual( actions, [
"open:anchortitle",
"open:inputtitle",
"close:inputtitle",
"close:anchortitle"
], "Both tooltips open and close" );
start();
}
step1();
});
}( jQuery ) );

View File

@ -86,6 +86,7 @@ return $.widget( "ui.tooltip", {
// IDs of generated tooltips, needed for destroy
this.tooltips = {};
// IDs of parent tooltips where we removed the title attribute
this.parents = {};
@ -117,8 +118,8 @@ return $.widget( "ui.tooltip", {
this._super( key, value );
if ( key === "content" ) {
$.each( this.tooltips, function( id, element ) {
that._updateContent( element );
$.each( this.tooltips, function( id, tooltipData ) {
that._updateContent( tooltipData.element );
});
}
},
@ -127,9 +128,9 @@ return $.widget( "ui.tooltip", {
var that = this;
// close open tooltips
$.each( this.tooltips, function( id, element ) {
$.each( this.tooltips, function( id, tooltipData ) {
var event = $.Event( "blur" );
event.target = event.currentTarget = element[0];
event.target = event.currentTarget = tooltipData.element[ 0 ];
that.close( event, true );
});
@ -231,7 +232,7 @@ return $.widget( "ui.tooltip", {
},
_open: function( event, target, content ) {
var tooltip, events, delayedShow, a11yContent,
var tooltipData, tooltip, events, delayedShow, a11yContent,
positionOption = $.extend( {}, this.options.position );
if ( !content ) {
@ -240,9 +241,9 @@ return $.widget( "ui.tooltip", {
// Content can be updated multiple times. If the tooltip already
// exists, then just update the content and bail.
tooltip = this._find( target );
if ( tooltip.length ) {
tooltip.find( ".ui-tooltip-content" ).html( content );
tooltipData = this._find( target );
if ( tooltipData ) {
tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
return;
}
@ -261,7 +262,8 @@ return $.widget( "ui.tooltip", {
}
}
tooltip = this._tooltip( target );
tooltipData = this._tooltip( target );
tooltip = tooltipData.tooltip;
this._addDescribedBy( target, tooltip.attr( "id" ) );
tooltip.find( ".ui-tooltip-content" ).html( content );
@ -296,8 +298,6 @@ return $.widget( "ui.tooltip", {
}, this.options.position ) );
}
this.hiding = false;
this.closing = false;
tooltip.hide();
this._show( tooltip, this.options.show );
@ -343,13 +343,21 @@ return $.widget( "ui.tooltip", {
},
close: function( event ) {
var that = this,
var tooltip,
that = this,
target = $( event ? event.currentTarget : this.element ),
tooltip = this._find( target );
tooltipData = this._find( target );
// The tooltip may already be closed
if ( !tooltipData ) {
return;
}
tooltip = tooltipData.tooltip;
// disabling closes the tooltip, so we need to track when we're closing
// to avoid an infinite loop in case the tooltip becomes disabled on close
if ( this.closing ) {
if ( tooltipData.closing ) {
return;
}
@ -364,12 +372,10 @@ return $.widget( "ui.tooltip", {
this._removeDescribedBy( target );
this.hiding = true;
tooltipData.hiding = true;
tooltip.stop( true );
this._hide( tooltip, this.options.hide, function() {
that._removeTooltip( $( this ) );
this.hiding = false;
this.closing = false;
});
target.removeData( "ui-tooltip-open" );
@ -388,10 +394,10 @@ return $.widget( "ui.tooltip", {
});
}
this.closing = true;
tooltipData.closing = true;
this._trigger( "close", event, { tooltip: tooltip } );
if ( !this.hiding ) {
this.closing = false;
if ( !tooltipData.hiding ) {
tooltipData.closing = false;
}
},
@ -407,13 +413,16 @@ return $.widget( "ui.tooltip", {
.appendTo( tooltip );
tooltip.appendTo( this.document[0].body );
this.tooltips[ id ] = element;
return tooltip;
return this.tooltips[ id ] = {
element: element,
tooltip: tooltip
};
},
_find: function( target ) {
var id = target.data( "ui-tooltip-id" );
return id ? $( "#" + id ) : $();
return id ? this.tooltips[ id ] : null;
},
_removeTooltip: function( tooltip ) {
@ -425,10 +434,11 @@ return $.widget( "ui.tooltip", {
var that = this;
// close open tooltips
$.each( this.tooltips, function( id, element ) {
$.each( this.tooltips, function( id, tooltipData ) {
// Delegate to close method to handle common cleanup
var event = $.Event( "blur" );
event.target = event.currentTarget = element[0];
var event = $.Event( "blur" ),
element = tooltipData.element;
event.target = event.currentTarget = element[ 0 ];
that.close( event, true );
// Remove immediately; destroying an open tooltip doesn't use the