From 22078b3f687a5e224b4785b2ee6483a19c10671b Mon Sep 17 00:00:00 2001 From: Anders Hartvoll Ruud Date: Thu, 14 Nov 2024 11:25:36 -0800 Subject: [PATCH] [@scope] Support '@import scope(...)' behind a flag This CL implements the ability to scope an entire stylesheet on import, via the new scope() function. The CSSWG has resolved to add the scope() function, but there is no spec yet. The WPTs are therefore marked as tentative for now. Note that this CL intentionally does not have parse-validity tests, such as scope() combined with other features of the @import prelude (e.g. layer(), media queries). This is because scope()'s "position" in the prelude grammar has not been defined, and the WG instead resolved allow full reordering of the conditions. This opens a new problem, tracked by Issue 10972 [1]. In other words, parsing tests are deferred until that issue is resolved. The WPTs in this only use @import scope(...)", which is assumed to be valid regardless of the outcome. Since regular top-level selectors are not relative selectors, they are not guaranteed to contain either '&' or ':scope' like selector parsing nested under CSSNestingType::kNesting or CSSNestingType::kScope (respectively). This means that selectors at the top-level of an imported stylesheet are not guaranteed to be scope-containing, so we need another way of enforcing the in-scope [2] requirement of scoped selectors. This is effectively done by always treating the last selector in a complex selector as scope-containing. Due to the same absence of '&' and ':scope' in the imported stylesheet, rules can also be incorrectly handled as "easy" or "covered by bucketing" even though they match in the context of a scope. Addressed this by disabling the optimization when context.style_scope is set. [1] https://github.com/w3c/csswg-drafts/issues/10972 [2] https://drafts.csswg.org/css-cascade-6/#in-scope Bug: 369876911 Change-Id: I75bc3514d959c6762232bc769f844682ed4a50fd --- css/css-cascade/resources/scope-imported.css | 21 ++++++++++++ .../scope-import-implicit.tentative.html | 25 +++++++++++++++ .../scope-import-inner-scope.tentative.html | 29 +++++++++++++++++ .../scope-import-multiple.tentative.html | 31 ++++++++++++++++++ .../scope-import-parent-pseudo.tentative.html | 32 +++++++++++++++++++ .../scope-import-scope-end.tentative.html | 27 ++++++++++++++++ .../scope-import-scope-pseudo.tentative.html | 29 +++++++++++++++++ .../scope-import-scope-start.tentative.html | 25 +++++++++++++++ 8 files changed, 219 insertions(+) create mode 100644 css/css-cascade/resources/scope-imported.css create mode 100644 css/css-cascade/scope-import-implicit.tentative.html create mode 100644 css/css-cascade/scope-import-inner-scope.tentative.html create mode 100644 css/css-cascade/scope-import-multiple.tentative.html create mode 100644 css/css-cascade/scope-import-parent-pseudo.tentative.html create mode 100644 css/css-cascade/scope-import-scope-end.tentative.html create mode 100644 css/css-cascade/scope-import-scope-pseudo.tentative.html create mode 100644 css/css-cascade/scope-import-scope-start.tentative.html diff --git a/css/css-cascade/resources/scope-imported.css b/css/css-cascade/resources/scope-imported.css new file mode 100644 index 000000000000000..d0fa1954022a5fe --- /dev/null +++ b/css/css-cascade/resources/scope-imported.css @@ -0,0 +1,21 @@ +.x { + --x: 1; +} + +:scope > .y { + --y: 1; +} + +@scope (.inner-scope) { + .z { + --z: 1; + } +} + +& > .w { + --w: 1; +} + +& > & > .u { + --u: 1; +} \ No newline at end of file diff --git a/css/css-cascade/scope-import-implicit.tentative.html b/css/css-cascade/scope-import-implicit.tentative.html new file mode 100644 index 000000000000000..3350afca77ce432 --- /dev/null +++ b/css/css-cascade/scope-import-implicit.tentative.html @@ -0,0 +1,25 @@ + +@import scope(), implicit scope + + + +
+
+ +
Inside
+
+
Outside
+
+ diff --git a/css/css-cascade/scope-import-inner-scope.tentative.html b/css/css-cascade/scope-import-inner-scope.tentative.html new file mode 100644 index 000000000000000..d30c9991bda7747 --- /dev/null +++ b/css/css-cascade/scope-import-inner-scope.tentative.html @@ -0,0 +1,29 @@ + +@import scope(), :scope rules in imported stylesheet + + + + +
+
+
+
Inside
+
+
+
+
Outside
+
+
+ diff --git a/css/css-cascade/scope-import-multiple.tentative.html b/css/css-cascade/scope-import-multiple.tentative.html new file mode 100644 index 000000000000000..5385c215cd30ac5 --- /dev/null +++ b/css/css-cascade/scope-import-multiple.tentative.html @@ -0,0 +1,31 @@ + +@import scope(), same stylesheet imported multiple times + + + + +
+
+
Inside
+
+
+
Inside
+
+
Outside
+
+ diff --git a/css/css-cascade/scope-import-parent-pseudo.tentative.html b/css/css-cascade/scope-import-parent-pseudo.tentative.html new file mode 100644 index 000000000000000..5fe7faa92a66080 --- /dev/null +++ b/css/css-cascade/scope-import-parent-pseudo.tentative.html @@ -0,0 +1,32 @@ + +@import scope(), '&' selectors + + + + +
+
+
Inside
+
+
Inner (W)
+
Inner (U)
+
+
+
+ diff --git a/css/css-cascade/scope-import-scope-end.tentative.html b/css/css-cascade/scope-import-scope-end.tentative.html new file mode 100644 index 000000000000000..98f2ac4adbf55ca --- /dev/null +++ b/css/css-cascade/scope-import-scope-end.tentative.html @@ -0,0 +1,27 @@ + +@import scope() with <scope-end> + + + + +
+
+
Inside
+
+
Below limit
+
+
+
+ diff --git a/css/css-cascade/scope-import-scope-pseudo.tentative.html b/css/css-cascade/scope-import-scope-pseudo.tentative.html new file mode 100644 index 000000000000000..da35c2981b2148c --- /dev/null +++ b/css/css-cascade/scope-import-scope-pseudo.tentative.html @@ -0,0 +1,29 @@ + +@import scope(), :scope rules in imported stylesheet + + + + +
+
+
Inside
+
+
Inside, but should not match
+
+
+
Outside
+
+ diff --git a/css/css-cascade/scope-import-scope-start.tentative.html b/css/css-cascade/scope-import-scope-start.tentative.html new file mode 100644 index 000000000000000..d1de75f8e1076bd --- /dev/null +++ b/css/css-cascade/scope-import-scope-start.tentative.html @@ -0,0 +1,25 @@ + +@import scope(), <scope-start> + + + + +
+
+
Inside
+
+
Outside
+
+