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
--- 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.
*