]> source.dussan.org Git - jquery-ui.git/commitdiff
Tooltip: Properly track hiding and closing for delegated tooltips
authorScott González <scott.gonzalez@gmail.com>
Tue, 30 Sep 2014 13:44:34 +0000 (09:44 -0400)
committerScott González <scott.gonzalez@gmail.com>
Thu, 9 Oct 2014 14:40:58 +0000 (10:40 -0400)
Fixes #10602
Closes gh-1353

tests/unit/tooltip/tooltip_core.js
ui/tooltip.js

index 760ffeed2eb5ddd71b1b7ef9023c63e367cee11c..2e029c7b0e5993ff285057ca9495d8dcd02e891f 100644 (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 ) );
index 048b6324a8e89f9ba596ca9d2614cad515200599..180c9f8e24c8fb346838dd6321d927ce26db20d4 100644 (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