mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-20 16:55:40 +00:00
Bug 1461522 - Add a mechanism to allow updating an HTMLTooltip's size and position; r=jdescottes
MozReview-Commit-ID: 4SDxlTTFp8E --HG-- extra : rebase_source : c8e429c8d88512bc807a3169b6651609e01e5556
This commit is contained in:
parent
1b60bc9ae5
commit
59e52349bd
@ -145,6 +145,7 @@ skip-if = e10s # Bug 1221911, bug 1222289, frequent e10s timeouts
|
||||
[browser_html_tooltip_height-auto.js]
|
||||
[browser_html_tooltip_hover.js]
|
||||
[browser_html_tooltip_offset.js]
|
||||
[browser_html_tooltip_resize.js]
|
||||
[browser_html_tooltip_rtl.js]
|
||||
[browser_html_tooltip_variable-height.js]
|
||||
[browser_html_tooltip_width-auto.js]
|
||||
|
77
devtools/client/shared/test/browser_html_tooltip_resize.js
Normal file
77
devtools/client/shared/test/browser_html_tooltip_resize.js
Normal file
@ -0,0 +1,77 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
/* import-globals-from helper_html_tooltip.js */
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Test the HTMLTooltip can be resized.
|
||||
*/
|
||||
|
||||
const HTML_NS = "http://www.w3.org/1999/xhtml";
|
||||
const TEST_URI = CHROME_URL_ROOT + "doc_html_tooltip.xul";
|
||||
|
||||
const {HTMLTooltip} = require("devtools/client/shared/widgets/tooltip/HTMLTooltip");
|
||||
loadHelperScript("helper_html_tooltip.js");
|
||||
|
||||
const TOOLBOX_WIDTH = 500;
|
||||
|
||||
add_task(async function() {
|
||||
await pushPref("devtools.toolbox.sidebar.width", TOOLBOX_WIDTH);
|
||||
|
||||
// Open the host on the right so that the doorhangers hang right.
|
||||
const [,, doc] = await createHost("right", TEST_URI);
|
||||
|
||||
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" });
|
||||
|
||||
// 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
|
||||
div.style.cssText = "width: 200px; height: 30px";
|
||||
tooltip.updateContainerBounds(box1, { position: "top" });
|
||||
|
||||
// The panel should have moved 100px to the left and 10px down
|
||||
const updatedPanelBounds =
|
||||
tooltip.panel.getBoxQuads({ relativeTo: doc })[0].getBounds();
|
||||
|
||||
const panelXMovement = `panel left: ${originalPanelBounds.left}->` +
|
||||
updatedPanelBounds.left;
|
||||
ok(Math.round(updatedPanelBounds.left - originalPanelBounds.left) === -100,
|
||||
`Panel should have moved 100px to the left (actual: ${panelXMovement})`);
|
||||
|
||||
const panelYMovement = `panel top: ${originalPanelBounds.top}->` +
|
||||
updatedPanelBounds.top;
|
||||
ok(Math.round(updatedPanelBounds.top - originalPanelBounds.top) === 10,
|
||||
`Panel should have moved 10px down (actual: ${panelYMovement})`);
|
||||
|
||||
// The arrow should be in the same position
|
||||
const updatedArrowBounds =
|
||||
tooltip.arrow.getBoxQuads({ relativeTo: doc })[0].getBounds();
|
||||
|
||||
const arrowXMovement = `arrow left: ${originalArrowBounds.left}->` +
|
||||
updatedArrowBounds.left;
|
||||
ok(Math.round(updatedArrowBounds.left - originalArrowBounds.left) === 0,
|
||||
`Arrow should not have moved (actual: ${arrowXMovement})`);
|
||||
|
||||
const arrowYMovement = `arrow top: ${originalArrowBounds.top}->` +
|
||||
updatedArrowBounds.top;
|
||||
ok(Math.round(updatedArrowBounds.top - originalArrowBounds.top) === 0,
|
||||
`Arrow should not have moved (actual: ${arrowYMovement})`);
|
||||
|
||||
await hideTooltip(tooltip);
|
||||
tooltip.destroy();
|
||||
});
|
@ -422,7 +422,7 @@ HTMLTooltip.prototype = {
|
||||
* @param {Element} anchor
|
||||
* The reference element with which the tooltip should be aligned
|
||||
* @param {Object} options
|
||||
* Settings for positioning the tooltip.
|
||||
* Optional settings for positioning the tooltip.
|
||||
* @param {String} options.position
|
||||
* Optional, possible values: top|bottom
|
||||
* If layout permits, the tooltip will be displayed on top/bottom
|
||||
@ -433,7 +433,55 @@ HTMLTooltip.prototype = {
|
||||
* @param {Number} options.y
|
||||
* Optional, vertical offset between the anchor and the tooltip.
|
||||
*/
|
||||
async show(anchor, {position, x = 0, y = 0} = {}) {
|
||||
async show(anchor, options) {
|
||||
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";
|
||||
}
|
||||
|
||||
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(() => {
|
||||
if (this.autofocus) {
|
||||
this.focus();
|
||||
}
|
||||
// Update 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);
|
||||
},
|
||||
|
||||
/**
|
||||
* Recalculate the dimensions and position of the tooltip in response to
|
||||
* changes to its content.
|
||||
*
|
||||
* Parameters are identical to show().
|
||||
*/
|
||||
updateContainerBounds(anchor, options) {
|
||||
if (!this.isVisible()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { left, top } = this._updateContainerBounds(anchor, options);
|
||||
|
||||
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} = {}) {
|
||||
// Get anchor geometry
|
||||
let anchorRect = getRelativeRect(anchor, this.doc);
|
||||
if (this.useXulWrapper) {
|
||||
@ -544,28 +592,7 @@ HTMLTooltip.prototype = {
|
||||
|
||||
this.container.style.height = height + "px";
|
||||
|
||||
if (this.useXulWrapper) {
|
||||
await this._showXulWrapperAt(left, top);
|
||||
} else {
|
||||
this.container.style.left = left + "px";
|
||||
this.container.style.top = top + "px";
|
||||
}
|
||||
|
||||
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(() => {
|
||||
if (this.autofocus) {
|
||||
this.focus();
|
||||
}
|
||||
// Update 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);
|
||||
return { left, top };
|
||||
},
|
||||
|
||||
/**
|
||||
@ -850,6 +877,11 @@ HTMLTooltip.prototype = {
|
||||
return onPanelShown;
|
||||
},
|
||||
|
||||
_moveXulWrapperTo: function(left, top) {
|
||||
const zoom = getCurrentZoom(this.xulPanelWrapper);
|
||||
this.xulPanelWrapper.moveTo(left * zoom, top * zoom);
|
||||
},
|
||||
|
||||
_hideXulWrapper: function() {
|
||||
this.xulPanelWrapper.removeEventListener("popuphidden", this._onXulPanelHidden);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user