Bug 1484371 - make *enter/*leave events uncomposed, r=masayuki
authorOlli Pettay <Olli.Pettay@helsinki.fi>
Wed, 22 Aug 2018 16:08:17 +0300
changeset 481133 971943621f6e52daa0e94e48c3d846567978ff26
parent 481132 41ebcb085bb01e54c1a7eea9e794cde45afbe734
child 481134 6cd69a56e853b2f2f3ef42e1ef406030cfbc9c1f
push id232
push userfmarier@mozilla.com
push dateWed, 05 Sep 2018 20:45:54 +0000
reviewersmasayuki
bugs1484371
milestone63.0a1
Bug 1484371 - make *enter/*leave events uncomposed, r=masayuki
dom/events/test/file_bug1484371.html
dom/events/test/mochitest.ini
dom/events/test/test_bug1484371.html
widget/BasicEvents.h
new file mode 100644
--- /dev/null
+++ b/dom/events/test/file_bug1484371.html
@@ -0,0 +1,94 @@
+<html>
+  <head>
+    <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+    <script>
+      var mouseEnterCount = 0;
+      function mouseEnter() {
+        ++mouseEnterCount;
+      }
+      var mouseLeaveCount = 0;
+      function mouseLeave() {
+        ++mouseLeaveCount;
+      }
+
+      var pointerEnterCount = 0;
+      function pointerEnter() {
+        ++pointerEnterCount;
+      }
+      var pointerLeaveCount = 0;
+      function pointerLeave() {
+        ++pointerLeaveCount;
+      }
+
+      function pointerEventsEnabled() {
+        return "onpointerenter" in document.body;
+      }
+
+      function checkEventCounts(expected, msg) {
+        parent.is(mouseEnterCount, expected.mouseEnterCount, msg + ": mouseenter event count");
+        parent.is(mouseLeaveCount, expected.mouseLeaveCount, msg + ": mouseleave event count");
+        if (pointerEventsEnabled()) {
+          parent.is(pointerEnterCount, expected.pointerEnterCount, msg + ": pointerenter event count");
+          parent.is(pointerLeaveCount, expected.pointerLeaveCount, msg + ": pointerleave event count");
+        }
+      }
+
+      function test() {
+        var lightDiv = document.getElementById("lightDiv");
+        var host = document.getElementById("host");
+        var sr = host.attachShadow({mode: "closed"});
+        sr.innerHTML = "<div>shadow DOM<div>";
+        var shadowDiv = sr.firstChild;
+
+        host.addEventListener("mouseenter", mouseEnter, true);
+        host.addEventListener("mouseleave", mouseLeave, true);
+        host.addEventListener("pointerenter", pointerEnter, true);
+        host.addEventListener("pointerleave", pointerLeave, true);
+
+        shadowDiv.addEventListener("mouseenter", mouseEnter, true);
+        shadowDiv.addEventListener("mouseleave", mouseLeave, true);
+        shadowDiv.addEventListener("pointerenter", pointerEnter, true);
+        shadowDiv.addEventListener("pointerleave", pointerLeave, true);
+
+        synthesizeMouseAtCenter(lightDiv, { type: "mousemove" });
+        checkEventCounts({ mouseEnterCount: 0,
+                           mouseLeaveCount: 0,
+                           pointerEnterCount: 0,
+                           pointerLeaveCount: 0
+                         },
+                         "Entered light DOM"
+                         );
+
+        synthesizeMouseAtCenter(shadowDiv, { type: "mousemove" })
+        checkEventCounts({ mouseEnterCount: 2,
+                           mouseLeaveCount: 0,
+                           pointerEnterCount: 2,
+                           pointerLeaveCount: 0
+                         },
+                         "Entered shadow DOM");
+
+        synthesizeMouseAtCenter(lightDiv, { type: "mousemove" })
+        checkEventCounts({ mouseEnterCount: 2,
+                           mouseLeaveCount: 2,
+                           pointerEnterCount: 2,
+                           pointerLeaveCount: 2
+                         },
+                         "Left shadow DOM"
+                         );
+
+        parent.SimpleTest.finish();
+      }
+
+    function lazyRequestAnimationFrame(fn) {
+      requestAnimationFrame(
+        function() {
+          setTimeout(fn);
+        });
+    }
+    </script>
+  </head>
+  <body onload="lazyRequestAnimationFrame(test)">
+    <div id="lightDiv">light DOM</div>
+    <div id="host"></div>
+  </body>
+</html>
--- a/dom/events/test/mochitest.ini
+++ b/dom/events/test/mochitest.ini
@@ -200,12 +200,14 @@ support-files = window_bug1369072.html
 skip-if = toolkit == 'android'
 [test_bug1429572.html]
 support-files = window_bug1429572.html
 [test_bug1446834.html]
 support-files = file_bug1446834.html
 [test_bug1447993.html]
 support-files = window_bug1447993.html
 skip-if = toolkit == 'android'
+[test_bug1484371.html]
+support-files = file_bug1484371.html
 [test_dnd_with_modifiers.html]
 [test_hover_mouseleave.html]
 [test_slotted_mouse_event.html]
 [test_slotted_text_click.html]
new file mode 100644
--- /dev/null
+++ b/dom/events/test/test_bug1484371.html
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1484371
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 1484371</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="application/javascript">
+
+  /** Test for Bug 1484371 **/
+
+  SimpleTest.waitForExplicitFinish();
+
+  window.onload = function() {
+    SpecialPowers.pushPrefEnv({"set": [["dom.webcomponents.shadowdom.enabled", true]]},
+      function() {
+        document.getElementById("iframe").src = "file_bug1484371.html";
+      });
+  }
+
+  </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1484371">Mozilla Bug 1484371</a>
+<iframe id="iframe"></iframe>
+</body>
+</html>
--- a/widget/BasicEvents.h
+++ b/widget/BasicEvents.h
@@ -939,29 +939,26 @@ public:
         mFlags.mComposed = mMessage == eKeyDown || mMessage == eKeyUp ||
                            mMessage == eKeyPress;
         break;
       case eMouseEventClass:
         mFlags.mComposed = mMessage == eMouseClick ||
                            mMessage == eMouseDoubleClick ||
                            mMessage == eMouseAuxClick ||
                            mMessage == eMouseDown || mMessage == eMouseUp ||
-                           mMessage == eMouseEnter || mMessage == eMouseLeave ||
                            mMessage == eMouseOver || mMessage == eMouseOut ||
                            mMessage == eMouseMove || mMessage == eContextMenu;
         break;
       case ePointerEventClass:
         // All pointer events are composed
         mFlags.mComposed = mMessage == ePointerDown ||
                            mMessage == ePointerMove || mMessage == ePointerUp ||
                            mMessage == ePointerCancel ||
                            mMessage == ePointerOver ||
                            mMessage == ePointerOut ||
-                           mMessage == ePointerEnter ||
-                           mMessage == ePointerLeave ||
                            mMessage == ePointerGotCapture ||
                            mMessage == ePointerLostCapture;
         break;
       case eTouchEventClass:
         // All touch events are composed
         mFlags.mComposed = mMessage == eTouchStart || mMessage == eTouchEnd ||
                            mMessage == eTouchMove || mMessage == eTouchCancel;
         break;