Source code

Revision control

Copy as Markdown

Other Tools

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
loader.lazyRequireGetter(
this,
"openDocLink",
true
);
class InactiveCssTooltipHelper {
constructor() {
this.addTab = this.addTab.bind(this);
}
/**
* Fill the tooltip with inactive CSS information.
*
* @param {String} propertyName
* The property name to be displayed in bold.
* @param {String} text
* The main text, which follows property name.
*/
async setContent(data, tooltip) {
const fragment = this.getTemplate(data, tooltip);
const { doc } = tooltip;
tooltip.panel.innerHTML = "";
tooltip.panel.addEventListener("click", this.addTab);
tooltip.once("hidden", () => {
tooltip.panel.removeEventListener("click", this.addTab);
});
// Because Fluent is async we need to manually translate the fragment and
// then insert it into the tooltip. This is needed in order for the tooltip
// to size to the contents properly and for tests.
await doc.l10n.translateFragment(fragment);
doc.l10n.pauseObserving();
tooltip.panel.appendChild(fragment);
doc.l10n.resumeObserving();
// Size the content.
tooltip.setContentSize({ width: 267, height: Infinity });
}
/**
* Get the template that the Fluent string will be merged with. This template
* looks something like this but there is a variable amount of properties in the
* fix section:
*
* <div class="devtools-tooltip-inactive-css">
* <p data-l10n-id="inactive-css-not-grid-or-flex-container"
* data-l10n-args="{&quot;property&quot;:&quot;align-content&quot;}">
* </p>
* <p data-l10n-id="inactive-css-not-grid-or-flex-container-fix">
* <span data-l10n-name="link" class="link"></span>
* </p>
* </div>
*
* @param {Object} data
* An object in the following format: {
* fixId: "inactive-css-not-grid-item-fix-2", // Fluent id containing the
* // Inactive CSS fix.
* msgId: "inactive-css-not-grid-item", // Fluent id containing the
* // Inactive CSS message.
* property: "color", // Property name
* }
* @param {HTMLTooltip} tooltip
* The tooltip we are targetting.
*/
getTemplate(data, tooltip) {
const XHTML_NS = "http://www.w3.org/1999/xhtml";
const { fixId, msgId, property, display, lineCount, learnMoreURL } = data;
const { doc } = tooltip;
const documentUrl = new URL(
learnMoreURL || `https://developer.mozilla.org/docs/Web/CSS/${property}`
);
this._currentTooltip = tooltip;
const { searchParams } = documentUrl;
searchParams.append("utm_source", "devtools");
searchParams.append("utm_medium", "inspector-inactive-css");
this._currentUrl = documentUrl.toString();
const templateNode = doc.createElementNS(XHTML_NS, "template");
// eslint-disable-next-line
templateNode.innerHTML = `
<div class="devtools-tooltip-inactive-css">
<p data-l10n-id="${msgId}"
data-l10n-args='${JSON.stringify({ property, display, lineCount })}'>
</p>
<p data-l10n-id="${fixId}">
<span data-l10n-name="link" class="link"></span>
</p>
</div>`;
return doc.importNode(templateNode.content, true);
}
/**
* Hide the tooltip, open `this._currentUrl` in a new tab and focus it.
*
* @param {DOMEvent} event
* The click event originating from the tooltip.
*
*/
addTab(event) {
// The XUL panel swallows click events so handlers can't be added directly
// to the link span. As a workaround we listen to all click events in the
// panel and if a link span is clicked we proceed.
if (event.target.className !== "link") {
return;
}
const tooltip = this._currentTooltip;
tooltip.hide();
openDocLink(this._currentUrl);
}
destroy() {
this._currentTooltip = null;
this._currentUrl = null;
}
}
module.exports = InactiveCssTooltipHelper;