tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 2bb25af37037a3c0516e2b53e8c49ae50f036b5b
parent 98b486020c1d538e194dccade88916a85e56f201
Author: Nicolas Chevobbe <nchevobbe@mozilla.com>
Date:   Wed, 10 Dec 2025 16:17:04 +0000

Bug 1895178 - [devtools] Add inactive CSS for unsupported properties in @position-try. r=devtools-reviewers,fluent-reviewers,bolsson,ochameau.

CSS variables can't be set in @position-try rules, so we need to add a new flag in
the inactiveCSS machinery to report those.

Differential Revision: https://phabricator.services.mozilla.com/D275096

Diffstat:
Mdevtools/client/inspector/rules/test/browser_rules_position-try.js | 14+++++++-------
Mdevtools/client/locales/en-US/tooltips.ftl | 2++
Mdevtools/server/actors/utils/inactive-property-helper.js | 66++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Adevtools/server/tests/chrome/inactive-property-helper/at-position-try-rules.mjs | 383+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdevtools/server/tests/chrome/inactive-property-helper/highlight-pseudo-elements.mjs | 2+-
Mdevtools/server/tests/chrome/test_inspector-inactive-property-helper.html | 1+
6 files changed, 458 insertions(+), 10 deletions(-)

diff --git a/devtools/client/inspector/rules/test/browser_rules_position-try.js b/devtools/client/inspector/rules/test/browser_rules_position-try.js @@ -42,6 +42,7 @@ const TEST_URI = `https://example.org/document-builder.sjs?html=${encodeURICompo top: anchor(bottom); left: anchor(right); color: tomato; + --m: 10px; } </style> <main> @@ -132,8 +133,7 @@ add_task(async function () { { name: "top", value: "anchor(bottom)" }, // we have this here to make sure it's not marked as overridden / does not override // color declaration for regular rules. - // Ultimately this should be marked as inactive (see Bug 1895178) - { name: "color", value: "gold" }, + { name: "color", value: "gold", inactiveCSS: true }, ], }, ]); @@ -167,8 +167,7 @@ add_task(async function () { { name: "top", value: "anchor(bottom)" }, // we have this here to make sure it's not marked as overridden / does not override // color declaration for regular rules. - // Ultimately this should be marked as inactive (see Bug 1895178) - { name: "color", value: "gold" }, + { name: "color", value: "gold", inactiveCSS: true }, ], }, { @@ -180,8 +179,8 @@ add_task(async function () { { name: "left", value: "anchor(right)" }, // we have this here to make sure it's not marked as overridden / does not override // color declaration for regular rules. - // Ultimately this should be marked as inactive (see Bug 1895178) - { name: "color", value: "tomato" }, + { name: "color", value: "tomato", inactiveCSS: true }, + { name: "--m", value: "10px", inactiveCSS: true }, ], }, ]); @@ -215,7 +214,8 @@ add_task(async function () { declarations: [ { name: "top", value: "anchor(bottom)" }, { name: "left", value: "anchor(right)" }, - { name: "color", value: "tomato" }, + { name: "color", value: "tomato", inactiveCSS: true }, + { name: "--m", value: "10px", inactiveCSS: true }, ], }, ]); diff --git a/devtools/client/locales/en-US/tooltips.ftl b/devtools/client/locales/en-US/tooltips.ftl @@ -89,6 +89,8 @@ inactive-css-highlight-pseudo-elements-not-supported = <strong>{ $property }</st inactive-css-cue-pseudo-element-not-supported = <strong>{ $property }</strong> is not supported on ::cue pseudo-elements. +inactive-css-at-position-try-not-supported = <strong>{ $property }</strong> is not supported in <strong>@position-try</strong> rules. + # Variables: # $lineCount (integer) - The number of lines the element has. inactive-css-text-wrap-balance-lines-exceeded = diff --git a/devtools/server/actors/utils/inactive-property-helper.js b/devtools/server/actors/utils/inactive-property-helper.js @@ -97,6 +97,9 @@ const FIRST_LETTER_PSEUDO_ELEMENT_STYLING_SPEC_URL = const PLACEHOLDER_PSEUDO_ELEMENT_STYLING_SPEC_URL = "https://www.w3.org/TR/css-pseudo-4/#placeholder-pseudo"; +const AT_POSITION_TRY_MDN_URL = + "https://developer.mozilla.org/docs/Web/CSS/Reference/At-rules/@position-try"; + class InactivePropertyHelper { /** * A list of rules for when CSS properties have no effect. @@ -787,6 +790,66 @@ class InactivePropertyHelper { fixId: "learn-more", learnMoreURL: CUE_PSEUDO_ELEMENT_STYLING_SPEC_URL, }, + // Constrained set of properties on @position-try rules + { + // List from Object.keys(CSSPositionTryDescriptors.prototype) + // We should directly retrieve the properties from the CSSPositionTryDescriptors.prototype + // See Bug 2005233 + acceptedProperties: new Set([ + "position-anchor", + "position-area", + // Inset property descriptors + "top", + "left", + "bottom", + "right", + "inset-block-start", + "inset-block-end", + "inset-inline-start", + "inset-inline-end", + "inset-block", + "inset-inline", + "inset", + // Margin property descriptors + "margin-top", + "margin-left", + "margin-bottom", + "margin-right", + "margin-block-start", + "margin-block-end", + "margin-inline-start", + "margin-inline-end", + "margin", + "margin-block", + "margin-inline", + "-moz-margin-start", + "-moz-margin-end", + // Sizing property descriptors + "width", + "height", + "min-width", + "min-height", + "max-width", + "max-height", + "block-size", + "inline-size", + "min-block-size", + "min-inline-size", + "max-block-size", + "max-inline-size", + // Self-alignment property descriptors + "align-self", + "justify-self", + "place-self", + "-webkit-align-self", + ]), + rejectCustomProperties: true, + when: () => + ChromeUtils.getClassName(this.cssRule) === "CSSPositionTryRule", + msgId: "inactive-css-at-position-try-not-supported", + fixId: "learn-more", + learnMoreURL: AT_POSITION_TRY_MDN_URL, + }, ]; /** @@ -851,8 +914,7 @@ class InactivePropertyHelper { } else if (validator.acceptedProperties) { isRuleConcerned = !validator.acceptedProperties.has(property) && - // custom properties can always be set - !property.startsWith("--"); + (!property.startsWith("--") || validator.rejectCustomProperties); } if (!isRuleConcerned) { diff --git a/devtools/server/tests/chrome/inactive-property-helper/at-position-try-rules.mjs b/devtools/server/tests/chrome/inactive-property-helper/at-position-try-rules.mjs @@ -0,0 +1,383 @@ +/* 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/. */ + +/* + InactivePropertyHelper `@position-try` + - position-anchor + - position-area + - Inset property descriptors + - top + - left + - bottom + - right + - inset-block-start + - inset-block-end + - inset-inline-start + - inset-inline-end + - inset-block + - inset-inline + - inset + - Margin property descriptors: + - margin-top + - margin-left + - margin-bottom + - margin-right + - margin-block-start + - margin-block-end + - margin-inline-start + - margin-inline-end + - margin + - margin-block + - margin-inline + - Sizing property descriptors: + - width + - height + - min-width + - min-height + - max-width + - max-height + - block-size + - inline-size + - min-block-size + - min-inline-size + - max-block-size + - max-inline-size + - Self-alignment property descriptors: + - align-self + - justify-self + - place-self +*/ + +export default [ + { + info: "color is inactive in @position-try", + property: "color", + tagName: "div", + rules: ["@position-try --pt { color: tomato; }"], + isActive: false, + expectedMsgId: "inactive-css-at-position-try-not-supported", + }, + { + info: "background is inactive in @position-try", + property: "background", + tagName: "div", + rules: ["@position-try --pt { background: gold; }"], + isActive: false, + expectedMsgId: "inactive-css-at-position-try-not-supported", + }, + { + info: "top is still inactive on non-fixed element", + property: "top", + tagName: "div", + rules: ["@position-try --pt { top: 0; }"], + isActive: false, + }, + { + info: "custom property are inactive in @position-try", + property: "--my-var", + tagName: "div", + rules: ["@position-try --pt { --my-var: red; }"], + isActive: false, + }, + { + info: "position-anchor is active in @position-try", + property: "position-anchor", + tagName: "div", + rules: ["@position-try --pt { position-anchor: auto; }"], + isActive: true, + }, + { + info: "position-area is active in @position-try", + property: "position-area", + tagName: "div", + rules: ["@position-try --pt { position-area: top left; }"], + isActive: true, + }, + { + info: "top is active in @position-try", + property: "top", + tagName: "div", + rules: ["@position-try --pt { top: 0; }", "div { position: fixed; }"], + isActive: true, + }, + { + info: "left is active in @position-try", + property: "left", + tagName: "div", + rules: ["@position-try --pt { left: 0; }", "div { position: fixed; }"], + isActive: true, + }, + { + info: "bottom is active in @position-try", + property: "bottom", + tagName: "div", + rules: ["@position-try --pt { bottom: 0; }", "div { position: fixed; }"], + isActive: true, + }, + { + info: "right is active in @position-try", + property: "right", + tagName: "div", + rules: ["@position-try --pt { right: 0; }", "div { position: fixed; }"], + isActive: true, + }, + { + info: "inset-block-start is active in @position-try", + property: "inset-block-start", + tagName: "div", + rules: [ + "@position-try --pt { inset-block-start: 0; }", + "div { position: fixed; }", + ], + isActive: true, + }, + { + info: "inset-block-end is active in @position-try", + property: "inset-block-end", + tagName: "div", + rules: [ + "@position-try --pt { inset-block-end: 0; }", + "div { position: fixed; }", + ], + isActive: true, + }, + { + info: "inset-inline-start is active in @position-try", + property: "inset-inline-start", + tagName: "div", + rules: [ + "@position-try --pt { inset-inline-start: 0; }", + "div { position: fixed; }", + ], + isActive: true, + }, + { + info: "inset-inline-end is active in @position-try", + property: "inset-inline-end", + tagName: "div", + rules: [ + "@position-try --pt { inset-inline-end: 0; }", + "div { position: fixed; }", + ], + isActive: true, + }, + { + info: "inset-block is active in @position-try", + property: "inset-block", + tagName: "div", + rules: [ + "@position-try --pt { inset-block: 0; }", + "div { position: fixed; }", + ], + isActive: true, + }, + { + info: "inset-inline is active in @position-try", + property: "inset-inline", + tagName: "div", + rules: [ + "@position-try --pt { inset-inline: 0; }", + "div { position: fixed; }", + ], + isActive: true, + }, + { + info: "inset is active in @position-try", + property: "inset", + tagName: "div", + rules: ["@position-try --pt { inset: 0; }", "div { position: fixed; }"], + isActive: true, + }, + { + info: "margin-top is active in @position-try", + property: "margin-top", + tagName: "div", + rules: ["@position-try --pt { margin-top: 10px; }"], + isActive: true, + }, + { + info: "margin-left is active in @position-try", + property: "margin-left", + tagName: "div", + rules: ["@position-try --pt { margin-left: 10px; }"], + isActive: true, + }, + { + info: "margin-bottom is active in @position-try", + property: "margin-bottom", + tagName: "div", + rules: ["@position-try --pt { margin-bottom: 10px; }"], + isActive: true, + }, + { + info: "margin-right is active in @position-try", + property: "margin-right", + tagName: "div", + rules: ["@position-try --pt { margin-right: 10px; }"], + isActive: true, + }, + { + info: "margin-block-start is active in @position-try", + property: "margin-block-start", + tagName: "div", + rules: ["@position-try --pt { margin-block-start: 10px; }"], + isActive: true, + }, + { + info: "margin-block-end is active in @position-try", + property: "margin-block-end", + tagName: "div", + rules: ["@position-try --pt { margin-block-end: 10px; }"], + isActive: true, + }, + { + info: "margin-inline-start is active in @position-try", + property: "margin-inline-start", + tagName: "div", + rules: ["@position-try --pt { margin-inline-start: 10px; }"], + isActive: true, + }, + { + info: "margin-inline-end is active in @position-try", + property: "margin-inline-end", + tagName: "div", + rules: ["@position-try --pt { margin-inline-end: 10px; }"], + isActive: true, + }, + { + info: "margin is active in @position-try", + property: "margin", + tagName: "div", + rules: ["@position-try --pt { margin: 10px; }"], + isActive: true, + }, + { + info: "margin-block is active in @position-try", + property: "margin-block", + tagName: "div", + rules: ["@position-try --pt { margin-block: 10px; }"], + isActive: true, + }, + { + info: "margin-inline is active in @position-try", + property: "margin-inline", + tagName: "div", + rules: ["@position-try --pt { margin-inline: 10px; }"], + isActive: true, + }, + { + info: "width is active in @position-try", + property: "width", + tagName: "div", + rules: ["@position-try --pt { width: 200px; }"], + isActive: true, + }, + { + info: "height is active in @position-try", + property: "height", + tagName: "div", + rules: ["@position-try --pt { height: 200px; }"], + isActive: true, + }, + { + info: "min-width is active in @position-try", + property: "min-width", + tagName: "div", + rules: ["@position-try --pt { min-width: 200px; }"], + isActive: true, + }, + { + info: "min-height is active in @position-try", + property: "min-height", + tagName: "div", + rules: ["@position-try --pt { min-height: 200px; }"], + isActive: true, + }, + { + info: "max-width is active in @position-try", + property: "max-width", + tagName: "div", + rules: ["@position-try --pt { max-width: 200px; }"], + isActive: true, + }, + { + info: "max-height is active in @position-try", + property: "max-height", + tagName: "div", + rules: ["@position-try --pt { max-height: 200px; }"], + isActive: true, + }, + { + info: "block-size is active in @position-try", + property: "block-size", + tagName: "div", + rules: ["@position-try --pt { block-size: 200px; }"], + isActive: true, + }, + { + info: "inline-size is active in @position-try", + property: "inline-size", + tagName: "div", + rules: ["@position-try --pt { inline-size: 200px; }"], + isActive: true, + }, + { + info: "min-block-size is active in @position-try", + property: "min-block-size", + tagName: "div", + rules: ["@position-try --pt { min-block-size: 200px; }"], + isActive: true, + }, + { + info: "min-inline-size is active in @position-try", + property: "min-inline-size", + tagName: "div", + rules: ["@position-try --pt { min-inline-size: 200px; }"], + isActive: true, + }, + { + info: "max-block-size is active in @position-try", + property: "max-block-size", + tagName: "div", + rules: ["@position-try --pt { max-block-size: 200px; }"], + isActive: true, + }, + { + info: "max-inline-size is active in @position-try", + property: "max-inline-size", + tagName: "div", + rules: ["@position-try --pt { max-inline-size: 200px; }"], + isActive: true, + }, + { + info: "align-self is active in @position-try", + property: "align-self", + tagName: "div", + rules: [ + "@position-try --pt { align-self: center; }", + "div { position: fixed; }", + ], + isActive: true, + }, + { + info: "justify-self is active in @position-try", + property: "justify-self", + tagName: "div", + rules: [ + "@position-try --pt { justify-self: center; }", + "div { position: fixed; }", + ], + isActive: true, + }, + { + info: "place-self is active in @position-try", + property: "place-self", + tagName: "div", + rules: [ + "@position-try --pt { place-self: center; }", + "div { position: fixed; }", + ], + isActive: true, + }, +]; diff --git a/devtools/server/tests/chrome/inactive-property-helper/highlight-pseudo-elements.mjs b/devtools/server/tests/chrome/inactive-property-helper/highlight-pseudo-elements.mjs @@ -173,7 +173,7 @@ export default [ info: "custom property is active on ::target-text", property: "--my-var", tagName: "span", - rules: ["span::target-text { -my-var: red; }"], + rules: ["span::target-text { --my-var: red; }"], isActive: true, }, ]; diff --git a/devtools/server/tests/chrome/test_inspector-inactive-property-helper.html b/devtools/server/tests/chrome/test_inspector-inactive-property-helper.html @@ -46,6 +46,7 @@ SimpleTest.waitForExplicitFinish(); // - {Boolean} isActive: should the property be active (e.g. getInactiveCssDataForProperty returns null). const testFiles = [ "align-content.mjs", + "at-position-try-rules.mjs", "anchor-name.mjs", "block-container-properties.mjs", "block-flex-grid-container-properties.mjs",