Bug 1266450 - part3: fix helper to check if click occurred in tooltip;r=bgrins draft
authorJulian Descottes <jdescottes@mozilla.com>
Fri, 03 Jun 2016 12:50:39 +0200
changeset 376619 32c9f5c6462180168a0ffeb26f047ed516ba6932
parent 376618 4470f401840d3aea01eb7c120c989e3553d24f99
child 376620 7d36b3b733b965a1875fc3e7670e587fc038095f
push id20630
push userjdescottes@mozilla.com
push dateWed, 08 Jun 2016 11:49:53 +0000
reviewersbgrins
bugs1266450
milestone50.0a1
Bug 1266450 - part3: fix helper to check if click occurred in tooltip;r=bgrins The existing helper checking if a click occurred inside or outside a HTMLTooltip container was failing if the click occurred in an iframe. MozReview-Commit-ID: 9AIACOukYUF
devtools/client/shared/test/browser_html_tooltip-02.js
devtools/client/shared/widgets/HTMLTooltip.js
--- a/devtools/client/shared/test/browser_html_tooltip-02.js
+++ b/devtools/client/shared/test/browser_html_tooltip-02.js
@@ -7,36 +7,40 @@
 /**
  * Test the HTMLTooltip is closed when clicking outside of its container.
  */
 
 const HTML_NS = "http://www.w3.org/1999/xhtml";
 const TEST_URI = `data:text/xml;charset=UTF-8,<?xml version="1.0"?>
   <?xml-stylesheet href="chrome://global/skin/global.css"?>
   <?xml-stylesheet href="chrome://devtools/skin/tooltips.css"?>
-  <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-   title="Tooltip test">
+  <window
+    xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+    htmlns="http://www.w3.org/1999/xhtml"
+    title="Tooltip test">
     <vbox flex="1">
       <hbox id="box1" flex="1">test1</hbox>
       <hbox id="box2" flex="1">test2</hbox>
       <hbox id="box3" flex="1">test3</hbox>
       <hbox id="box4" flex="1">test4</hbox>
+      <iframe id="frame" width="200"></iframe>
     </vbox>
   </window>`;
 
 const {HTMLTooltip} = require("devtools/client/shared/widgets/HTMLTooltip");
 loadHelperScript("helper_html_tooltip.js");
 
 add_task(function* () {
   yield addTab("about:blank");
   let [,, doc] = yield createHost("bottom", TEST_URI);
 
   yield testTooltipNotClosingOnInsideClick(doc);
   yield testConsumeOutsideClicksFalse(doc);
   yield testConsumeOutsideClicksTrue(doc);
+  yield testClickInsideIframe(doc);
 });
 
 function* testTooltipNotClosingOnInsideClick(doc) {
   info("Test a tooltip is not closed when clicking inside itself");
 
   let tooltip = new HTMLTooltip({doc}, {});
   yield tooltip.setContent(getTooltipContent(doc), 100, 50);
   yield showTooltip(tooltip, doc.getElementById("box1"));
@@ -85,15 +89,31 @@ function* testConsumeOutsideClicksTrue(d
   yield onHidden;
 
   is(box4clicks, 0, "box4 catched no click event");
   is(tooltip.isVisible(), false, "Tooltip is hidden");
 
   tooltip.destroy();
 }
 
+function* testClickInsideIframe(doc) {
+  info("Test closing a tooltip via click inside an iframe");
+  let frame = doc.getElementById("frame");
+
+  let tooltip = new HTMLTooltip({doc});
+  yield tooltip.setContent(getTooltipContent(doc), 100, 50);
+  yield showTooltip(tooltip, doc.getElementById("box1"));
+
+  let onHidden = once(tooltip, "hidden");
+  EventUtils.synthesizeMouseAtCenter(frame, {}, doc.defaultView);
+  yield onHidden;
+
+  is(tooltip.isVisible(), false, "Tooltip is hidden");
+  tooltip.destroy();
+}
+
 function getTooltipContent(doc) {
   let div = doc.createElementNS(HTML_NS, "div");
   div.style.height = "50px";
   div.style.boxSizing = "border-box";
   div.textContent = "tooltip";
   return div;
 }
--- a/devtools/client/shared/widgets/HTMLTooltip.js
+++ b/devtools/client/shared/widgets/HTMLTooltip.js
@@ -224,32 +224,37 @@ HTMLTooltip.prototype = {
     this.hide();
     if (this.consumeOutsideClicks) {
       e.preventDefault();
       e.stopPropagation();
     }
   },
 
   _isInTooltipContainer: function (node) {
-    let contentWindow = this.panel.ownerDocument.defaultView;
+    let tooltipWindow = this.panel.ownerDocument.defaultView;
     let win = node.ownerDocument.defaultView;
 
-    if (win === contentWindow) {
-      // If node is in the same window as the tooltip, check if the tooltip
-      // parent contains node.
+    if (this.arrow && this.arrow === node) {
+      return true;
+    }
+
+    if (win === tooltipWindow) {
+      // If node is in the same window as the tooltip, check if the tooltip panel
+      // contains node.
       return this.panel.contains(node);
     }
 
-    // Otherwise check if the node window is in the tooltip window.
+    // Otherwise check if the node window is in the tooltip container.
     while (win.parent && win.parent != win) {
       win = win.parent;
-      if (win === contentWindow) {
-        return true;
+      if (win === tooltipWindow) {
+        return this.panel.contains(win.frameElement);
       }
     }
+
     return false;
   },
 
   /**
    * Calculates the best possible position to display the tooltip near the
    * provided anchor. An optional position can be provided, but will be
    * respected only if it doesn't force the tooltip to be resized.
    *