Skip to content

Commit

Permalink
Use pull request #11418 from ncoden/refactor/mouseleave-special-case …
Browse files Browse the repository at this point in the history
…for v6.5.0

9bd7f93 refactor: move dropdownMenu mouseleave special case to its own utility function
8f2470c docs: add doc for core utility onLeaveElement
90de67a refactor: make the magic mouseleave utility a simple event filter
adeee97 docs: add some doc in the magic mouseleave utility "ignoreMousedisappear"
f46e78b fix: prevent Dropdown and Tooltip to hide when moving mouse to browser UI elements
5bdec3a tests: add visual test for the Dropdown magic mousleave bug
f0168bb style: fix incorrectly named variable in ignoreMousedisappear utility
1847f6c fix: make the "ignoreMousedisappear()" handler called before mouseenter
3ec7915 docs: improve doc in "ignoreMousedisappear()"

Signed-off-by: Nicolas Coden <nicolas@ncoden.fr>
  • Loading branch information
ncoden committed Sep 12, 2018
1 parent 296bd17 commit 55e60ee
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 19 deletions.
30 changes: 29 additions & 1 deletion js/foundation.core.utils.js
Expand Up @@ -90,4 +90,32 @@ function onLoad($elem, handler) {
return eventType;
}

export { rtl, GetYoDigits, RegExpEscape, transitionend, onLoad };
function onLeaveElement($elem, handler, { leaveWindow = true } = {}) {
const eventType = 'mouseleave.zf.util.onLeaveElement';

if ($elem && handler) {

$elem.on(eventType, function leaveHandler(e, ...rest) {
const _this = this;
setTimeout(function leaveEventDebouncer() {

if (e.relatedTarget === null && leaveWindow && document.hasFocus && document.hasFocus()) {

$(document).one('mouseenter', function reenterHandler(reeenterE) {
if ($elem.has(reeenterE.target).length) { return false };
e.relatedTarget = reeenterE.target;
handler.call(_this, e, ...rest);
});

return false;
}

handler.call(_this, e, ...rest);
});
});
}

return eventType;
}

export { rtl, GetYoDigits, RegExpEscape, transitionend, onLoad, onLeaveElement };
26 changes: 8 additions & 18 deletions js/foundation.dropdownMenu.js
@@ -1,12 +1,11 @@
'use strict';

import $ from 'jquery';
import { Plugin } from './foundation.core.plugin';
import { rtl as Rtl, onLeaveElement } from './foundation.core.utils';
import { Keyboard } from './foundation.util.keyboard';
import { Nest } from './foundation.util.nest';
import { Box } from './foundation.util.box';
import { rtl as Rtl } from './foundation.core.utils';
import { Plugin } from './foundation.core.plugin';


/**
* DropdownMenu module.
Expand Down Expand Up @@ -135,37 +134,28 @@ class DropdownMenu extends Plugin {
}

if (!this.options.disableHover) {
this.$menuItems.on('mouseenter.zf.dropdownmenu', function(e) {
this.$menuItems.on('mouseenter.zf.dropdownmenu', function (e) {
var $elem = $(this),
hasSub = $elem.hasClass(parClass);
hasSub = $elem.hasClass(parClass);

if (hasSub) {
clearTimeout($elem.data('_delay'));
$elem.data('_delay', setTimeout(function() {
$elem.data('_delay', setTimeout(function () {
_this._show($elem.children('.is-dropdown-submenu'));
}, _this.options.hoverDelay));
}
}).on('mouseleave.zf.dropdownmenu', function(e) {
});

onLeaveElement(this.$menuItems, function (e) {
var $elem = $(this),
hasSub = $elem.hasClass(parClass);
if (hasSub && _this.options.autoclose) {
if ($elem.attr('data-is-click') === 'true' && _this.options.clickOpen) { return false; }

clearTimeout($elem.data('_delay'));
$elem.data('_delay', setTimeout(function () {

// Ignore "magic mouseleave": when the mouse simply disapear from the document
// (like when entering in browser input suggestions See https://git.io/zf-11410),
// unless we actually left the window (and document lost focus).
//
// In firefox, document will not focus at the time the event is triggered, so we have
// to make this test after the delay.
if (e.relatedTarget === null && document.hasFocus && document.hasFocus()) { return false; }

_this._hide($elem);

}, _this.options.closingTime));

}
});
}
Expand Down

0 comments on commit 55e60ee

Please sign in to comment.