mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-17 23:35:34 +00:00
Bug 1276876 - ruleview: migrate font&image preview tooltips to HTMLTooltips;r=tromey
Migrate the previewTooltip used in the ruleview (& computedview) to use a HTMLTooltip instance. Helper methods from Tooltip.js have been removed, migrated to HTML and are now in style-inspector-overlays.js (not used by any other client). Tests have been updated to be compatible with HTML Image preview tooltips. The behavior should be the same as before, so no new test has been added. MozReview-Commit-ID: HuFatuPi5VM --HG-- extra : rebase_source : cc0f0af816c9d2a276f595120210e1e5f0197039 extra : amend_source : a6390ffac7dff0325a96be6f884b344db621b439
This commit is contained in:
parent
9dbe902fe1
commit
8e32fa1b37
@ -43,7 +43,8 @@ function* testColorChangeIsntRevertedWhenOtherTooltipIsShown(ruleView) {
|
||||
});
|
||||
|
||||
let spectrum = yield picker.spectrum;
|
||||
let onModifications = ruleView.once("ruleview-changed");
|
||||
|
||||
let onModifications = waitForNEvents(ruleView, "ruleview-changed", 2);
|
||||
let onHidden = picker.tooltip.once("hidden");
|
||||
EventUtils.sendKey("RETURN", spectrum.element.ownerDocument.defaultView);
|
||||
yield onHidden;
|
||||
@ -53,8 +54,7 @@ function* testColorChangeIsntRevertedWhenOtherTooltipIsShown(ruleView) {
|
||||
let value = getRuleViewProperty(ruleView, "body", "background").valueSpan;
|
||||
let url = value.querySelector(".theme-link");
|
||||
onShown = ruleView.tooltips.previewTooltip.once("shown");
|
||||
let anchor = yield isHoverTooltipTarget(ruleView.tooltips.previewTooltip,
|
||||
url);
|
||||
let anchor = yield isHoverTooltipTarget(ruleView.tooltips.previewTooltip, url);
|
||||
ruleView.tooltips.previewTooltip.show(anchor);
|
||||
yield onShown;
|
||||
|
||||
|
@ -12,8 +12,14 @@
|
||||
// - in-content highlighters that appear when hovering over property values
|
||||
// - etc.
|
||||
|
||||
const {getTheme} = require("devtools/client/shared/theme");
|
||||
const {HTMLTooltip} = require("devtools/client/shared/widgets/HTMLTooltip");
|
||||
const {
|
||||
getImageDimensions,
|
||||
setImageTooltip,
|
||||
setBrokenImageTooltip,
|
||||
} = require("devtools/client/shared/widgets/tooltip/ImageTooltipHelper");
|
||||
const {
|
||||
Tooltip,
|
||||
SwatchColorPickerTooltip,
|
||||
SwatchCubicBezierTooltip,
|
||||
CssDocsTooltip,
|
||||
@ -273,7 +279,9 @@ TooltipsOverlay.prototype = {
|
||||
let panelDoc = this.view.inspector.panelDoc;
|
||||
|
||||
// Image, fonts, ... preview tooltip
|
||||
this.previewTooltip = new Tooltip(panelDoc);
|
||||
this.previewTooltip = new HTMLTooltip(this.view.inspector.toolbox, {
|
||||
type: "arrow"
|
||||
});
|
||||
this.previewTooltip.startTogglingOnHover(this.view.element,
|
||||
this._onPreviewTooltipTargetHover.bind(this));
|
||||
|
||||
@ -395,23 +403,85 @@ TooltipsOverlay.prototype = {
|
||||
let inspector = this.view.inspector;
|
||||
|
||||
if (type === TOOLTIP_IMAGE_TYPE) {
|
||||
let dim = Services.prefs.getIntPref(PREF_IMAGE_TOOLTIP_SIZE);
|
||||
// nodeInfo contains an absolute uri
|
||||
let uri = nodeInfo.value.url;
|
||||
yield this.previewTooltip.setRelativeImageContent(uri,
|
||||
inspector.inspector, dim);
|
||||
try {
|
||||
yield this._setImagePreviewTooltip(nodeInfo.value.url);
|
||||
} catch (e) {
|
||||
yield setBrokenImageTooltip(this.previewTooltip, this.view.inspector.panelDoc);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (type === TOOLTIP_FONTFAMILY_TYPE) {
|
||||
yield this.previewTooltip.setFontFamilyContent(nodeInfo.value.value,
|
||||
inspector.selection.nodeFront);
|
||||
let font = nodeInfo.value.value;
|
||||
let nodeFront = inspector.selection.nodeFront;
|
||||
yield this._setFontPreviewTooltip(font, nodeFront);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}),
|
||||
|
||||
/**
|
||||
* Set the content of the preview tooltip to display an image preview. The image URL can
|
||||
* be relative, a call will be made to the debuggee to retrieve the image content as an
|
||||
* imageData URI.
|
||||
*
|
||||
* @param {String} imageUrl
|
||||
* The image url value (may be relative or absolute).
|
||||
* @return {Promise} A promise that resolves when the preview tooltip content is ready
|
||||
*/
|
||||
_setImagePreviewTooltip: Task.async(function* (imageUrl) {
|
||||
let doc = this.view.inspector.panelDoc;
|
||||
let maxDim = Services.prefs.getIntPref(PREF_IMAGE_TOOLTIP_SIZE);
|
||||
|
||||
let naturalWidth, naturalHeight;
|
||||
if (imageUrl.startsWith("data:")) {
|
||||
// If the imageUrl already is a data-url, save ourselves a round-trip
|
||||
let size = yield getImageDimensions(doc, imageUrl);
|
||||
naturalWidth = size.naturalWidth;
|
||||
naturalHeight = size.naturalHeight;
|
||||
} else {
|
||||
let inspectorFront = this.view.inspector.inspector;
|
||||
let {data, size} = yield inspectorFront.getImageDataFromURL(imageUrl, maxDim);
|
||||
imageUrl = yield data.string();
|
||||
naturalWidth = size.naturalWidth;
|
||||
naturalHeight = size.naturalHeight;
|
||||
}
|
||||
|
||||
yield setImageTooltip(this.previewTooltip, doc, imageUrl,
|
||||
{maxDim, naturalWidth, naturalHeight});
|
||||
}),
|
||||
|
||||
/**
|
||||
* Set the content of the preview tooltip to display a font family preview.
|
||||
*
|
||||
* @param {String} font
|
||||
* The font family value.
|
||||
* @param {object} nodeFront
|
||||
* The NodeActor that will used to retrieve the dataURL for the font
|
||||
* family tooltip contents.
|
||||
* @return {Promise} A promise that resolves when the preview tooltip content is ready
|
||||
*/
|
||||
_setFontPreviewTooltip: Task.async(function* (font, nodeFront) {
|
||||
if (!font || !nodeFront || typeof nodeFront.getFontFamilyDataURL !== "function") {
|
||||
throw new Error("Unable to create font preview tooltip content.");
|
||||
}
|
||||
|
||||
font = font.replace(/"/g, "'");
|
||||
font = font.replace("!important", "");
|
||||
font = font.trim();
|
||||
|
||||
let fillStyle = getTheme() === "light" ? "black" : "white";
|
||||
let {data, size: maxDim} = yield nodeFront.getFontFamilyDataURL(font, fillStyle);
|
||||
|
||||
let imageUrl = yield data.string();
|
||||
let doc = this.view.inspector.panelDoc;
|
||||
let {naturalWidth, naturalHeight} = yield getImageDimensions(doc, imageUrl);
|
||||
|
||||
yield setImageTooltip(this.previewTooltip, doc, imageUrl,
|
||||
{hideDimensionLabel: true, maxDim, naturalWidth, naturalHeight});
|
||||
}),
|
||||
|
||||
_onNewSelection: function () {
|
||||
if (this.previewTooltip) {
|
||||
this.previewTooltip.hide();
|
||||
|
@ -65,7 +65,7 @@ function* testBodyRuleView(view) {
|
||||
|
||||
yield assertHoverTooltipOn(view.tooltips.previewTooltip, uriSpan);
|
||||
|
||||
let images = panel.getElementsByTagName("image");
|
||||
let images = panel.getElementsByTagName("img");
|
||||
is(images.length, 1, "Tooltip contains an image");
|
||||
ok(images[0].getAttribute("src")
|
||||
.indexOf("iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHe") !== -1,
|
||||
@ -81,7 +81,7 @@ function* testDivRuleView(view) {
|
||||
|
||||
yield assertHoverTooltipOn(view.tooltips.previewTooltip, uriSpan);
|
||||
|
||||
let images = panel.getElementsByTagName("image");
|
||||
let images = panel.getElementsByTagName("img");
|
||||
is(images.length, 1, "Tooltip contains an image");
|
||||
ok(images[0].getAttribute("src").startsWith("data:"),
|
||||
"Tooltip contains a data-uri image as expected");
|
||||
@ -117,7 +117,7 @@ function* testComputedView(view) {
|
||||
|
||||
yield assertHoverTooltipOn(view.tooltips.previewTooltip, uriSpan);
|
||||
|
||||
let images = panel.getElementsByTagName("image");
|
||||
let images = panel.getElementsByTagName("img");
|
||||
is(images.length, 1, "Tooltip contains an image");
|
||||
|
||||
ok(images[0].getAttribute("src").startsWith("data:"),
|
||||
|
@ -7,6 +7,7 @@
|
||||
// Test that if a tooltip is visible when a new selection is made, it closes
|
||||
|
||||
const TEST_URI = "<div class='one'>el 1</div><div class='two'>el 2</div>";
|
||||
const XHTML_NS = "http://www.w3.org/1999/xhtml";
|
||||
|
||||
add_task(function* () {
|
||||
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
|
||||
@ -25,7 +26,9 @@ function* testRuleView(ruleView, inspector) {
|
||||
info("Showing the tooltip");
|
||||
|
||||
let tooltip = ruleView.tooltips.previewTooltip;
|
||||
tooltip.setTextContent({messages: ["rule-view tooltip"]});
|
||||
let tooltipContent = ruleView.styleDocument.createElementNS(XHTML_NS, "div");
|
||||
yield tooltip.setContent(tooltipContent, 100, 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
|
||||
@ -48,7 +51,8 @@ function* testComputedView(computedView, inspector) {
|
||||
info("Showing the tooltip");
|
||||
|
||||
let tooltip = computedView.tooltips.previewTooltip;
|
||||
tooltip.setTextContent({messages: ["computed-view tooltip"]});
|
||||
let tooltipContent = computedView.styleDocument.createElementNS(XHTML_NS, "div");
|
||||
yield tooltip.setContent(tooltipContent, 100, 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
|
||||
|
@ -51,7 +51,7 @@ function* testRuleView(ruleView, nodeFront) {
|
||||
// And verify that the tooltip gets shown on this property
|
||||
yield assertHoverTooltipOn(tooltip, valueSpan);
|
||||
|
||||
let images = panel.getElementsByTagName("image");
|
||||
let images = panel.getElementsByTagName("img");
|
||||
is(images.length, 1, "Tooltip contains an image");
|
||||
ok(images[0].getAttribute("src").startsWith("data:"),
|
||||
"Tooltip contains a data-uri image as expected");
|
||||
@ -70,7 +70,7 @@ function* testComputedView(computedView, nodeFront) {
|
||||
|
||||
yield assertHoverTooltipOn(tooltip, valueSpan);
|
||||
|
||||
let images = panel.getElementsByTagName("image");
|
||||
let images = panel.getElementsByTagName("img");
|
||||
is(images.length, 1, "Tooltip contains an image");
|
||||
ok(images[0].getAttribute("src").startsWith("data:"),
|
||||
"Tooltip contains a data-uri image as expected");
|
||||
@ -97,7 +97,7 @@ function* testExpandedComputedViewProperty(computedView, nodeFront) {
|
||||
|
||||
yield assertHoverTooltipOn(tooltip, valueSpan);
|
||||
|
||||
let images = panel.getElementsByTagName("image");
|
||||
let images = panel.getElementsByTagName("img");
|
||||
is(images.length, 1, "Tooltip contains an image");
|
||||
ok(images[0].getAttribute("src").startsWith("data:"),
|
||||
"Tooltip contains a data-uri image as expected");
|
||||
|
@ -45,7 +45,7 @@ function* testComputedViewUrls(inspector) {
|
||||
*/
|
||||
function* performChecks(view, propertyValue) {
|
||||
function checkTooltip(panel, imageSrc) {
|
||||
let images = panel.getElementsByTagName("image");
|
||||
let images = panel.getElementsByTagName("img");
|
||||
is(images.length, 1, "Tooltip contains an image");
|
||||
is(images[0].getAttribute("src"), imageSrc, "The image URL is correct");
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ function* testRuleView(ruleView, nodeFront) {
|
||||
// And verify that the tooltip gets shown on this property
|
||||
yield assertHoverTooltipOn(tooltip, valueSpan);
|
||||
|
||||
let images = panel.getElementsByTagName("image");
|
||||
let images = panel.getElementsByTagName("img");
|
||||
is(images.length, 1, "Tooltip contains an image");
|
||||
ok(images[0].getAttribute("src")
|
||||
.startsWith("data:"), "Tooltip contains a data-uri image as expected");
|
||||
|
@ -39,12 +39,12 @@ function* testImageDimension(ruleView) {
|
||||
|
||||
info("Showing the tooltip");
|
||||
let onShown = tooltip.once("shown");
|
||||
tooltip.show();
|
||||
tooltip.show(uriSpan);
|
||||
yield onShown;
|
||||
|
||||
// Let's not test for a specific size, but instead let's make sure it's at
|
||||
// least as big as the image
|
||||
let imageRect = panel.querySelector("image").getBoundingClientRect();
|
||||
let imageRect = panel.querySelector("img").getBoundingClientRect();
|
||||
let panelRect = panel.getBoundingClientRect();
|
||||
|
||||
ok(panelRect.width >= imageRect.width,
|
||||
|
@ -18,7 +18,6 @@ const Heritage = require("sdk/core/heritage");
|
||||
const {Eyedropper} = require("devtools/client/eyedropper/eyedropper");
|
||||
const Editor = require("devtools/client/sourceeditor/editor");
|
||||
const Services = require("Services");
|
||||
const {Task} = require("devtools/shared/task");
|
||||
|
||||
loader.lazyRequireGetter(this, "beautify", "devtools/shared/jsbeautify/beautify");
|
||||
loader.lazyRequireGetter(this, "setNamedTimeout", "devtools/client/shared/widgets/view-helpers", true);
|
||||
@ -520,31 +519,6 @@ Tooltip.prototype = {
|
||||
this.panel.setAttribute("clamped-dimensions", "");
|
||||
},
|
||||
|
||||
/**
|
||||
* Uses the provided inspectorFront's getImageDataFromURL method to resolve
|
||||
* the relative URL on the server-side, in the page context, and then sets the
|
||||
* tooltip content with the resulting image just like |setImageContent| does.
|
||||
* @return a promise that resolves when the image is shown in the tooltip or
|
||||
* resolves when the broken image tooltip content is ready, but never rejects.
|
||||
*/
|
||||
setRelativeImageContent: Task.async(function* (imageUrl, inspectorFront,
|
||||
maxDim) {
|
||||
if (imageUrl.startsWith("data:")) {
|
||||
// If the imageUrl already is a data-url, save ourselves a round-trip
|
||||
this.setImageContent(imageUrl, {maxDim: maxDim});
|
||||
} else if (inspectorFront) {
|
||||
try {
|
||||
let {data, size} = yield inspectorFront.getImageDataFromURL(imageUrl,
|
||||
maxDim);
|
||||
size.maxDim = maxDim;
|
||||
let str = yield data.string();
|
||||
this.setImageContent(str, size);
|
||||
} catch (e) {
|
||||
this.setBrokenImageContent();
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
||||
/**
|
||||
* Fill the tooltip with a message explaining the the image is missing
|
||||
*/
|
||||
@ -560,7 +534,7 @@ Tooltip.prototype = {
|
||||
* Fill the tooltip with an image and add the image dimension at the bottom.
|
||||
*
|
||||
* Only use this for absolute URLs that can be queried from the devtools
|
||||
* client-side. For relative URLs, use |setRelativeImageContent|.
|
||||
* client-side.
|
||||
*
|
||||
* @param {string} imageUrl
|
||||
* The url to load the image from
|
||||
@ -768,38 +742,6 @@ Tooltip.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Set the content of the tooltip to display a font family preview.
|
||||
* This is based on Lea Verou's Dablet.
|
||||
* See https://github.com/LeaVerou/dabblet
|
||||
* for more info.
|
||||
* @param {String} font The font family value.
|
||||
* @param {object} nodeFront
|
||||
* The NodeActor that will used to retrieve the dataURL for the font
|
||||
* family tooltip contents.
|
||||
* @return A promise that resolves when the font tooltip content is ready, or
|
||||
* rejects if no font is provided
|
||||
*/
|
||||
setFontFamilyContent: Task.async(function* (font, nodeFront) {
|
||||
if (!font || !nodeFront) {
|
||||
throw new Error("Missing font");
|
||||
}
|
||||
|
||||
if (typeof nodeFront.getFontFamilyDataURL === "function") {
|
||||
font = font.replace(/"/g, "'");
|
||||
font = font.replace("!important", "");
|
||||
font = font.trim();
|
||||
|
||||
let fillStyle =
|
||||
(Services.prefs.getCharPref("devtools.theme") === "light") ?
|
||||
"black" : "white";
|
||||
|
||||
let {data, size} = yield nodeFront.getFontFamilyDataURL(font, fillStyle);
|
||||
let str = yield data.string();
|
||||
this.setImageContent(str, { hideDimensionLabel: true, maxDim: size });
|
||||
}
|
||||
}),
|
||||
|
||||
/**
|
||||
* Set the content of this tooltip to the MDN docs widget.
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user