aboutsummaryrefslogtreecommitdiffstats
path: root/components/style
diff options
context:
space:
mode:
authorJosh Matthews <josh@joshmatthews.net>2017-08-23 17:50:13 -0700
committerJosh Matthews <josh@joshmatthews.net>2017-08-24 10:41:06 -0700
commit1297c0ff51f1f5ab39221d6489574bcd7a85663b (patch)
tree33dba5dec67902da55351107336968a8145b3e0e /components/style
parent2e775abfa4563fc5db467c5c79f9d2507f6bb2e7 (diff)
downloadservo-1297c0ff51f1f5ab39221d6489574bcd7a85663b.tar.gz
servo-1297c0ff51f1f5ab39221d6489574bcd7a85663b.zip
Devirtualize CSS error reporting.
Diffstat (limited to 'components/style')
-rw-r--r--components/style/counter_style/mod.rs17
-rw-r--r--components/style/encoding_support.rs40
-rw-r--r--components/style/font_face.rs15
-rw-r--r--components/style/gecko/wrapper.rs11
-rw-r--r--components/style/parser.rs24
-rw-r--r--components/style/properties/declaration_block.rs51
-rw-r--r--components/style/properties/properties.mako.rs3
-rw-r--r--components/style/stylesheets/font_feature_values_rule.rs27
-rw-r--r--components/style/stylesheets/keyframes_rule.rs26
-rw-r--r--components/style/stylesheets/mod.rs4
-rw-r--r--components/style/stylesheets/rule_parser.rs43
-rw-r--r--components/style/stylesheets/stylesheet.rs52
-rw-r--r--components/style/stylesheets/viewport_rule.rs16
13 files changed, 191 insertions, 138 deletions
diff --git a/components/style/counter_style/mod.rs b/components/style/counter_style/mod.rs
index df405e9f262..26895688971 100644
--- a/components/style/counter_style/mod.rs
+++ b/components/style/counter_style/mod.rs
@@ -9,10 +9,10 @@
use Atom;
use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser};
use cssparser::{Parser, Token, serialize_identifier, BasicParseError, CowRcStr};
-use error_reporting::ContextualParseError;
+use error_reporting::{ContextualParseError, ParseErrorReporter};
#[cfg(feature = "gecko")] use gecko::rules::CounterStyleDescriptors;
#[cfg(feature = "gecko")] use gecko_bindings::structs::nsCSSCounterDesc;
-use parser::{ParserContext, Parse};
+use parser::{ParserContext, ParserErrorContext, Parse};
use selectors::parser::SelectorParseError;
use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
use std::ascii::AsciiExt;
@@ -50,8 +50,13 @@ pub fn parse_counter_style_name<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Cu
}
/// Parse the body (inside `{}`) of an @counter-style rule
-pub fn parse_counter_style_body<'i, 't>(name: CustomIdent, context: &ParserContext, input: &mut Parser<'i, 't>)
- -> Result<CounterStyleRuleData, ParseError<'i>> {
+pub fn parse_counter_style_body<'i, 't, R>(name: CustomIdent,
+ context: &ParserContext,
+ error_context: &ParserErrorContext<R>,
+ input: &mut Parser<'i, 't>)
+ -> Result<CounterStyleRuleData, ParseError<'i>>
+ where R: ParseErrorReporter
+{
let start = input.current_source_location();
let mut rule = CounterStyleRuleData::empty(name);
{
@@ -63,7 +68,7 @@ pub fn parse_counter_style_body<'i, 't>(name: CustomIdent, context: &ParserConte
while let Some(declaration) = iter.next() {
if let Err(err) = declaration {
let error = ContextualParseError::UnsupportedCounterStyleDescriptorDeclaration(err.slice, err.error);
- context.log_css_error(err.location, error)
+ context.log_css_error(error_context, err.location, error)
}
}
}
@@ -95,7 +100,7 @@ pub fn parse_counter_style_body<'i, 't>(name: CustomIdent, context: &ParserConte
_ => None
};
if let Some(error) = error {
- context.log_css_error(start, error);
+ context.log_css_error(error_context, start, error);
Err(StyleParseError::UnspecifiedError.into())
} else {
Ok(rule)
diff --git a/components/style/encoding_support.rs b/components/style/encoding_support.rs
index 6560342e942..a354938c3a7 100644
--- a/components/style/encoding_support.rs
+++ b/components/style/encoding_support.rs
@@ -49,17 +49,19 @@ impl Stylesheet {
///
/// Takes care of decoding the network bytes and forwards the resulting
/// string to `Stylesheet::from_str`.
- pub fn from_bytes(bytes: &[u8],
- url_data: UrlExtraData,
- protocol_encoding_label: Option<&str>,
- environment_encoding: Option<EncodingRef>,
- origin: Origin,
- media: MediaList,
- shared_lock: SharedRwLock,
- stylesheet_loader: Option<&StylesheetLoader>,
- error_reporter: &ParseErrorReporter,
- quirks_mode: QuirksMode)
- -> Stylesheet {
+ pub fn from_bytes<R>(bytes: &[u8],
+ url_data: UrlExtraData,
+ protocol_encoding_label: Option<&str>,
+ environment_encoding: Option<EncodingRef>,
+ origin: Origin,
+ media: MediaList,
+ shared_lock: SharedRwLock,
+ stylesheet_loader: Option<&StylesheetLoader>,
+ error_reporter: &R,
+ quirks_mode: QuirksMode)
+ -> Stylesheet
+ where R: ParseErrorReporter
+ {
let (string, _) = decode_stylesheet_bytes(
bytes, protocol_encoding_label, environment_encoding);
Stylesheet::from_str(&string,
@@ -75,13 +77,15 @@ impl Stylesheet {
/// Updates an empty stylesheet with a set of bytes that reached over the
/// network.
- pub fn update_from_bytes(existing: &Stylesheet,
- bytes: &[u8],
- protocol_encoding_label: Option<&str>,
- environment_encoding: Option<EncodingRef>,
- url_data: UrlExtraData,
- stylesheet_loader: Option<&StylesheetLoader>,
- error_reporter: &ParseErrorReporter) {
+ pub fn update_from_bytes<R>(existing: &Stylesheet,
+ bytes: &[u8],
+ protocol_encoding_label: Option<&str>,
+ environment_encoding: Option<EncodingRef>,
+ url_data: UrlExtraData,
+ stylesheet_loader: Option<&StylesheetLoader>,
+ error_reporter: &R)
+ where R: ParseErrorReporter
+ {
let (string, _) = decode_stylesheet_bytes(
bytes, protocol_encoding_label, environment_encoding);
Self::update_from_str(existing,
diff --git a/components/style/font_face.rs b/components/style/font_face.rs
index b2d130cc510..48658e9c6fa 100644
--- a/components/style/font_face.rs
+++ b/components/style/font_face.rs
@@ -13,10 +13,10 @@ use computed_values::{font_feature_settings, font_stretch, font_style, font_weig
use computed_values::font_family::FamilyName;
use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser};
use cssparser::{SourceLocation, CowRcStr};
-use error_reporting::ContextualParseError;
+use error_reporting::{ContextualParseError, ParseErrorReporter};
#[cfg(feature = "gecko")] use gecko_bindings::structs::CSSFontFaceDescriptors;
#[cfg(feature = "gecko")] use cssparser::UnicodeRange;
-use parser::{ParserContext, Parse};
+use parser::{ParserContext, ParserErrorContext, Parse};
#[cfg(feature = "gecko")]
use properties::longhands::font_language_override;
use selectors::parser::SelectorParseError;
@@ -108,8 +108,13 @@ impl Parse for FontWeight {
/// Parse the block inside a `@font-face` rule.
///
/// Note that the prelude parsing code lives in the `stylesheets` module.
-pub fn parse_font_face_block(context: &ParserContext, input: &mut Parser, location: SourceLocation)
- -> FontFaceRuleData {
+pub fn parse_font_face_block<R>(context: &ParserContext,
+ error_context: &ParserErrorContext<R>,
+ input: &mut Parser,
+ location: SourceLocation)
+ -> FontFaceRuleData
+ where R: ParseErrorReporter
+{
let mut rule = FontFaceRuleData::empty(location);
{
let parser = FontFaceRuleParser {
@@ -120,7 +125,7 @@ pub fn parse_font_face_block(context: &ParserContext, input: &mut Parser, locati
while let Some(declaration) = iter.next() {
if let Err(err) = declaration {
let error = ContextualParseError::UnsupportedFontFaceDescriptor(err.slice, err.error);
- context.log_css_error(err.location, error)
+ context.log_css_error(error_context, err.location, error)
}
}
}
diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs
index 4b7e5993334..7261d02afc7 100644
--- a/components/style/gecko/wrapper.rs
+++ b/components/style/gecko/wrapper.rs
@@ -467,10 +467,13 @@ impl<'le> fmt::Debug for GeckoElement<'le> {
impl<'le> GeckoElement<'le> {
/// Parse the style attribute of an element.
- pub fn parse_style_attribute(value: &str,
- url_data: &UrlExtraData,
- quirks_mode: QuirksMode,
- reporter: &ParseErrorReporter) -> PropertyDeclarationBlock {
+ pub fn parse_style_attribute<R>(value: &str,
+ url_data: &UrlExtraData,
+ quirks_mode: QuirksMode,
+ reporter: &R)
+ -> PropertyDeclarationBlock
+ where R: ParseErrorReporter
+ {
parse_style_attribute(value, url_data, reporter, quirks_mode)
}
diff --git a/components/style/parser.rs b/components/style/parser.rs
index 4d38549ee69..c4167b6865a 100644
--- a/components/style/parser.rs
+++ b/components/style/parser.rs
@@ -38,6 +38,12 @@ pub fn assert_parsing_mode_match() {
}
}
+/// The context required to report a parse error.
+pub struct ParserErrorContext<'a, R: 'a> {
+ /// An error reporter to report syntax errors.
+ pub error_reporter: &'a R,
+}
+
/// The data that the parser needs from outside in order to parse a stylesheet.
pub struct ParserContext<'a> {
/// The `Origin` of the stylesheet, whether it's a user, author or
@@ -45,8 +51,6 @@ pub struct ParserContext<'a> {
pub stylesheet_origin: Origin,
/// The extra data we need for resolving url values.
pub url_data: &'a UrlExtraData,
- /// An error reporter to report syntax errors.
- pub error_reporter: &'a ParseErrorReporter,
/// The current rule type, if any.
pub rule_type: Option<CssRuleType>,
/// Line number offsets for inline stylesheets
@@ -64,7 +68,6 @@ impl<'a> ParserContext<'a> {
pub fn new(
stylesheet_origin: Origin,
url_data: &'a UrlExtraData,
- error_reporter: &'a ParseErrorReporter,
rule_type: Option<CssRuleType>,
parsing_mode: ParsingMode,
quirks_mode: QuirksMode,
@@ -72,7 +75,6 @@ impl<'a> ParserContext<'a> {
ParserContext {
stylesheet_origin: stylesheet_origin,
url_data: url_data,
- error_reporter: error_reporter,
rule_type: rule_type,
line_number_offset: 0u64,
parsing_mode: parsing_mode,
@@ -84,7 +86,6 @@ impl<'a> ParserContext<'a> {
/// Create a parser context for on-the-fly parsing in CSSOM
pub fn new_for_cssom(
url_data: &'a UrlExtraData,
- error_reporter: &'a ParseErrorReporter,
rule_type: Option<CssRuleType>,
parsing_mode: ParsingMode,
quirks_mode: QuirksMode
@@ -92,7 +93,6 @@ impl<'a> ParserContext<'a> {
Self::new(
Origin::Author,
url_data,
- error_reporter,
rule_type,
parsing_mode,
quirks_mode,
@@ -108,7 +108,6 @@ impl<'a> ParserContext<'a> {
ParserContext {
stylesheet_origin: context.stylesheet_origin,
url_data: context.url_data,
- error_reporter: context.error_reporter,
rule_type: Some(rule_type),
line_number_offset: context.line_number_offset,
parsing_mode: context.parsing_mode,
@@ -121,7 +120,6 @@ impl<'a> ParserContext<'a> {
pub fn new_with_line_number_offset(
stylesheet_origin: Origin,
url_data: &'a UrlExtraData,
- error_reporter: &'a ParseErrorReporter,
line_number_offset: u64,
parsing_mode: ParsingMode,
quirks_mode: QuirksMode,
@@ -129,7 +127,6 @@ impl<'a> ParserContext<'a> {
ParserContext {
stylesheet_origin: stylesheet_origin,
url_data: url_data,
- error_reporter: error_reporter,
rule_type: None,
line_number_offset: line_number_offset,
parsing_mode: parsing_mode,
@@ -144,12 +141,17 @@ impl<'a> ParserContext<'a> {
}
/// Record a CSS parse error with this context’s error reporting.
- pub fn log_css_error(&self, location: SourceLocation, error: ContextualParseError) {
+ pub fn log_css_error<R>(&self,
+ context: &ParserErrorContext<R>,
+ location: SourceLocation,
+ error: ContextualParseError)
+ where R: ParseErrorReporter
+ {
let location = SourceLocation {
line: location.line + self.line_number_offset as u32,
column: location.column,
};
- self.error_reporter.report_error(self.url_data, location, error)
+ context.error_reporter.report_error(self.url_data, location, error)
}
}
diff --git a/components/style/properties/declaration_block.rs b/components/style/properties/declaration_block.rs
index 07bc5eeab1d..1136f514857 100644
--- a/components/style/properties/declaration_block.rs
+++ b/components/style/properties/declaration_block.rs
@@ -10,7 +10,7 @@ use context::QuirksMode;
use cssparser::{DeclarationListParser, parse_important, ParserInput, CowRcStr};
use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter, ParseError as CssParseError};
use error_reporting::{ParseErrorReporter, ContextualParseError};
-use parser::ParserContext;
+use parser::{ParserContext, ParserErrorContext};
use properties::animated_properties::AnimationValue;
use selectors::parser::SelectorParseError;
use shared_lock::Locked;
@@ -896,36 +896,39 @@ pub fn append_serialization<'a, W, I, N>(dest: &mut W,
/// A helper to parse the style attribute of an element, in order for this to be
/// shared between Servo and Gecko.
-pub fn parse_style_attribute(input: &str,
- url_data: &UrlExtraData,
- error_reporter: &ParseErrorReporter,
- quirks_mode: QuirksMode)
- -> PropertyDeclarationBlock {
+pub fn parse_style_attribute<R>(input: &str,
+ url_data: &UrlExtraData,
+ error_reporter: &R,
+ quirks_mode: QuirksMode)
+ -> PropertyDeclarationBlock
+ where R: ParseErrorReporter
+{
let context = ParserContext::new(Origin::Author,
url_data,
- error_reporter,
Some(CssRuleType::Style),
PARSING_MODE_DEFAULT,
quirks_mode);
+ let error_context = ParserErrorContext { error_reporter: error_reporter };
let mut input = ParserInput::new(input);
- parse_property_declaration_list(&context, &mut Parser::new(&mut input))
+ parse_property_declaration_list(&context, &error_context, &mut Parser::new(&mut input))
}
/// Parse a given property declaration. Can result in multiple
/// `PropertyDeclaration`s when expanding a shorthand, for example.
///
/// This does not attempt to parse !important at all.
-pub fn parse_one_declaration_into(declarations: &mut SourcePropertyDeclaration,
- id: PropertyId,
- input: &str,
- url_data: &UrlExtraData,
- error_reporter: &ParseErrorReporter,
- parsing_mode: ParsingMode,
- quirks_mode: QuirksMode)
- -> Result<(), ()> {
+pub fn parse_one_declaration_into<R>(declarations: &mut SourcePropertyDeclaration,
+ id: PropertyId,
+ input: &str,
+ url_data: &UrlExtraData,
+ error_reporter: &R,
+ parsing_mode: ParsingMode,
+ quirks_mode: QuirksMode)
+ -> Result<(), ()>
+ where R: ParseErrorReporter
+{
let context = ParserContext::new(Origin::Author,
url_data,
- error_reporter,
Some(CssRuleType::Style),
parsing_mode,
quirks_mode);
@@ -939,7 +942,8 @@ pub fn parse_one_declaration_into(declarations: &mut SourcePropertyDeclaration,
}).map_err(|err| {
let error = ContextualParseError::UnsupportedPropertyDeclaration(
parser.slice_from(start_position), err);
- context.log_css_error(start_location, error);
+ let error_context = ParserErrorContext { error_reporter: error_reporter };
+ context.log_css_error(&error_context, start_location, error);
})
}
@@ -997,9 +1001,12 @@ impl<'a, 'b, 'i> DeclarationParser<'i> for PropertyDeclarationParser<'a, 'b> {
/// Parse a list of property declarations and return a property declaration
/// block.
-pub fn parse_property_declaration_list(context: &ParserContext,
- input: &mut Parser)
- -> PropertyDeclarationBlock {
+pub fn parse_property_declaration_list<R>(context: &ParserContext,
+ error_context: &ParserErrorContext<R>,
+ input: &mut Parser)
+ -> PropertyDeclarationBlock
+ where R: ParseErrorReporter
+{
let mut declarations = SourcePropertyDeclaration::new();
let mut block = PropertyDeclarationBlock::new();
let parser = PropertyDeclarationParser {
@@ -1024,7 +1031,7 @@ pub fn parse_property_declaration_list(context: &ParserContext,
}
let error = ContextualParseError::UnsupportedPropertyDeclaration(err.slice, err.error);
- context.log_css_error(err.location, error);
+ context.log_css_error(error_context, err.location, error);
}
}
}
diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs
index f64117e1bfc..b7986e2cac4 100644
--- a/components/style/properties/properties.mako.rs
+++ b/components/style/properties/properties.mako.rs
@@ -23,7 +23,6 @@ use cssparser::ParserInput;
#[cfg(feature = "servo")] use euclid::SideOffsets2D;
use computed_values;
use context::QuirksMode;
-use error_reporting::NullReporter;
use font_metrics::FontMetricsProvider;
#[cfg(feature = "gecko")] use gecko_bindings::bindings;
#[cfg(feature = "gecko")] use gecko_bindings::structs::{self, nsCSSPropertyID};
@@ -828,10 +827,8 @@ impl UnparsedValue {
.ok()
.and_then(|css| {
// As of this writing, only the base URL is used for property values:
- let reporter = NullReporter;
let context = ParserContext::new(Origin::Author,
&self.url_data,
- &reporter,
None,
PARSING_MODE_DEFAULT,
quirks_mode);
diff --git a/components/style/stylesheets/font_feature_values_rule.rs b/components/style/stylesheets/font_feature_values_rule.rs
index df30013b35b..3d765616367 100644
--- a/components/style/stylesheets/font_feature_values_rule.rs
+++ b/components/style/stylesheets/font_feature_values_rule.rs
@@ -10,8 +10,8 @@ use Atom;
use computed_values::font_family::FamilyName;
use cssparser::{AtRuleParser, AtRuleType, BasicParseError, DeclarationListParser, DeclarationParser, Parser};
use cssparser::{CowRcStr, RuleListParser, SourceLocation, QualifiedRuleParser, Token, serialize_identifier};
-use error_reporting::ContextualParseError;
-use parser::{ParserContext, Parse};
+use error_reporting::{ContextualParseError, ParseErrorReporter};
+use parser::{ParserContext, ParserErrorContext, Parse};
use selectors::parser::SelectorParseError;
use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
use std::fmt;
@@ -210,20 +210,26 @@ macro_rules! font_feature_values_blocks {
}
/// Parses a `FontFeatureValuesRule`.
- pub fn parse(context: &ParserContext, input: &mut Parser,
- family_names: Vec<FamilyName>, location: SourceLocation)
- -> FontFeatureValuesRule {
+ pub fn parse<R>(context: &ParserContext,
+ error_context: &ParserErrorContext<R>,
+ input: &mut Parser,
+ family_names: Vec<FamilyName>,
+ location: SourceLocation)
+ -> FontFeatureValuesRule
+ where R: ParseErrorReporter
+ {
let mut rule = FontFeatureValuesRule::new(family_names, location);
{
let mut iter = RuleListParser::new_for_nested_rule(input, FontFeatureValuesRuleParser {
context: context,
+ error_context: error_context,
rule: &mut rule,
});
while let Some(result) = iter.next() {
if let Err(err) = result {
let error = ContextualParseError::UnsupportedRule(err.slice, err.error);
- context.log_css_error(err.location, error);
+ context.log_css_error(error_context, err.location, error);
}
}
}
@@ -293,19 +299,20 @@ macro_rules! font_feature_values_blocks {
/// }
/// <feature-type> = @stylistic | @historical-forms | @styleset |
/// @character-variant | @swash | @ornaments | @annotation
- struct FontFeatureValuesRuleParser<'a> {
+ struct FontFeatureValuesRuleParser<'a, R: 'a> {
context: &'a ParserContext<'a>,
+ error_context: &'a ParserErrorContext<'a, R>,
rule: &'a mut FontFeatureValuesRule,
}
/// Default methods reject all qualified rules.
- impl<'a, 'i> QualifiedRuleParser<'i> for FontFeatureValuesRuleParser<'a> {
+ impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for FontFeatureValuesRuleParser<'a, R> {
type Prelude = ();
type QualifiedRule = ();
type Error = SelectorParseError<'i, StyleParseError<'i>>;
}
- impl<'a, 'i> AtRuleParser<'i> for FontFeatureValuesRuleParser<'a> {
+ impl<'a, 'i, R: ParseErrorReporter> AtRuleParser<'i> for FontFeatureValuesRuleParser<'a, R> {
type Prelude = BlockType;
type AtRule = ();
type Error = SelectorParseError<'i, StyleParseError<'i>>;
@@ -341,7 +348,7 @@ macro_rules! font_feature_values_blocks {
if let Err(err) = declaration {
let error = ContextualParseError::UnsupportedKeyframePropertyDeclaration(
err.slice, err.error);
- self.context.log_css_error(err.location, error);
+ self.context.log_css_error(self.error_context, err.location, error);
}
}
},
diff --git a/components/style/stylesheets/keyframes_rule.rs b/components/style/stylesheets/keyframes_rule.rs
index 7fc292a339e..17828b334d3 100644
--- a/components/style/stylesheets/keyframes_rule.rs
+++ b/components/style/stylesheets/keyframes_rule.rs
@@ -6,8 +6,8 @@
use cssparser::{AtRuleParser, Parser, QualifiedRuleParser, RuleListParser, ParserInput, CowRcStr};
use cssparser::{DeclarationListParser, DeclarationParser, parse_one_rule, SourceLocation};
-use error_reporting::{NullReporter, ContextualParseError};
-use parser::ParserContext;
+use error_reporting::{NullReporter, ContextualParseError, ParseErrorReporter};
+use parser::{ParserContext, ParserErrorContext};
use properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock, PropertyId, PropertyParserContext};
use properties::{PropertyDeclarationId, LonghandId, SourcePropertyDeclaration};
use properties::LonghandIdSet;
@@ -218,11 +218,11 @@ impl Keyframe {
let mut context = ParserContext::new(
parent_stylesheet_contents.origin,
&url_data,
- &error_reporter,
Some(CssRuleType::Keyframe),
PARSING_MODE_DEFAULT,
parent_stylesheet_contents.quirks_mode
);
+ let error_context = ParserErrorContext { error_reporter: &error_reporter };
context.namespaces = Some(&*namespaces);
let mut input = ParserInput::new(css);
let mut input = Parser::new(&mut input);
@@ -230,6 +230,7 @@ impl Keyframe {
let mut declarations = SourcePropertyDeclaration::new();
let mut rule_parser = KeyframeListParser {
context: &context,
+ error_context: &error_context,
shared_lock: &lock,
declarations: &mut declarations,
};
@@ -447,37 +448,42 @@ impl KeyframesAnimation {
/// 40%, 60%, 100% {
/// width: 100%;
/// }
-struct KeyframeListParser<'a> {
+struct KeyframeListParser<'a, R: 'a> {
context: &'a ParserContext<'a>,
+ error_context: &'a ParserErrorContext<'a, R>,
shared_lock: &'a SharedRwLock,
declarations: &'a mut SourcePropertyDeclaration,
}
/// Parses a keyframe list from CSS input.
-pub fn parse_keyframe_list(
+pub fn parse_keyframe_list<R>(
context: &ParserContext,
+ error_context: &ParserErrorContext<R>,
input: &mut Parser,
shared_lock: &SharedRwLock
-) -> Vec<Arc<Locked<Keyframe>>> {
+) -> Vec<Arc<Locked<Keyframe>>>
+ where R: ParseErrorReporter
+{
debug_assert!(context.namespaces.is_some(),
"Parsing a keyframe list from a context without namespaces?");
let mut declarations = SourcePropertyDeclaration::new();
RuleListParser::new_for_nested_rule(input, KeyframeListParser {
context: context,
+ error_context: error_context,
shared_lock: shared_lock,
declarations: &mut declarations,
}).filter_map(Result::ok).collect()
}
enum Void {}
-impl<'a, 'i> AtRuleParser<'i> for KeyframeListParser<'a> {
+impl<'a, 'i, R> AtRuleParser<'i> for KeyframeListParser<'a, R> {
type Prelude = Void;
type AtRule = Arc<Locked<Keyframe>>;
type Error = SelectorParseError<'i, StyleParseError<'i>>;
}
-impl<'a, 'i> QualifiedRuleParser<'i> for KeyframeListParser<'a> {
+impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for KeyframeListParser<'a, R> {
type Prelude = KeyframeSelector;
type QualifiedRule = Arc<Locked<Keyframe>>;
type Error = SelectorParseError<'i, StyleParseError<'i>>;
@@ -489,7 +495,7 @@ impl<'a, 'i> QualifiedRuleParser<'i> for KeyframeListParser<'a> {
Ok(sel) => Ok(sel),
Err(e) => {
let error = ContextualParseError::InvalidKeyframeRule(input.slice_from(start_position), e.clone());
- self.context.log_css_error(start_location, error);
+ self.context.log_css_error(self.error_context, start_location, error);
Err(e)
}
}
@@ -518,7 +524,7 @@ impl<'a, 'i> QualifiedRuleParser<'i> for KeyframeListParser<'a> {
Err(err) => {
iter.parser.declarations.clear();
let error = ContextualParseError::UnsupportedKeyframePropertyDeclaration(err.slice, err.error);
- context.log_css_error(err.location, error);
+ context.log_css_error(self.error_context, err.location, error);
}
}
// `parse_important` is not called here, `!important` is not allowed in keyframe blocks.
diff --git a/components/style/stylesheets/mod.rs b/components/style/stylesheets/mod.rs
index 1ec7cbbfb06..25a91b4f7a9 100644
--- a/components/style/stylesheets/mod.rs
+++ b/components/style/stylesheets/mod.rs
@@ -26,7 +26,7 @@ pub mod viewport_rule;
use cssparser::{parse_one_rule, Parser, ParserInput};
use error_reporting::NullReporter;
-use parser::ParserContext;
+use parser::{ParserContext, ParserErrorContext};
use servo_arc::Arc;
use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard};
use std::fmt;
@@ -230,7 +230,6 @@ impl CssRule {
let context = ParserContext::new(
parent_stylesheet_contents.origin,
&url_data,
- &error_reporter,
None,
PARSING_MODE_DEFAULT,
parent_stylesheet_contents.quirks_mode,
@@ -246,6 +245,7 @@ impl CssRule {
let mut rule_parser = TopLevelRuleParser {
stylesheet_origin: parent_stylesheet_contents.origin,
context: context,
+ error_context: ParserErrorContext { error_reporter: &error_reporter },
shared_lock: &shared_lock,
loader: loader,
state: state,
diff --git a/components/style/stylesheets/rule_parser.rs b/components/style/stylesheets/rule_parser.rs
index 4f9fe566c90..65bcd7cd149 100644
--- a/components/style/stylesheets/rule_parser.rs
+++ b/components/style/stylesheets/rule_parser.rs
@@ -9,10 +9,10 @@ use computed_values::font_family::FamilyName;
use counter_style::{parse_counter_style_body, parse_counter_style_name};
use cssparser::{AtRuleParser, AtRuleType, Parser, QualifiedRuleParser, RuleListParser};
use cssparser::{CowRcStr, SourceLocation, BasicParseError};
-use error_reporting::ContextualParseError;
+use error_reporting::{ContextualParseError, ParseErrorReporter};
use font_face::parse_font_face_block;
use media_queries::{parse_media_query_list, MediaList};
-use parser::{Parse, ParserContext};
+use parser::{Parse, ParserContext, ParserErrorContext};
use properties::parse_property_declaration_list;
use selector_parser::{SelectorImpl, SelectorParser};
use selectors::SelectorList;
@@ -35,7 +35,7 @@ use values::KeyframesName;
use values::specified::url::SpecifiedUrl;
/// The parser for the top-level rules in a stylesheet.
-pub struct TopLevelRuleParser<'a> {
+pub struct TopLevelRuleParser<'a, R: 'a> {
/// The origin of the stylesheet we're parsing.
pub stylesheet_origin: Origin,
/// A reference to the lock we need to use to create rules.
@@ -47,6 +47,8 @@ pub struct TopLevelRuleParser<'a> {
/// This won't contain any namespaces, and only nested parsers created with
/// `ParserContext::new_with_rule_type` will.
pub context: ParserContext<'a>,
+ /// The context required for reporting parse errors.
+ pub error_context: ParserErrorContext<'a, R>,
/// The current state of the parser.
pub state: State,
/// Whether we have tried to parse was invalid due to being in the wrong
@@ -59,12 +61,13 @@ pub struct TopLevelRuleParser<'a> {
pub namespaces: &'a mut Namespaces,
}
-impl<'b> TopLevelRuleParser<'b> {
- fn nested<'a: 'b>(&'a self) -> NestedRuleParser<'a, 'b> {
+impl<'b, R> TopLevelRuleParser<'b, R> {
+ fn nested<'a: 'b>(&'a self) -> NestedRuleParser<'a, 'b, R> {
NestedRuleParser {
stylesheet_origin: self.stylesheet_origin,
shared_lock: self.shared_lock,
context: &self.context,
+ error_context: &self.error_context,
namespaces: &self.namespaces,
}
}
@@ -147,7 +150,7 @@ fn register_namespace(_: &Namespace) -> Result<(), ()> {
Ok(()) // servo doesn't use namespace ids
}
-impl<'a, 'i> AtRuleParser<'i> for TopLevelRuleParser<'a> {
+impl<'a, 'i, R: ParseErrorReporter> AtRuleParser<'i> for TopLevelRuleParser<'a, R> {
type Prelude = AtRulePrelude;
type AtRule = CssRule;
type Error = SelectorParseError<'i, StyleParseError<'i>>;
@@ -256,7 +259,7 @@ pub struct QualifiedRuleParserPrelude {
source_location: SourceLocation,
}
-impl<'a, 'i> QualifiedRuleParser<'i> for TopLevelRuleParser<'a> {
+impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for TopLevelRuleParser<'a, R> {
type Prelude = QualifiedRuleParserPrelude;
type QualifiedRule = CssRule;
type Error = SelectorParseError<'i, StyleParseError<'i>>;
@@ -281,14 +284,15 @@ impl<'a, 'i> QualifiedRuleParser<'i> for TopLevelRuleParser<'a> {
}
#[derive(Clone)] // shallow, relatively cheap .clone
-struct NestedRuleParser<'a, 'b: 'a> {
+struct NestedRuleParser<'a, 'b: 'a, R: 'b> {
stylesheet_origin: Origin,
shared_lock: &'a SharedRwLock,
context: &'a ParserContext<'b>,
+ error_context: &'a ParserErrorContext<'b, R>,
namespaces: &'a Namespaces,
}
-impl<'a, 'b> NestedRuleParser<'a, 'b> {
+impl<'a, 'b, R: ParseErrorReporter> NestedRuleParser<'a, 'b, R> {
fn parse_nested_rules(
&mut self,
input: &mut Parser,
@@ -301,6 +305,7 @@ impl<'a, 'b> NestedRuleParser<'a, 'b> {
stylesheet_origin: self.stylesheet_origin,
shared_lock: self.shared_lock,
context: &context,
+ error_context: &self.error_context,
namespaces: self.namespaces,
};
@@ -311,7 +316,7 @@ impl<'a, 'b> NestedRuleParser<'a, 'b> {
Ok(rule) => rules.push(rule),
Err(err) => {
let error = ContextualParseError::UnsupportedRule(err.slice, err.error);
- self.context.log_css_error(err.location, error);
+ self.context.log_css_error(self.error_context, err.location, error);
}
}
}
@@ -319,7 +324,7 @@ impl<'a, 'b> NestedRuleParser<'a, 'b> {
}
}
-impl<'a, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'b> {
+impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a, 'b, R> {
type Prelude = AtRulePrelude;
type AtRule = CssRule;
type Error = SelectorParseError<'i, StyleParseError<'i>>;
@@ -428,7 +433,7 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'b> {
);
Ok(CssRule::FontFace(Arc::new(self.shared_lock.wrap(
- parse_font_face_block(&context, input, location).into()))))
+ parse_font_face_block(&context, self.error_context, input, location).into()))))
}
AtRulePrelude::FontFeatureValues(family_names, location) => {
let context =
@@ -438,7 +443,7 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'b> {
self.namespaces,
);
Ok(CssRule::FontFeatureValues(Arc::new(self.shared_lock.wrap(
- FontFeatureValuesRule::parse(&context, input, family_names, location)))))
+ FontFeatureValuesRule::parse(&context, self.error_context, input, family_names, location)))))
}
AtRulePrelude::CounterStyle(name) => {
let context =
@@ -448,7 +453,7 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'b> {
self.namespaces,
);
Ok(CssRule::CounterStyle(Arc::new(self.shared_lock.wrap(
- parse_counter_style_body(name, &context, input)?.into()))))
+ parse_counter_style_body(name, &context, self.error_context, input)?.into()))))
}
AtRulePrelude::Media(media_queries, location) => {
Ok(CssRule::Media(Arc::new(self.shared_lock.wrap(MediaRule {
@@ -480,7 +485,7 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'b> {
self.namespaces,
);
Ok(CssRule::Viewport(Arc::new(self.shared_lock.wrap(
- ViewportRule::parse(&context, input)?))))
+ ViewportRule::parse(&context, self.error_context, input)?))))
}
AtRulePrelude::Keyframes(name, prefix, location) => {
let context =
@@ -492,7 +497,7 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'b> {
Ok(CssRule::Keyframes(Arc::new(self.shared_lock.wrap(KeyframesRule {
name: name,
- keyframes: parse_keyframe_list(&context, input, self.shared_lock),
+ keyframes: parse_keyframe_list(&context, self.error_context, input, self.shared_lock),
vendor_prefix: prefix,
source_location: location,
}))))
@@ -504,7 +509,7 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'b> {
CssRuleType::Page,
self.namespaces,
);
- let declarations = parse_property_declaration_list(&context, input);
+ let declarations = parse_property_declaration_list(&context, self.error_context, input);
Ok(CssRule::Page(Arc::new(self.shared_lock.wrap(PageRule {
block: Arc::new(self.shared_lock.wrap(declarations)),
source_location: location,
@@ -525,7 +530,7 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'b> {
}
}
-impl<'a, 'b, 'i> QualifiedRuleParser<'i> for NestedRuleParser<'a, 'b> {
+impl<'a, 'b, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for NestedRuleParser<'a, 'b, R> {
type Prelude = QualifiedRuleParserPrelude;
type QualifiedRule = CssRule;
type Error = SelectorParseError<'i, StyleParseError<'i>>;
@@ -561,7 +566,7 @@ impl<'a, 'b, 'i> QualifiedRuleParser<'i> for NestedRuleParser<'a, 'b> {
CssRuleType::Style,
self.namespaces,
);
- let declarations = parse_property_declaration_list(&context, input);
+ let declarations = parse_property_declaration_list(&context, self.error_context, input);
Ok(CssRule::Style(Arc::new(self.shared_lock.wrap(StyleRule {
selectors: prelude.selectors,
block: Arc::new(self.shared_lock.wrap(declarations)),
diff --git a/components/style/stylesheets/stylesheet.rs b/components/style/stylesheets/stylesheet.rs
index 9dc8446f6b6..b71863dab6b 100644
--- a/components/style/stylesheets/stylesheet.rs
+++ b/components/style/stylesheets/stylesheet.rs
@@ -10,7 +10,7 @@ use fnv::FnvHashMap;
use invalidation::media_queries::{MediaListKey, ToMediaListKey};
use media_queries::{MediaList, Device};
use parking_lot::RwLock;
-use parser::ParserContext;
+use parser::{ParserContext, ParserErrorContext};
use servo_arc::Arc;
use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard};
use std::mem;
@@ -67,13 +67,13 @@ pub struct StylesheetContents {
impl StylesheetContents {
/// Parse a given CSS string, with a given url-data, origin, and
/// quirks mode.
- pub fn from_str(
+ pub fn from_str<R: ParseErrorReporter>(
css: &str,
url_data: UrlExtraData,
origin: Origin,
shared_lock: &SharedRwLock,
stylesheet_loader: Option<&StylesheetLoader>,
- error_reporter: &ParseErrorReporter,
+ error_reporter: &R,
quirks_mode: QuirksMode,
line_number_offset: u64
) -> Self {
@@ -313,12 +313,14 @@ impl StylesheetInDocument for DocumentStyleSheet {
impl Stylesheet {
/// Updates an empty stylesheet from a given string of text.
- pub fn update_from_str(existing: &Stylesheet,
- css: &str,
- url_data: UrlExtraData,
- stylesheet_loader: Option<&StylesheetLoader>,
- error_reporter: &ParseErrorReporter,
- line_number_offset: u64) {
+ pub fn update_from_str<R>(existing: &Stylesheet,
+ css: &str,
+ url_data: UrlExtraData,
+ stylesheet_loader: Option<&StylesheetLoader>,
+ error_reporter: &R,
+ line_number_offset: u64)
+ where R: ParseErrorReporter
+ {
let namespaces = RwLock::new(Namespaces::default());
let (rules, dirty_on_viewport_size_change, source_map_url) =
Stylesheet::parse_rules(
@@ -347,14 +349,14 @@ impl Stylesheet {
*existing.contents.source_map_url.write() = source_map_url;
}
- fn parse_rules(
+ fn parse_rules<R: ParseErrorReporter>(
css: &str,
url_data: &UrlExtraData,
origin: Origin,
namespaces: &mut Namespaces,
shared_lock: &SharedRwLock,
stylesheet_loader: Option<&StylesheetLoader>,
- error_reporter: &ParseErrorReporter,
+ error_reporter: &R,
quirks_mode: QuirksMode,
line_number_offset: u64
) -> (Vec<CssRule>, bool, Option<String>) {
@@ -366,17 +368,18 @@ impl Stylesheet {
ParserContext::new_with_line_number_offset(
origin,
url_data,
- error_reporter,
line_number_offset,
PARSING_MODE_DEFAULT,
quirks_mode
);
+ let error_context = ParserErrorContext { error_reporter };
let rule_parser = TopLevelRuleParser {
stylesheet_origin: origin,
shared_lock: shared_lock,
loader: stylesheet_loader,
context: context,
+ error_context: error_context,
state: State::Start,
had_hierarchy_error: false,
namespaces: namespaces,
@@ -393,7 +396,8 @@ impl Stylesheet {
Ok(rule) => rules.push(rule),
Err(err) => {
let error = ContextualParseError::InvalidRule(err.slice, err.error);
- iter.parser.context.log_css_error(err.location, error);
+ iter.parser.context.log_css_error(&iter.parser.error_context,
+ err.location, error);
}
}
}
@@ -408,16 +412,18 @@ impl Stylesheet {
///
/// Effectively creates a new stylesheet and forwards the hard work to
/// `Stylesheet::update_from_str`.
- pub fn from_str(css: &str,
- url_data: UrlExtraData,
- origin: Origin,
- media: Arc<Locked<MediaList>>,
- shared_lock: SharedRwLock,
- stylesheet_loader: Option<&StylesheetLoader>,
- error_reporter: &ParseErrorReporter,
- quirks_mode: QuirksMode,
- line_number_offset: u64)
- -> Stylesheet {
+ pub fn from_str<R: ParseErrorReporter>(
+ css: &str,
+ url_data: UrlExtraData,
+ origin: Origin,
+ media: Arc<Locked<MediaList>>,
+ shared_lock: SharedRwLock,
+ stylesheet_loader: Option<&StylesheetLoader>,
+ error_reporter: &R,
+ quirks_mode: QuirksMode,
+ line_number_offset: u64)
+ -> Stylesheet
+ {
let contents = StylesheetContents::from_str(
css,
url_data,
diff --git a/components/style/stylesheets/viewport_rule.rs b/components/style/stylesheets/viewport_rule.rs
index a98f5807fa6..1e58553e676 100644
--- a/components/style/stylesheets/viewport_rule.rs
+++ b/components/style/stylesheets/viewport_rule.rs
@@ -11,11 +11,11 @@ use app_units::Au;
use context::QuirksMode;
use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser, parse_important};
use cssparser::{CowRcStr, ToCss as ParserToCss};
-use error_reporting::ContextualParseError;
+use error_reporting::{ContextualParseError, ParseErrorReporter};
use euclid::TypedSize2D;
use font_metrics::get_metrics_provider_for_product;
use media_queries::Device;
-use parser::{Parse, ParserContext};
+use parser::{ParserContext, ParserErrorContext};
use properties::StyleBuilder;
use selectors::parser::SelectorParseError;
use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
@@ -346,8 +346,14 @@ fn is_whitespace_separator_or_equals(c: &char) -> bool {
WHITESPACE.contains(c) || SEPARATOR.contains(c) || *c == '='
}
-impl Parse for ViewportRule {
- fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
+impl ViewportRule {
+ /// Parse a single @viewport rule.
+ pub fn parse<'i, 't, R>(context: &ParserContext,
+ error_context: &ParserErrorContext<R>,
+ input: &mut Parser<'i, 't>)
+ -> Result<Self, ParseError<'i>>
+ where R: ParseErrorReporter
+ {
let parser = ViewportRuleParser { context: context };
let mut cascade = Cascade::new();
@@ -361,7 +367,7 @@ impl Parse for ViewportRule {
}
Err(err) => {
let error = ContextualParseError::UnsupportedViewportDescriptorDeclaration(err.slice, err.error);
- context.log_css_error(err.location, error);
+ context.log_css_error(error_context, err.location, error);
}
}
}