Bug 1892192 - [devtools] Display @starting-style rules in Rules view. r=devtools-reviewers,bomsy.

This takes care of displaying `@starting-style` rules in the Rules view.
A test is added to cover this, as well as a test case to make sure those
starting style rules are not impacting the computed panel.

Depends on D210363

Differential Revision: https://phabricator.services.mozilla.com/D209329
This commit is contained in:
Nicolas Chevobbe 2024-06-10 07:09:04 +00:00
Родитель e76d75367b
Коммит 5f5e0ad8a3
8 изменённых файлов: 144 добавлений и 1 удалений

Просмотреть файл

@ -7,6 +7,7 @@
const TEST_URI = URL_ROOT + "doc_matched_selectors.html";
add_task(async function () {
await pushPref("layout.css.starting-style-at-rules.enabled", true);
await addTab(TEST_URI);
const { inspector, view } = await openComputedView();

Просмотреть файл

@ -40,6 +40,11 @@
min-width: 10px;
min-height: 10px;
display: inline-block;
/* starting-style rules should be ignored by the computed view */
@starting-style {
background-color: honeydew;
}
}
</style>
</head>

Просмотреть файл

@ -72,6 +72,8 @@ skip-if = ["verify && debug && os == 'win'"]
["browser_rules_at_scope.js"]
["browser_rules_at_starting-style.js"]
["browser_rules_authored.js"]
["browser_rules_authored_color.js"]

Просмотреть файл

@ -0,0 +1,126 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test that the rule-view properly handles @starting-style rules.
const TEST_URI = `
<style>
h1, [data-test="top-level"] {
color: tomato;
transition: all 1s;
@starting-style {
color: gold;
}
}
@starting-style {
body, [data-test="in-starting-style"] {
color: navy;
}
@layer {
body, [data-test="in-starting-style-layer"] {
color: hotpink;
}
}
h1, [data-test="in-starting-style"] {
background-color: salmon;
}
}
</style>
<h1>Hello @starting-style!</h1>`;
add_task(async function () {
await pushPref("layout.css.starting-style-at-rules.enabled", true);
await addTab(
"https://example.com/document-builder.sjs?html=" +
encodeURIComponent(TEST_URI)
);
const { inspector, view } = await openRuleView();
await assertRules("body", [
{ selector: `element`, ancestorRulesData: null },
{
selector: `body, [data-test="in-starting-style"]`,
ancestorRulesData: ["@starting-style {"],
},
{
selector: `body, [data-test="in-starting-style-layer"]`,
ancestorRulesData: ["@starting-style {", " @layer {"],
},
]);
await assertRules("h1", [
{ selector: `element`, ancestorRulesData: null },
{
selector: `&`,
ancestorRulesData: [
`h1, [data-test="top-level"] {`,
" @starting-style {",
],
},
{
selector: `h1, [data-test="in-starting-style"]`,
ancestorRulesData: ["@starting-style {"],
},
{
selector: `h1, [data-test="top-level"]`,
ancestorRulesData: null,
},
]);
// TODO: Check overridden and "transitioned" properties
async function assertRules(nodeSelector, expectedRules) {
await selectNode(nodeSelector, inspector);
const rulesInView = Array.from(
view.element.querySelectorAll(".ruleview-rule")
);
is(
rulesInView.length,
expectedRules.length,
`[${nodeSelector}] All expected rules are displayed`
);
for (let i = 0; i < expectedRules.length; i++) {
const expectedRule = expectedRules[i];
info(`[${nodeSelector}] Checking rule #${i}: ${expectedRule.selector}`);
const selector = rulesInView[i].querySelector(
".ruleview-selectors-container"
)?.innerText;
is(
selector,
expectedRule.selector,
`[${nodeSelector}] Expected selector for rule #${i}`
);
const isInherited = rulesInView[i].matches(
".ruleview-header-inherited + .ruleview-rule"
);
if (expectedRule.inherited) {
ok(isInherited, `[${nodeSelector}] rule #${i} is inherited`);
} else {
ok(!isInherited, `[${nodeSelector}] rule #${i} is not inherited`);
}
if (expectedRule.ancestorRulesData == null) {
is(
getRuleViewAncestorRulesDataElementByIndex(view, i),
null,
`[${nodeSelector}] No ancestor rules data displayed for ${selector}`
);
} else {
is(
getRuleViewAncestorRulesDataTextByIndex(view, i),
expectedRule.ancestorRulesData.join("\n"),
`[${nodeSelector}] Expected ancestor rules data displayed for ${selector}`
);
}
}
}
});

Просмотреть файл

@ -263,6 +263,8 @@ RuleEditor.prototype = {
}
}
selectorContainer.append(this.doc.createTextNode(text));
} else if (ancestorData.type == "starting-style") {
selectorContainer.append(this.doc.createTextNode(`@starting-style`));
} else if (ancestorData.selectors) {
ancestorData.selectors.forEach((selector, i) => {
if (i !== 0) {

Просмотреть файл

@ -751,7 +751,9 @@ class PageStyleActor extends Actor {
const domRules = InspectorUtils.getCSSStyleRules(
node,
pseudo,
CssLogic.hasVisitedState(node)
CssLogic.hasVisitedState(node),
/* we don't need to retrieve inherited starting style rules */
!inherited
);
if (!domRules) {

Просмотреть файл

@ -550,6 +550,10 @@ class StyleRuleActor extends Actor {
start: rawRule.start,
end: rawRule.end,
});
} else if (ruleClassName === "CSSStartingStyleRule") {
ancestorData.push({
type,
});
} else if (rawRule.selectorText) {
// All the previous cases where about at-rules; this one is for regular rule
// that are ancestors because CSS nesting was used.

Просмотреть файл

@ -75,6 +75,7 @@ exports.CSSAtRuleClassNameType = {
CSSNamespaceRule: "namespace",
CSSPageRule: "page",
CSSScopeRule: "scope",
CSSStartingStyleRule: "starting-style",
CSSSupportsRule: "supports",
};