From 1ecb7e8f230c31524c6b9170a121f14198585709 Mon Sep 17 00:00:00 2001 From: Anders Hartvoll Ruud Date: Thu, 22 Aug 2024 08:42:52 -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 [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 | 163 ++++++++++++++++++ css/css-nesting/nesting-basic.html | 4 +- .../serialize-group-rules-with-decls.html | 8 +- .../custom-property-rule-ambiguity.html | 7 +- 6 files changed, 329 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 d299ba30370516..c0fc7150fae00a 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 00000000000000..42e3930fbeb5df --- /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 00000000000000..0dc272e1a7ba5b --- /dev/null +++ b/css/css-nesting/nested-declarations-matching.html @@ -0,0 +1,163 @@ + +CSS Nesting: CSSNestedDeclarations matching + + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + +
+ + + +
+ + + + +
+ diff --git a/css/css-nesting/nesting-basic.html b/css/css-nesting/nesting-basic.html index 19ff48e4a29588..9edff4ea1af6a2 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 7e9aaafbeb894c..e15210c2dd2dca 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 04f908acde2e72..a8ac1de2c556ea 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');