From bfc0c72a164561885d6f8df97f2eaf931fc1c0be Mon Sep 17 00:00:00 2001 From: Anders Hartvoll Ruud Date: Tue, 27 Aug 2024 02:54:21 -0700 Subject: [PATCH] [css-nesting] Implement CSSNestedDeclarations behind a flag The CSSWG recently resolved to change how "bare" declarations work when mixed with nested style rules. Previously, any declaration following a nested style rule would be "shifted up" to join the leading declarations, but as of the work leading up to Issue 10234 [1], such declarations now instead remain in place (wrapped in a CSSNestedDeclarations rule). This CL implements this rule, as well as the parser changes needed to produce those rules during ConsumeDeclarationList. The parsing behavior is similar to the behavior previously seen for emitting signalling/invisible rules (removed in CL:5593832), although naturally without any signalling, nor any invisibility. Per spec, CSSNestedDeclarations is a kind of style rule that matches exactly what its parent style rule matches, and with the same specificity behavior. This is different from the '&' pseudo-class, which uses the maximum specificity across its arguments, and can't match pseudo-elements. This CL implements this via an inner StyleRule, held by the CSSNestedDeclarations rule. This inner StyleRule can't be observed via CSSOM. It exists primarily to be able to bucket the rule normally on RuleSet. Change-Id: If9afe0cbb41e7de0acdd781ecfbf6884d677c6f8 Binary-Size: crbug.com/344608183 Bug: 343463516, 361600667 [1] https://github.com/w3c/csswg-drafts/issues/10234 --- css/css-cascade/scope-nesting.html | 13 +- .../nested-declarations-cssom.html | 150 +++++++++++++ .../nested-declarations-matching.html | 197 ++++++++++++++++++ css/css-nesting/nesting-basic.html | 4 +- .../serialize-group-rules-with-decls.html | 8 +- .../custom-property-rule-ambiguity.html | 7 +- 6 files changed, 363 insertions(+), 16 deletions(-) create mode 100644 css/css-nesting/nested-declarations-cssom.html create mode 100644 css/css-nesting/nested-declarations-matching.html diff --git a/css/css-cascade/scope-nesting.html b/css/css-cascade/scope-nesting.html index d299ba30370516a..c0fc7150fae00ad 100644 --- a/css/css-cascade/scope-nesting.html +++ b/css/css-cascade/scope-nesting.html @@ -339,16 +339,15 @@
diff --git a/css/css-nesting/nested-declarations-cssom.html b/css/css-nesting/nested-declarations-cssom.html new file mode 100644 index 000000000000000..42e3930fbeb5df2 --- /dev/null +++ b/css/css-nesting/nested-declarations-cssom.html @@ -0,0 +1,150 @@ + +CSS Nesting: CSSNestedDeclarations CSSOM + + + + diff --git a/css/css-nesting/nested-declarations-matching.html b/css/css-nesting/nested-declarations-matching.html new file mode 100644 index 000000000000000..b6c0fe7a75dfe22 --- /dev/null +++ b/css/css-nesting/nested-declarations-matching.html @@ -0,0 +1,197 @@ + +CSS Nesting: CSSNestedDeclarations matching + + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + +
+ + + +
+ + + + +
+ + + +
+
A1
+
A2
+
+ diff --git a/css/css-nesting/nesting-basic.html b/css/css-nesting/nesting-basic.html index 19ff48e4a29588e..9edff4ea1af6a21 100644 --- a/css/css-nesting/nesting-basic.html +++ b/css/css-nesting/nesting-basic.html @@ -68,9 +68,9 @@ .test-10 { & { - background-color: green; + background-color: red; } - background-color: red; + background-color: green; } .test-11 { diff --git a/css/css-nesting/serialize-group-rules-with-decls.html b/css/css-nesting/serialize-group-rules-with-decls.html index 7e9aaafbeb894c2..e15210c2dd2dca8 100644 --- a/css/css-nesting/serialize-group-rules-with-decls.html +++ b/css/css-nesting/serialize-group-rules-with-decls.html @@ -35,12 +35,12 @@ assert_becomes( "div { @media screen { color: red; background-color: green; } }", - "div {\n @media screen {\n & { color: red; background-color: green; }\n}\n}", + "div {\n @media screen {\n color: red; background-color: green;\n}\n}", "Mixed declarations/rules are on two lines." ); assert_becomes( "div {\n @supports selector(&) { color: red; background-color: green; } &:hover { color: navy; } }", - "div {\n @supports selector(&) {\n & { color: red; background-color: green; }\n}\n &:hover { color: navy; }\n}", + "div {\n @supports selector(&) {\n color: red; background-color: green;\n}\n &:hover { color: navy; }\n}", "Implicit rule is serialized", ); @@ -62,12 +62,12 @@ ); assert_becomes( "div { @media screen { color: red; & { color: red; }", - "div {\n @media screen {\n & { color: red; }\n & { color: red; }\n}\n}", + "div {\n @media screen {\n color: red;\n & { color: red; }\n}\n}", "Implicit like rule after decls" ); assert_becomes( "div { @media screen { color: red; & { color: blue; }", - "div {\n @media screen {\n & { color: red; }\n & { color: blue; }\n}\n}", + "div {\n @media screen {\n color: red;\n & { color: blue; }\n}\n}", "Implicit like rule after decls, missing closing braces" ); assert_becomes( diff --git a/css/css-syntax/custom-property-rule-ambiguity.html b/css/css-syntax/custom-property-rule-ambiguity.html index 04f908acde2e72f..a8ac1de2c556ea1 100644 --- a/css/css-syntax/custom-property-rule-ambiguity.html +++ b/css/css-syntax/custom-property-rule-ambiguity.html @@ -46,11 +46,12 @@ assert_equals(rules.length, 1); assert_equals(rules[0].selectorText, 'div'); let div = rules[0]; - let x = div.style.getPropertyValue('--x'); - assert_equals(x.trim(), 'hover { }\n .b { }'); let childRules = div.cssRules; - assert_equals(childRules.length, 1); + assert_equals(childRules.length, 2); assert_equals(childRules[0].selectorText, '& .a'); + assert_true(childRules[1] instanceof CSSNestedDeclarations) + let x = childRules[1].style.getPropertyValue('--x'); + assert_equals(x.trim(), 'hover { }\n .b { }'); }, 'Nested rule that looks like a custom property declaration');