--- a/devtools/client/inspector/markup/markup.js
+++ b/devtools/client/inspector/markup/markup.js
@@ -91,16 +91,17 @@ function MarkupView(inspector, frame, co
this._containers = new Map();
// This weakmap will hold keys used with the _containers map, in order to retrieve the
// slotted container for a given node front.
this._slottedContainerKeys = new WeakMap();
// Binding functions that need to be called in scope.
this._handleRejectionIfNotDestroyed = this._handleRejectionIfNotDestroyed.bind(this);
this._isImagePreviewTarget = this._isImagePreviewTarget.bind(this);
+ this._setImagePreview = this._setImagePreview.bind(this);
this._mutationObserver = this._mutationObserver.bind(this);
this._onBlur = this._onBlur.bind(this);
this._onCopy = this._onCopy.bind(this);
this._onCollapseAttributesPrefChange = this._onCollapseAttributesPrefChange.bind(this);
this._onDisplayChange = this._onDisplayChange.bind(this);
this._onFocus = this._onFocus.bind(this);
this._onMouseClick = this._onMouseClick.bind(this);
this._onMouseMove = this._onMouseMove.bind(this);
@@ -168,17 +169,18 @@ MarkupView.prototype = {
type: "arrow",
useXulWrapper: true,
});
this._enableImagePreviewTooltip();
},
_enableImagePreviewTooltip: function() {
this.imagePreviewTooltip.startTogglingOnHover(this._elt,
- this._isImagePreviewTarget);
+ this._isImagePreviewTarget, {},
+ this._setImagePreview);
},
_disableImagePreviewTooltip: function() {
this.imagePreviewTooltip.stopTogglingOnHover();
},
_onToolboxPickerHover: function(nodeFront) {
this.showNode(nodeFront).then(() => {
@@ -561,16 +563,28 @@ MarkupView.prototype = {
break;
}
}
// Recursively update each node starting with documentElement.
updateChildren(documentElement);
},
+ _getContainerFromTarget(target) {
+ let parent = target, container;
+ while (parent) {
+ if (parent.container) {
+ container = parent.container;
+ break;
+ }
+ parent = parent.parentNode;
+ }
+ return container;
+ },
+
/**
* Executed when the mouse hovers over a target in the markup-view and is used
* to decide whether this target should be used to display an image preview
* tooltip.
* Delegates the actual decision to the corresponding MarkupContainer instance
* if one is found.
*
* @return {Promise} the promise returned by
@@ -578,32 +592,32 @@ MarkupView.prototype = {
*/
async _isImagePreviewTarget(target) {
// From the target passed here, let's find the parent MarkupContainer
// and ask it if the tooltip should be shown
if (this.isDragging) {
return false;
}
- let parent = target, container;
- while (parent) {
- if (parent.container) {
- container = parent.container;
- break;
- }
- parent = parent.parentNode;
- }
-
+ let container = this._getContainerFromTarget(target);
if (container instanceof MarkupElementContainer) {
return container.isImagePreviewTarget(target, this.imagePreviewTooltip);
}
return false;
},
+ async _setImagePreview(target, tooltip) {
+ let container = this._getContainerFromTarget(target);
+ if (!(container instanceof MarkupElementContainer)) {
+ return;
+ }
+ await container.showImagePreview(target, this.imagePreviewTooltip);
+ },
+
/**
* Given the known reason, should the current selection be briefly highlighted
* In a few cases, we don't want to highlight the node:
* - If the reason is null (used to reset the selection),
* - if it's "inspector-open" (when the inspector opens up, let's not
* highlight the default node)
* - if it's "navigateaway" (since the page is being navigated away from)
* - if it's "test" (this is a special case for mochitest. In tests, we often
--- a/devtools/client/inspector/markup/views/element-container.js
+++ b/devtools/client/inspector/markup/views/element-container.js
@@ -5,17 +5,17 @@
"use strict";
const PREVIEW_MAX_DIM_PREF = "devtools.inspector.imagePreviewTooltipSize";
const promise = require("promise");
const Services = require("Services");
const nodeConstants = require("devtools/shared/dom-node-constants");
const clipboardHelper = require("devtools/shared/platform/clipboard");
-const {setImageTooltip, setBrokenImageTooltip} =
+const {setImageTooltip, getImageTooltip, setBrokenImageTooltip, getBrokenImageTooltip} =
require("devtools/client/shared/widgets/tooltip/ImageTooltipHelper");
const MarkupContainer = require("devtools/client/inspector/markup/views/markup-container");
const ElementEditor = require("devtools/client/inspector/markup/views/element-editor");
const {extend} = require("devtools/shared/extend");
// Lazy load this module as _buildEventTooltipContent is only called on click
loader.lazyRequireGetter(this, "setEventTooltip",
"devtools/client/shared/widgets/tooltip/EventTooltipHelper", true);
@@ -102,17 +102,18 @@ MarkupElementContainer.prototype = exten
async _buildEventTooltipContent(target) {
const tooltip = this.markup.eventDetailsTooltip;
await tooltip.hide();
const listenerInfo = await this.node.getEventListenerInfo();
const toolbox = this.markup.toolbox;
- setEventTooltip(tooltip, listenerInfo, toolbox);
+ const { content, option: { width, height } } =
+ setEventTooltip(tooltip, listenerInfo, toolbox);
// Disable the image preview tooltip while we display the event details
this.markup._disableImagePreviewTooltip();
tooltip.once("hidden", () => {
// Enable the image preview tooltip after closing the event details
this.markup._enableImagePreviewTooltip();
// Allow clicks on the event badge to display the event popup again
// (but allow the currently queued click event to run first).
@@ -122,17 +123,17 @@ MarkupElementContainer.prototype = exten
}
}, 0);
});
// Prevent clicks on the event badge to display the event popup again.
if (this.editor._eventBadge) {
this.editor._eventBadge.style.pointerEvents = "none";
}
- tooltip.show(target);
+ tooltip.show(target, { width, height }, content);
},
/**
* Generates the an image preview for this Element. The element must be an
* image or canvas (@see isPreviewable).
*
* @return {Promise} that is resolved with an object of form
* { data, size: { naturalWidth, naturalHeight, resizeRatio } } where
@@ -164,17 +165,17 @@ MarkupElementContainer.prototype = exten
this.tooltipDataPromise = null;
return { data, size: preview.size };
}.bind(this))();
return this.tooltipDataPromise;
},
/**
- * Executed by MarkupView._isImagePreviewTarget which is itself called when
+ * Executed by MarkupView._isImagePrevieTwarget which is itself called when
* the mouse hovers over a target in the markup-view.
* Checks if the target is indeed something we want to have an image tooltip
* preview over and, if so, inserts content into the tooltip.
*
* @return {Promise} that resolves when the tooltip content is ready. Resolves
* true if the tooltip should be displayed, false otherwise.
*/
async isImagePreviewTarget(target, tooltip) {
@@ -187,31 +188,39 @@ MarkupElementContainer.prototype = exten
// over the src url. If not, the tooltip is shown when hovering over the tag
// name.
const src = this.editor.getAttributeElement("src");
const expectedTarget = src ? src.querySelector(".link") : this.editor.tag;
if (target !== expectedTarget) {
return false;
}
+ return true;
+ },
+
+ async showImagePreview(target, tooltip) {
+ let tooltipContent, tooltipOption;
try {
const { data, size } = await this._getPreview();
// The preview is ready.
const options = {
naturalWidth: size.naturalWidth,
naturalHeight: size.naturalHeight,
maxDim: Services.prefs.getIntPref(PREVIEW_MAX_DIM_PREF)
};
- setImageTooltip(tooltip, this.markup.doc, data, options);
+ let { content: tooltipContent, option: tooltipOption } =
+ getImageTooltip(tooltip, this.markup.doc, data, options);
+ tooltip.show(target, tooltipOption, tooltipContent);
} catch (e) {
// Indicate the failure but show the tooltip anyway.
- setBrokenImageTooltip(tooltip, this.markup.doc);
+ let { content: tooltipContent, option: tooltipOption } =
+ getBrokenImageTooltip(tooltip, this.markup.doc);
+ tooltip.show(target, tooltipOption, tooltipContent);
}
- return true;
},
copyImageDataUri: function() {
// We need to send again a request to gettooltipData even if one was sent
// for the tooltip, because we want the full-size image
this.node.getImageData().then(data => {
data.data.string().then(str => {
clipboardHelper.copyString(str);
--- a/devtools/client/inspector/shared/test/browser_styleinspector_tooltip-closes-on-new-selection.js
+++ b/devtools/client/inspector/shared/test/browser_styleinspector_tooltip-closes-on-new-selection.js
@@ -22,26 +22,27 @@ add_task(async function() {
await testComputedView(view, inspector);
});
async function testRuleView(ruleView, inspector) {
info("Showing the tooltip");
const tooltip = ruleView.tooltips.getTooltip("previewTooltip");
const tooltipContent = ruleView.styleDocument.createElementNS(XHTML_NS, "div");
- await tooltip.setContent(tooltipContent, {width: 100, height: 30});
// Stop listening for mouse movements because it's not needed for this test,
// and causes intermittent failures on Linux. When this test runs in the suite
// sometimes a mouseleave event is dispatched at the start, which causes the
// tooltip to hide in the middle of being shown, which causes timeouts later.
tooltip.stopTogglingOnHover();
const onShown = tooltip.once("shown");
- tooltip.show(ruleView.styleDocument.firstElementChild);
+ tooltip.show(ruleView.styleDocument.firstElementChild,
+ {width: 100, height: 30},
+ tooltipContent);
await onShown;
info("Selecting a new node");
const onHidden = tooltip.once("hidden");
await selectNode(".two", inspector);
await onHidden;
ok(true, "Rule view tooltip closed after a new node got selected");
--- a/devtools/client/inspector/shared/three-pane-onboarding-tooltip.js
+++ b/devtools/client/inspector/shared/three-pane-onboarding-tooltip.js
@@ -63,20 +63,20 @@ class ThreePaneOnboardingTooltip {
this.closeButton = doc.createElementNS(XHTML_NS, "button");
this.closeButton.className = "onboarding-close-button devtools-button";
container.appendChild(this.closeButton);
this.closeButton.addEventListener("click", this.onCloseButtonClick);
this.learnMoreLink.addEventListener("click", this.onLearnMoreLinkClick);
- this.tooltip.setContent(container, { width: CONTAINER_WIDTH });
this.tooltip.show(this.doc.querySelector("#inspector-sidebar .sidebar-toggle"), {
position: "top",
- });
+ width: CONTAINER_WIDTH,
+ }, container);
}
destroy() {
this.closeButton.removeEventListener("click", this.onCloseButtonClick);
this.learnMoreLink.removeEventListener("click", this.onLearnMoreLinkClick);
this.tooltip.destroy();
--- a/devtools/client/responsive.html/setting-onboarding-tooltip.js
+++ b/devtools/client/responsive.html/setting-onboarding-tooltip.js
@@ -37,20 +37,21 @@ class SettingOnboardingTooltip {
container.appendChild(content);
this.closeButton = doc.createElement("button");
this.closeButton.className = "onboarding-close-button devtools-button";
container.appendChild(this.closeButton);
this.closeButton.addEventListener("click", this.onCloseButtonClick);
- this.tooltip.setContent(container, { width: CONTAINER_WIDTH });
+// this.tooltip.setContent(container, { width: CONTAINER_WIDTH });
this.tooltip.show(this.doc.getElementById("settings-button"), {
position: "bottom",
- });
+ width: CONTAINER_WIDTH,
+ }, container);
}
destroy() {
this.closeButton.removeEventListener("click", this.onCloseButtonClick);
this.tooltip.destroy();
this.closeButton = null;
--- a/devtools/client/shadereditor/shadereditor.js
+++ b/devtools/client/shadereditor/shadereditor.js
@@ -580,28 +580,40 @@ class ShadersEditorsView {
return;
}
const tooltip = node._markerErrorsTooltip = new HTMLTooltip(document, {
type: "arrow",
useXulWrapper: true
});
+ /*
const div = document.createElementNS(XHTML_NS, "div");
div.className = "devtools-shader-tooltip-container";
for (const message of messages) {
const messageDiv = document.createElementNS(XHTML_NS, "div");
messageDiv.className = "devtools-tooltip-simple-text";
messageDiv.textContent = message;
div.appendChild(messageDiv);
}
tooltip.setContent(div);
+ */
tooltip.startTogglingOnHover(node, () => true, {
toggleDelay: GUTTER_ERROR_PANEL_DELAY
+ }, (target, tooltip) => {
+ const div = document.createElementNS(XHTML_NS, "div");
+ div.className = "devtools-shader-tooltip-container";
+ for (const message of messages) {
+ const messageDiv = document.createElementNS(XHTML_NS, "div");
+ messageDiv.className = "devtools-tooltip-simple-text";
+ messageDiv.textContent = message;
+ div.appendChild(messageDiv);
+ }
+ tooltip.show(target, {}, div);
});
}
/**
* Removes all the gutter markers and line classes from the editor.
*/
_cleanEditor(type) {
this._getEditor(type).then(editor => {
--- a/devtools/client/shared/autocomplete-popup.js
+++ b/devtools/client/shared/autocomplete-popup.js
@@ -67,17 +67,17 @@ function AutocompletePopup(toolboxDoc, o
.getPropertyValue(paddingPropertyName)
.replace("px", "");
this._listPadding = 0;
if (!Number.isNaN(Number(listPadding))) {
this._listPadding = Number(listPadding);
}
- this._tooltip.setContent(this._list, { height: Infinity });
+// this._tooltip.setContent(this._list, { height: Infinity });
this.onClick = this.onClick.bind(this);
this._list.addEventListener("click", this.onClick);
// Array of raw autocomplete items
this.items = [];
// Map of autocompleteItem to HTMLElement
this.elements = new WeakMap();
@@ -130,17 +130,18 @@ AutocompletePopup.prototype = {
// We want the autocomplete items to be perflectly lined-up with the string the
// user entered, so we need to remove the left-padding and the left-border from
// the xOffset.
const leftBorderSize = 1;
this._tooltip.show(anchor, {
x: xOffset - this._listPadding - leftBorderSize,
y: yOffset,
position: this.position,
- });
+ height: Infinity,
+ }, this._list);
this._tooltip.once("shown", () => {
if (this.autoSelect) {
this.selectItemAtIndex(index, options);
}
this.emit("popup-opened");
});
--- a/devtools/client/shared/test/browser_html_tooltip-01.js
+++ b/devtools/client/shared/test/browser_html_tooltip-01.js
@@ -36,27 +36,28 @@ add_task(async function() {
await runTests(doc);
});
async function runTests(doc) {
await addTab("about:blank");
const tooltip = new HTMLTooltip(doc, {useXulWrapper});
info("Set tooltip content");
- tooltip.setContent(getTooltipContent(doc), {width: 100, height: 50});
is(tooltip.isVisible(), false, "Tooltip is not visible");
info("Show the tooltip and check the expected events are fired.");
let shown = 0;
tooltip.on("shown", () => shown++);
const onShown = tooltip.once("shown");
- tooltip.show(doc.getElementById("box1"));
+ tooltip.show(doc.getElementById("box1"),
+ {width: 100, height: 50},
+ getTooltipContent(doc));
await onShown;
is(shown, 1, "Event shown was fired once");
await waitForReflow(tooltip);
is(tooltip.isVisible(), true, "Tooltip is visible");
info("Hide the tooltip and check the expected events are fired.");
--- a/devtools/client/shared/test/browser_html_tooltip-02.js
+++ b/devtools/client/shared/test/browser_html_tooltip-02.js
@@ -36,34 +36,38 @@ async function runTests(doc) {
await testClickInOuterIframe(doc);
await testClickInInnerIframe(doc);
}
async function testClickInTooltipContent(doc) {
info("Test a tooltip is not closed when clicking inside itself");
const tooltip = new HTMLTooltip(doc, {useXulWrapper});
- tooltip.setContent(getTooltipContent(doc), {width: 100, height: 50});
- await showTooltip(tooltip, doc.getElementById("box1"));
+ await showTooltip(tooltip,
+ doc.getElementById("box1"),
+ {width: 100, height: 50},
+ getTooltipContent(doc));
const onTooltipContainerClick = once(tooltip.container, "click");
EventUtils.synthesizeMouseAtCenter(tooltip.container, {}, doc.defaultView);
await onTooltipContainerClick;
is(tooltip.isVisible(), true, "Tooltip is still visible");
tooltip.destroy();
}
async function testConsumeOutsideClicksFalse(doc) {
info("Test closing a tooltip via click with consumeOutsideClicks: false");
const box4 = doc.getElementById("box4");
const tooltip = new HTMLTooltip(doc, {consumeOutsideClicks: false, useXulWrapper});
- tooltip.setContent(getTooltipContent(doc), {width: 100, height: 50});
- await showTooltip(tooltip, doc.getElementById("box1"));
+ await showTooltip(tooltip,
+ doc.getElementById("box1"),
+ {width: 100, height: 50},
+ getTooltipContent(doc));
const onBox4Clicked = once(box4, "click");
const onHidden = once(tooltip, "hidden");
EventUtils.synthesizeMouseAtCenter(box4, {}, doc.defaultView);
await onHidden;
await onBox4Clicked;
is(tooltip.isVisible(), false, "Tooltip is hidden");
@@ -75,36 +79,40 @@ async function testConsumeOutsideClicksT
info("Test closing a tooltip via click with consumeOutsideClicks: true");
const box4 = doc.getElementById("box4");
// Count clicks on box4
let box4clicks = 0;
box4.addEventListener("click", () => box4clicks++);
const tooltip = new HTMLTooltip(doc, {consumeOutsideClicks: true, useXulWrapper});
- tooltip.setContent(getTooltipContent(doc), {width: 100, height: 50});
- await showTooltip(tooltip, doc.getElementById("box1"));
+ await showTooltip(tooltip,
+ doc.getElementById("box1"),
+ {width: 100, height: 50},
+ getTooltipContent(doc));
const onHidden = once(tooltip, "hidden");
EventUtils.synthesizeMouseAtCenter(box4, {}, doc.defaultView);
await onHidden;
is(box4clicks, 0, "box4 catched no click event");
is(tooltip.isVisible(), false, "Tooltip is hidden");
tooltip.destroy();
}
async function testConsumeWithRightClick(doc) {
info("Test closing a tooltip with a right-click, with consumeOutsideClicks: true");
const box4 = doc.getElementById("box4");
const tooltip = new HTMLTooltip(doc, {consumeOutsideClicks: true, useXulWrapper});
- tooltip.setContent(getTooltipContent(doc), {width: 100, height: 50});
- await showTooltip(tooltip, doc.getElementById("box1"));
+ await showTooltip(tooltip,
+ doc.getElementById("box1"),
+ {width: 100, height: 50},
+ getTooltipContent(doc));
// Only left-click events should be consumed, so we expect to catch a click when using
// {button: 2}, which simulates a right-click.
info("Right click on box4, expect tooltip to be hidden, event should not be consumed");
const onBox4Clicked = once(box4, "click");
const onHidden = once(tooltip, "hidden");
EventUtils.synthesizeMouseAtCenter(box4, {button: 2}, doc.defaultView);
await onHidden;
@@ -115,18 +123,20 @@ async function testConsumeWithRightClick
tooltip.destroy();
}
async function testClickInOuterIframe(doc) {
info("Test clicking an iframe outside of the tooltip closes the tooltip");
const frame = doc.getElementById("frame");
const tooltip = new HTMLTooltip(doc, {useXulWrapper});
- tooltip.setContent(getTooltipContent(doc), {width: 100, height: 50});
- await showTooltip(tooltip, doc.getElementById("box1"));
+ await showTooltip(tooltip,
+ doc.getElementById("box1"),
+ {width: 100, height: 50},
+ getTooltipContent(doc));
const onHidden = once(tooltip, "hidden");
EventUtils.synthesizeMouseAtCenter(frame, {}, doc.defaultView);
await onHidden;
is(tooltip.isVisible(), false, "Tooltip is hidden");
tooltip.destroy();
}
@@ -134,18 +144,20 @@ async function testClickInOuterIframe(do
async function testClickInInnerIframe(doc) {
info("Test clicking an iframe inside the tooltip content does not close the tooltip");
const tooltip = new HTMLTooltip(doc, {consumeOutsideClicks: false, useXulWrapper});
const iframe = doc.createElementNS(HTML_NS, "iframe");
iframe.style.width = "100px";
iframe.style.height = "50px";
- tooltip.setContent(iframe, {width: 100, height: 50});
- await showTooltip(tooltip, doc.getElementById("box1"));
+ await showTooltip(tooltip,
+ doc.getElementById("box1"),
+ {width: 100, height: 50},
+ iframe);
const onTooltipContainerClick = once(tooltip.container, "click");
EventUtils.synthesizeMouseAtCenter(tooltip.container, {}, doc.defaultView);
await onTooltipContainerClick;
is(tooltip.isVisible(), true, "Tooltip is still visible");
tooltip.destroy();
--- a/devtools/client/shared/test/browser_html_tooltip-03.js
+++ b/devtools/client/shared/test/browser_html_tooltip-03.js
@@ -29,19 +29,22 @@ add_task(async function() {
await runTests(doc);
});
async function runTests(doc) {
await focusNode(doc, "#box4-input");
ok(doc.activeElement.closest("#box4-input"), "Focus is in the #box4-input");
info("Test a tooltip will not take focus");
- const tooltip = await createTooltip(doc);
+ const { tooltip, content } = await createTooltip(doc);
- await showTooltip(tooltip, doc.getElementById("box1"));
+ await showTooltip(tooltip,
+ doc.getElementById("box1"),
+ { width: 150, height: 50 },
+ content);
ok(doc.activeElement.closest("#box4-input"), "Focus is still in the #box4-input");
await hideTooltip(tooltip);
await blurNode(doc, "#box4-input");
tooltip.destroy();
}
@@ -81,10 +84,10 @@ function createTooltip(doc) {
div.classList.add("tooltip-content");
div.style.height = "50px";
const input = doc.createElementNS(HTML_NS, "input");
input.setAttribute("type", "text");
div.appendChild(input);
tooltip.setContent(div, {width: 150, height: 50});
- return tooltip;
+ return { tooltip, content: div };
}
--- a/devtools/client/shared/test/browser_html_tooltip-04.js
+++ b/devtools/client/shared/test/browser_html_tooltip-04.js
@@ -24,73 +24,84 @@ add_task(async function() {
await addTab("about:blank");
const [,, doc] = await createHost("bottom", TEST_URI);
info("Create HTML tooltip");
const tooltip = new HTMLTooltip(doc, {useXulWrapper: false});
const div = doc.createElementNS(HTML_NS, "div");
div.style.height = "100%";
- tooltip.setContent(div, {width: TOOLTIP_WIDTH, height: TOOLTIP_HEIGHT});
const box1 = doc.getElementById("box1");
const box2 = doc.getElementById("box2");
const box3 = doc.getElementById("box3");
const box4 = doc.getElementById("box4");
const height = TOOLTIP_HEIGHT, width = TOOLTIP_WIDTH;
// box1: Can only fit below box1
info("Display the tooltip on box1.");
- await showTooltip(tooltip, box1);
+ await showTooltip(tooltip, box1, {width: TOOLTIP_WIDTH, height: TOOLTIP_HEIGHT}, div);
let expectedTooltipGeometry = {position: "bottom", height, width};
checkTooltipGeometry(tooltip, box1, expectedTooltipGeometry);
await hideTooltip(tooltip);
info("Try to display the tooltip on top of box1.");
- await showTooltip(tooltip, box1, {position: "top"});
+ await showTooltip(tooltip,
+ box1,
+ {position: "top", width: TOOLTIP_WIDTH, height: TOOLTIP_HEIGHT},
+ div);
expectedTooltipGeometry = {position: "bottom", height, width};
checkTooltipGeometry(tooltip, box1, expectedTooltipGeometry);
await hideTooltip(tooltip);
// box2: Can fit above or below, will default to bottom, more height
// available.
info("Try to display the tooltip on box2.");
- await showTooltip(tooltip, box2);
+ await showTooltip(tooltip, box2, {width: TOOLTIP_WIDTH, height: TOOLTIP_HEIGHT}, div);
expectedTooltipGeometry = {position: "bottom", height, width};
checkTooltipGeometry(tooltip, box2, expectedTooltipGeometry);
await hideTooltip(tooltip);
info("Try to display the tooltip on top of box2.");
- await showTooltip(tooltip, box2, {position: "top"});
+ await showTooltip(tooltip,
+ box2,
+ {position: "top", width: TOOLTIP_WIDTH, height: TOOLTIP_HEIGHT},
+ div);
expectedTooltipGeometry = {position: "top", height, width};
checkTooltipGeometry(tooltip, box2, expectedTooltipGeometry);
await hideTooltip(tooltip);
// box3: Can fit above or below, will default to top, more height available.
info("Try to display the tooltip on box3.");
- await showTooltip(tooltip, box3);
+ await showTooltip(tooltip, box3, {width: TOOLTIP_WIDTH, height: TOOLTIP_HEIGHT}, div);
expectedTooltipGeometry = {position: "top", height, width};
checkTooltipGeometry(tooltip, box3, expectedTooltipGeometry);
await hideTooltip(tooltip);
info("Try to display the tooltip on bottom of box3.");
- await showTooltip(tooltip, box3, {position: "bottom"});
+ await showTooltip(tooltip,
+ box3,
+ {position: "bottom", width: TOOLTIP_WIDTH, height: TOOLTIP_HEIGHT},
+ div);
expectedTooltipGeometry = {position: "bottom", height, width};
checkTooltipGeometry(tooltip, box3, expectedTooltipGeometry);
await hideTooltip(tooltip);
// box4: Can only fit above box4
info("Display the tooltip on box4.");
- await showTooltip(tooltip, box4);
+ await showTooltip(tooltip, box4, {width: TOOLTIP_WIDTH, height: TOOLTIP_HEIGHT}, div);
expectedTooltipGeometry = {position: "top", height, width};
checkTooltipGeometry(tooltip, box4, expectedTooltipGeometry);
await hideTooltip(tooltip);
info("Try to display the tooltip on bottom of box4.");
- await showTooltip(tooltip, box4, {position: "bottom"});
+ await showTooltip(tooltip,
+ box4,
+ {position: "bottom", width: TOOLTIP_WIDTH, height: TOOLTIP_HEIGHT},
+ div);
expectedTooltipGeometry = {position: "top", height, width};
checkTooltipGeometry(tooltip, box4, expectedTooltipGeometry);
await hideTooltip(tooltip);
is(tooltip.isVisible(), false, "Tooltip is not visible");
tooltip.destroy();
});
--- a/devtools/client/shared/test/browser_html_tooltip-05.js
+++ b/devtools/client/shared/test/browser_html_tooltip-05.js
@@ -23,76 +23,87 @@ add_task(async function() {
await pushPref("devtools.toolbox.footer.height", 200);
await addTab("about:blank");
const [,, doc] = await createHost("bottom", TEST_URI);
info("Create HTML tooltip");
const tooltip = new HTMLTooltip(doc, {useXulWrapper: false});
const div = doc.createElementNS(HTML_NS, "div");
div.style.height = "100%";
- tooltip.setContent(div, {width: TOOLTIP_WIDTH, height: TOOLTIP_HEIGHT});
const box1 = doc.getElementById("box1");
const box2 = doc.getElementById("box2");
const box3 = doc.getElementById("box3");
const box4 = doc.getElementById("box4");
const width = TOOLTIP_WIDTH;
// box1: Can not fit above or below box1, default to bottom with a reduced
// height of 150px.
info("Display the tooltip on box1.");
- await showTooltip(tooltip, box1);
+ await showTooltip(tooltip, box1, {width: TOOLTIP_WIDTH, height: TOOLTIP_HEIGHT}, div);
let expectedTooltipGeometry = {position: "bottom", height: 150, width};
checkTooltipGeometry(tooltip, box1, expectedTooltipGeometry);
await hideTooltip(tooltip);
info("Try to display the tooltip on top of box1.");
- await showTooltip(tooltip, box1, {position: "top"});
+ await showTooltip(tooltip,
+ box1,
+ {position: "top", width: TOOLTIP_WIDTH, height: TOOLTIP_HEIGHT},
+ div);
expectedTooltipGeometry = {position: "bottom", height: 150, width};
checkTooltipGeometry(tooltip, box1, expectedTooltipGeometry);
await hideTooltip(tooltip);
// box2: Can not fit above or below box2, default to bottom with a reduced
// height of 100px.
info("Try to display the tooltip on box2.");
- await showTooltip(tooltip, box2);
+ await showTooltip(tooltip, box2, {width: TOOLTIP_WIDTH, height: TOOLTIP_HEIGHT}, div);
expectedTooltipGeometry = {position: "bottom", height: 100, width};
checkTooltipGeometry(tooltip, box2, expectedTooltipGeometry);
await hideTooltip(tooltip);
info("Try to display the tooltip on top of box2.");
- await showTooltip(tooltip, box2, {position: "top"});
+ await showTooltip(tooltip,
+ box2,
+ {position: "top", width: TOOLTIP_WIDTH, height: TOOLTIP_HEIGHT},
+ div);
expectedTooltipGeometry = {position: "bottom", height: 100, width};
checkTooltipGeometry(tooltip, box2, expectedTooltipGeometry);
await hideTooltip(tooltip);
// box3: Can not fit above or below box3, default to top with a reduced height
// of 100px.
info("Try to display the tooltip on box3.");
- await showTooltip(tooltip, box3);
+ await showTooltip(tooltip, box3, {width: TOOLTIP_WIDTH, height: TOOLTIP_HEIGHT}, div);
expectedTooltipGeometry = {position: "top", height: 100, width};
checkTooltipGeometry(tooltip, box3, expectedTooltipGeometry);
await hideTooltip(tooltip);
info("Try to display the tooltip on bottom of box3.");
- await showTooltip(tooltip, box3, {position: "bottom"});
+ await showTooltip(tooltip,
+ box3,
+ {position: "bottom", width: TOOLTIP_WIDTH, height: TOOLTIP_HEIGHT},
+ div);
expectedTooltipGeometry = {position: "top", height: 100, width};
checkTooltipGeometry(tooltip, box3, expectedTooltipGeometry);
await hideTooltip(tooltip);
// box4: Can not fit above or below box4, default to top with a reduced height
// of 150px.
info("Display the tooltip on box4.");
- await showTooltip(tooltip, box4);
+ await showTooltip(tooltip, box4, {width: TOOLTIP_WIDTH, height: TOOLTIP_HEIGHT}, div);
expectedTooltipGeometry = {position: "top", height: 150, width};
checkTooltipGeometry(tooltip, box4, expectedTooltipGeometry);
await hideTooltip(tooltip);
info("Try to display the tooltip on bottom of box4.");
- await showTooltip(tooltip, box4, {position: "bottom"});
+ await showTooltip(tooltip,
+ box4,
+ {position: "bottom", width: TOOLTIP_WIDTH, height: TOOLTIP_HEIGHT},
+ div);
expectedTooltipGeometry = {position: "top", height: 150, width};
checkTooltipGeometry(tooltip, box4, expectedTooltipGeometry);
await hideTooltip(tooltip);
is(tooltip.isVisible(), false, "Tooltip is not visible");
tooltip.destroy();
});
--- a/devtools/client/shared/test/browser_html_tooltip_arrow-01.js
+++ b/devtools/client/shared/test/browser_html_tooltip_arrow-01.js
@@ -33,24 +33,23 @@ add_task(async function() {
await runTests(doc);
});
async function runTests(doc) {
info("Create HTML tooltip");
const tooltip = new HTMLTooltip(doc, {type: "arrow", useXulWrapper});
const div = doc.createElementNS(HTML_NS, "div");
div.style.height = "35px";
- tooltip.setContent(div, {width: 200, height: 35});
const {right: docRight} = doc.documentElement.getBoundingClientRect();
const elements = [...doc.querySelectorAll(".anchor")];
for (const el of elements) {
info("Display the tooltip on an anchor.");
- await showTooltip(tooltip, el);
+ await showTooltip(tooltip, el, {width: 200, height: 35}, div);
const arrow = tooltip.arrow;
ok(arrow, "Tooltip has an arrow");
// Get the geometry of the anchor, the tooltip panel & arrow.
const arrowBounds = arrow.getBoxQuads({relativeTo: doc})[0].getBounds();
const panelBounds = tooltip.panel.getBoxQuads({relativeTo: doc})[0].getBounds();
const anchorBounds = el.getBoxQuads({relativeTo: doc})[0].getBounds();
--- a/devtools/client/shared/test/browser_html_tooltip_arrow-02.js
+++ b/devtools/client/shared/test/browser_html_tooltip_arrow-02.js
@@ -32,24 +32,23 @@ add_task(async function() {
await runTests(doc);
});
async function runTests(doc) {
info("Create HTML tooltip");
const tooltip = new HTMLTooltip(doc, {type: "arrow", useXulWrapper});
const div = doc.createElementNS(HTML_NS, "div");
div.style.height = "35px";
- tooltip.setContent(div, {width: 200, height: 35});
const {right: docRight} = doc.documentElement.getBoundingClientRect();
const elements = [...doc.querySelectorAll(".anchor")];
for (const el of elements) {
info("Display the tooltip on an anchor.");
- await showTooltip(tooltip, el);
+ await showTooltip(tooltip, el, {width: 200, height: 35}, div);
const arrow = tooltip.arrow;
ok(arrow, "Tooltip has an arrow");
// Get the geometry of the anchor, the tooltip panel & arrow.
const arrowBounds = arrow.getBoxQuads({relativeTo: doc})[0].getBounds();
const panelBounds = tooltip.panel.getBoxQuads({relativeTo: doc})[0].getBounds();
const anchorBounds = el.getBoxQuads({relativeTo: doc})[0].getBounds();
--- a/devtools/client/shared/test/browser_html_tooltip_consecutive-show.js
+++ b/devtools/client/shared/test/browser_html_tooltip_consecutive-show.js
@@ -28,33 +28,32 @@ add_task(async function() {
const box1 = doc.getElementById("box1");
const box2 = doc.getElementById("box2");
const box3 = doc.getElementById("box3");
const box4 = doc.getElementById("box4");
const width = 100, height = 50;
const tooltip = new HTMLTooltip(doc, {useXulWrapper: false});
- tooltip.setContent(getTooltipContent(doc), {width, height});
info("Show the tooltip on each of the 4 hbox, without calling hide in between");
info("Show tooltip on box1");
- tooltip.show(box1);
+ tooltip.show(box1, {width, height}, getTooltipContent(doc));
checkTooltipGeometry(tooltip, box1, {position: "bottom", width, height});
info("Show tooltip on box2");
- tooltip.show(box2);
+ tooltip.show(box2, {width, height}, getTooltipContent(doc));
checkTooltipGeometry(tooltip, box2, {position: "bottom", width, height});
info("Show tooltip on box3");
- tooltip.show(box3);
+ tooltip.show(box3, {width, height}, getTooltipContent(doc));
checkTooltipGeometry(tooltip, box3, {position: "top", width, height});
info("Show tooltip on box4");
- tooltip.show(box4);
+ tooltip.show(box4, {width, height}, getTooltipContent(doc));
checkTooltipGeometry(tooltip, box4, {position: "top", width, height});
info("Hide tooltip before leaving test");
await hideTooltip(tooltip);
tooltip.destroy();
});
--- a/devtools/client/shared/test/browser_html_tooltip_doorhanger-01.js
+++ b/devtools/client/shared/test/browser_html_tooltip_doorhanger-01.js
@@ -35,24 +35,23 @@ add_task(async function() {
});
async function runTests(doc) {
info("Create HTML tooltip");
const tooltip = new HTMLTooltip(doc, {type: "doorhanger", useXulWrapper});
const div = doc.createElementNS(HTML_NS, "div");
div.style.width = "200px";
div.style.height = "35px";
- tooltip.setContent(div);
const docBounds = doc.documentElement.getBoundingClientRect();
const elements = [...doc.querySelectorAll(".anchor")];
for (const el of elements) {
info("Display the tooltip on an anchor.");
- await showTooltip(tooltip, el);
+ await showTooltip(tooltip, el, {}, div);
const arrow = tooltip.arrow;
ok(arrow, "Tooltip has an arrow");
// Get the geometry of the anchor, the tooltip panel & arrow.
const anchorBounds = el.getBoxQuads({ relativeTo: doc })[0].getBounds();
const panelBounds =
tooltip.panel.getBoxQuads({ relativeTo: doc })[0].getBounds();
--- a/devtools/client/shared/test/browser_html_tooltip_doorhanger-02.js
+++ b/devtools/client/shared/test/browser_html_tooltip_doorhanger-02.js
@@ -35,22 +35,21 @@ add_task(async function() {
});
async function runTests(doc) {
info("Create HTML tooltip");
const tooltip = new HTMLTooltip(doc, {type: "doorhanger", useXulWrapper});
const div = doc.createElementNS(HTML_NS, "div");
div.style.width = "200px";
div.style.height = "35px";
- tooltip.setContent(div);
const elements = [...doc.querySelectorAll(".anchor")];
for (const el of elements) {
info("Display the tooltip on an anchor.");
- await showTooltip(tooltip, el);
+ await showTooltip(tooltip, el, {}, div);
const arrow = tooltip.arrow;
ok(arrow, "Tooltip has an arrow");
// Get the geometry of the anchor and arrow.
const anchorBounds = el.getBoxQuads({ relativeTo: doc })[0].getBounds();
const arrowBounds = arrow.getBoxQuads({ relativeTo: doc })[0].getBounds();
--- a/devtools/client/shared/test/browser_html_tooltip_height-auto.js
+++ b/devtools/client/shared/test/browser_html_tooltip_height-auto.js
@@ -34,34 +34,32 @@ add_task(async function() {
async function runTests(doc) {
const tooltip = new HTMLTooltip(doc, {useXulWrapper});
info("Create tooltip content height to 150px");
const tooltipContent = doc.createElementNS(HTML_NS, "div");
tooltipContent.style.cssText =
"width: 300px; height: 150px; background: red;";
info("Set tooltip content using width:auto and height:auto");
- tooltip.setContent(tooltipContent);
info("Show the tooltip and check the tooltip panel dimensions.");
- await showTooltip(tooltip, doc.getElementById("box1"));
+ await showTooltip(tooltip, doc.getElementById("box1"), {}, tooltipContent);
let panelRect = tooltip.panel.getBoundingClientRect();
is(panelRect.width, 300, "Tooltip panel has the expected width.");
is(panelRect.height, 150, "Tooltip panel has the expected width.");
await hideTooltip(tooltip);
info("Set tooltip content using fixed width and height:auto");
tooltipContent.style.cssText =
"width: auto; height: 200px; background: red;";
- tooltip.setContent(tooltipContent, { width: 400 });
info("Show the tooltip and check the tooltip panel height.");
- await showTooltip(tooltip, doc.getElementById("box1"));
+ await showTooltip(tooltip, doc.getElementById("box1"), { width: 400 }, tooltipContent);
panelRect = tooltip.panel.getBoundingClientRect();
is(panelRect.height, 200, "Tooltip panel has the expected width.");
await hideTooltip(tooltip);
tooltip.destroy();
}
--- a/devtools/client/shared/test/browser_html_tooltip_hover.js
+++ b/devtools/client/shared/test/browser_html_tooltip_hover.js
@@ -18,20 +18,24 @@ add_task(async function() {
const [,, doc] = await createHost("bottom", TEST_URI);
// Wait for full page load before synthesizing events on the page.
await waitUntil(() => doc.readyState === "complete");
const width = 100, height = 50;
const tooltipContent = doc.createElementNS(HTML_NS, "div");
tooltipContent.textContent = "tooltip";
const tooltip = new HTMLTooltip(doc, {useXulWrapper: false});
- tooltip.setContent(tooltipContent, {width, height});
const container = doc.getElementById("container");
- tooltip.startTogglingOnHover(container, () => true);
+ tooltip.startTogglingOnHover(container,
+ () => true,
+ {},
+ (target) => {
+ tooltip.show(target, {width, height}, tooltipContent);
+ });
info("Hover on each of the 4 boxes, expect the tooltip to appear");
async function showAndCheck(boxId, position) {
info(`Show tooltip on ${boxId}`);
const box = doc.getElementById(boxId);
const shown = tooltip.once("shown");
EventUtils.synthesizeMouseAtCenter(box, { type: "mousemove" }, doc.defaultView);
await shown;
--- a/devtools/client/shared/test/browser_html_tooltip_offset.js
+++ b/devtools/client/shared/test/browser_html_tooltip_offset.js
@@ -27,55 +27,54 @@ add_task(async function() {
const box4 = doc.getElementById("box4");
const tooltip = new HTMLTooltip(doc, {useXulWrapper: false});
const div = doc.createElementNS(HTML_NS, "div");
div.style.height = "100px";
div.style.boxSizing = "border-box";
div.textContent = "tooltip";
- tooltip.setContent(div, {width: 50, height: 100});
info("Display the tooltip on box1.");
- await showTooltip(tooltip, box1, {x: 5, y: 10});
+ await showTooltip(tooltip, box1, {x: 5, y: 10, width: 50, height: 100}, div);
let panelRect = tooltip.container.getBoundingClientRect();
let anchorRect = box1.getBoundingClientRect();
// Tooltip will be displayed below box1
is(panelRect.top, anchorRect.bottom + 10, "Tooltip top has 10px offset");
is(panelRect.left, anchorRect.left + 5, "Tooltip left has 5px offset");
is(panelRect.height, 100, "Tooltip height is at 100px as expected");
info("Display the tooltip on box2.");
- await showTooltip(tooltip, box2, {x: 5, y: 10});
+ await showTooltip(tooltip, box2, {x: 5, y: 10, width: 50, height: 100}, div);
panelRect = tooltip.container.getBoundingClientRect();
anchorRect = box2.getBoundingClientRect();
// Tooltip will be displayed below box2, but can't be fully displayed because of the
// offset
is(panelRect.top, anchorRect.bottom + 10, "Tooltip top has 10px offset");
is(panelRect.left, anchorRect.left + 5, "Tooltip left has 5px offset");
is(panelRect.height, 90, "Tooltip height is only 90px");
info("Display the tooltip on box3.");
- await showTooltip(tooltip, box3, {x: 5, y: 10});
+ await showTooltip(tooltip, box3, {x: 5, y: 10, width: 50, height: 100}, div);
panelRect = tooltip.container.getBoundingClientRect();
anchorRect = box3.getBoundingClientRect();
// Tooltip will be displayed above box3, but can't be fully displayed because of the
// offset
is(panelRect.bottom, anchorRect.top - 10, "Tooltip bottom is 10px above anchor");
is(panelRect.left, anchorRect.left + 5, "Tooltip left has 5px offset");
is(panelRect.height, 90, "Tooltip height is only 90px");
info("Display the tooltip on box4.");
- await showTooltip(tooltip, box4, {x: 5, y: 10});
+ await showTooltip(tooltip, box4, {x: 5, y: 10, width: 50, height: 100}, div);
panelRect = tooltip.container.getBoundingClientRect();
anchorRect = box4.getBoundingClientRect();
// Tooltip will be displayed above box4
is(panelRect.bottom, anchorRect.top - 10, "Tooltip bottom is 10px above anchor");
is(panelRect.left, anchorRect.left + 5, "Tooltip left has 5px offset");
is(panelRect.height, 100, "Tooltip height is at 100px as expected");
--- a/devtools/client/shared/test/browser_html_tooltip_resize.js
+++ b/devtools/client/shared/test/browser_html_tooltip_resize.js
@@ -23,21 +23,20 @@ add_task(async function() {
info("Test resizing of a tooltip");
const tooltip =
new HTMLTooltip(doc, { useXulWrapper: true, type: "doorhanger" });
const div = doc.createElementNS(HTML_NS, "div");
div.textContent = "tooltip";
div.style.cssText = "width: 100px; height: 40px";
- tooltip.setContent(div);
const box1 = doc.getElementById("box1");
- await showTooltip(tooltip, box1, { position: "top" });
+ await showTooltip(tooltip, box1, { position: "top" }, div);
// Get the original position of the panel and arrow.
const originalPanelBounds =
tooltip.panel.getBoxQuads({ relativeTo: doc })[0].getBounds();
const originalArrowBounds =
tooltip.arrow.getBoxQuads({ relativeTo: doc })[0].getBounds();
// Resize the content
--- a/devtools/client/shared/test/browser_html_tooltip_rtl.js
+++ b/devtools/client/shared/test/browser_html_tooltip_rtl.js
@@ -25,28 +25,27 @@ add_task(async function() {
const [,, doc] = await createHost("right", TEST_URI);
info("Test the positioning of tooltips in RTL and LTR directions");
const tooltip = new HTMLTooltip(doc, {useXulWrapper: false});
const div = doc.createElementNS(HTML_NS, "div");
div.textContent = "tooltip";
div.style.cssText = "box-sizing: border-box; border: 1px solid black";
- tooltip.setContent(div, {width: TOOLTIP_WIDTH, height: TOOLTIP_HEIGHT});
- await testRtlAnchors(doc, tooltip);
- await testLtrAnchors(doc, tooltip);
+ await testRtlAnchors(doc, tooltip, div);
+ await testLtrAnchors(doc, tooltip, div);
await hideTooltip(tooltip);
tooltip.destroy();
await testRtlArrow(doc);
});
-async function testRtlAnchors(doc, tooltip) {
+async function testRtlAnchors(doc, tooltip, content) {
/*
* The layout of the test page is as follows:
* _______________________________
* | toolbox |
* | _____ _____ _____ _____ |
* || | | | | | | ||
* || box1| | box2| | box3| | box4||
* ||_____| |_____| |_____| |_____||
@@ -56,40 +55,46 @@ async function testRtlAnchors(doc, toolt
* - box2 is displayed right after box1
* - total toolbox width is 500px so each box is 125px wide
*/
const box1 = doc.getElementById("box1");
const box2 = doc.getElementById("box2");
info("Display the tooltip on box1.");
- await showTooltip(tooltip, box1, {position: "bottom"});
+ await showTooltip(tooltip,
+ box1,
+ { position: "bottom", width: TOOLTIP_WIDTH, height: TOOLTIP_HEIGHT },
+ content);
let panelRect = tooltip.container.getBoundingClientRect();
let anchorRect = box1.getBoundingClientRect();
// box1 uses RTL direction, so the tooltip should be aligned with the right edge of the
// anchor, but it is shifted to the right to fit in the toolbox.
is(panelRect.left, 0, "Tooltip is aligned with left edge of the toolbox");
is(panelRect.top, anchorRect.bottom, "Tooltip aligned with the anchor bottom edge");
is(panelRect.height, TOOLTIP_HEIGHT, "Tooltip height is at 100px as expected");
info("Display the tooltip on box2.");
- await showTooltip(tooltip, box2, {position: "bottom"});
+ await showTooltip(tooltip,
+ box2,
+ { position: "bottom", width: TOOLTIP_WIDTH, height: TOOLTIP_HEIGHT },
+ content);
panelRect = tooltip.container.getBoundingClientRect();
anchorRect = box2.getBoundingClientRect();
// box2 uses RTL direction, so the tooltip is aligned with the right edge of the anchor
is(panelRect.right, anchorRect.right, "Tooltip is aligned with right edge of anchor");
is(panelRect.top, anchorRect.bottom, "Tooltip aligned with the anchor bottom edge");
is(panelRect.height, TOOLTIP_HEIGHT, "Tooltip height is at 100px as expected");
}
-async function testLtrAnchors(doc, tooltip) {
+async function testLtrAnchors(doc, tooltip, content) {
/*
* The layout of the test page is as follows:
* _______________________________
* | toolbox |
* | _____ _____ _____ _____ |
* || | | | | | | ||
* || box1| | box2| | box3| | box4||
* ||_____| |_____| |_____| |_____||
@@ -99,28 +104,34 @@ async function testLtrAnchors(doc, toolt
* - box4 is aligned with the right edge of the toolbox
* - total toolbox width is 500px so each box is 125px wide
*/
const box3 = doc.getElementById("box3");
const box4 = doc.getElementById("box4");
info("Display the tooltip on box3.");
- await showTooltip(tooltip, box3, {position: "bottom"});
+ await showTooltip(tooltip,
+ box3,
+ {position: "bottom", width: TOOLTIP_WIDTH, height: TOOLTIP_HEIGHT},
+ content);
let panelRect = tooltip.container.getBoundingClientRect();
let anchorRect = box3.getBoundingClientRect();
// box3 uses LTR direction, so the tooltip is aligned with the left edge of the anchor.
is(panelRect.left, anchorRect.left, "Tooltip is aligned with left edge of anchor");
is(panelRect.top, anchorRect.bottom, "Tooltip aligned with the anchor bottom edge");
is(panelRect.height, TOOLTIP_HEIGHT, "Tooltip height is at 100px as expected");
info("Display the tooltip on box4.");
- await showTooltip(tooltip, box4, {position: "bottom"});
+ await showTooltip(tooltip,
+ box4,
+ {position: "bottom", width: TOOLTIP_WIDTH, height: TOOLTIP_HEIGHT},
+ content);
panelRect = tooltip.container.getBoundingClientRect();
anchorRect = box4.getBoundingClientRect();
// box4 uses LTR direction, so the tooltip should be aligned with the left edge of the
// anchor, but it is shifted to the left to fit in the toolbox.
is(panelRect.right, TOOLBOX_WIDTH, "Tooltip is aligned with right edge of toolbox");
is(panelRect.top, anchorRect.bottom, "Tooltip aligned with the anchor bottom edge");
@@ -129,27 +140,26 @@ async function testLtrAnchors(doc, toolt
async function testRtlArrow(doc) {
// Set up the arrow-style tooltip
const arrowTooltip =
new HTMLTooltip(doc, { type: "arrow", useXulWrapper: false });
const div = doc.createElementNS(HTML_NS, "div");
div.textContent = "tooltip";
div.style.cssText = "box-sizing: border-box; border: 1px solid black";
- arrowTooltip.setContent(div, {
- width: TOOLTIP_WIDTH,
- height: TOOLTIP_HEIGHT,
- });
// box2 uses RTL direction and is far enough from the edge that the arrow
// should not be squashed in the wrong direction.
const box2 = doc.getElementById("box2");
info("Display the arrow tooltip on box2.");
- await showTooltip(arrowTooltip, box2, { position: "top" });
+ await showTooltip(arrowTooltip,
+ box2,
+ { position: "top", width: TOOLTIP_WIDTH, height: TOOLTIP_HEIGHT },
+ div);
const arrow = arrowTooltip.arrow;
ok(arrow, "Tooltip has an arrow");
const panelRect = arrowTooltip.container.getBoundingClientRect();
const arrowRect = arrow.getBoundingClientRect();
// The arrow should be offset from the right edge, but still closer to the
--- a/devtools/client/shared/test/browser_html_tooltip_variable-height.js
+++ b/devtools/client/shared/test/browser_html_tooltip_variable-height.js
@@ -24,34 +24,40 @@ add_task(async function() {
await addTab("about:blank");
const [,, doc] = await createHost("bottom", TEST_URI);
const tooltip = new HTMLTooltip(doc, {useXulWrapper: false});
info("Set tooltip content 50px tall, but request a container 200px tall");
const tooltipContent = doc.createElementNS(HTML_NS, "div");
tooltipContent.style.cssText = "height: " + TOOLTIP_HEIGHT + "px; background: red;";
- tooltip.setContent(tooltipContent, {width: CONTAINER_WIDTH, height: Infinity});
info("Show the tooltip and check the container and panel height.");
- await showTooltip(tooltip, doc.getElementById("box1"));
+ await showTooltip(
+ tooltip,
+ doc.getElementById("box1"),
+ {width: CONTAINER_WIDTH, height: Infinity},
+ tooltipContent);
const containerRect = tooltip.container.getBoundingClientRect();
const panelRect = tooltip.panel.getBoundingClientRect();
is(containerRect.height, CONTAINER_HEIGHT,
"Tooltip container has the expected height.");
is(panelRect.height, TOOLTIP_HEIGHT, "Tooltip panel has the expected height.");
info("Click below the tooltip panel but in the tooltip filler element.");
let onHidden = once(tooltip, "hidden");
EventUtils.synthesizeMouse(tooltip.container, 100, 100, {}, doc.defaultView);
await onHidden;
info("Show the tooltip one more time, and increase the content height");
- await showTooltip(tooltip, doc.getElementById("box1"));
+ await showTooltip(tooltip,
+ doc.getElementById("box1"),
+ {width: CONTAINER_WIDTH, height: Infinity},
+ tooltipContent);
tooltipContent.style.height = (2 * CONTAINER_HEIGHT) + "px";
info("Click at the same coordinates as earlier, this time it should hit the tooltip.");
const onPanelClick = once(tooltip.panel, "click");
EventUtils.synthesizeMouse(tooltip.container, 100, 100, {}, doc.defaultView);
await onPanelClick;
is(tooltip.isVisible(), true, "Tooltip is still visible");
--- a/devtools/client/shared/test/browser_html_tooltip_width-auto.js
+++ b/devtools/client/shared/test/browser_html_tooltip_width-auto.js
@@ -31,20 +31,22 @@ add_task(async function() {
async function runTests(doc) {
const tooltip = new HTMLTooltip(doc, {useXulWrapper});
info("Create tooltip content width to 150px");
const tooltipContent = doc.createElementNS(HTML_NS, "div");
tooltipContent.style.cssText = "height: 100%; width: 150px; background: red;";
info("Set tooltip content using width:auto");
- tooltip.setContent(tooltipContent, {width: "auto", height: 50});
info("Show the tooltip and check the tooltip panel width.");
- await showTooltip(tooltip, doc.getElementById("box1"));
+ await showTooltip(tooltip,
+ doc.getElementById("box1"),
+ { width: "auto", height: 50 },
+ tooltipContent);
const panelRect = tooltip.panel.getBoundingClientRect();
is(panelRect.width, 150, "Tooltip panel has the expected width.");
await hideTooltip(tooltip);
tooltip.destroy();
}
--- a/devtools/client/shared/test/browser_html_tooltip_xul-wrapper.js
+++ b/devtools/client/shared/test/browser_html_tooltip_xul-wrapper.js
@@ -40,29 +40,34 @@ add_task(async function() {
win.top.moveTo(originalTop, originalLeft);
});
info("Create HTML tooltip");
const tooltip = new HTMLTooltip(doc, {useXulWrapper: true});
const div = doc.createElementNS(HTML_NS, "div");
div.style.height = "200px";
div.style.background = "red";
- tooltip.setContent(div, {width: TOOLTIP_WIDTH, height: TOOLTIP_HEIGHT});
const box1 = doc.getElementById("box1");
// Above box1: check that the tooltip can overflow onto the content page.
info("Display the tooltip above box1.");
- await showTooltip(tooltip, box1, {position: "top"});
+ await showTooltip(tooltip,
+ box1,
+ { position: "top", width: TOOLTIP_WIDTH, height: TOOLTIP_HEIGHT },
+ div);
checkTooltip(tooltip, "top", TOOLTIP_HEIGHT);
await hideTooltip(tooltip);
// Below box1: check that the tooltip can overflow out of the browser window.
info("Display the tooltip below box1.");
- await showTooltip(tooltip, box1, {position: "bottom"});
+ await showTooltip(tooltip,
+ box1,
+ { position: "bottom", width: TOOLTIP_WIDTH, height: TOOLTIP_HEIGHT },
+ div);
checkTooltip(tooltip, "bottom", TOOLTIP_HEIGHT);
await hideTooltip(tooltip);
is(tooltip.isVisible(), false, "Tooltip is not visible");
tooltip.destroy();
});
--- a/devtools/client/shared/test/browser_html_tooltip_zoom.js
+++ b/devtools/client/shared/test/browser_html_tooltip_zoom.js
@@ -28,23 +28,24 @@ add_task(async function() {
await pushPref("devtools.toolbox.zoomValue", zoom.toString(10));
// Change this xul zoom to the x1.5 since this test doesn't use the toolbox preferences.
const contentViewer = host.frame.docShell.contentViewer;
contentViewer.fullZoom = zoom;
const tooltip = new HTMLTooltip(doc, {useXulWrapper: true});
info("Set tooltip content");
- tooltip.setContent(getTooltipContent(doc), {width: 100, height: 50});
is(tooltip.isVisible(), false, "Tooltip is not visible");
info("Show the tooltip and check the expected events are fired.");
const onShown = tooltip.once("shown");
- tooltip.show(doc.getElementById("box1"));
+ tooltip.show(doc.getElementById("box1"),
+ { width: 100, height: 50 },
+ getTooltipContent(doc));
await onShown;
const menuRect = doc.querySelector(".tooltip-xul-wrapper")
.getBoxQuads({relativeTo: doc})[0]
.getBounds();
const anchorRect = doc.getElementById("box1")
.getBoxQuads({relativeTo: doc})[0]
.getBounds();
--- a/devtools/client/shared/test/helper_html_tooltip.js
+++ b/devtools/client/shared/test/helper_html_tooltip.js
@@ -15,19 +15,22 @@
* @param {HTMLTooltip} tooltip
* The tooltip instance to display
* @param {Node} anchor
* The anchor that should be used to display the tooltip
* @param {Object} see HTMLTooltip:show documentation
* @return {Promise} promise that resolves when "shown" has been fired, reflow
* and repaint done.
*/
-async function showTooltip(tooltip, anchor, {position, x, y} = {}) {
+async function showTooltip(tooltip,
+ anchor,
+ {position, x, y, width, height} = {},
+ content) {
const onShown = tooltip.once("shown");
- tooltip.show(anchor, {position, x, y});
+ tooltip.show(anchor, {position, x, y, width, height}, content);
await onShown;
return waitForReflow(tooltip);
}
/**
* Hide an existing HTMLTooltip. After the tooltip "hidden" event has been fired
* a reflow will be triggered.
*
--- a/devtools/client/shared/widgets/tooltip/EventTooltipHelper.js
+++ b/devtools/client/shared/widgets/tooltip/EventTooltipHelper.js
@@ -24,17 +24,17 @@ const CONTAINER_WIDTH = 500;
* The tooltip instance on which the event details content should be set
* @param {Array} eventListenerInfos
* A list of event listeners
* @param {Toolbox} toolbox
* Toolbox used to select debugger panel
*/
function setEventTooltip(tooltip, eventListenerInfos, toolbox) {
const eventTooltip = new EventTooltip(tooltip, eventListenerInfos, toolbox);
- eventTooltip.init();
+ return eventTooltip.init();
}
function EventTooltip(tooltip, eventListenerInfos, toolbox) {
this._tooltip = tooltip;
this._eventListenerInfos = eventListenerInfos;
this._toolbox = toolbox;
this._eventEditors = new WeakMap();
@@ -192,21 +192,26 @@ EventTooltip.prototype = {
});
content.className = "event-tooltip-content-box";
this.container.appendChild(content);
this._addContentListeners(header);
}
- this._tooltip.setContent(
- this.container,
- {width: CONTAINER_WIDTH, height: Infinity}
- );
+// this._tooltip.setContent(
+// this.container,
+// {width: CONTAINER_WIDTH, height: Infinity}
+// );
this._tooltip.on("hidden", this.destroy);
+
+ return {
+ content: this.container,
+ option: { width: CONTAINER_WIDTH, height: Infinity}
+ };
},
_addContentListeners: function(header) {
header.addEventListener("click", this._headerClicked);
},
_headerClicked: function(event) {
if (event.target.classList.contains("event-tooltip-debugger-icon")) {
--- a/devtools/client/shared/widgets/tooltip/HTMLTooltip.js
+++ b/devtools/client/shared/widgets/tooltip/HTMLTooltip.js
@@ -311,18 +311,19 @@ function HTMLTooltip(toolboxDoc, {
EventEmitter.decorate(this);
this.doc = toolboxDoc;
this.id = id;
this.className = className;
this.type = type;
this.consumeOutsideClicks = consumeOutsideClicks;
this.useXulWrapper = this._isXUL() && useXulWrapper;
- this.preferredWidth = "auto";
- this.preferredHeight = "auto";
+ // T.B.D Remove this definition.
+ // this.preferredWidth = "auto";
+ // this.preferredHeight = "auto";
// 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();
this._position = null;
this._onClick = this._onClick.bind(this);
@@ -399,23 +400,25 @@ HTMLTooltip.prototype = {
* For tooltips whose content height may change while being
* displayed, the special value Infinity may be used to produce
* a flexible container that accommodates resizing content. Note,
* however, that when used in combination with the XUL wrapper the
* unfilled part of this container will consume all mouse events
* making content behind this area inaccessible until the tooltip is
* dismissed.
*/
+ /*
setContent: function(content, {width = "auto", height = "auto"} = {}) {
this.preferredWidth = width;
this.preferredHeight = height;
this.panel.innerHTML = "";
this.panel.appendChild(content);
},
+ */
/**
* Show the tooltip next to the provided anchor element. A preferred position
* can be set. The event "shown" will be fired after the tooltip is displayed.
*
* @param {Element} anchor
* The reference element with which the tooltip should be aligned
* @param {Object} options
@@ -424,18 +427,31 @@ HTMLTooltip.prototype = {
* Optional, possible values: top|bottom
* If layout permits, the tooltip will be displayed on top/bottom
* of the anchor. If omitted, the tooltip will be displayed where
* more space is available.
* @param {Number} options.x
* Optional, horizontal offset between the anchor and the tooltip.
* @param {Number} options.y
* Optional, vertical offset between the anchor and the tooltip.
+ * @param {Number} option.width
+ * Optional, width of the tooltip.
+ * @param {Number} option.height
+ * Optional, height of the tooltip.
+ * @param {Object}
+ * Require, target content
*/
- async show(anchor, options) {
+ async show(anchor, options, content) {
+ if (content) {
+ this.panel.innerHTML = "";
+ this.panel.appendChild(content);
+ // flush
+ this.topWindow.getComputedStyle(content).width;
+ }
+
const { left, top } = this._updateContainerBounds(anchor, options);
if (this.useXulWrapper) {
await this._showXulWrapperAt(left, top);
} else {
this.container.style.left = left + "px";
this.container.style.top = top + "px";
}
@@ -471,78 +487,78 @@ HTMLTooltip.prototype = {
if (this.useXulWrapper) {
this._moveXulWrapperTo(left, top);
} else {
this.container.style.left = left + "px";
this.container.style.top = top + "px";
}
},
- _updateContainerBounds(anchor, {position, x = 0, y = 0} = {}) {
+ _updateContainerBounds(anchor, {position, x = 0, y = 0, width = "auto", height = "auto"} = {}) {
// Get anchor geometry
let anchorRect = getRelativeRect(anchor, this.doc);
if (this.useXulWrapper) {
anchorRect = this._convertToScreenRect(anchorRect);
}
const { viewportRect, windowRect } = this._getBoundingRects();
// Calculate the horizonal position and width
let preferredWidth;
// Record the height too since it might save us from having to look it up
// later.
let measuredHeight;
- if (this.preferredWidth === "auto") {
+ if (width === "auto") {
// Reset any styles that constrain the dimensions we want to calculate.
this.container.style.width = "auto";
- if (this.preferredHeight === "auto") {
+ if (height === "auto") {
this.container.style.height = "auto";
}
({
width: preferredWidth,
height: measuredHeight,
} = this._measureContainerSize());
} else {
const themeWidth = 2 * EXTRA_BORDER[this.type];
- preferredWidth = this.preferredWidth + themeWidth;
+ preferredWidth = width + themeWidth;
}
const anchorWin = anchor.ownerDocument.defaultView;
const anchorCS = anchorWin.getComputedStyle(anchor);
const isRtl = anchorCS.direction === "rtl";
let borderRadius = 0;
if (this.type === TYPE.DOORHANGER) {
borderRadius = parseFloat(
anchorCS.getPropertyValue("--theme-arrowpanel-border-radius")
);
if (Number.isNaN(borderRadius)) {
borderRadius = 0;
}
}
- const {left, width, arrowLeft} = calculateHorizontalPosition(
+ const {left, width: calculatedWidth, arrowLeft} = calculateHorizontalPosition(
anchorRect,
viewportRect,
windowRect,
preferredWidth,
this.type,
x,
borderRadius,
isRtl
);
// If we constrained the width, then any measured height we have is no
// longer valid.
- if (measuredHeight && width !== preferredWidth) {
+ if (measuredHeight && calculatedWidth !== preferredWidth) {
measuredHeight = undefined;
}
// Apply width and arrow positioning
- this.container.style.width = width + "px";
+ this.container.style.width = calculatedWidth + "px";
if (this.type === TYPE.ARROW || this.type === TYPE.DOORHANGER) {
this.arrow.style.left = arrowLeft + "px";
}
// Work out how much vertical margin we have.
//
// This relies on us having set either .tooltip-top or .tooltip-bottom
// and on the margins for both being symmetrical. Fortunately the call to
@@ -551,46 +567,46 @@ HTMLTooltip.prototype = {
const panelWindow = this.panel.ownerDocument.defaultView;
const panelComputedStyle = panelWindow.getComputedStyle(this.panel);
const verticalMargin =
parseFloat(panelComputedStyle.marginTop) +
parseFloat(panelComputedStyle.marginBottom);
// Calculate the vertical position and height
let preferredHeight;
- if (this.preferredHeight === "auto") {
+ if (height === "auto") {
if (measuredHeight) {
this.container.style.height = "auto";
preferredHeight = measuredHeight;
} else {
({ height: preferredHeight } = this._measureContainerSize());
}
preferredHeight += verticalMargin;
} else {
const themeHeight =
EXTRA_HEIGHT[this.type] +
verticalMargin +
2 * EXTRA_BORDER[this.type];
- preferredHeight = this.preferredHeight + themeHeight;
+ preferredHeight = height + themeHeight;
}
- const {top, height, computedPosition} =
+ const {top, height: calculatedHeight, computedPosition} =
calculateVerticalPosition(anchorRect, viewportRect, preferredHeight, position, y);
this._position = computedPosition;
const isTop = computedPosition === POSITION.TOP;
this.container.classList.toggle("tooltip-top", isTop);
this.container.classList.toggle("tooltip-bottom", !isTop);
// If the preferred height is set to Infinity, the tooltip container should grow based
// on its content's height and use as much height as possible.
this.container.classList.toggle("tooltip-flexible-height",
- this.preferredHeight === Infinity);
+ preferredHeight === Infinity);
- this.container.style.height = height + "px";
+ this.container.style.height = calculatedHeight + "px";
return { left, top };
},
/**
* Calculate the following boundary rectangles:
*
* - Viewport rect: This is the region that limits the tooltip dimensions.
--- a/devtools/client/shared/widgets/tooltip/ImageTooltipHelper.js
+++ b/devtools/client/shared/widgets/tooltip/ImageTooltipHelper.js
@@ -114,16 +114,76 @@ function setImageTooltip(tooltip, doc, i
if (!hideDimensionLabel) {
height += LABEL_HEIGHT;
}
const width = Math.max(CONTAINER_MIN_WIDTH, imgWidth + 2 * IMAGE_PADDING);
tooltip.setContent(div, {width, height});
}
+function getImageTooltip(tooltip, doc, imageUrl, options) {
+ let {naturalWidth, naturalHeight, hideDimensionLabel,
+ hideCheckeredBackground, maxDim} = options;
+ maxDim = maxDim || MAX_DIMENSION;
+
+ let imgHeight = naturalHeight;
+ let imgWidth = naturalWidth;
+ if (imgHeight > maxDim || imgWidth > maxDim) {
+ const scale = maxDim / Math.max(imgHeight, imgWidth);
+ // Only allow integer values to avoid rounding errors.
+ imgHeight = Math.floor(scale * naturalHeight);
+ imgWidth = Math.ceil(scale * naturalWidth);
+ }
+
+ let imageClass = "";
+ if (!hideCheckeredBackground) {
+ imageClass = "devtools-tooltip-tiles";
+ }
+
+ // Create tooltip content
+ const div = doc.createElementNS(XHTML_NS, "div");
+ div.style.cssText = `
+ height: 100%;
+ min-width: 100px;
+ display: flex;
+ flex-direction: column;
+ text-align: center;`;
+ let html = `
+ <div style="flex: 1;
+ display: flex;
+ padding: ${IMAGE_PADDING}px;
+ align-items: center;
+ justify-content: center;
+ min-height: 1px;">
+ <img class="${imageClass}"
+ style="height: ${imgHeight}px; max-height: 100%;"
+ src="${encodeURI(imageUrl)}"/>
+ </div>`;
+
+ if (!hideDimensionLabel) {
+ const label = naturalWidth + " \u00D7 " + naturalHeight;
+ html += `
+ <div style="height: ${LABEL_HEIGHT}px;
+ text-align: center;">
+ <span class="theme-comment devtools-tooltip-caption">${label}</span>
+ </div>`;
+ }
+ // eslint-disable-next-line no-unsanitized/property
+ div.innerHTML = html;
+
+ // Calculate tooltip dimensions
+ let height = imgHeight + 2 * IMAGE_PADDING;
+ if (!hideDimensionLabel) {
+ height += LABEL_HEIGHT;
+ }
+ const width = Math.max(CONTAINER_MIN_WIDTH, imgWidth + 2 * IMAGE_PADDING);
+
+ return { content: div, option: { width, height } };
+}
+
/*
* Set the tooltip content of a provided HTMLTooltip instance to display a
* fallback error message when an image preview tooltip can not be displayed.
*
* @param {HTMLTooltip} tooltip
* The tooltip instance on which the image preview content should be set
* @param {Document} doc
* A document element to create the HTML elements needed for the tooltip
@@ -131,11 +191,21 @@ function setImageTooltip(tooltip, doc, i
function setBrokenImageTooltip(tooltip, doc) {
const div = doc.createElementNS(XHTML_NS, "div");
div.className = "theme-comment devtools-tooltip-image-broken";
const message = L10N.getStr("previewTooltip.image.brokenImage");
div.textContent = message;
tooltip.setContent(div);
}
+function getBrokenImageTooltip(tooltip, doc) {
+ const div = doc.createElementNS(XHTML_NS, "div");
+ div.className = "theme-comment devtools-tooltip-image-broken";
+ const message = L10N.getStr("previewTooltip.image.brokenImage");
+ div.textContent = message;
+ return { content: div, option: {} };
+}
+
module.exports.getImageDimensions = getImageDimensions;
module.exports.setImageTooltip = setImageTooltip;
+module.exports.getImageTooltip = getImageTooltip;
module.exports.setBrokenImageTooltip = setBrokenImageTooltip;
+module.exports.getBrokenImageTooltip = getBrokenImageTooltip;
--- a/devtools/client/shared/widgets/tooltip/SwatchBasedEditorTooltip.js
+++ b/devtools/client/shared/widgets/tooltip/SwatchBasedEditorTooltip.js
@@ -71,16 +71,19 @@ class SwatchBasedEditorTooltip {
this.swatches = new Map();
// When a swatch is clicked, and for as long as the tooltip is shown, the
// activeSwatch property will hold the reference to the swatch DOM element
// that was clicked
this.activeSwatch = null;
this._onSwatchClick = this._onSwatchClick.bind(this);
+
+ this._tooltipContent = null;
+ this._tooltipOption = null;
}
/**
* Reports if the tooltip is currently shown
*
* @return {Boolean} True if the tooltip is displayed.
*/
isVisible() {
@@ -105,17 +108,21 @@ class SwatchBasedEditorTooltip {
show() {
const tooltipAnchor = this.useInline ?
this.activeSwatch.closest(`.${INLINE_TOOLTIP_CLASS}`) :
this.activeSwatch;
if (tooltipAnchor) {
const onShown = this.tooltip.once("shown");
- this.tooltip.show(tooltipAnchor, "topcenter bottomleft");
+ this.tooltip.show(tooltipAnchor,
+ !this._tooltipOption
+ ? "topcenter bottomleft"
+ : Object.assign({ position: "topcenter bottomleft" }, this._tooltipOption),
+ this._tooltipContent);
this.tooltip.once("hidden", () => this.onTooltipHidden());
return onShown;
}
return Promise.resolve();
}
--- a/devtools/client/shared/widgets/tooltip/SwatchColorPickerTooltip.js
+++ b/devtools/client/shared/widgets/tooltip/SwatchColorPickerTooltip.js
@@ -55,17 +55,19 @@ class SwatchColorPickerTooltip extends S
const container = doc.createElementNS(XHTML_NS, "div");
container.id = "spectrum-tooltip";
const node = doc.createElementNS(XHTML_NS, "div");
node.id = "spectrum";
container.appendChild(node);
const widget = new Spectrum(node, color);
- this.tooltip.setContent(container, { width: 218, height: 224 });
+ this._tooltipContent = container;
+ this._tooltipOption = { width: 218, height: 224 };
+// this.tooltip.setContent(container, { width: 218, height: 224 });
widget.inspector = this.inspector;
const eyedropper = doc.createElementNS(XHTML_NS, "button");
eyedropper.id = "eyedropper-button";
eyedropper.className = "devtools-button";
/* pointerEvents for eyedropper has to be set auto to display tooltip when
* eyedropper is disabled in non-HTML documents.
--- a/devtools/client/shared/widgets/tooltip/SwatchCubicBezierTooltip.js
+++ b/devtools/client/shared/widgets/tooltip/SwatchCubicBezierTooltip.js
@@ -40,17 +40,19 @@ class SwatchCubicBezierTooltip extends S
*/
setCubicBezierContent(bezier) {
const { doc } = this.tooltip;
const container = doc.createElementNS(XHTML_NS, "div");
container.className = "cubic-bezier-container";
- this.tooltip.setContent(container, { width: 510, height: 370 });
+// this.tooltip.setContent(container, { width: 510, height: 370 });
+ this._tooltipContent = container;
+ this._tooltipOption = { width: 510, height:370 };
const def = defer();
// Wait for the tooltip to be shown before calling instanciating the widget
// as it expect its DOM elements to be visible.
this.tooltip.once("shown", () => {
const widget = new CubicBezierWidget(container, bezier);
def.resolve(widget);
--- a/devtools/client/shared/widgets/tooltip/SwatchFilterTooltip.js
+++ b/devtools/client/shared/widgets/tooltip/SwatchFilterTooltip.js
@@ -42,17 +42,19 @@ class SwatchFilterTooltip extends Swatch
*/
setFilterContent(filter) {
const { doc } = this.tooltip;
const container = doc.createElementNS(XHTML_NS, "div");
container.id = "filter-container";
- this.tooltip.setContent(container, { width: 510, height: 200 });
+// this.tooltip.setContent(container, { width: 510, height: 200 });
+ this._tooltipContent = container;
+ this._tooltipOption = { width: 510, height: 200 };
return new CSSFilterEditorWidget(container, filter, this._cssIsValid);
}
async show() {
// Call the parent class' show function
await super.show();
// Then set the filter value and listen to changes to preview them
--- a/devtools/client/shared/widgets/tooltip/TooltipToggle.js
+++ b/devtools/client/shared/widgets/tooltip/TooltipToggle.js
@@ -53,38 +53,43 @@ TooltipToggle.prototype = {
* should be displayed. Possible return values are:
* - false (or a falsy value) if the tooltip should not be displayed
* - true if the tooltip should be displayed
* - a DOM node to display the tooltip on the returned anchor
* The function can also return a promise that will resolve to one of
* the values listed above.
* If omitted, the tooltip will be shown everytime.
* @param {Object} options
- Set of optional arguments:
+ * Set of optional arguments:
* - {Number} toggleDelay
* An optional delay (in ms) that will be observed before showing
* and before hiding the tooltip. Defaults to DEFAULT_TOGGLE_DELAY.
* - {Boolean} interactive
* If enabled, the tooltip is not hidden when mouse leaves the
* target element and enters the tooltip. Allows the tooltip
* content to be interactive.
+ * @param {Function} onShowCb
+ * A function to be invoked before showing the panel.
+ * This function will be called with tooltip object parameter.
*/
start: function(baseNode, targetNodeCb,
- {toggleDelay = DEFAULT_TOGGLE_DELAY, interactive = false} = {}) {
+ {toggleDelay = DEFAULT_TOGGLE_DELAY, interactive = false} = {},
+ onShowCb) {
this.stop();
if (!baseNode) {
// Calling tool is in the process of being destroyed.
return;
}
this._baseNode = baseNode;
this._targetNodeCb = targetNodeCb || (() => true);
this._toggleDelay = toggleDelay;
this._interactive = interactive;
+ this._onShowCb = onShowCb;
baseNode.addEventListener("mousemove", this._onMouseMove);
baseNode.addEventListener("mouseout", this._onMouseOut);
if (this._interactive) {
this.tooltip.container.addEventListener("mouseover", this._onTooltipMouseOver);
this.tooltip.container.addEventListener("mouseout", this._onTooltipMouseOut);
}
@@ -122,17 +127,21 @@ TooltipToggle.prototype = {
this.win.clearTimeout(this.toggleTimer);
this.toggleTimer = this.win.setTimeout(() => {
this.tooltip.hide();
this.isValidHoverTarget(event.target).then(target => {
if (target === null || !this._baseNode) {
// bail out if no target or if the toggle has been destroyed.
return;
}
- this.tooltip.show(target);
+ if (this._onShowCb) {
+ this._onShowCb(target, this.tooltip);
+ } else {
+ this.tooltip.show(target);
+ }
}, reason => {
console.error("isValidHoverTarget rejected with unexpected reason:");
console.error(reason);
});
}, this._toggleDelay);
}
},