]> git.ipfire.org Git - thirdparty/foundation/foundation-sites.git/commitdiff
Use pull request #11418 from ncoden/refactor/mouseleave-special-case for v6.5.0
authorNicolas Coden <nicolas@ncoden.fr>
Wed, 12 Sep 2018 20:25:53 +0000 (22:25 +0200)
committerNicolas Coden <nicolas@ncoden.fr>
Wed, 12 Sep 2018 20:25:53 +0000 (22:25 +0200)
9bd7f933c refactor: move dropdownMenu mouseleave special case to its own utility function
8f2470c28 docs: add doc for core utility onLeaveElement
90de67a17 refactor: make the magic mouseleave utility a simple event filter
adeee972d docs: add some doc in the magic mouseleave utility "ignoreMousedisappear"
f46e78bd1 fix: prevent Dropdown and Tooltip to hide when moving mouse to browser UI elements
5bdec3a3c tests: add visual test for the Dropdown magic mousleave bug
f0168bb9f style: fix incorrectly named variable in ignoreMousedisappear utility
1847f6c9b fix: make the "ignoreMousedisappear()" handler called before mouseenter
3ec791559 docs: improve doc in "ignoreMousedisappear()"

Signed-off-by: Nicolas Coden <nicolas@ncoden.fr>
js/foundation.core.utils.js
js/foundation.dropdownMenu.js

index 46b2f0ed4ac4b4c2c7435dbe3dbd6789192d1d67..5bc46b9a57170c97f57db936c957f14b725331fa 100644 (file)
@@ -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 };
index dc9fb57ba73760873bf848333254864134b70f61..2b1d6b77618922033e2c1b195d84ab3748f59e77 100644 (file)
@@ -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.
@@ -135,17 +134,19 @@ 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) {
@@ -153,19 +154,8 @@ class DropdownMenu extends Plugin {
 
           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));
-
         }
       });
     }