mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
style: Cleanup ParserContext::new_with_rule_type.
This commit is contained in:
parent
4763d05cf0
commit
a962c54928
8 changed files with 118 additions and 40 deletions
|
@ -36,9 +36,13 @@ impl CSS {
|
||||||
decl.push_str(&value);
|
decl.push_str(&value);
|
||||||
let decl = Declaration(decl);
|
let decl = Declaration(decl);
|
||||||
let url = win.Document().url();
|
let url = win.Document().url();
|
||||||
let context = ParserContext::new_for_cssom(&url, win.css_error_reporter(), Some(CssRuleType::Supports),
|
let context = ParserContext::new_for_cssom(
|
||||||
PARSING_MODE_DEFAULT,
|
&url,
|
||||||
QuirksMode::NoQuirks);
|
win.css_error_reporter(),
|
||||||
|
Some(CssRuleType::Style),
|
||||||
|
PARSING_MODE_DEFAULT,
|
||||||
|
QuirksMode::NoQuirks
|
||||||
|
);
|
||||||
decl.eval(&context)
|
decl.eval(&context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,9 +53,13 @@ impl CSS {
|
||||||
let cond = parse_condition_or_declaration(&mut input);
|
let cond = parse_condition_or_declaration(&mut input);
|
||||||
if let Ok(cond) = cond {
|
if let Ok(cond) = cond {
|
||||||
let url = win.Document().url();
|
let url = win.Document().url();
|
||||||
let context = ParserContext::new_for_cssom(&url, win.css_error_reporter(), Some(CssRuleType::Supports),
|
let context = ParserContext::new_for_cssom(
|
||||||
PARSING_MODE_DEFAULT,
|
&url,
|
||||||
QuirksMode::NoQuirks);
|
win.css_error_reporter(),
|
||||||
|
Some(CssRuleType::Style),
|
||||||
|
PARSING_MODE_DEFAULT,
|
||||||
|
QuirksMode::NoQuirks
|
||||||
|
);
|
||||||
cond.eval(&context)
|
cond.eval(&context)
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
|
|
|
@ -102,17 +102,18 @@ impl<'a> ParserContext<'a> {
|
||||||
/// Create a parser context based on a previous context, but with a modified rule type.
|
/// Create a parser context based on a previous context, but with a modified rule type.
|
||||||
pub fn new_with_rule_type(
|
pub fn new_with_rule_type(
|
||||||
context: &'a ParserContext,
|
context: &'a ParserContext,
|
||||||
rule_type: Option<CssRuleType>
|
rule_type: CssRuleType,
|
||||||
|
namespaces: &'a Namespaces,
|
||||||
) -> ParserContext<'a> {
|
) -> ParserContext<'a> {
|
||||||
ParserContext {
|
ParserContext {
|
||||||
stylesheet_origin: context.stylesheet_origin,
|
stylesheet_origin: context.stylesheet_origin,
|
||||||
url_data: context.url_data,
|
url_data: context.url_data,
|
||||||
error_reporter: context.error_reporter,
|
error_reporter: context.error_reporter,
|
||||||
rule_type: rule_type,
|
rule_type: Some(rule_type),
|
||||||
line_number_offset: context.line_number_offset,
|
line_number_offset: context.line_number_offset,
|
||||||
parsing_mode: context.parsing_mode,
|
parsing_mode: context.parsing_mode,
|
||||||
quirks_mode: context.quirks_mode,
|
quirks_mode: context.quirks_mode,
|
||||||
namespaces: context.namespaces,
|
namespaces: Some(namespaces),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -322,14 +322,17 @@ macro_rules! font_feature_values_blocks {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_block<'t>(&mut self, prelude: Self::Prelude, input: &mut Parser<'i, 't>)
|
fn parse_block<'t>(
|
||||||
-> Result<Self::AtRule, ParseError<'i>> {
|
&mut self,
|
||||||
let context = ParserContext::new_with_rule_type(self.context, Some(CssRuleType::FontFeatureValues));
|
prelude: Self::Prelude,
|
||||||
|
input: &mut Parser<'i, 't>
|
||||||
|
) -> Result<Self::AtRule, ParseError<'i>> {
|
||||||
|
debug_assert_eq!(self.context.rule_type(), CssRuleType::FontFeatureValues);
|
||||||
match prelude {
|
match prelude {
|
||||||
$(
|
$(
|
||||||
BlockType::$ident_camel => {
|
BlockType::$ident_camel => {
|
||||||
let parser = FFVDeclarationsParser {
|
let parser = FFVDeclarationsParser {
|
||||||
context: &context,
|
context: &self.context,
|
||||||
declarations: &mut self.rule.$ident,
|
declarations: &mut self.rule.$ident,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -338,7 +341,7 @@ macro_rules! font_feature_values_blocks {
|
||||||
if let Err(err) = declaration {
|
if let Err(err) = declaration {
|
||||||
let error = ContextualParseError::UnsupportedKeyframePropertyDeclaration(
|
let error = ContextualParseError::UnsupportedKeyframePropertyDeclaration(
|
||||||
err.slice, err.error);
|
err.slice, err.error);
|
||||||
context.log_css_error(err.location, error);
|
self.context.log_css_error(err.location, error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -450,8 +450,14 @@ struct KeyframeListParser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses a keyframe list from CSS input.
|
/// Parses a keyframe list from CSS input.
|
||||||
pub fn parse_keyframe_list(context: &ParserContext, input: &mut Parser, shared_lock: &SharedRwLock)
|
pub fn parse_keyframe_list(
|
||||||
-> Vec<Arc<Locked<Keyframe>>> {
|
context: &ParserContext,
|
||||||
|
input: &mut Parser,
|
||||||
|
shared_lock: &SharedRwLock
|
||||||
|
) -> Vec<Arc<Locked<Keyframe>>> {
|
||||||
|
debug_assert!(context.namespaces.is_some(),
|
||||||
|
"Parsing a keyframe list from a context without namespaces?");
|
||||||
|
|
||||||
let mut declarations = SourcePropertyDeclaration::new();
|
let mut declarations = SourcePropertyDeclaration::new();
|
||||||
RuleListParser::new_for_nested_rule(input, KeyframeListParser {
|
RuleListParser::new_for_nested_rule(input, KeyframeListParser {
|
||||||
context: context,
|
context: context,
|
||||||
|
@ -487,7 +493,13 @@ impl<'a, 'i> QualifiedRuleParser<'i> for KeyframeListParser<'a> {
|
||||||
|
|
||||||
fn parse_block<'t>(&mut self, prelude: Self::Prelude, input: &mut Parser<'i, 't>)
|
fn parse_block<'t>(&mut self, prelude: Self::Prelude, input: &mut Parser<'i, 't>)
|
||||||
-> Result<Self::QualifiedRule, ParseError<'i>> {
|
-> Result<Self::QualifiedRule, ParseError<'i>> {
|
||||||
let context = ParserContext::new_with_rule_type(self.context, Some(CssRuleType::Keyframe));
|
let context =
|
||||||
|
ParserContext::new_with_rule_type(
|
||||||
|
self.context,
|
||||||
|
CssRuleType::Keyframe,
|
||||||
|
self.context.namespaces.unwrap(),
|
||||||
|
);
|
||||||
|
|
||||||
let parser = KeyframeDeclarationParser {
|
let parser = KeyframeDeclarationParser {
|
||||||
context: &context,
|
context: &context,
|
||||||
declarations: self.declarations,
|
declarations: self.declarations,
|
||||||
|
|
|
@ -134,7 +134,7 @@ impl MallocSizeOfWithGuard for CssRule {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
#[derive(PartialEq, Eq, Copy, Clone)]
|
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
||||||
pub enum CssRuleType {
|
pub enum CssRuleType {
|
||||||
// https://drafts.csswg.org/cssom/#the-cssrule-interface
|
// https://drafts.csswg.org/cssom/#the-cssrule-interface
|
||||||
Style = 1,
|
Style = 1,
|
||||||
|
|
|
@ -44,9 +44,8 @@ pub struct TopLevelRuleParser<'a> {
|
||||||
pub loader: Option<&'a StylesheetLoader>,
|
pub loader: Option<&'a StylesheetLoader>,
|
||||||
/// The top-level parser context.
|
/// The top-level parser context.
|
||||||
///
|
///
|
||||||
/// This won't contain any namespaces, and will only be filled right because
|
/// This won't contain any namespaces, and only nested parsers created with
|
||||||
/// parsing style rules, on the assumption that they're the only rules that
|
/// `ParserContext::new_with_rule_type` will.
|
||||||
/// need them.
|
|
||||||
pub context: ParserContext<'a>,
|
pub context: ParserContext<'a>,
|
||||||
/// The current state of the parser.
|
/// The current state of the parser.
|
||||||
pub state: State,
|
pub state: State,
|
||||||
|
@ -295,10 +294,8 @@ impl<'a, 'b> NestedRuleParser<'a, 'b> {
|
||||||
input: &mut Parser,
|
input: &mut Parser,
|
||||||
rule_type: CssRuleType
|
rule_type: CssRuleType
|
||||||
) -> Arc<Locked<CssRules>> {
|
) -> Arc<Locked<CssRules>> {
|
||||||
let context = ParserContext::new_with_rule_type(
|
let context =
|
||||||
self.context,
|
ParserContext::new_with_rule_type(self.context, rule_type, self.namespaces);
|
||||||
Some(rule_type),
|
|
||||||
);
|
|
||||||
|
|
||||||
let nested_parser = NestedRuleParser {
|
let nested_parser = NestedRuleParser {
|
||||||
stylesheet_origin: self.stylesheet_origin,
|
stylesheet_origin: self.stylesheet_origin,
|
||||||
|
@ -423,17 +420,33 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'b> {
|
||||||
) -> Result<CssRule, ParseError<'i>> {
|
) -> Result<CssRule, ParseError<'i>> {
|
||||||
match prelude {
|
match prelude {
|
||||||
AtRulePrelude::FontFace(location) => {
|
AtRulePrelude::FontFace(location) => {
|
||||||
let context = ParserContext::new_with_rule_type(self.context, Some(CssRuleType::FontFace));
|
let context =
|
||||||
|
ParserContext::new_with_rule_type(
|
||||||
|
self.context,
|
||||||
|
CssRuleType::FontFace,
|
||||||
|
self.namespaces,
|
||||||
|
);
|
||||||
|
|
||||||
Ok(CssRule::FontFace(Arc::new(self.shared_lock.wrap(
|
Ok(CssRule::FontFace(Arc::new(self.shared_lock.wrap(
|
||||||
parse_font_face_block(&context, input, location).into()))))
|
parse_font_face_block(&context, input, location).into()))))
|
||||||
}
|
}
|
||||||
AtRulePrelude::FontFeatureValues(family_names, location) => {
|
AtRulePrelude::FontFeatureValues(family_names, location) => {
|
||||||
let context = ParserContext::new_with_rule_type(self.context, Some(CssRuleType::FontFeatureValues));
|
let context =
|
||||||
|
ParserContext::new_with_rule_type(
|
||||||
|
self.context,
|
||||||
|
CssRuleType::FontFeatureValues,
|
||||||
|
self.namespaces,
|
||||||
|
);
|
||||||
Ok(CssRule::FontFeatureValues(Arc::new(self.shared_lock.wrap(
|
Ok(CssRule::FontFeatureValues(Arc::new(self.shared_lock.wrap(
|
||||||
FontFeatureValuesRule::parse(&context, input, family_names, location)))))
|
FontFeatureValuesRule::parse(&context, input, family_names, location)))))
|
||||||
}
|
}
|
||||||
AtRulePrelude::CounterStyle(name) => {
|
AtRulePrelude::CounterStyle(name) => {
|
||||||
let context = ParserContext::new_with_rule_type(self.context, Some(CssRuleType::CounterStyle));
|
let context =
|
||||||
|
ParserContext::new_with_rule_type(
|
||||||
|
self.context,
|
||||||
|
CssRuleType::CounterStyle,
|
||||||
|
self.namespaces,
|
||||||
|
);
|
||||||
Ok(CssRule::CounterStyle(Arc::new(self.shared_lock.wrap(
|
Ok(CssRule::CounterStyle(Arc::new(self.shared_lock.wrap(
|
||||||
parse_counter_style_body(name, &context, input)?.into()))))
|
parse_counter_style_body(name, &context, input)?.into()))))
|
||||||
}
|
}
|
||||||
|
@ -445,7 +458,13 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'b> {
|
||||||
}))))
|
}))))
|
||||||
}
|
}
|
||||||
AtRulePrelude::Supports(cond, location) => {
|
AtRulePrelude::Supports(cond, location) => {
|
||||||
let enabled = cond.eval(self.context);
|
let eval_context =
|
||||||
|
ParserContext::new_with_rule_type(
|
||||||
|
self.context,
|
||||||
|
CssRuleType::Style,
|
||||||
|
self.namespaces,
|
||||||
|
);
|
||||||
|
let enabled = cond.eval(&eval_context);
|
||||||
Ok(CssRule::Supports(Arc::new(self.shared_lock.wrap(SupportsRule {
|
Ok(CssRule::Supports(Arc::new(self.shared_lock.wrap(SupportsRule {
|
||||||
condition: cond,
|
condition: cond,
|
||||||
rules: self.parse_nested_rules(input, CssRuleType::Supports),
|
rules: self.parse_nested_rules(input, CssRuleType::Supports),
|
||||||
|
@ -454,12 +473,23 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'b> {
|
||||||
}))))
|
}))))
|
||||||
}
|
}
|
||||||
AtRulePrelude::Viewport => {
|
AtRulePrelude::Viewport => {
|
||||||
let context = ParserContext::new_with_rule_type(self.context, Some(CssRuleType::Viewport));
|
let context =
|
||||||
|
ParserContext::new_with_rule_type(
|
||||||
|
self.context,
|
||||||
|
CssRuleType::Viewport,
|
||||||
|
self.namespaces,
|
||||||
|
);
|
||||||
Ok(CssRule::Viewport(Arc::new(self.shared_lock.wrap(
|
Ok(CssRule::Viewport(Arc::new(self.shared_lock.wrap(
|
||||||
ViewportRule::parse(&context, input)?))))
|
ViewportRule::parse(&context, input)?))))
|
||||||
}
|
}
|
||||||
AtRulePrelude::Keyframes(name, prefix, location) => {
|
AtRulePrelude::Keyframes(name, prefix, location) => {
|
||||||
let context = ParserContext::new_with_rule_type(self.context, Some(CssRuleType::Keyframes));
|
let context =
|
||||||
|
ParserContext::new_with_rule_type(
|
||||||
|
self.context,
|
||||||
|
CssRuleType::Keyframes,
|
||||||
|
self.namespaces,
|
||||||
|
);
|
||||||
|
|
||||||
Ok(CssRule::Keyframes(Arc::new(self.shared_lock.wrap(KeyframesRule {
|
Ok(CssRule::Keyframes(Arc::new(self.shared_lock.wrap(KeyframesRule {
|
||||||
name: name,
|
name: name,
|
||||||
keyframes: parse_keyframe_list(&context, input, self.shared_lock),
|
keyframes: parse_keyframe_list(&context, input, self.shared_lock),
|
||||||
|
@ -468,7 +498,12 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'b> {
|
||||||
}))))
|
}))))
|
||||||
}
|
}
|
||||||
AtRulePrelude::Page(location) => {
|
AtRulePrelude::Page(location) => {
|
||||||
let context = ParserContext::new_with_rule_type(self.context, Some(CssRuleType::Page));
|
let context =
|
||||||
|
ParserContext::new_with_rule_type(
|
||||||
|
self.context,
|
||||||
|
CssRuleType::Page,
|
||||||
|
self.namespaces,
|
||||||
|
);
|
||||||
let declarations = parse_property_declaration_list(&context, input);
|
let declarations = parse_property_declaration_list(&context, input);
|
||||||
Ok(CssRule::Page(Arc::new(self.shared_lock.wrap(PageRule {
|
Ok(CssRule::Page(Arc::new(self.shared_lock.wrap(PageRule {
|
||||||
block: Arc::new(self.shared_lock.wrap(declarations)),
|
block: Arc::new(self.shared_lock.wrap(declarations)),
|
||||||
|
@ -520,8 +555,12 @@ impl<'a, 'b, 'i> QualifiedRuleParser<'i> for NestedRuleParser<'a, 'b> {
|
||||||
prelude: QualifiedRuleParserPrelude,
|
prelude: QualifiedRuleParserPrelude,
|
||||||
input: &mut Parser<'i, 't>
|
input: &mut Parser<'i, 't>
|
||||||
) -> Result<CssRule, ParseError<'i>> {
|
) -> Result<CssRule, ParseError<'i>> {
|
||||||
let mut context = ParserContext::new_with_rule_type(self.context, Some(CssRuleType::Style));
|
let context =
|
||||||
context.namespaces = Some(self.namespaces);
|
ParserContext::new_with_rule_type(
|
||||||
|
self.context,
|
||||||
|
CssRuleType::Style,
|
||||||
|
self.namespaces,
|
||||||
|
);
|
||||||
let declarations = parse_property_declaration_list(&context, input);
|
let declarations = parse_property_declaration_list(&context, input);
|
||||||
Ok(CssRule::Style(Arc::new(self.shared_lock.wrap(StyleRule {
|
Ok(CssRule::Style(Arc::new(self.shared_lock.wrap(StyleRule {
|
||||||
selectors: prelude.selectors,
|
selectors: prelude.selectors,
|
||||||
|
|
|
@ -241,16 +241,19 @@ impl Declaration {
|
||||||
/// Determine if a declaration parses
|
/// Determine if a declaration parses
|
||||||
///
|
///
|
||||||
/// https://drafts.csswg.org/css-conditional-3/#support-definition
|
/// https://drafts.csswg.org/css-conditional-3/#support-definition
|
||||||
pub fn eval(&self, cx: &ParserContext) -> bool {
|
pub fn eval(&self, context: &ParserContext) -> bool {
|
||||||
|
debug_assert_eq!(context.rule_type(), CssRuleType::Style);
|
||||||
|
|
||||||
let mut input = ParserInput::new(&self.0);
|
let mut input = ParserInput::new(&self.0);
|
||||||
let mut input = Parser::new(&mut input);
|
let mut input = Parser::new(&mut input);
|
||||||
input.parse_entirely(|input| {
|
input.parse_entirely(|input| {
|
||||||
let prop = input.expect_ident().unwrap().as_ref().to_owned();
|
let prop = input.expect_ident().unwrap().as_ref().to_owned();
|
||||||
input.expect_colon().unwrap();
|
input.expect_colon().unwrap();
|
||||||
let context = ParserContext::new_with_rule_type(cx, Some(CssRuleType::Style));
|
|
||||||
let property_context = PropertyParserContext::new(&context);
|
let property_context = PropertyParserContext::new(&context);
|
||||||
let id = PropertyId::parse(&prop, Some(&property_context))
|
let id = PropertyId::parse(&prop, Some(&property_context))
|
||||||
.map_err(|_| StyleParseError::UnspecifiedError)?;
|
.map_err(|_| StyleParseError::UnspecifiedError)?;
|
||||||
|
|
||||||
let mut declarations = SourcePropertyDeclaration::new();
|
let mut declarations = SourcePropertyDeclaration::new();
|
||||||
input.parse_until_before(Delimiter::Bang, |input| {
|
input.parse_until_before(Delimiter::Bang, |input| {
|
||||||
PropertyDeclaration::parse_into(&mut declarations, id, &context, input)
|
PropertyDeclaration::parse_into(&mut declarations, id, &context, input)
|
||||||
|
|
|
@ -1508,6 +1508,11 @@ pub extern "C" fn Servo_KeyframesRule_AppendRule(
|
||||||
let css = unsafe { css.as_ref().unwrap().as_str_unchecked() };
|
let css = unsafe { css.as_ref().unwrap().as_str_unchecked() };
|
||||||
let contents = StylesheetContents::as_arc(&contents);
|
let contents = StylesheetContents::as_arc(&contents);
|
||||||
let global_style_data = &*GLOBAL_STYLE_DATA;
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||||
|
|
||||||
|
// FIXME(emilio): What happens with namespaces here?
|
||||||
|
//
|
||||||
|
// We seem to ignore it, but someone could still set content: attr(..) from
|
||||||
|
// a declaration inside the keyframe block.
|
||||||
match Keyframe::parse(css, &contents, &global_style_data.shared_lock) {
|
match Keyframe::parse(css, &contents, &global_style_data.shared_lock) {
|
||||||
Ok(keyframe) => {
|
Ok(keyframe) => {
|
||||||
write_locked_arc(rule, |rule: &mut KeyframesRule| {
|
write_locked_arc(rule, |rule: &mut KeyframesRule| {
|
||||||
|
@ -2811,9 +2816,16 @@ pub extern "C" fn Servo_CSSSupports(cond: *const nsACString) -> bool {
|
||||||
if let Ok(cond) = cond {
|
if let Ok(cond) = cond {
|
||||||
let url_data = unsafe { dummy_url_data() };
|
let url_data = unsafe { dummy_url_data() };
|
||||||
let reporter = NullReporter;
|
let reporter = NullReporter;
|
||||||
let context = ParserContext::new_for_cssom(url_data, &reporter, Some(CssRuleType::Style),
|
// NOTE(emilio): The supports API is not associated to any stylesheet,
|
||||||
PARSING_MODE_DEFAULT,
|
// so the fact that there are no namespace map here is fine.
|
||||||
QuirksMode::NoQuirks);
|
let context =
|
||||||
|
ParserContext::new_for_cssom(
|
||||||
|
url_data,
|
||||||
|
&reporter,
|
||||||
|
Some(CssRuleType::Style),
|
||||||
|
PARSING_MODE_DEFAULT,
|
||||||
|
QuirksMode::NoQuirks,
|
||||||
|
);
|
||||||
cond.eval(&context)
|
cond.eval(&context)
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue