style: Tweak at-rule parsing APIs to support cascade layers

This needs https://github.com/servo/rust-cssparser/pull/287 and a
cssparser update.

Differential Revision: https://phabricator.services.mozilla.com/D124216
This commit is contained in:
Emilio Cobos Álvarez 2023-05-26 15:01:51 +02:00 committed by Oriol Brufau
parent 32b3cb291f
commit 623c8d8d45
2 changed files with 23 additions and 29 deletions

View file

@ -396,13 +396,14 @@ macro_rules! font_feature_values_blocks {
type AtRule = (); type AtRule = ();
type Error = StyleParseErrorKind<'i>; type Error = StyleParseErrorKind<'i>;
fn parse_prelude<'t>(&mut self, fn parse_prelude<'t>(
name: CowRcStr<'i>, &mut self,
input: &mut Parser<'i, 't>) name: CowRcStr<'i>,
-> Result<Self::Prelude, ParseError<'i>> { input: &mut Parser<'i, 't>,
) -> Result<BlockType, ParseError<'i>> {
match_ignore_ascii_case! { &*name, match_ignore_ascii_case! { &*name,
$( $(
$name => Ok(Self::Prelude::$ident_camel), $name => Ok(BlockType::$ident_camel),
)* )*
_ => Err(input.new_error(BasicParseErrorKind::AtRuleBodyInvalid)), _ => Err(input.new_error(BasicParseErrorKind::AtRuleBodyInvalid)),
} }

View file

@ -27,9 +27,7 @@ use crate::values::computed::font::FamilyName;
use crate::values::{CssUrl, CustomIdent, KeyframesName}; use crate::values::{CssUrl, CustomIdent, KeyframesName};
use crate::{Namespace, Prefix}; use crate::{Namespace, Prefix};
use cssparser::{AtRuleParser, Parser, QualifiedRuleParser, RuleListParser}; use cssparser::{AtRuleParser, Parser, QualifiedRuleParser, RuleListParser};
use cssparser::{ use cssparser::{BasicParseError, BasicParseErrorKind, CowRcStr, ParserState, SourcePosition};
BasicParseError, BasicParseErrorKind, CowRcStr, ParseErrorKind, ParserState, SourcePosition,
};
use selectors::SelectorList; use selectors::SelectorList;
use servo_arc::Arc; use servo_arc::Arc;
use style_traits::{ParseError, StyleParseErrorKind}; use style_traits::{ParseError, StyleParseErrorKind};
@ -182,7 +180,7 @@ impl<'a, 'i> AtRuleParser<'i> for TopLevelRuleParser<'a> {
&mut self, &mut self,
name: CowRcStr<'i>, name: CowRcStr<'i>,
input: &mut Parser<'i, 't>, input: &mut Parser<'i, 't>,
) -> Result<Self::Prelude, ParseError<'i>> { ) -> Result<AtRulePrelude, ParseError<'i>> {
match_ignore_ascii_case! { &*name, match_ignore_ascii_case! { &*name,
"import" => { "import" => {
if !self.check_state(State::Imports) { if !self.check_state(State::Imports) {
@ -206,9 +204,7 @@ impl<'a, 'i> AtRuleParser<'i> for TopLevelRuleParser<'a> {
let media = MediaList::parse(&self.context, input); let media = MediaList::parse(&self.context, input);
let media = Arc::new(self.shared_lock.wrap(media)); let media = Arc::new(self.shared_lock.wrap(media));
let prelude = AtRulePrelude::Import(url, media); return Ok(AtRulePrelude::Import(url, media));
return Ok(prelude);
}, },
"namespace" => { "namespace" => {
if !self.check_state(State::Namespaces) { if !self.check_state(State::Namespaces) {
@ -225,8 +221,7 @@ impl<'a, 'i> AtRuleParser<'i> for TopLevelRuleParser<'a> {
Err(e) => return Err(e.into()), Err(e) => return Err(e.into()),
}; };
let url = Namespace::from(maybe_namespace.as_ref()); let url = Namespace::from(maybe_namespace.as_ref());
let prelude = AtRulePrelude::Namespace(prefix, url); return Ok(AtRulePrelude::Namespace(prefix, url));
return Ok(prelude);
}, },
// @charset is removed by rust-cssparser if its the first rule in the stylesheet // @charset is removed by rust-cssparser if its the first rule in the stylesheet
// anything left is invalid. // anything left is invalid.
@ -261,7 +256,7 @@ impl<'a, 'i> AtRuleParser<'i> for TopLevelRuleParser<'a> {
&mut self, &mut self,
prelude: AtRulePrelude, prelude: AtRulePrelude,
start: &ParserState, start: &ParserState,
) -> Result<Self::AtRule, ()> { ) -> Result<Self::AtRule, ()> {
let rule = match prelude { let rule = match prelude {
AtRulePrelude::Import(url, media) => { AtRulePrelude::Import(url, media) => {
let loader = self let loader = self
@ -383,14 +378,14 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'b> {
"media" => { "media" => {
let media_queries = MediaList::parse(self.context, input); let media_queries = MediaList::parse(self.context, input);
let arc = Arc::new(self.shared_lock.wrap(media_queries)); let arc = Arc::new(self.shared_lock.wrap(media_queries));
Ok(Self::Prelude::Media(arc)) Ok(AtRulePrelude::Media(arc))
}, },
"supports" => { "supports" => {
let cond = SupportsCondition::parse(input)?; let cond = SupportsCondition::parse(input)?;
Ok(Self::Prelude::Supports(cond)) Ok(AtRulePrelude::Supports(cond))
}, },
"font-face" => { "font-face" => {
Ok(Self::Prelude::FontFace) Ok(AtRulePrelude::FontFace)
}, },
"font-feature-values" => { "font-feature-values" => {
if !cfg!(feature = "gecko") { if !cfg!(feature = "gecko") {
@ -398,7 +393,7 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'b> {
return Err(input.new_custom_error(StyleParseErrorKind::UnsupportedAtRule(name.clone()))) return Err(input.new_custom_error(StyleParseErrorKind::UnsupportedAtRule(name.clone())))
} }
let family_names = parse_family_name_list(self.context, input)?; let family_names = parse_family_name_list(self.context, input)?;
Ok(Self::Prelude::FontFeatureValues(family_names)) Ok(AtRulePrelude::FontFeatureValues(family_names))
}, },
"counter-style" => { "counter-style" => {
if !cfg!(feature = "gecko") { if !cfg!(feature = "gecko") {
@ -406,11 +401,11 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'b> {
return Err(input.new_custom_error(StyleParseErrorKind::UnsupportedAtRule(name.clone()))) return Err(input.new_custom_error(StyleParseErrorKind::UnsupportedAtRule(name.clone())))
} }
let name = parse_counter_style_name_definition(input)?; let name = parse_counter_style_name_definition(input)?;
Ok(Self::Prelude::CounterStyle(name)) Ok(AtRulePrelude::CounterStyle(name))
}, },
"viewport" => { "viewport" => {
if viewport_rule::enabled() { if viewport_rule::enabled() {
Ok(Self::Prelude::Viewport) Ok(AtRulePrelude::Viewport)
} else { } else {
Err(input.new_custom_error(StyleParseErrorKind::UnsupportedAtRule(name.clone()))) Err(input.new_custom_error(StyleParseErrorKind::UnsupportedAtRule(name.clone())))
} }
@ -430,7 +425,7 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'b> {
} }
let name = KeyframesName::parse(self.context, input)?; let name = KeyframesName::parse(self.context, input)?;
Ok(Self::Prelude::Keyframes(name, prefix)) Ok(AtRulePrelude::Keyframes(name, prefix))
}, },
"page" => { "page" => {
if cfg!(feature = "gecko") { if cfg!(feature = "gecko") {
@ -447,7 +442,7 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'b> {
} }
let cond = DocumentCondition::parse(self.context, input)?; let cond = DocumentCondition::parse(self.context, input)?;
Ok(Self::Prelude::Document(cond)) Ok(AtRulePrelude::Document(cond))
}, },
_ => Err(input.new_custom_error(StyleParseErrorKind::UnsupportedAtRule(name.clone()))) _ => Err(input.new_custom_error(StyleParseErrorKind::UnsupportedAtRule(name.clone())))
} }
@ -577,12 +572,10 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'b> {
}, },
)))) ))))
}, },
_ => Err(ParseError { AtRulePrelude::Import(..) | AtRulePrelude::Namespace(..) => {
kind: ParseErrorKind::Basic(BasicParseErrorKind::AtRuleInvalid(CowRcStr::from( // These rules don't have blocks.
"Unsupported AtRule Prelude.", Err(input.new_unexpected_token_error(cssparser::Token::CurlyBracketBlock))
))), },
location: start.source_location(),
}),
} }
} }
} }