Issue #2862 - Fix a few nested selectors

This commit is contained in:
Basilisk-Dev 2026-03-11 22:49:25 -04:00 • committed by wuggy
commit f2560c57b6
2 changed files with 134 additions and 145 deletions

View file

@ -683,7 +683,7 @@ private:
if (c == '{') { if (c == '{') {
return true; return true;
} }
if (c == ':' || c == ';' || c == '}') { if (c == ';' || c == '}') {
return false; return false;
} }
} }

View file

@ -1,157 +1,146 @@
<!doctype html> <!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8">
<title>Test for Basic CSS Nesting Lowering</title> <title>Test for Basic CSS Nesting Lowering</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script> <script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css" /> <link rel="stylesheet" href="/tests/SimpleTest/test.css">
</head> </head>
<body> <body>
<div id="scope" class="scope order"> <div id="scope" class="scope order">
<span id="desc" class="desc"></span> <span id="desc" class="desc"></span>
</div> </div>
<div id="button" class="button active"></div> <div id="button" class="button active"></div>
<pre id="standalone-log"></pre> <pre id="standalone-log"></pre>
<script> <script>
"use strict"; "use strict";
function colorOf(win, element, property) { function colorOf(win, element, property) {
return win.getComputedStyle(element).getPropertyValue(property); return win.getComputedStyle(element).getPropertyValue(property);
} }
function appendTestSheet() { function appendTestSheet() {
var style = document.createElement("style"); var style = document.createElement("style");
style.textContent = style.textContent =
".scope {\n" + ".scope {\n" +
" color: rgb(1, 2, 3);\n" + " color: rgb(1, 2, 3);\n" +
" .desc {\n" + " .desc {\n" +
" color: rgb(4, 5, 6);\n" + " color: rgb(4, 5, 6);\n" +
" }\n" + " }\n" +
" span {\n" + " span {\n" +
" border-left-style: solid;\n" + " border-left-style: solid;\n" +
" border-left-color: rgb(19, 20, 21);\n" + " border-left-color: rgb(19, 20, 21);\n" +
" }\n" + " }\n" +
" background-color: rgb(7, 8, 9);\n" + " span:first-child, span:last-child {\n" +
"}\n" + " border-bottom-style: solid;\n" +
"\n" + " border-bottom-color: rgb(22, 23, 24);\n" +
".button {\n" + " }\n" +
" &.active {\n" + " background-color: rgb(7, 8, 9);\n" +
" color: rgb(10, 11, 12);\n" + "}\n" +
" }\n" + "\n" +
"}\n" + ".button {\n" +
"\n" + " &.active {\n" +
".order {\n" + " color: rgb(10, 11, 12);\n" +
" border-top-style: solid;\n" + " }\n" +
" @media all {\n" + "}\n" +
" & {\n" + "\n" +
" border-top-color: rgb(13, 14, 15);\n" + ".order {\n" +
" }\n" + " border-top-style: solid;\n" +
" }\n" + " @media all {\n" +
" border-right-style: solid;\n" + " & {\n" +
" border-right-color: rgb(16, 17, 18);\n" + " border-top-color: rgb(13, 14, 15);\n" +
"}\n"; " }\n" +
document.head.appendChild(style); " }\n" +
return style; " border-right-style: solid;\n" +
} " border-right-color: rgb(16, 17, 18);\n" +
"}\n";
document.head.appendChild(style);
return style;
}
function runChecks(style, report) { function runChecks(style, report) {
var scope = document.getElementById("scope"); var scope = document.getElementById("scope");
var desc = document.getElementById("desc"); var desc = document.getElementById("desc");
var button = document.getElementById("button"); var button = document.getElementById("button");
report( report(colorOf(window, scope, "color") === "rgb(1, 2, 3)",
colorOf(window, scope, "color") === "rgb(1, 2, 3)", "outer rule declarations should apply",
"outer rule declarations should apply", colorOf(window, scope, "color"),
colorOf(window, scope, "color"), "rgb(1, 2, 3)");
"rgb(1, 2, 3)", report(colorOf(window, desc, "color") === "rgb(4, 5, 6)",
); "nested descendant rule should be lowered",
report( colorOf(window, desc, "color"),
colorOf(window, desc, "color") === "rgb(4, 5, 6)", "rgb(4, 5, 6)");
"nested descendant rule should be lowered", report(colorOf(window, desc, "border-left-color") === "rgb(19, 20, 21)",
colorOf(window, desc, "color"), "nested type selector rule should be lowered",
"rgb(4, 5, 6)", colorOf(window, desc, "border-left-color"),
); "rgb(19, 20, 21)");
report( report(colorOf(window, desc, "border-bottom-color") === "rgb(22, 23, 24)",
colorOf(window, desc, "border-left-color") === "rgb(19, 20, 21)", "nested type selector pseudos should be lowered",
"nested type selector rule should be lowered", colorOf(window, desc, "border-bottom-color"),
colorOf(window, desc, "border-left-color"), "rgb(22, 23, 24)");
"rgb(19, 20, 21)", report(colorOf(window, scope, "background-color") === "rgb(7, 8, 9)",
); "declarations after a nested rule should preserve order",
report( colorOf(window, scope, "background-color"),
colorOf(window, scope, "background-color") === "rgb(7, 8, 9)", "rgb(7, 8, 9)");
"declarations after a nested rule should preserve order", report(colorOf(window, button, "color") === "rgb(10, 11, 12)",
colorOf(window, scope, "background-color"), "ampersand selectors should be expanded",
"rgb(7, 8, 9)", colorOf(window, button, "color"),
); "rgb(10, 11, 12)");
report( report(colorOf(window, scope, "border-top-color") === "rgb(13, 14, 15)",
colorOf(window, button, "color") === "rgb(10, 11, 12)", "nested group rules should target the parent selector",
"ampersand selectors should be expanded", colorOf(window, scope, "border-top-color"),
colorOf(window, button, "color"), "rgb(13, 14, 15)");
"rgb(10, 11, 12)", report(colorOf(window, scope, "border-right-color") === "rgb(16, 17, 18)",
); "declarations after nested group rules should still apply",
report( colorOf(window, scope, "border-right-color"),
colorOf(window, scope, "border-top-color") === "rgb(13, 14, 15)", "rgb(16, 17, 18)");
"nested group rules should target the parent selector", report(style.sheet.cssRules.length === 9,
colorOf(window, scope, "border-top-color"), "lowering should produce flat top-level rules",
"rgb(13, 14, 15)", String(style.sheet.cssRules.length),
); "9");
report( }
colorOf(window, scope, "border-right-color") === "rgb(16, 17, 18)",
"declarations after nested group rules should still apply",
colorOf(window, scope, "border-right-color"),
"rgb(16, 17, 18)",
);
report(
style.sheet.cssRules.length === 8,
"lowering should produce flat top-level rules",
String(style.sheet.cssRules.length),
"8",
);
}
function runStandalone() { function runStandalone() {
var log = document.getElementById("standalone-log"); var log = document.getElementById("standalone-log");
var lines = [ var lines = [
"Standalone mode.", "Standalone mode.",
"This page only demonstrates nesting if layout.css.nesting.enabled is already true in the browser.", "This page only demonstrates nesting if layout.css.nesting.enabled is already true in the browser.",
"", ""
]; ];
var style = appendTestSheet(); var style = appendTestSheet();
runChecks(style, function (pass, message, actual, expected) { runChecks(style, function(pass, message, actual, expected) {
lines.push((pass ? "PASS" : "FAIL") + ": " + message); lines.push((pass ? "PASS" : "FAIL") + ": " + message);
if (!pass) { if (!pass) {
lines.push(" expected: " + expected); lines.push(" expected: " + expected);
lines.push(" actual: " + actual); lines.push(" actual: " + actual);
} }
}); });
log.textContent = lines.join("\n"); log.textContent = lines.join("\n");
} }
function runMochitest() { function runMochitest() {
SimpleTest.waitForExplicitFinish(); SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv( SpecialPowers.pushPrefEnv({
{ set: [["layout.css.nesting.enabled", true]]
set: [["layout.css.nesting.enabled", true]], }, function() {
}, var style = appendTestSheet();
function () {
var style = appendTestSheet();
runChecks(style, function (pass, message, actual, expected) { runChecks(style, function(pass, message, actual, expected) {
is(actual, expected, message); is(actual, expected, message);
}); });
SimpleTest.finish(); SimpleTest.finish();
}, });
); }
}
if (typeof SimpleTest !== "undefined" && typeof SpecialPowers !== "undefined") { if (typeof SimpleTest !== "undefined" && typeof SpecialPowers !== "undefined") {
runMochitest(); runMochitest();
} else { } else {
runStandalone(); runStandalone();
} }
</script> </script>
</body> </body>
</html> </html>