Skip to content

Commit

Permalink
fix(tooltip): delay timeouts
Browse files Browse the repository at this point in the history
The show and hide delay timeouts where not getting
cancelled correctly resulting in tooltips staying
open when both popup and popup-close delays were
in use.

Closes angular-ui#4621
Fixes angular-ui#4618
  • Loading branch information
RobJacobs authored and aroop committed Oct 16, 2015
1 parent 4525f3a commit 56f0302
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 30 deletions.
23 changes: 23 additions & 0 deletions src/tooltip/test/tooltip.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,29 @@ describe('tooltip', function() {
});
});

describe('with specified popup and popup close delay', function() {
var $timeout;
beforeEach(inject(function($compile, _$timeout_) {
$timeout = _$timeout_;
scope.delay = '1000';
elm = $compile(angular.element(
'<span uib-tooltip="tooltip text" tooltip-popup-close-delay="{{delay}}" tooltip-popup-close-delay="{{delay}}" ng-disabled="disabled">Selector Text</span>'
))(scope);
elmScope = elm.scope();
tooltipScope = elmScope.$$childTail;
scope.$digest();
}));

it('should not open if mouseleave before timeout', function() {
trigger(elm, 'mouseenter');
$timeout.flush(500);
trigger(elm, 'mouseleave');
$timeout.flush();

expect(tooltipScope.isOpen).toBe(false);
});
});

describe('with an is-open attribute', function() {
beforeEach(inject(function ($compile) {
scope.isOpen = false;
Expand Down
64 changes: 34 additions & 30 deletions src/tooltip/tooltip.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ angular.module('ui.bootstrap.tooltip', ['ui.bootstrap.position', 'ui.bootstrap.s
return;
}

cancelHide();
prepareTooltip();

if (ttScope.popupDelay) {
Expand All @@ -206,30 +207,21 @@ angular.module('ui.bootstrap.tooltip', ['ui.bootstrap.position', 'ui.bootstrap.s
}

function hideTooltipBind() {
cancelShow();

if (ttScope.popupCloseDelay) {
hideTimeout = $timeout(hide, ttScope.popupCloseDelay, false);
if (!hideTimeout) {
hideTimeout = $timeout(hide, ttScope.popupCloseDelay, false);
}
} else {
hide();
}
}

// Show the tooltip popup element.
function show() {
if (showTimeout) {
$timeout.cancel(showTimeout);
showTimeout = null;
}

// If there is a pending remove transition, we must cancel it, lest the
// tooltip be mysteriously removed.
if (hideTimeout) {
$timeout.cancel(hideTimeout);
hideTimeout = null;
}
if (transitionTimeout) {
$timeout.cancel(transitionTimeout);
transitionTimeout = null;
}
cancelShow();
cancelHide();

// Don't show empty tooltips.
if (!ttScope.content) {
Expand All @@ -246,13 +238,7 @@ angular.module('ui.bootstrap.tooltip', ['ui.bootstrap.position', 'ui.bootstrap.s
});
}

// Hide the tooltip popup element.
function hide() {
if (!ttScope) {
return;
}

//if tooltip is going to be shown after delay, we must cancel this
function cancelShow() {
if (showTimeout) {
$timeout.cancel(showTimeout);
showTimeout = null;
Expand All @@ -262,6 +248,16 @@ angular.module('ui.bootstrap.tooltip', ['ui.bootstrap.position', 'ui.bootstrap.s
$timeout.cancel(positionTimeout);
positionTimeout = null;
}
}

// Hide the tooltip popup element.
function hide() {
cancelShow();
cancelHide();

if (!ttScope) {
return;
}

// First things first: we don't show it anymore.
ttScope.$evalAsync(function() {
Expand All @@ -281,6 +277,17 @@ angular.module('ui.bootstrap.tooltip', ['ui.bootstrap.position', 'ui.bootstrap.s
});
}

function cancelHide() {
if (hideTimeout) {
$timeout.cancel(hideTimeout);
hideTimeout = null;
}
if (transitionTimeout) {
$timeout.cancel(transitionTimeout);
transitionTimeout = null;
}
}

function createTooltip() {
// There can only be one tooltip element per directive shown at once.
if (tooltip) {
Expand Down Expand Up @@ -349,9 +356,8 @@ angular.module('ui.bootstrap.tooltip', ['ui.bootstrap.position', 'ui.bootstrap.s
* Observe the relevant attributes.
*/
attrs.$observe('disabled', function(val) {
if (showTimeout && val) {
$timeout.cancel(showTimeout);
showTimeout = null;
if (val) {
cancelShow();
}

if (val && ttScope.isOpen) {
Expand Down Expand Up @@ -495,10 +501,8 @@ angular.module('ui.bootstrap.tooltip', ['ui.bootstrap.position', 'ui.bootstrap.s

// Make sure tooltip is destroyed and removed.
scope.$on('$destroy', function onDestroyTooltip() {
$timeout.cancel(transitionTimeout);
$timeout.cancel(showTimeout);
$timeout.cancel(hideTimeout);
$timeout.cancel(positionTimeout);
cancelShow();
cancelHide();
unregisterTriggers();
removeTooltip();
openedTooltips.remove(ttScope);
Expand Down

0 comments on commit 56f0302

Please sign in to comment.