Skip to content
This repository has been archived by the owner on May 29, 2019. It is now read-only.

fix(tooltip): popup close delay not respected #4597

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/popover/docs/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ will display:
- `popover-animation`: Should it fade in and out? Defaults to "true".
- `popover-popup-delay`: For how long should the user have to have the mouse
over the element before the popover shows (in milliseconds)? Defaults to 0.
- `popover-close-popup-delay`: For how long should the popover remain open
after the close trigger event? Defaults to 0.
- `popover-trigger`: What should trigger the show of the popover? See the
`tooltip` directive for supported values.
- `popover-append-to-body`: Should the tooltip be appended to `$body` instead of
Expand Down
4 changes: 3 additions & 1 deletion src/tooltip/docs/demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
pharetra convallis posuere morbi leo urna,
<a href="#" tooltip-animation="false" uib-tooltip="I don't fade. :-(">fading</a>
at elementum eu, facilisis sed odio morbi quis commodo odio. In cursus
<a href="#" tooltip-popup-delay='1000' uib-tooltip='appears with delay'>delayed</a> turpis massa tincidunt dui ut.
<a href="#" tooltip-popup-delay='1000' uib-tooltip='appears with delay'>show delay</a>
turpis massa tincidunt dui ut. In cursus
<a href="#" tooltip-popup-close-delay='1000' uib-tooltip='hides with delay'>hide delay</a>
<a href="#" uib-tooltip-template="'myTooltipTemplate.html'">Custom template</a>
nunc sed velit dignissim sodales ut eu sem integer vitae. Turpis egestas
</p>
Expand Down
3 changes: 2 additions & 1 deletion src/tooltip/docs/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ will display:
- `tooltip-animation`: Should it fade in and out? Defaults to "true".
- `tooltip-popup-delay`: For how long should the user have to have the mouse
over the element before the tooltip shows (in milliseconds)? Defaults to 0.
- `tooltip-close-popup-delay`: For how long should the tooltip remained open?
- `tooltip-close-popup-delay`: For how long should the tooltip remain open
after the close trigger event? Defaults to 0.
- `tooltip-trigger`: What should trigger a show of the tooltip? Supports a space separated list of event names.
Note: this attribute is no longer observable. See `tooltip-enable`.
- `tooltip-enable`: Is it enabled? It will enable or disable the configured
Expand Down
4 changes: 2 additions & 2 deletions src/tooltip/test/tooltip.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -386,11 +386,11 @@ describe('tooltip', function() {
expect(tooltipScope.isOpen).toBe(false);
});

it('should use default popup close delay if specified delay is not a number and close after delay', function() {
it('should use default popup close delay if specified delay is not a number and close immediately', function() {
scope.delay = 'text1000';
scope.$digest();
trigger(elm, 'mouseenter');
expect(tooltipScope.popupCloseDelay).toBe(500);
expect(tooltipScope.popupCloseDelay).toBe(0);
expect(tooltipScope.isOpen).toBe(true);
trigger(elm, 'mouseleave');
$timeout.flush();
Expand Down
87 changes: 51 additions & 36 deletions src/tooltip/tooltip.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ angular.module('ui.bootstrap.tooltip', ['ui.bootstrap.position', 'ui.bootstrap.s
placement: 'top',
animation: true,
popupDelay: 0,
popupCloseDelay: 500,
popupCloseDelay: 0,
useContentExp: false
};

Expand Down Expand Up @@ -135,7 +135,8 @@ angular.module('ui.bootstrap.tooltip', ['ui.bootstrap.position', 'ui.bootstrap.s
var tooltip;
var tooltipLinkedScope;
var transitionTimeout;
var popupTimeout;
var showTimeout;
var hideTimeout;
var positionTimeout;
var appendToBody = angular.isDefined(options.appendToBody) ? options.appendToBody : false;
var triggers = getTriggers(undefined);
Expand Down Expand Up @@ -196,27 +197,35 @@ angular.module('ui.bootstrap.tooltip', ['ui.bootstrap.position', 'ui.bootstrap.s
if (ttScope.popupDelay) {
// Do nothing if the tooltip was already scheduled to pop-up.
// This happens if show is triggered multiple times before any hide is triggered.
if (!popupTimeout) {
popupTimeout = $timeout(show, ttScope.popupDelay, false);
if (!showTimeout) {
showTimeout = $timeout(show, ttScope.popupDelay, false);
}
} else {
show();
}
}

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

// Show the tooltip popup element.
function show() {
if (popupTimeout) {
$timeout.cancel(popupTimeout);
popupTimeout = null;
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;
Expand All @@ -232,10 +241,7 @@ angular.module('ui.bootstrap.tooltip', ['ui.bootstrap.position', 'ui.bootstrap.s
// And show the tooltip.
ttScope.$evalAsync(function() {
ttScope.isOpen = true;
if (isOpenParse && angular.isFunction(isOpenParse.assign)) {
isOpenParse.assign(ttScope.origScope, ttScope.isOpen);
}

assignIsOpen(true);
positionTooltip();
});
}
Expand All @@ -246,31 +252,33 @@ angular.module('ui.bootstrap.tooltip', ['ui.bootstrap.position', 'ui.bootstrap.s
return;
}

//if tooltip is going to be shown after delay, we must cancel this
if (showTimeout) {
$timeout.cancel(showTimeout);
showTimeout = null;
}

if (positionTimeout) {
$timeout.cancel(positionTimeout);
positionTimeout = null;
}

// First things first: we don't show it anymore.
ttScope.$evalAsync(function() {
ttScope.isOpen = false;
if (isOpenParse && angular.isFunction(isOpenParse.assign)) {
isOpenParse.assign(ttScope.origScope, ttScope.isOpen);
assignIsOpen(false);
// And now we remove it from the DOM. However, if we have animation, we
// need to wait for it to expire beforehand.
// FIXME: this is a placeholder for a port of the transitions library.
// The fade transition in TWBS is 150ms.
if (ttScope.animation) {
if (!transitionTimeout) {
transitionTimeout = $timeout(removeTooltip, 150, false);
}
} else {
removeTooltip();
}
});

//if tooltip is going to be shown after delay, we must cancel this
$timeout.cancel(popupTimeout);
popupTimeout = null;

$timeout.cancel(positionTimeout);
positionTimeout = null;

// And now we remove it from the DOM. However, if we have animation, we
// need to wait for it to expire beforehand.
// FIXME: this is a placeholder for a port of the transitions library.
if (ttScope.animation) {
if (!transitionTimeout) {
transitionTimeout = $timeout(removeTooltip, ttScope.popupCloseDelay);
}
} else {
removeTooltip();
}
}

function createTooltip() {
Expand Down Expand Up @@ -327,6 +335,12 @@ angular.module('ui.bootstrap.tooltip', ['ui.bootstrap.position', 'ui.bootstrap.s
ttScope.popupCloseDelay = !isNaN(closeDelay) ? closeDelay : options.popupCloseDelay;
}

function assignIsOpen(isOpen) {
if (isOpenParse && angular.isFunction(isOpenParse.assign)) {
isOpenParse.assign(scope, isOpen);
}
}

ttScope.contentExp = function() {
return ttScope.content;
};
Expand All @@ -335,9 +349,9 @@ angular.module('ui.bootstrap.tooltip', ['ui.bootstrap.position', 'ui.bootstrap.s
* Observe the relevant attributes.
*/
attrs.$observe('disabled', function(val) {
if (popupTimeout && val) {
$timeout.cancel(popupTimeout);
popupTimeout = null;
if (showTimeout && val) {
$timeout.cancel(showTimeout);
showTimeout = null;
}

if (val && ttScope.isOpen) {
Expand Down Expand Up @@ -482,7 +496,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(popupTimeout);
$timeout.cancel(showTimeout);
$timeout.cancel(hideTimeout);
$timeout.cancel(positionTimeout);
unregisterTriggers();
removeTooltip();
Expand Down