diff --git a/src/core.js b/src/core.js old mode 100644 new mode 100755 index 9c4db57c..370fa255 --- a/src/core.js +++ b/src/core.js @@ -43,6 +43,7 @@ var session = { previousY: 0, desyncTimeout: null, closeDelayTimeout: null, + openDelayTimeout: null, mouseTrackingActive: false, delayInProgress: false, windowWidth: 0, @@ -134,7 +135,7 @@ $.fn.powerTip = function(opts, arg) { }); } else { targetElements.on(evt + EVENT_NAMESPACE, function elementOpen(event) { - $.powerTip.show(this, event); + $.powerTip.show(this, event, false); }); } }); @@ -176,6 +177,7 @@ $.fn.powerTip.defaults = { intentSensitivity: 7, intentPollInterval: 100, closeDelay: 100, + openDelay: 100, placement: 'n', smartPlacement: false, offset: 10, @@ -215,18 +217,19 @@ $.powerTip = { * @param {jQuery|Element} element The element to open the tooltip for. * @param {jQuery.Event=} event jQuery event for hover intent and mouse * tracking (optional). + * @param {Boolean=} disableDelay Disable open delay (Optional) * @return {jQuery|Element} The original jQuery object or DOM Element. */ - show: function apiShowTip(element, event) { + show: function apiShowTip(element, event, disableDelay) { // if we were given a mouse event then run the hover intent testing, // otherwise, simply show the tooltip asap if (isMouseEvent(event)) { trackMouse(event); session.previousX = event.pageX; session.previousY = event.pageY; - $(element).data(DATA_DISPLAYCONTROLLER).show(); + $(element).data(DATA_DISPLAYCONTROLLER).show(element, undefined, disableDelay); } else { - $(element).first().data(DATA_DISPLAYCONTROLLER).show(true, true); + $(element).first().data(DATA_DISPLAYCONTROLLER).show(true, true, disableDelay); } return element; }, @@ -285,7 +288,7 @@ $.powerTip = { $.powerTip.hide(element, !isMouseEvent(event)); } else { // tooltip for element is not active, so open it - $.powerTip.show(element, event); + $.powerTip.show(element, event, true); } return element; }, diff --git a/src/displaycontroller.js b/src/displaycontroller.js old mode 100644 new mode 100755 index d0f1b0e6..78396359 --- a/src/displaycontroller.js +++ b/src/displaycontroller.js @@ -18,16 +18,23 @@ */ function DisplayController(element, options, tipController) { var hoverTimer = null, - myCloseDelay = null; + myCloseDelay = null, + myOpenDelay = null; /** * Begins the process of showing a tooltip. * @private * @param {boolean=} immediate Skip intent testing (optional). * @param {boolean=} forceOpen Ignore cursor position and force tooltip to + * @param {boolean=} disableDelay Disable open delay (optional). * open (optional). */ - function openTooltip(immediate, forceOpen) { + function openTooltip(immediate, forceOpen, disableDelay) { + // if this instance already has an open delay in progress then halt it + if (myOpenDelay) { + myOpenDelay = session.openDelayTimeout = clearTimeout(myOpenDelay); + session.delayInProgress = false; + } cancelTimer(); if (!element.data(DATA_HASACTIVEHOVER)) { if (!immediate) { @@ -44,7 +51,23 @@ function DisplayController(element, options, tipController) { element.data(DATA_FORCEDOPEN, true); } closeAnyDelayed(); - tipController.showTip(element); + if (!disableDelay) { + session.delayInProgress = true; + session.openDelayTimeout = setTimeout( + function openDelay() { + session.openDelayTimeout = null; + tipController.showTip(element); + session.delayInProgress = false; + myOpenDelay = null; + }, + options.openDelay + ); + // save internal reference open delay id so we can check if the + // active open delay belongs to this instance + myOpenDelay = session.openDelayTimeout; + } else { + tipController.showTip(element); + } } } else { // cursor left and returned to this element, cancel close @@ -123,6 +146,10 @@ function DisplayController(element, options, tipController) { if (session.closeDelayTimeout && myCloseDelay === session.closeDelayTimeout || stopClose) { cancelClose(); } + // Cancel the current open delay + if (myOpenDelay === session.openDelayTimeout) { + cancelOpen(); + } } /** @@ -133,6 +160,14 @@ function DisplayController(element, options, tipController) { session.closeDelayTimeout = clearTimeout(session.closeDelayTimeout); session.delayInProgress = false; } + /** + * Cancels any active open delay timer. + * @private + */ + function cancelOpen() { + session.openDelayTimeout = clearTimeout(session.openDelayTimeout); + session.delayInProgress = false; + } /** * Asks any tooltips waiting on their close delay to close now. diff --git a/test/edge-cases.html b/test/edge-cases.html old mode 100644 new mode 100755 index 244892ab..e9c180f4 --- a/test/edge-cases.html +++ b/test/edge-cases.html @@ -110,12 +110,19 @@
The button below will disable itself 2 seconds after you hover or focus on it. The tooltip should close.
-The two buttons below have tooltips with long delays. Mousing from one to the other should open tooltips normally.
+The two buttons below have tooltips with long close delays. Mousing from one to the other should open tooltips normally.
The two buttons below have tooltips , one with long open delay, the other with no open delay.
+ + +The buttons below have tooltips, one with manual enabled, the other with mouseOnToPopup enabled. The manual tooltip should not close when you mouse off of the tooltip element.
diff --git a/test/tests-edge.js b/test/tests-edge.js old mode 100644 new mode 100755 index d95fdcc5..40fe8f80 --- a/test/tests-edge.js +++ b/test/tests-edge.js @@ -41,9 +41,13 @@ $(function() { }); $('#auto-disable-button input').powerTip({ placement: 'e' }); - // Long delay tooltips - $('#long-delay #first-button').powerTip({ closeDelay: 2000, mouseOnToPopup: true }); - $('#long-delay #second-button').powerTip({ closeDelay: 2000 }); + // Long close delay tooltips + $('#long-close-delay #first-button').powerTip({ closeDelay: 2000, mouseOnToPopup: true }); + $('#long-close-delay #second-button').powerTip({ closeDelay: 2000 }); + + // Long open delay tooltips + $('#long-open-delay #first-button').powerTip({ openDelay: 2000 }); + $('#long-open-delay #second-button').powerTip(); // Manual and interactive tooltips $('#manual-and-interactive #manual-button').on('click', function() { diff --git a/test/unit/core.js b/test/unit/core.js old mode 100644 new mode 100755 index 3d2f6fed..93084872 --- a/test/unit/core.js +++ b/test/unit/core.js @@ -17,6 +17,7 @@ $(function() { ok($.fn.powerTip.defaults.hasOwnProperty('intentSensitivity'), 'intentSensitivity exists'); ok($.fn.powerTip.defaults.hasOwnProperty('intentPollInterval'), 'intentPollInterval exists'); ok($.fn.powerTip.defaults.hasOwnProperty('closeDelay'), 'closeDelay exists'); + ok($.fn.powerTip.defaults.hasOwnProperty('openDelay'), 'openDelay exists'); ok($.fn.powerTip.defaults.hasOwnProperty('placement'), 'placement exists'); ok($.fn.powerTip.defaults.hasOwnProperty('smartPlacement'), 'smartPlacement exists'); ok($.fn.powerTip.defaults.hasOwnProperty('offset'), 'offset exists'); diff --git a/test/unit/displaycontroller.js b/test/unit/displaycontroller.js old mode 100644 new mode 100755 index 4ba8da30..a7f99ad3 --- a/test/unit/displaycontroller.js +++ b/test/unit/displaycontroller.js @@ -91,7 +91,7 @@ $(function() { ) ); - dc.show(true); + dc.show(true, undefined, true); ok(showCalled, 'showTip called'); });