195 lines
6.8 KiB
JavaScript
195 lines
6.8 KiB
JavaScript
/* 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";
|
|
|
|
const XHTML_NS = "http://www.w3.org/1999/xhtml";
|
|
|
|
const OutputParser = require("resource://devtools/client/shared/output-parser.js");
|
|
loader.lazyGetter(this, "L10N", function () {
|
|
const { LocalizationHelper } = require("resource://devtools/shared/l10n.js");
|
|
return new LocalizationHelper(
|
|
"devtools/shared/locales/styleinspector.properties"
|
|
);
|
|
});
|
|
loader.lazyGetter(this, "L10N_EMPTY", function () {
|
|
return L10N.getStr("rule.variableEmpty");
|
|
});
|
|
loader.lazyGetter(this, "L10N_COMPUTED_VALUE", function () {
|
|
return L10N.getStr("rule.variableComputedValue");
|
|
});
|
|
|
|
/**
|
|
* Set the tooltip content of a provided HTMLTooltip instance to display a
|
|
* variable preview matching the provided text.
|
|
*
|
|
* @param {HTMLTooltip} tooltip
|
|
* The tooltip instance on which the text preview content should be set.
|
|
* @param {Document} doc
|
|
* A document element to create the HTML elements needed for the tooltip.
|
|
* @param {Object} params
|
|
* @param {String} params.computed
|
|
* The computed value for the variable.
|
|
* @param {Object} params.outputParserOptions
|
|
* Options to pass to the OutputParser. At the moment, this is the same object that
|
|
* we use in the Rules view, so we have the same output in the variable tooltip
|
|
* than in the Rules view.
|
|
* @param {Object} params.registeredProperty
|
|
* Contains the registered property data, if the variable was registered (@property or CSS.registerProperty)
|
|
* @param {String} params.registeredProperty.syntax
|
|
* The registered property `syntax` value
|
|
* @param {Boolean} params.registeredProperty.inherits
|
|
* The registered property `inherits` value
|
|
* @param {String} params.registeredProperty.initialValue
|
|
* The registered property `initial-value`
|
|
* @param {String} params.startingStyle
|
|
* The text for @starting-style value (e.g. `red`)
|
|
* @param {String} params.topSectionText
|
|
* Text to display in the top section of tooltip (e.g. "blue" or "--x is not defined").
|
|
* @param {String} params.variableName
|
|
* The name of the variable we're showing the tooltip for
|
|
*/
|
|
function setVariableTooltip(
|
|
tooltip,
|
|
doc,
|
|
{
|
|
computed,
|
|
cssProperties,
|
|
outputParserOptions,
|
|
registeredProperty,
|
|
startingStyle,
|
|
topSectionText,
|
|
variableName,
|
|
}
|
|
) {
|
|
// Create tooltip content
|
|
const div = doc.createElementNS(XHTML_NS, "div");
|
|
div.classList.add("devtools-monospace", "devtools-tooltip-css-variable");
|
|
|
|
const outputParser = new OutputParser(doc, cssProperties);
|
|
const parse = value =>
|
|
outputParser.parseCssProperty(variableName, value, {
|
|
...outputParserOptions,
|
|
colorSwatchReadOnly: true,
|
|
});
|
|
|
|
const valueEl = doc.createElementNS(XHTML_NS, "section");
|
|
valueEl.classList.add("variable-value");
|
|
const varData = outputParserOptions.getVariableData(variableName);
|
|
// If the variable is not defined, append the text as is so we don't get the additional
|
|
// class added by appendValue.
|
|
if (
|
|
typeof varData.value !== "string" &&
|
|
typeof registeredProperty?.initialValue !== "string"
|
|
) {
|
|
valueEl.append(doc.createTextNode(topSectionText));
|
|
} else {
|
|
appendValue(doc, valueEl, topSectionText, parse);
|
|
}
|
|
div.appendChild(valueEl);
|
|
|
|
if (typeof computed !== "undefined") {
|
|
const section = doc.createElementNS(XHTML_NS, "section");
|
|
section.classList.add("computed", "variable-tooltip-section");
|
|
|
|
const h2 = doc.createElementNS(XHTML_NS, "h2");
|
|
h2.append(doc.createTextNode(L10N_COMPUTED_VALUE));
|
|
const computedValueEl = doc.createElementNS(XHTML_NS, "div");
|
|
appendValue(doc, computedValueEl, computed, parse);
|
|
section.append(h2, computedValueEl);
|
|
|
|
div.appendChild(section);
|
|
}
|
|
|
|
if (typeof startingStyle !== "undefined") {
|
|
const section = doc.createElementNS(XHTML_NS, "section");
|
|
section.classList.add("starting-style", "variable-tooltip-section");
|
|
|
|
const h2 = doc.createElementNS(XHTML_NS, "h2");
|
|
h2.append(doc.createTextNode("@starting-style"));
|
|
const startingStyleValue = doc.createElementNS(XHTML_NS, "div");
|
|
appendValue(doc, startingStyleValue, startingStyle, parse);
|
|
section.append(h2, startingStyleValue);
|
|
|
|
div.appendChild(section);
|
|
}
|
|
|
|
// A registered property always have a non-falsy syntax
|
|
if (registeredProperty?.syntax) {
|
|
const section = doc.createElementNS(XHTML_NS, "section");
|
|
section.classList.add("registered-property", "variable-tooltip-section");
|
|
|
|
const h2 = doc.createElementNS(XHTML_NS, "h2");
|
|
h2.append(doc.createTextNode("@property"));
|
|
|
|
const dl = doc.createElementNS(XHTML_NS, "dl");
|
|
const addProperty = ({ label, value, parseValue, lineBreak }) => {
|
|
const dt = doc.createElementNS(XHTML_NS, "dt");
|
|
dt.append(doc.createTextNode(label));
|
|
const dd = doc.createElementNS(XHTML_NS, "dd");
|
|
appendValue(doc, dd, value, parseValue ? parse : null);
|
|
dl.append(dt, dd);
|
|
if (lineBreak) {
|
|
dl.append(doc.createElementNS(XHTML_NS, "br"));
|
|
}
|
|
};
|
|
|
|
const hasInitialValue = typeof registeredProperty.initialValue === "string";
|
|
|
|
addProperty({
|
|
label: "syntax:",
|
|
value: `"${registeredProperty.syntax}"`,
|
|
parseValue: false,
|
|
lineBreak: true,
|
|
});
|
|
addProperty({
|
|
label: "inherits:",
|
|
value: registeredProperty.inherits,
|
|
parseValue: false,
|
|
lineBreak: hasInitialValue,
|
|
});
|
|
if (hasInitialValue) {
|
|
addProperty({
|
|
label: "initial-value:",
|
|
value: registeredProperty.initialValue,
|
|
parseValue: true,
|
|
lineBreak: false,
|
|
});
|
|
}
|
|
|
|
section.append(h2, dl);
|
|
div.appendChild(section);
|
|
}
|
|
|
|
tooltip.panel.innerHTML = "";
|
|
tooltip.panel.appendChild(div);
|
|
tooltip.setContentSize({ width: "auto", height: "auto" });
|
|
}
|
|
|
|
/**
|
|
* Append a value into the passed element.
|
|
*
|
|
* @param {Document} doc: A document that will be used to create elements
|
|
* @param {Element} el: The element into which the rendered value will be appended
|
|
* @param {String} value: The value we want to append
|
|
* @param {Function} parse: An optional function that will be called with `value`, and whose
|
|
* result will be appended to `el`. If not passed, `value` will be appended
|
|
* as is in `el`, as a text node (if it's not empty).
|
|
*/
|
|
function appendValue(doc, el, value, parse) {
|
|
if (value !== "") {
|
|
const frag = parse && parse(value);
|
|
if (frag) {
|
|
el.append(frag);
|
|
} else {
|
|
el.append(doc.createTextNode(value));
|
|
}
|
|
el.classList.add("theme-fg-color1");
|
|
} else {
|
|
el.append(doc.createTextNode(`<${L10N_EMPTY}>`));
|
|
el.classList.add("empty-css-variable");
|
|
}
|
|
}
|
|
|
|
module.exports.setVariableTooltip = setVariableTooltip;
|