Bug 1287090 - HTMLTooltip: support host changes by retrieving top window dynamically;r=bgrins
MozReview-Commit-ID: 9RcM2h41DdV
--- a/devtools/client/inspector/markup/test/browser.ini
+++ b/devtools/client/inspector/markup/test/browser.ini
@@ -85,16 +85,17 @@ subsuite = clipboard
[browser_markup_events_jquery_1.3.js]
[browser_markup_events_jquery_1.4.js]
[browser_markup_events_jquery_1.6.js]
[browser_markup_events_jquery_1.7.js]
[browser_markup_events_jquery_1.11.1.js]
[browser_markup_events_jquery_2.1.1.js]
[browser_markup_events-overflow.js]
skip-if = true # Bug 1177550
+[browser_markup_events-windowed-host.js]
[browser_markup_links_01.js]
[browser_markup_links_02.js]
[browser_markup_links_03.js]
[browser_markup_links_04.js]
subsuite = clipboard
[browser_markup_links_05.js]
[browser_markup_links_06.js]
[browser_markup_links_07.js]
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/markup/test/browser_markup_events-windowed-host.js
@@ -0,0 +1,61 @@
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+"use strict";
+
+/*
+ * Test that the event details tooltip can be hidden by clicking outside of the tooltip
+ * after switching hosts.
+ */
+
+const TEST_URL = URL_ROOT + "doc_markup_events-overflow.html";
+
+registerCleanupFunction(() => {
+ // Restore the default Toolbox host position after the test.
+ Services.prefs.clearUserPref("devtools.toolbox.host");
+});
+
+add_task(function* () {
+ let { inspector, toolbox } = yield openInspectorForURL(TEST_URL);
+ yield runTests(inspector);
+
+ yield toolbox.switchHost("window");
+ yield runTests(inspector);
+
+ yield toolbox.switchHost("bottom");
+ yield runTests(inspector);
+
+ yield toolbox.destroy();
+});
+
+function* runTests(inspector) {
+ let markupContainer = yield getContainerForSelector("#events", inspector);
+ let evHolder = markupContainer.elt.querySelector(".markupview-events");
+ let tooltip = inspector.markup.eventDetailsTooltip;
+
+ info("Clicking to open event tooltip.");
+
+ let onInspectorUpdated = inspector.once("inspector-updated");
+ let onTooltipShown = tooltip.once("shown");
+ EventUtils.synthesizeMouseAtCenter(evHolder, {}, inspector.markup.doc.defaultView);
+
+ yield onTooltipShown;
+ // New node is selected when clicking on the events bubble, wait for inspector-updated.
+ yield onInspectorUpdated;
+
+ ok(tooltip.isVisible(), "EventTooltip visible.");
+
+ onInspectorUpdated = inspector.once("inspector-updated");
+ let onTooltipHidden = tooltip.once("hidden");
+
+ info("Click on another tag to hide the event tooltip");
+ let h1 = yield getContainerForSelector("h1", inspector);
+ let tag = h1.elt.querySelector(".tag");
+ EventUtils.synthesizeMouseAtCenter(tag, {}, inspector.markup.doc.defaultView);
+
+ yield onTooltipHidden;
+ // New node is selected, wait for inspector-updated.
+ yield onInspectorUpdated;
+
+ ok(!tooltip.isVisible(), "EventTooltip hidden.");
+}
--- a/devtools/client/shared/widgets/HTMLTooltip.js
+++ b/devtools/client/shared/widgets/HTMLTooltip.js
@@ -217,20 +217,21 @@ function HTMLTooltip(toolbox, {
EventEmitter.decorate(this);
this.doc = toolbox.doc;
this.type = type;
this.autofocus = autofocus;
this.consumeOutsideClicks = consumeOutsideClicks;
this.useXulWrapper = this._isXUL() && useXulWrapper;
- this._position = null;
+ // The top window is used to attach click event listeners to close the tooltip if the
+ // user clicks on the content page.
+ this.topWindow = this._getTopWindow();
- // Use the topmost window to listen for click events to close the tooltip
- this.topWindow = this.doc.defaultView.top;
+ this._position = null;
this._onClick = this._onClick.bind(this);
this._toggle = new TooltipToggle(this);
this.startTogglingOnHover = this._toggle.start.bind(this._toggle);
this.stopTogglingOnHover = this._toggle.stop.bind(this._toggle);
this.container = this._createContainer();
@@ -377,16 +378,18 @@ HTMLTooltip.prototype = {
this.container.classList.add("tooltip-visible");
// Keep a pointer on the focused element to refocus it when hiding the tooltip.
this._focusedElement = this.doc.activeElement;
this.doc.defaultView.clearTimeout(this.attachEventsTimer);
this.attachEventsTimer = this.doc.defaultView.setTimeout(() => {
this._maybeFocusTooltip();
+ // Updated the top window reference each time in case the host changes.
+ this.topWindow = this._getTopWindow();
this.topWindow.addEventListener("click", this._onClick, true);
this.emit("shown");
}, 0);
}),
/**
* Calculate the rect of the viewport that limits the tooltip dimensions. When using a
* XUL panel wrapper, the viewport will be able to use the whole screen (excluding space
@@ -545,16 +548,20 @@ HTMLTooltip.prototype = {
// http://stackoverflow.com/questions/1599660/which-html-elements-can-receive-focus .
let focusableSelector = "a, button, iframe, input, select, textarea";
let focusableElement = this.panel.querySelector(focusableSelector);
if (this.autofocus && focusableElement) {
focusableElement.focus();
}
},
+ _getTopWindow: function () {
+ return this.doc.defaultView.top;
+ },
+
/**
* Check if the tooltip's owner document is a XUL document.
*/
_isXUL: function () {
return this.doc.documentElement.namespaceURI === XUL_NS;
},
_createXulPanelWrapper: function () {