Bug 1519905 - Always return false in NodeAllowsClickThrough for browser elements;r=mstange
authorBrian Grinstead <bgrinstead@mozilla.com>
Mon, 14 Jan 2019 20:42:50 +0000
changeset 510928 36b1b39a97754dc150db4d96749b59efb510ee6e
parent 510927 c15b18fe44c403e5d3c88fdf2192eea5e4d26b3e
child 510929 d8a71e4402fc20fba8095a49fb96db7592cdb3e8
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs1519905
milestone66.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1519905 - Always return false in NodeAllowsClickThrough for browser elements;r=mstange This prevents mouse events from firing on browsers in unfocused windows. It used to be done with the [clickthrough=never] attribute set from XBL content. Differential Revision: https://phabricator.services.mozilla.com/D16498
dom/events/EventStateManager.cpp
widget/tests/test_bug596600.xul
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -2815,16 +2815,19 @@ void EventStateManager::DecideGestureEve
   }    // ancestor chain
   aEvent->mDisplayPanFeedback = displayPanFeedback;
   aEvent->mPanDirection = panDirection;
 }
 
 #ifdef XP_MACOSX
 static bool NodeAllowsClickThrough(nsINode* aNode) {
   while (aNode) {
+    if (aNode->IsXULElement(nsGkAtoms::browser)) {
+      return false;
+    }
     if (aNode->IsXULElement()) {
       mozilla::dom::Element* element = aNode->AsElement();
       static Element::AttrValuesArray strings[] = {nsGkAtoms::always,
                                                    nsGkAtoms::never, nullptr};
       switch (element->FindAttrValueIn(
           kNameSpaceID_None, nsGkAtoms::clickthrough, strings, eCaseMatters)) {
         case 0:
           return true;
--- a/widget/tests/test_bug596600.xul
+++ b/widget/tests/test_bug596600.xul
@@ -18,47 +18,44 @@
 </body>
 
 <script class="testbody" type="application/javascript">
 <![CDATA[
 
 const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
 const NSMouseMoved = 5;
 
-var gLeftWindow, gRightWindow, gIFrame;
+var gLeftWindow, gRightWindow, gBrowserElement;
 var gExpectedEvents = [];
 
 function moveMouseTo(x, y, andThen) {
   var utils = gLeftWindow.windowUtils;
   utils.sendNativeMouseEvent(x, y, NSMouseMoved, 0, gLeftWindow.documentElement);
   SimpleTest.executeSoon(andThen);
 }
 
 function openWindows() {
   gLeftWindow = open('empty_window.xul', '_blank', 'chrome,screenX=50,screenY=50,width=200,height=200');
   SimpleTest.waitForFocus(function () {
     gRightWindow = open('empty_window.xul', '', 'chrome,screenX=300,screenY=50,width=200,height=200');
-    SimpleTest.waitForFocus(attachIFrameToRightWindow, gRightWindow);
+    SimpleTest.waitForFocus(attachBrowserToLeftWindow, gRightWindow);
   }, gLeftWindow);
 }
 
-function attachIFrameToRightWindow() {
-  gIFrame = gLeftWindow.document.createElementNS(XUL_NS, "iframe");
-  gIFrame.setAttribute("type", "content");
-  gIFrame.setAttribute("clickthrough", "never");
-  gIFrame.setAttribute("src", "file_bug596600.html");
-  gIFrame.style.width = "100px";
-  gIFrame.style.height = "100px";
-  gIFrame.style.margin = "50px";
-  gLeftWindow.document.documentElement.appendChild(gIFrame);
-  gIFrame.addEventListener("load", function (e) {
-    gIFrame.removeEventListener("load", arguments.callee, true);
+function attachBrowserToLeftWindow() {
+  gBrowserElement = gLeftWindow.document.createXULElement("browser");
+  gBrowserElement.setAttribute("type", "content");
+  gBrowserElement.setAttribute("src", "file_bug596600.html");
+  gBrowserElement.style.width = "100px";
+  gBrowserElement.style.height = "100px";
+  gBrowserElement.style.margin = "50px";
+  gLeftWindow.document.documentElement.appendChild(gBrowserElement);
+  gBrowserElement.addEventListener("load", function (e) {
     test1();
-  }, true);
-
+  }, { capture: true, once: true });
 }
 
 function test1() {
   // gRightWindow is active, gLeftWindow is inactive.
   moveMouseTo(0, 0, function () {
     var expectMouseOver = false, expectMouseOut = false;
     function mouseOverListener(e) {
       ok(expectMouseOver, "Got expected mouseover at " + e.screenX + ", " + e.screenY);
@@ -71,46 +68,46 @@ function test1() {
     gLeftWindow.addEventListener("mouseover", mouseOverListener, false);
     gLeftWindow.addEventListener("mouseout", mouseOutListener, false);
 
     // Move into the left window
     expectMouseOver = true;
     moveMouseTo(80, 80, function () {
       ok(!expectMouseOver, "Should have got mouseover event");
 
-      // Move over the iframe, which has clickthrough="never".
+      // Move over the browser
       expectMouseOut = true;
       moveMouseTo(150, 150, function () {
         ok (!expectMouseOut, "Should have got mouseout event");
         gLeftWindow.removeEventListener("mouseover", mouseOverListener, false);
         gLeftWindow.removeEventListener("mouseout", mouseOutListener, false);
         test2();
       });
     });
   });
 }
 
 function test2() {
-  // Make the iframe cover the whole window.
-  gIFrame.style.margin = "0";
-  gIFrame.style.width = gIFrame.style.height = "200px";
+  // Make the browser cover the whole window.
+  gBrowserElement.style.margin = "0";
+  gBrowserElement.style.width = gBrowserElement.style.height = "200px";
 
-  // Add a box to the iframe at the left edge.
-  var doc = gIFrame.contentDocument;
+  // Add a box to the browser at the left edge.
+  var doc = gBrowserElement.contentDocument;
   var box = doc.createElement("div");
   box.setAttribute("id", "box");
   box.style.position = "absolute";
   box.style.left = "0";
   box.style.top = "50px";
   box.style.width = "100px";
   box.style.height = "100px";
   box.style.backgroundColor = "green";
   doc.body.appendChild(box);
 
-  ok(!box.matches(":hover"), "Box shouldn't be hovered (since the mouse isn't over it and since it's in a non-clickthrough iframe in a background window)");
+  ok(!box.matches(":hover"), "Box shouldn't be hovered (since the mouse isn't over it and since it's in a non-clickthrough browser in a background window)");
 
   // A function to waitForFocus and then wait for synthetic mouse
   // events to happen.  Note that those happen off the refresh driver,
   // and happen after animation frame requests.
   function changeFocusAndAwaitSyntheticMouse(callback, winToFocus,
                                              elementToWatchForMouseEventOn) {
      function mouseWatcher() {
        elementToWatchForMouseEventOn.removeEventListener("mouseover",
@@ -129,32 +126,32 @@ function test2() {
                                                     false);
      // Just pass a dummy function to waitForFocus; the mouseout/over listener
      // will actually handle things for us.
      SimpleTest.waitForFocus(function() {}, winToFocus);
   }
 
   // Move the mouse over the box.
   moveMouseTo(100, 150, function () {
-    ok(!box.matches(":hover"), "Box shouldn't be hovered (since it's in a non-clickthrough iframe in a background window)");
+    ok(!box.matches(":hover"), "Box shouldn't be hovered (since it's in a non-clickthrough browser in a background window)");
     // Activate the left window.
     changeFocusAndAwaitSyntheticMouse(function () {
-      ok(gIFrame.matches(":hover"), "iframe should be hovered");
+      ok(gBrowserElement.matches(":hover"), "browser should be hovered");
       ok(box.matches(":hover"), "Box should be hovered");
       // De-activate the window (by activating the right window).
       changeFocusAndAwaitSyntheticMouse(function () {
-        ok(!gIFrame.matches(":hover"), "iframe shouldn't be hovered");
+        ok(!gBrowserElement.matches(":hover"), "browser shouldn't be hovered");
         ok(!box.matches(":hover"), "Box shouldn't be hovered");
         // Re-activate it.
         changeFocusAndAwaitSyntheticMouse(function () {
-          ok(gIFrame.matches(":hover"), "iframe should be hovered");
+          ok(gBrowserElement.matches(":hover"), "browser should be hovered");
           ok(box.matches(":hover"), "Box should be hovered");
-          // Unhover box and iframe by moving the mouse outside the window.
+          // Unhover box and browser by moving the mouse outside the window.
           moveMouseTo(0, 150, function () {
-            ok(!gIFrame.matches(":hover"), "iframe shouldn't be hovered");
+            ok(!gBrowserElement.matches(":hover"), "browser shouldn't be hovered");
             ok(!box.matches(":hover"), "box shouldn't be hovered");
             finalize();
           });
         }, gLeftWindow, box);
       }, gRightWindow, box);
     }, gLeftWindow, box);
   });
 }