From: Nicolas Coden Date: Mon, 10 Sep 2018 20:37:41 +0000 (+0200) Subject: Merge branch 'develop' into refactor/mouseleave-special-case X-Git-Tag: v6.6.0~3^2~95^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F11418%2Fhead;p=thirdparty%2Ffoundation%2Ffoundation-sites.git Merge branch 'develop' into refactor/mouseleave-special-case --- 998cb252be30b9fadd23e7e830f1a6cbadaa0c81 diff --cc js/foundation.core.utils.js index 3bb5d5385,46b2f0ed4..b6778b72b --- a/js/foundation.core.utils.js +++ b/js/foundation.core.utils.js @@@ -90,55 -90,4 +90,55 @@@ function onLoad($elem, handler) return eventType; } -export { rtl, GetYoDigits, RegExpEscape, transitionend, onLoad }; +/** + * Retuns an handler for the `mouseleave` that ignore disappeared mouses. + * + * If the mouse "disappeared" from the document (like when going on a browser UI element, See https://git.io/zf-11410), + * the event is ignored. + * - If the `ignoreLeaveWindow` is `true`, the event is ignored when the user actually left the window + * (like by switching to an other window with [Alt]+[Tab]). + * - If the `ignoreReappear` is `true`, the event will be ignored when the mouse will reappear later on the document + * outside of the element it left. + * + * @function + * + * @param {Function} [] handler - handler for the filtered `mouseleave` event to watch. + * @param {Object} [] options - object of options: + * - {Boolean} [false] ignoreLeaveWindow - also ignore when the user switched windows. + * - {Boolean} [false] ignoreReappear - also ignore when the mouse reappeared outside of the element it left. + * @returns {Function} - filtered handler to use to listen on the `mouseleave` event. + */ +function ignoreMousedisappear(handler, { ignoreLeaveWindow = false, ignoreReappear = false } = {}) { + return function leaveEventHandler(eLeave, ...rest) { + const callback = handler.bind(this, eLeave, ...rest); + + // The mouse left: call the given callback if the mouse entered elsewhere + if (eLeave.relatedTarget !== null) { + return callback(); + } + + // Otherwise, check if the mouse actually left the window. + // In firefox if the user switched between windows, the window sill have the focus by the time + // the event is triggered. We have to debounce the event to test this case. + setTimeout(function leaveEventDebouncer() { + if (!ignoreLeaveWindow && document.hasFocus && !document.hasFocus()) { + return callback(); + } + + // Otherwise, wait for the mouse to reeapear outside of the element, + if (!ignoreReappear) { + $(document).one('mouseenter', function reenterEventHandler(eReenter) { + if (!$(eLeave.currentTarget).has(eReenter.target).length) { + // Fill where the mouse finally entered. + eLeave.relatedTarget = eReenter.target; + callback(); + } + }); + } + + }, 0); + }; +} + + - export {rtl, GetYoDigits, RegExpEscape, transitionend, onLoad, ignoreMousedisappear}; ++export { rtl, GetYoDigits, RegExpEscape, transitionend, onLoad, ignoreMousedisappear };