mirror of
https://github.com/HeyPuter/firefox.git
synced 2026-11-13 20:14:57 -10:00
The computed panel was already read only, but this was done by checking the swatch class name directly in the output parser, which is not ideal. Here we have a proper setting, that we can use in the computed panel, as well as in the variable tooltip, where we can't interact with the swatches. The pointer cursor is only added onto swatches that are a button or have a button role. Tests are updated accordingly. Differential Revision: https://phabricator.services.mozilla.com/D220819
196 lines
6.8 KiB
JavaScript
196 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;
|