summaryrefslogtreecommitdiffstats
path: root/servo/components/style/stylesheets/rule_parser.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-15 03:35:49 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-15 03:35:49 +0000
commitd8bbc7858622b6d9c278469aab701ca0b609cddf (patch)
treeeff41dc61d9f714852212739e6b3738b82a2af87 /servo/components/style/stylesheets/rule_parser.rs
parentReleasing progress-linux version 125.0.3-1~progress7.99u1. (diff)
downloadfirefox-d8bbc7858622b6d9c278469aab701ca0b609cddf.tar.xz
firefox-d8bbc7858622b6d9c278469aab701ca0b609cddf.zip
Merging upstream version 126.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'servo/components/style/stylesheets/rule_parser.rs')
-rw-r--r--servo/components/style/stylesheets/rule_parser.rs71
1 files changed, 57 insertions, 14 deletions
diff --git a/servo/components/style/stylesheets/rule_parser.rs b/servo/components/style/stylesheets/rule_parser.rs
index 742ad5d250..634f7c1af3 100644
--- a/servo/components/style/stylesheets/rule_parser.rs
+++ b/servo/components/style/stylesheets/rule_parser.rs
@@ -23,6 +23,8 @@ use crate::stylesheets::font_feature_values_rule::parse_family_name_list;
use crate::stylesheets::import_rule::{ImportLayer, ImportRule, ImportSupportsCondition};
use crate::stylesheets::keyframes_rule::parse_keyframe_list;
use crate::stylesheets::layer_rule::{LayerBlockRule, LayerName, LayerStatementRule};
+use crate::stylesheets::scope_rule::{ScopeBounds, ScopeRule};
+use crate::stylesheets::starting_style_rule::StartingStyleRule;
use crate::stylesheets::supports_rule::SupportsCondition;
use crate::stylesheets::{
AllowImportRules, CorsMode, CssRule, CssRuleType, CssRuleTypes, CssRules, DocumentRule,
@@ -50,6 +52,8 @@ pub struct InsertRuleContext<'a> {
pub index: usize,
/// The containing rule types of our ancestors.
pub containing_rule_types: CssRuleTypes,
+ /// Rule type determining if and how we parse relative selector syntax.
+ pub parse_relative_rule_type: Option<CssRuleType>,
}
impl<'a> InsertRuleContext<'a> {
@@ -231,6 +235,10 @@ pub enum AtRulePrelude {
Namespace(Option<Prefix>, Namespace),
/// A @layer rule prelude.
Layer(Vec<LayerName>),
+ /// A @scope rule prelude.
+ Scope(ScopeBounds),
+ /// A @starting-style prelude.
+ StartingStyle,
}
impl AtRulePrelude {
@@ -251,6 +259,8 @@ impl AtRulePrelude {
Self::Margin(..) => "margin",
Self::Namespace(..) => "namespace",
Self::Layer(..) => "layer",
+ Self::Scope(..) => "scope",
+ Self::StartingStyle => "starting-style",
}
}
}
@@ -483,18 +493,29 @@ impl NestedParseResult {
impl<'a, 'i> NestedRuleParser<'a, 'i> {
#[inline]
fn in_style_rule(&self) -> bool {
- self.context.rule_types.contains(CssRuleType::Style)
+ self.context
+ .nesting_context
+ .rule_types
+ .contains(CssRuleType::Style)
}
#[inline]
fn in_page_rule(&self) -> bool {
- self.context.rule_types.contains(CssRuleType::Page)
+ self.context
+ .nesting_context
+ .rule_types
+ .contains(CssRuleType::Page)
}
#[inline]
fn in_style_or_page_rule(&self) -> bool {
let types = CssRuleTypes::from_bits(CssRuleType::Style.bit() | CssRuleType::Page.bit());
- self.context.rule_types.intersects(types)
+ self.context.nesting_context.rule_types.intersects(types)
+ }
+
+ #[inline]
+ fn parse_relative(&self) -> ParseRelative {
+ self.context.nesting_context.parse_relative
}
// https://drafts.csswg.org/css-nesting/#conditionals
@@ -507,7 +528,9 @@ impl<'a, 'i> NestedRuleParser<'a, 'i> {
AtRulePrelude::Supports(..) |
AtRulePrelude::Container(..) |
AtRulePrelude::Document(..) |
- AtRulePrelude::Layer(..) => true,
+ AtRulePrelude::Layer(..) |
+ AtRulePrelude::Scope(..) |
+ AtRulePrelude::StartingStyle => true,
AtRulePrelude::Namespace(..) |
AtRulePrelude::FontFace |
@@ -523,10 +546,9 @@ impl<'a, 'i> NestedRuleParser<'a, 'i> {
}
fn nest_for_rule<R>(&mut self, rule_type: CssRuleType, cb: impl FnOnce(&mut Self) -> R) -> R {
- let old_rule_types = self.context.rule_types;
- self.context.rule_types.insert(rule_type);
+ let old = self.context.nesting_context.save(rule_type);
let r = cb(self);
- self.context.rule_types = old_rule_types;
+ self.context.nesting_context.restore(old);
r
}
@@ -701,6 +723,13 @@ impl<'a, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'i> {
let cond = DocumentCondition::parse(&self.context, input)?;
AtRulePrelude::Document(cond)
},
+ "scope" if static_prefs::pref!("layout.css.at-scope.enabled") => {
+ let bounds = ScopeBounds::parse(&self.context, input, self.in_style_rule());
+ AtRulePrelude::Scope(bounds)
+ },
+ "starting-style" if static_prefs::pref!("layout.css.starting-style-at-rules.enabled") => {
+ AtRulePrelude::StartingStyle
+ },
_ => {
if static_prefs::pref!("layout.css.margin-rules.enabled") {
if let Some(margin_rule_type) = MarginRuleType::match_name(&name) {
@@ -862,11 +891,30 @@ impl<'a, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'i> {
block: Arc::new(self.shared_lock.wrap(declarations)),
source_location: start.source_location(),
}))
- }
+ },
AtRulePrelude::Import(..) | AtRulePrelude::Namespace(..) => {
// These rules don't have blocks.
return Err(input.new_unexpected_token_error(cssparser::Token::CurlyBracketBlock));
},
+ AtRulePrelude::Scope(bounds) => {
+ let source_location = start.source_location();
+ CssRule::Scope(Arc::new(ScopeRule {
+ bounds,
+ rules: self
+ .parse_nested(input, CssRuleType::Scope)
+ .into_rules(self.shared_lock, source_location),
+ source_location,
+ }))
+ },
+ AtRulePrelude::StartingStyle => {
+ let source_location = start.source_location();
+ CssRule::StartingStyle(Arc::new(StartingStyleRule {
+ rules: self
+ .parse_nested(input, CssRuleType::StartingStyle)
+ .into_rules(self.shared_lock, source_location),
+ source_location,
+ }))
+ },
};
self.rules.push(rule);
Ok(())
@@ -913,12 +961,7 @@ impl<'a, 'i> QualifiedRuleParser<'i> for NestedRuleParser<'a, 'i> {
url_data: self.context.url_data,
for_supports_rule: false,
};
- let parse_relative = if self.in_style_rule() {
- ParseRelative::ForNesting
- } else {
- ParseRelative::No
- };
- SelectorList::parse(&selector_parser, input, parse_relative)
+ SelectorList::parse(&selector_parser, input, self.parse_relative())
}
fn parse_block<'t>(