Bug 1155355, e10s, rewrite and reenable browser tests in layout/xul/test, don't show tooltips during a drag, use system event listeners for tooltips, r=billm
authorNeil Deakin <neil@mozilla.com>
Tue, 21 Apr 2015 20:09:14 -0400
changeset 240444 c36ce7aed6d9eb43e3b4962afe1cb961087ed558
parent 240443 fa9178ca5dc206197e68a589b9d82aa282dafcc6
child 240445 9b75aac198d0480ed6171099d086d37da97f29ff
push id28636
push userkwierso@gmail.com
push dateThu, 23 Apr 2015 00:16:12 +0000
treeherdermozilla-central@a5af73b32ac8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbillm
bugs1155355
milestone40.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 1155355, e10s, rewrite and reenable browser tests in layout/xul/test, don't show tooltips during a drag, use system event listeners for tooltips, r=billm
browser/base/content/browser.js
embedding/browser/nsDocShellTreeOwner.cpp
layout/xul/test/browser.ini
layout/xul/test/browser_bug685470.js
layout/xul/test/browser_bug703210.js
layout/xul/test/browser_bug706743.js
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -3989,16 +3989,21 @@ var XULBrowserWindow = {
     if (gURLBar && gURLBar._mayTrimURLs /* corresponds to browser.urlbar.trimURLs */)
       url = trimURL(url);
 
     this.overLink = url;
     LinkTargetDisplay.update();
   },
 
   showTooltip: function (x, y, tooltip) {
+    if (Cc["@mozilla.org/widget/dragservice;1"].getService(Ci.nsIDragService).
+        getCurrentSession()) {
+      return;
+    }
+
     // The x,y coordinates are relative to the <browser> element using
     // the chrome zoom level.
     let elt = document.getElementById("remoteBrowserTooltip");
     elt.label = tooltip;
 
     let anchor = gBrowser.selectedBrowser;
     elt.openPopupAtScreen(anchor.boxObject.screenX + x, anchor.boxObject.screenY + y, false, null);
   },
--- a/embedding/browser/nsDocShellTreeOwner.cpp
+++ b/embedding/browser/nsDocShellTreeOwner.cpp
@@ -1169,27 +1169,27 @@ ChromeTooltipListener::AddChromeListener
 // Subscribe to the events that will allow us to track tooltips. We need "mouse" for mouseExit,
 // "mouse motion" for mouseMove, and "key" for keyDown. As we add the listeners, keep track
 // of how many succeed so we can clean up correctly in Release().
 //
 NS_IMETHODIMP
 ChromeTooltipListener::AddTooltipListener()
 {
   if (mEventTarget) {
-    nsresult rv = mEventTarget->AddEventListener(NS_LITERAL_STRING("keydown"),
-                                                 this, false, false);
+    nsresult rv = mEventTarget->AddSystemEventListener(NS_LITERAL_STRING("keydown"),
+                                                       this, false, false);
     NS_ENSURE_SUCCESS(rv, rv);
-    rv = mEventTarget->AddEventListener(NS_LITERAL_STRING("mousedown"), this,
-                                        false, false);
+    rv = mEventTarget->AddSystemEventListener(NS_LITERAL_STRING("mousedown"), this,
+                                              false, false);
     NS_ENSURE_SUCCESS(rv, rv);
-    rv = mEventTarget->AddEventListener(NS_LITERAL_STRING("mouseout"), this,
-                                        false, false);
+    rv = mEventTarget->AddSystemEventListener(NS_LITERAL_STRING("mouseout"), this,
+                                              false, false);
     NS_ENSURE_SUCCESS(rv, rv);
-    rv = mEventTarget->AddEventListener(NS_LITERAL_STRING("mousemove"), this,
-                                        false, false);
+    rv = mEventTarget->AddSystemEventListener(NS_LITERAL_STRING("mousemove"), this,
+                                              false, false);
     NS_ENSURE_SUCCESS(rv, rv);
 
     mTooltipListenerInstalled = true;
   }
 
   return NS_OK;
 }
 
@@ -1221,27 +1221,27 @@ ChromeTooltipListener::RemoveChromeListe
 //
 // Unsubscribe from all the various tooltip events that we were listening to
 //
 NS_IMETHODIMP
 ChromeTooltipListener::RemoveTooltipListener()
 {
   if (mEventTarget) {
     nsresult rv =
-      mEventTarget->RemoveEventListener(NS_LITERAL_STRING("keydown"), this,
-                                        false);
+      mEventTarget->RemoveSystemEventListener(NS_LITERAL_STRING("keydown"), this,
+                                              false);
     NS_ENSURE_SUCCESS(rv, rv);
-    rv = mEventTarget->RemoveEventListener(NS_LITERAL_STRING("mousedown"),
-                                           this, false);
+    rv = mEventTarget->RemoveSystemEventListener(NS_LITERAL_STRING("mousedown"),
+                                                 this, false);
     NS_ENSURE_SUCCESS(rv, rv);
-    rv = mEventTarget->RemoveEventListener(NS_LITERAL_STRING("mouseout"), this,
+    rv = mEventTarget->RemoveSystemEventListener(NS_LITERAL_STRING("mouseout"), this,
                                            false);
     NS_ENSURE_SUCCESS(rv, rv);
-    rv = mEventTarget->RemoveEventListener(NS_LITERAL_STRING("mousemove"),
-                                           this, false);
+    rv = mEventTarget->RemoveSystemEventListener(NS_LITERAL_STRING("mousemove"),
+                                                 this, false);
     NS_ENSURE_SUCCESS(rv, rv);
 
     mTooltipListenerInstalled = false;
   }
 
   return NS_OK;
 }
 
--- a/layout/xul/test/browser.ini
+++ b/layout/xul/test/browser.ini
@@ -1,8 +1,5 @@
 [DEFAULT]
 
 [browser_bug685470.js]
-skip-if = e10s # Bug ?????? - test touches content (TypeError: doc.documentElement is null)
 [browser_bug703210.js]
-skip-if = e10s # Bug 933103 - mochitest's EventUtils.synthesizeMouse functions not e10s friendly
 [browser_bug706743.js]
-skip-if = e10s # Bug 933103 - mochitest's EventUtils.synthesizeMouse functions not e10s friendly
--- a/layout/xul/test/browser_bug685470.js
+++ b/layout/xul/test/browser_bug685470.js
@@ -1,51 +1,33 @@
-function test() {
-  waitForExplicitFinish();
+add_task(function* () {
+  const html = "<p id=\"p1\" title=\"tooltip is here\">This paragraph has a tooltip.</p>";
+  yield BrowserTestUtils.openNewForegroundTab(gBrowser, "data:text/html," + html);
 
-  gBrowser.selectedTab = gBrowser.addTab();
-
-  SpecialPowers.setIntPref("ui.tooltipDelay", 0);
+  yield new Promise(resolve => {
+    SpecialPowers.pushPrefEnv({"set": [["ui.tooltipDelay", 0]]}, resolve);
+  });
 
   var popup = false;
   var doc;
   var win;
   var p1;
 
   let onPopupShown = function(aEvent) {
     popup = true;
   }
+  document.addEventListener("popupshown", onPopupShown, true);
 
-  // test that a mouse click prior to the tooltip appearing blocks it
-  let runTest = function() {
-    EventUtils.synthesizeMouseAtCenter(p1, { type: "mousemove" }, win);
-    EventUtils.sendMouseEvent({type:'mousedown'}, p1, win);
-    EventUtils.sendMouseEvent({type:'mouseup'}, p1, win);
+  // Send a mousemove at a known position to start the test.
+  BrowserTestUtils.synthesizeMouseAtCenter("#p1", { type: "mousemove" },
+                                           gBrowser.selectedBrowser);
+  BrowserTestUtils.synthesizeMouseAtCenter("#p1", { }, gBrowser.selectedBrowser);
 
+  yield new Promise(resolve => {
     setTimeout(function() {
       is(popup, false, "shouldn't get tooltip after click");
-
-      document.removeEventListener("popupshown", onPopupShown, true);
-      SpecialPowers.clearUserPref("ui.tooltipDelay");
-
-      gBrowser.removeCurrentTab();
-      finish();
+      resolve();
     }, 200);
-  }
-
-  let onLoad = function (aEvent) {
-    doc = gBrowser.contentDocument;
-    win = gBrowser.contentWindow;
-    p1 = doc.getElementById("p1");
+  });
 
-    document.addEventListener("popupshown", onPopupShown, true);
-
-    runTest();
-  }
-
-  gBrowser.selectedBrowser.addEventListener("load", function loadListener() {
-    gBrowser.selectedBrowser.removeEventListener("load", loadListener, true);
-    setTimeout(onLoad, 0);
-  }, true);
-
-  content.location = "data:text/html," +
-    "<p id=\"p1\" title=\"tooltip is here\">This paragraph has a tooltip.</p>";
-}
+  document.removeEventListener("popupshown", onPopupShown, true);
+  gBrowser.removeCurrentTab();
+});
--- a/layout/xul/test/browser_bug703210.js
+++ b/layout/xul/test/browser_bug703210.js
@@ -1,72 +1,33 @@
-function test() {
-  waitForExplicitFinish();
-
-  gBrowser.selectedTab = gBrowser.addTab();
-
-  SpecialPowers.setIntPref("ui.tooltipDelay", 0);
-
-  let doStopPropagation = function (aEvent)
-  {
-    aEvent.stopPropagation();
-  }
+add_task(function* () {
+  const url = "data:text/html," +
+    "<html onmousemove='event.stopPropagation()'" +
+    " onmouseenter='event.stopPropagation()' onmouseleave='event.stopPropagation()'" +
+    " onmouseover='event.stopPropagation()' onmouseout='event.stopPropagation()'>" +
+    "<p id=\"p1\" title=\"tooltip is here\">This paragraph has a tooltip.</p>" +
+    "<p id=\"p2\">This paragraph doesn't have tooltip.</p></html>";
 
-  let onPopupShown = function (aEvent)
-  {
-    is(aEvent.originalTarget.localName, "tooltip", "tooltip is showing");
+  let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, url);
+  let browser = gBrowser.selectedBrowser;
 
-    let doc = gBrowser.contentDocument;
-    let win = gBrowser.contentWindow;
-    let p2 = doc.getElementById("p2");
-    setTimeout(function () {
-      EventUtils.synthesizeMouseAtCenter(p2, { type: "mousemove" }, win); }, 0);
-  }
-
-  let onPopupHiding = function (aEvent)
-  {
-    is(aEvent.originalTarget.localName, "tooltip", "tooltip is hiding");
-
-    let doc = gBrowser.contentDocument;
+  yield new Promise(resolve => {
+    SpecialPowers.pushPrefEnv({"set": [["ui.tooltipDelay", 0]]}, resolve);
+  });
 
-    doc.removeEventListener("mousemove", doStopPropagation, true);
-    doc.removeEventListener("mouseenter", doStopPropagation, true);
-    doc.removeEventListener("mouseleave", doStopPropagation, true);
-    doc.removeEventListener("mouseover", doStopPropagation, true);
-    doc.removeEventListener("mouseout", doStopPropagation, true);
-    document.removeEventListener("popupshown", onPopupShown, true);
-    document.removeEventListener("popuphiding", onPopupHiding, true);
-
-    SpecialPowers.clearUserPref("ui.tooltipDelay");
-
-    gBrowser.removeCurrentTab();
-    finish();
-  }
-
-  let onLoad = function (aEvent)
-  {
-    let doc = gBrowser.contentDocument;
-    let win = gBrowser.contentWindow;
-    let p1 = doc.getElementById("p1");
-    let p2 = doc.getElementById("p2");
+  // Send a mousemove at a known position to start the test.
+  yield BrowserTestUtils.synthesizeMouseAtCenter("#p2", { type: "mousemove" }, browser);
+  let popupShownPromise = BrowserTestUtils.waitForEvent(document, "popupshown", event => {
+    is(event.originalTarget.localName, "tooltip", "tooltip is showing");
+    return true;
+  });
+  yield BrowserTestUtils.synthesizeMouseAtCenter("#p1", { type: "mousemove" }, browser);
+  yield popupShownPromise;
 
-    EventUtils.synthesizeMouseAtCenter(p2, { type: "mousemove" }, win);
-
-    doc.addEventListener("mousemove", doStopPropagation, true);
-    doc.addEventListener("mouseenter", doStopPropagation, true);
-    doc.addEventListener("mouseleave", doStopPropagation, true);
-    doc.addEventListener("mouseover", doStopPropagation, true);
-    doc.addEventListener("mouseout", doStopPropagation, true);
-    document.addEventListener("popupshown", onPopupShown, true);
-    document.addEventListener("popuphiding", onPopupHiding, true);
+  let popupHiddenPromise = BrowserTestUtils.waitForEvent(document, "popuphidden", event => {
+    is(event.originalTarget.localName, "tooltip", "tooltip is hidden");
+    return true;
+  });
+  yield BrowserTestUtils.synthesizeMouseAtCenter("#p2", { type: "mousemove" }, browser);
+  yield popupHiddenPromise;
 
-    EventUtils.synthesizeMouseAtCenter(p1, { type: "mousemove" }, win);
-  }
-
-  gBrowser.selectedBrowser.addEventListener("load", function loadListener() {
-    gBrowser.selectedBrowser.removeEventListener("load", loadListener, true);
-    setTimeout(onLoad, 0);
-  }, true);
-
-  content.location = "data:text/html," +
-    "<p id=\"p1\" title=\"tooltip is here\">This paragraph has a tooltip.</p>" +
-    "<p id=\"p2\">This paragraph doesn't have tooltip.</p>";
-}
+  gBrowser.removeCurrentTab();
+});
--- a/layout/xul/test/browser_bug706743.js
+++ b/layout/xul/test/browser_bug706743.js
@@ -1,154 +1,84 @@
-function test() {
-  waitForExplicitFinish();
-  gBrowser.selectedTab = gBrowser.addTab();
+add_task(function* () {
+  const url = "data:text/html,<html><head></head><body>" +
+    "<a id=\"target\" href=\"about:blank\" title=\"This is tooltip text\" " +
+            "style=\"display:block;height:20px;margin:10px;\" " +
+            "onclick=\"return false;\">here is an anchor element</a></body></html>";
 
-  SpecialPowers.setIntPref("ui.tooltipDelay", 0);
+  let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, url);
+  let browser = gBrowser.selectedBrowser;
+
+  yield new Promise(resolve => {
+    SpecialPowers.pushPrefEnv({"set": [["ui.tooltipDelay", 0]]}, resolve);
+  });
+
+  // Send a mousemove at a known position to start the test.
+  yield BrowserTestUtils.synthesizeMouse("#target", -5, -5, { type: "mousemove" }, browser);
 
-  let target;
-  let doc;
-  let win;
-  let callbackOnPopupShown;
-  let callbackOnPopupHidden;
+  // show tooltip by mousemove into target.
+  let popupShownPromise = BrowserTestUtils.waitForEvent(document, "popupshown");
+  yield BrowserTestUtils.synthesizeMouse("#target", 5, 15, { type: "mousemove" }, browser);
+  yield popupShownPromise;
+
+  // hide tooltip by mousemove to outside.
+  let popupHiddenPromise = BrowserTestUtils.waitForEvent(document, "popuphidden");
+  yield BrowserTestUtils.synthesizeMouse("#target", -5, 15, { type: "mousemove" }, browser);
+  yield popupHiddenPromise;
+
+  // mousemove into the target and start drag by emulation via nsIDragService.
+  // Note that on some platforms, we cannot actually start the drag by
+  // synthesized events.  E.g., Windows waits an actual mousemove event after
+  // dragstart.
+
+  // Emulate a buggy mousemove event.  widget might dispatch mousemove event
+  // during drag.
+
+  function tooltipNotExpected()
+  {
+    ok(false, "tooltip is shown during drag");
+  }
+  addEventListener("popupshown", tooltipNotExpected, true);
+
   let dragService = Components.classes["@mozilla.org/widget/dragservice;1"].
                       getService(Components.interfaces.nsIDragService);
-
-  let onPopupHidden = function (aEvent)
-  {
-    if (aEvent.originalTarget.localName != "tooltip") {
-      return;
-    }
-    if (callbackOnPopupHidden) {
-      setTimeout(callbackOnPopupHidden, 0);
-    }
-  }
+  dragService.startDragSession();
+  yield BrowserTestUtils.synthesizeMouse("#target", 5, 15, { type: "mousemove" }, browser);
 
-  let onPopupShown = function (aEvent)
-  {
-    if (aEvent.originalTarget.localName != "tooltip") {
-      return;
-    }
-    if (callbackOnPopupShown) {
-      setTimeout(callbackOnPopupShown, 0);
-    }
-  }
-
-  let finishTest = function ()
-  {
-    document.removeEventListener("popupshown", onPopupShown, true);
-    document.removeEventListener("popuphidden", onPopupHidden, true);
-
-    SpecialPowers.clearUserPref("ui.tooltipDelay");
-
-    gBrowser.removeCurrentTab();
-    finish();
-  }
+  yield new Promise(resolve => setTimeout(resolve, 100));
+  removeEventListener("popupshown", tooltipNotExpected, true);
+  dragService.endDragSession(true);
 
-  let testHideTooltipByMouseDown = function ()
-  {
-    callbackOnPopupShown = function () {
-      callbackOnPopupShown = null;
-      ok(true, "tooltip is shown before testing mousedown");
+  yield BrowserTestUtils.synthesizeMouse("#target", -5, -5, { type: "mousemove" }, browser);
 
-      // hide tooltip by mousemove to outside.
-      callbackOnPopupHidden = function () {
-        callbackOnPopupHidden = null;
-        ok(true, "The tooltip is hidden by mousedown");
-
-        EventUtils.synthesizeMouse(target, 5, 15, { type: "mouseup" }, win);
-        EventUtils.synthesizeMouse(target, -5, 15, { type: "mousemove" }, win);
+  // If tooltip listener used a flag for managing D&D state, we would need
+  // to test if the tooltip is shown after drag.
 
-        setTimeout(finishTest, 0);
-      }
-      EventUtils.synthesizeMouse(target, 5, 15, { type: "mousedown" }, win);
-    }
-    EventUtils.synthesizeMouse(target, 5, 15, { type: "mousemove" }, win);
-  }
-
-  let testShowTooltipAgain = function ()
-  {
-    // If tooltip listener used a flag for managing D&D state, we would need
-    // to test if the tooltip is shown after drag.
-    callbackOnPopupShown = function () {
-      callbackOnPopupShown = null;
-      ok(true, "tooltip is shown after drag");
-
-      // hide tooltip by mousemove to outside.
-      callbackOnPopupHidden = function () {
-        callbackOnPopupHidden = null;
-        ok(true, "The tooltip is hidden again");
+  // show tooltip by mousemove into target.
+  popupShownPromise = BrowserTestUtils.waitForEvent(document, "popupshown");
+  yield BrowserTestUtils.synthesizeMouse("#target", 5, 15, { type: "mousemove" }, browser);
+  yield popupShownPromise;
 
-        setTimeout(testHideTooltipByMouseDown, 0);
-      }
-      EventUtils.synthesizeMouse(target, -5, 15, { type: "mousemove" }, win);
-    }
-    EventUtils.synthesizeMouse(target, 5, 15, { type: "mousemove" }, win);
-  }
+  // hide tooltip by mousemove to outside.
+  popupHiddenPromise = BrowserTestUtils.waitForEvent(document, "popuphidden");
+  yield BrowserTestUtils.synthesizeMouse("#target", -5, 15, { type: "mousemove" }, browser);
+  yield popupHiddenPromise;
 
-  let testDuringDnD = function ()
-  {
-    // mousemove into the target and start drag by emulation via nsIDragService.
-    // Note that on some platforms, we cannot actually start the drag by
-    // synthesized events.  E.g., Windows waits an actual mousemove event after
-    // dragstart.
-    callbackOnPopupShown = function () {
-      callbackOnPopupShown = null;
-      ok(false, "tooltip is shown during drag");
-    }
-    dragService.startDragSession();
-    // Emulate a buggy mousemove event.  widget might dispatch mousemove event
-    // during drag.
-    EventUtils.synthesizeMouse(target, 5, 15, { type: "mousemove" }, win);
-    setTimeout(function () {
-      callbackOnPopupShown = null;
-      ok(true, "tooltip isn't shown during drag");
-      dragService.endDragSession(true);
-      EventUtils.synthesizeMouse(target, -5, -5, { type: "mousemove" }, win);
-
-      setTimeout(testShowTooltipAgain, 0);
-    }, 100);
-  }
+  // Show tooltip after mousedown
+  popupShownPromise = BrowserTestUtils.waitForEvent(document, "popupshown");
+  yield BrowserTestUtils.synthesizeMouse("#target", 5, 15, { type: "mousemove" }, browser);
+  yield popupShownPromise;
 
-  let onLoad = function (aEvent)
-  {
-    doc = gBrowser.contentDocument;
-    win = gBrowser.contentWindow;
-    target = doc.getElementById("target");
-
-    document.addEventListener("popupshown", onPopupShown, true);
-    document.addEventListener("popuphidden", onPopupHidden, true);
-
-    EventUtils.synthesizeMouse(target, -5, -5, { type: "mousemove" }, win);
-
-    // show tooltip by mousemove into target.
-    callbackOnPopupShown = function ()
-    {
-      callbackOnPopupShown = null;
-      ok(true, "The tooltip is shown");
+  popupHiddenPromise = BrowserTestUtils.waitForEvent(document, "popuphidden");
+  yield BrowserTestUtils.synthesizeMouse("#target", 5, 15, { type: "mousedown" }, browser);
+  yield popupHiddenPromise;
 
-      // hide tooltip by mousemove to outside.
-      callbackOnPopupHidden = function () {
-        callbackOnPopupHidden = null;
-        ok(true, "The tooltip is hidden");
-
-        setTimeout(testDuringDnD, 0);
-      }
-      EventUtils.synthesizeMouse(target, -5, 15, { type: "mousemove" }, win);
-    }
-    EventUtils.synthesizeMouse(target, 5, 15, { type: "mousemove" }, win);
-  }
+  yield BrowserTestUtils.synthesizeMouse("#target", 5, 15, { type: "mouseup" }, browser);
+  yield BrowserTestUtils.synthesizeMouse("#target", -5, 15, { type: "mousemove" }, browser);
 
-  gBrowser.selectedBrowser.addEventListener("load",
-    function () {
-      gBrowser.selectedBrowser.
-        removeEventListener("load", arguments.callee, true);
-      setTimeout(onLoad, 0);
-   }, true);
+  ok(true, "tooltips appear properly");
 
-  content.location = "data:text/html,<html><head></head><body>" +
-    "<a id=\"target\" href=\"about:blank\" title=\"This is tooltip text\" " +
-       "style=\"display:block;height:20px;margin:10px;\" " +
-       "onclick=\"return false;\">here is an anchor element</a></body></html>";
-}
+  gBrowser.removeCurrentTab();
+});
 
 
 
+