diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2017-03-13 16:50:26 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-03-13 16:50:26 -0700 |
commit | 8c8edb8731dc01d254839d0922590fba72f278c6 (patch) | |
tree | c0c0297ced2c9b58828f4f68dadd50055e53ce6d | |
parent | 35028f8f60d172a6bde8133ebe26e887eb33d9e6 (diff) | |
parent | b4de69e3ebf5b2a6e82b68b66df090e9220b9e61 (diff) | |
download | servo-8c8edb8731dc01d254839d0922590fba72f278c6.tar.gz servo-8c8edb8731dc01d254839d0922590fba72f278c6.zip |
Auto merge of #15931 - emilio:die-defaultvalues-die, r=mbrubeck
style: Kill SharedStyleContext::default_computed_values.
This is on top of https://github.com/servo/servo/pull/15928.
Now that cascade() gets a Device ref, we can use the default computed values
from there to avoid propagating that state all over the place.
<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/15931)
<!-- Reviewable:end -->
54 files changed, 414 insertions, 258 deletions
diff --git a/components/layout/construct.rs b/components/layout/construct.rs index 1125261dce4..a6571d0e093 100644 --- a/components/layout/construct.rs +++ b/components/layout/construct.rs @@ -662,8 +662,8 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> if node_is_input_or_text_area { style = self.style_context() .stylist - .style_for_anonymous_box(&PseudoElement::ServoInputText, &style, - &self.style_context().default_computed_values) + .style_for_anonymous_box(&PseudoElement::ServoInputText, + &style) } self.create_fragments_for_node_text_content(&mut initial_fragments, node, &style) @@ -1100,7 +1100,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> let wrapper_style = self.style_context() .stylist .style_for_anonymous_box(&PseudoElement::ServoTableWrapper, - &table_style, &self.style_context().default_computed_values); + &table_style); let wrapper_fragment = Fragment::from_opaque_node_and_style(node.opaque(), PseudoElementType::Normal, @@ -2080,7 +2080,8 @@ impl Legalizer { let reference_block = reference.as_block(); let mut new_style = reference_block.fragment.style.clone(); for pseudo in pseudos { - new_style = context.stylist.style_for_anonymous_box(pseudo, &new_style, &context.default_computed_values) + new_style = context.stylist.style_for_anonymous_box(pseudo, + &new_style) } let fragment = reference_block.fragment .create_similar_anonymous_fragment(new_style, diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs index 529100c06d8..58f81a71a59 100644 --- a/components/layout_thread/lib.rs +++ b/components/layout_thread/lib.rs @@ -110,11 +110,10 @@ use style::animation::Animation; use style::context::{QuirksMode, ReflowGoal, SharedStyleContext, ThreadLocalStyleContextCreationInfo}; use style::data::StoredRestyleHint; use style::dom::{ShowSubtree, ShowSubtreeDataAndPrimaryValues, TElement, TNode}; -use style::error_reporting::{ParseErrorReporter, StdoutErrorReporter}; +use style::error_reporting::StdoutErrorReporter; use style::logical_geometry::LogicalPoint; use style::media_queries::{Device, MediaType}; use style::parser::ParserContextExtraData; -use style::properties::ComputedValues; use style::servo::restyle_damage::{REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, REPOSITION, STORE_OVERFLOW}; use style::stylesheets::{Origin, Stylesheet, UserAgentStylesheets}; use style::stylist::Stylist; @@ -506,15 +505,10 @@ impl LayoutThread { stylist: rw_data.stylist.clone(), running_animations: self.running_animations.clone(), expired_animations: self.expired_animations.clone(), - error_reporter: self.error_reporter.clone(), + error_reporter: Box::new(self.error_reporter.clone()), local_context_creation_data: Mutex::new(thread_local_style_context_creation_data), timer: self.timer.clone(), quirks_mode: self.quirks_mode.unwrap(), - // FIXME(bz): This isn't really right, but it's no more wrong - // than what we used to do. See - // https://github.com/servo/servo/issues/14773 for fixing it - // properly. - default_computed_values: Arc::new(ComputedValues::initial_values().clone()), }, image_cache_thread: Mutex::new(self.image_cache_thread.clone()), font_cache_thread: Mutex::new(self.font_cache_thread.clone()), @@ -1569,7 +1563,7 @@ fn get_ua_stylesheets() -> Result<UserAgentStylesheets, &'static str> { Origin::UserAgent, Default::default(), None, - Box::new(StdoutErrorReporter), + &StdoutErrorReporter, ParserContextExtraData::default())) } @@ -1582,8 +1576,7 @@ fn get_ua_stylesheets() -> Result<UserAgentStylesheets, &'static str> { for &(ref contents, ref url) in &opts::get().user_stylesheets { user_or_user_agent_stylesheets.push(Stylesheet::from_bytes( &contents, url.clone(), None, None, Origin::User, Default::default(), - None, Box::new(StdoutErrorReporter), - ParserContextExtraData::default())); + None, &StdoutErrorReporter, ParserContextExtraData::default())); } let quirks_mode_stylesheet = try!(parse_ua_stylesheet("quirks-mode.css")); diff --git a/components/script/dom/css.rs b/components/script/dom/css.rs index e24b3657775..92c15a10067 100644 --- a/components/script/dom/css.rs +++ b/components/script/dom/css.rs @@ -29,7 +29,7 @@ impl CSS { pub fn Supports(win: &Window, property: DOMString, value: DOMString) -> bool { let decl = Declaration { prop: property.into(), val: value.into() }; let url = win.Document().url(); - let context = ParserContext::new_for_cssom(&url); + let context = ParserContext::new_for_cssom(&url, win.css_error_reporter()); decl.eval(&context) } @@ -39,7 +39,7 @@ impl CSS { let cond = parse_condition_or_declaration(&mut input); if let Ok(cond) = cond { let url = win.Document().url(); - let context = ParserContext::new_for_cssom(&url); + let context = ParserContext::new_for_cssom(&url, win.css_error_reporter()); cond.eval(&context) } else { false diff --git a/components/script/dom/csssupportsrule.rs b/components/script/dom/csssupportsrule.rs index 7b1e77a6c8f..0cc113bef1c 100644 --- a/components/script/dom/csssupportsrule.rs +++ b/components/script/dom/csssupportsrule.rs @@ -56,8 +56,10 @@ impl CSSSupportsRule { let mut input = Parser::new(&text); let cond = SupportsCondition::parse(&mut input); if let Ok(cond) = cond { - let url = self.global().as_window().Document().url(); - let context = ParserContext::new_for_cssom(&url); + let global = self.global(); + let win = global.as_window(); + let url = win.Document().url(); + let context = ParserContext::new_for_cssom(&url, win.css_error_reporter()); let enabled = cond.eval(&context); let mut rule = self.supportsrule.write(); rule.condition = cond; diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index 64a303c9412..fcb7f85d4cf 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -331,8 +331,8 @@ impl Window { &self.bluetooth_extra_permission_data } - pub fn css_error_reporter(&self) -> Box<ParseErrorReporter + Send> { - self.error_reporter.clone() + pub fn css_error_reporter(&self) -> &ParseErrorReporter { + &self.error_reporter } /// Sets a new list of scroll offsets. diff --git a/components/script_layout_interface/reporter.rs b/components/script_layout_interface/reporter.rs index 171f96d9d06..1c84bd31fc5 100644 --- a/components/script_layout_interface/reporter.rs +++ b/components/script_layout_interface/reporter.rs @@ -11,7 +11,7 @@ use servo_url::ServoUrl; use std::sync::{Mutex, Arc}; use style::error_reporting::ParseErrorReporter; -#[derive(HeapSizeOf)] +#[derive(HeapSizeOf, Clone)] pub struct CSSErrorReporter { pub pipelineid: PipelineId, // Arc+Mutex combo is necessary to make this struct Sync, @@ -22,11 +22,18 @@ pub struct CSSErrorReporter { } impl ParseErrorReporter for CSSErrorReporter { - fn report_error(&self, input: &mut Parser, position: SourcePosition, message: &str, - url: &ServoUrl) { + fn report_error(&self, + input: &mut Parser, + position: SourcePosition, + message: &str, + url: &ServoUrl) { let location = input.source_location(position); if log_enabled!(log::LogLevel::Info) { - info!("Url:\t{}\n{}:{} {}", url.as_str(), location.line, location.column, message) + info!("Url:\t{}\n{}:{} {}", + url.as_str(), + location.line, + location.column, + message) } //TODO: report a real filename @@ -37,11 +44,4 @@ impl ParseErrorReporter for CSSErrorReporter { location.column, message.to_owned())); } - - fn clone(&self) -> Box<ParseErrorReporter + Send + Sync> { - box CSSErrorReporter { - pipelineid: self.pipelineid, - script_chan: self.script_chan.clone(), - } - } } diff --git a/components/script_layout_interface/wrapper_traits.rs b/components/script_layout_interface/wrapper_traits.rs index d8768384245..0e7cb160334 100644 --- a/components/script_layout_interface/wrapper_traits.rs +++ b/components/script_layout_interface/wrapper_traits.rs @@ -407,7 +407,6 @@ pub trait ThreadSafeLayoutElement: Clone + Copy + Sized + Debug + context.stylist.precomputed_values_for_pseudo( &style_pseudo, Some(data.styles().primary.values()), - &context.default_computed_values, CascadeFlags::empty()); data.styles_mut().pseudos .insert(style_pseudo.clone(), new_style); @@ -424,8 +423,7 @@ pub trait ThreadSafeLayoutElement: Clone + Copy + Sized + Debug + .lazily_compute_pseudo_element_style( unsafe { &self.unsafe_get() }, &style_pseudo, - data.styles().primary.values(), - &context.default_computed_values); + data.styles().primary.values()); data.styles_mut().pseudos .insert(style_pseudo.clone(), new_style.unwrap()); } diff --git a/components/style/animation.rs b/components/style/animation.rs index 048c1bfa521..ddf1498d983 100644 --- a/components/style/animation.rs +++ b/components/style/animation.rs @@ -426,14 +426,13 @@ fn compute_style_for_animation_step(context: &SharedStyleContext, }; let computed = - properties::apply_declarations(context.viewport_size(), + properties::apply_declarations(&context.stylist.device, /* is_root = */ false, iter, previous_style, previous_style, - &context.default_computed_values, /* cascade_info = */ None, - context.error_reporter.clone(), + &*context.error_reporter, /* Metrics provider */ None, CascadeFlags::empty()); computed diff --git a/components/style/context.rs b/components/style/context.rs index fa3e6182c0f..44485915c2c 100644 --- a/components/style/context.rs +++ b/components/style/context.rs @@ -14,7 +14,6 @@ use error_reporting::ParseErrorReporter; use euclid::Size2D; use matching::StyleSharingCandidateCache; use parking_lot::RwLock; -use properties::ComputedValues; use selector_parser::PseudoElement; use selectors::matching::ElementSelectorFlags; use servo_config::opts; @@ -73,7 +72,7 @@ pub struct SharedStyleContext { pub expired_animations: Arc<RwLock<HashMap<OpaqueNode, Vec<Animation>>>>, ///The CSS error reporter for all CSS loaded in this layout thread - pub error_reporter: Box<ParseErrorReporter + Sync>, + pub error_reporter: Box<ParseErrorReporter>, /// Data needed to create the thread-local style context from the shared one. pub local_context_creation_data: Mutex<ThreadLocalStyleContextCreationInfo>, @@ -84,10 +83,6 @@ pub struct SharedStyleContext { /// The QuirksMode state which the document needs to be rendered with pub quirks_mode: QuirksMode, - - /// The default computed values to use for elements with no rules - /// applying to them. - pub default_computed_values: Arc<ComputedValues>, } impl SharedStyleContext { diff --git a/components/style/error_reporting.rs b/components/style/error_reporting.rs index e815d0bf29e..ca62212fdaf 100644 --- a/components/style/error_reporting.rs +++ b/components/style/error_reporting.rs @@ -11,16 +11,16 @@ use log; use servo_url::ServoUrl; /// A generic trait for an error reporter. -pub trait ParseErrorReporter { +pub trait ParseErrorReporter : Sync + Send { /// Called the style engine detects an error. /// /// Returns the current input being parsed, the source position it was /// reported from, and a message. - fn report_error(&self, input: &mut Parser, position: SourcePosition, message: &str, url: &ServoUrl); - /// Clone this error reporter. - /// - /// TODO(emilio): I'm pretty sure all the box shenanigans can go away. - fn clone(&self) -> Box<ParseErrorReporter + Send + Sync>; + fn report_error(&self, + input: &mut Parser, + position: SourcePosition, + message: &str, + url: &ServoUrl); } /// An error reporter that reports the errors to the `info` log channel. @@ -28,15 +28,14 @@ pub trait ParseErrorReporter { /// TODO(emilio): The name of this reporter is a lie, and should be renamed! pub struct StdoutErrorReporter; impl ParseErrorReporter for StdoutErrorReporter { - fn report_error(&self, input: &mut Parser, position: SourcePosition, message: &str, - url: &ServoUrl) { + fn report_error(&self, + input: &mut Parser, + position: SourcePosition, + message: &str, + url: &ServoUrl) { if log_enabled!(log::LogLevel::Info) { let location = input.source_location(position); info!("Url:\t{}\n{}:{} {}", url.as_str(), location.line, location.column, message) } } - - fn clone(&self) -> Box<ParseErrorReporter + Send + Sync> { - Box::new(StdoutErrorReporter) - } } diff --git a/components/style/gecko/data.rs b/components/style/gecko/data.rs index 89c18fa6a06..627b3845051 100644 --- a/components/style/gecko/data.rs +++ b/components/style/gecko/data.rs @@ -103,7 +103,7 @@ impl PerDocumentStyleDataImpl { /// Get the default computed values for this document. pub fn default_computed_values(&self) -> &Arc<ComputedValues> { - self.stylist.device.default_values_arc() + self.stylist.device.default_computed_values_arc() } } diff --git a/components/style/gecko/media_queries.rs b/components/style/gecko/media_queries.rs index 47c904cbe0e..4b557aa2f8c 100644 --- a/components/style/gecko/media_queries.rs +++ b/components/style/gecko/media_queries.rs @@ -29,7 +29,7 @@ pub struct Device { /// NB: The pres context lifetime is tied to the styleset, who owns the /// stylist, and thus the `Device`, so having a raw pres context pointer /// here is fine. - pres_context: RawGeckoPresContextOwned, + pub pres_context: RawGeckoPresContextOwned, default_values: Arc<ComputedValues>, viewport_override: Option<ViewportConstraints>, } @@ -54,10 +54,16 @@ impl Device { /// Returns the default computed values as a reference, in order to match /// Servo. - pub fn default_values(&self) -> &ComputedValues { + pub fn default_computed_values(&self) -> &ComputedValues { &*self.default_values } + /// Returns the default computed values, but wrapped in an arc for cheap + /// cloning. + pub fn default_computed_values_arc(&self) -> &Arc<ComputedValues> { + &self.default_values + } + /// Returns the default computed values as an `Arc`, in order to avoid /// clones. pub fn default_values_arc(&self) -> &Arc<ComputedValues> { @@ -491,19 +497,19 @@ impl Expression { self.feature.mRangeType == nsMediaFeature_RangeType::eMinMaxAllowed, "Whoops, wrong range"); - let default_values = device.default_values(); + let default_values = device.default_computed_values(); // http://dev.w3.org/csswg/mediaqueries3/#units // em units are relative to the initial font-size. let context = computed::Context { is_root_element: false, - viewport_size: device.au_viewport_size(), + device: device, inherited_style: default_values, layout_parent_style: default_values, // This cloning business is kind of dumb.... It's because Context // insists on having an actual ComputedValues inside itself. style: default_values.clone(), - font_metrics_provider: None + font_metrics_provider: None, }; let required_value = match self.value { diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index 85ed9152580..ffeda8793cc 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -299,7 +299,7 @@ impl<'le> GeckoElement<'le> { pub fn parse_style_attribute(value: &str, base_url: &ServoUrl, extra_data: ParserContextExtraData) -> PropertyDeclarationBlock { - parse_style_attribute(value, base_url, Box::new(StdoutErrorReporter), extra_data) + parse_style_attribute(value, base_url, &StdoutErrorReporter, extra_data) } fn flags(&self) -> u32 { diff --git a/components/style/keyframes.rs b/components/style/keyframes.rs index 348bc028ee6..068dc169e9e 100644 --- a/components/style/keyframes.rs +++ b/components/style/keyframes.rs @@ -126,10 +126,10 @@ impl Keyframe { parent_stylesheet: &Stylesheet, extra_data: ParserContextExtraData) -> Result<Arc<RwLock<Self>>, ()> { - let error_reporter = Box::new(MemoryHoleReporter); + let error_reporter = MemoryHoleReporter; let context = ParserContext::new_with_extra_data(parent_stylesheet.origin, &parent_stylesheet.base_url, - error_reporter, + &error_reporter, extra_data); let mut input = Parser::new(css); diff --git a/components/style/matching.rs b/components/style/matching.rs index 2fbf2760ce8..619e1d57f7a 100644 --- a/components/style/matching.rs +++ b/components/style/matching.rs @@ -539,13 +539,12 @@ trait PrivateMatchMethods: TElement { // Invoke the cascade algorithm. let values = - Arc::new(cascade(shared_context.viewport_size(), + Arc::new(cascade(&shared_context.stylist.device, rule_node, inherited_values, layout_parent_style, - &shared_context.default_computed_values, Some(&mut cascade_info), - shared_context.error_reporter.clone(), + &*shared_context.error_reporter, cascade_flags)); cascade_info.finish(&self.as_node()); diff --git a/components/style/parser.rs b/components/style/parser.rs index b6ac5968c07..8a8628d2d89 100644 --- a/components/style/parser.rs +++ b/components/style/parser.rs @@ -12,7 +12,7 @@ use error_reporting::ParseErrorReporter; use gecko_bindings::sugar::refptr::{GeckoArcPrincipal, GeckoArcURI}; use servo_url::ServoUrl; use style_traits::OneOrMoreCommaSeparated; -use stylesheets::{MemoryHoleReporter, Origin}; +use stylesheets::Origin; /// Extra data that the style backend may need to parse stylesheets. #[cfg(not(feature = "gecko"))] @@ -67,7 +67,7 @@ pub struct ParserContext<'a> { /// The base url we're parsing this stylesheet as. pub base_url: &'a ServoUrl, /// An error reporter to report syntax errors. - pub error_reporter: Box<ParseErrorReporter + Send>, + pub error_reporter: &'a ParseErrorReporter, /// Implementation-dependent extra data. pub extra_data: ParserContextExtraData, } @@ -76,7 +76,7 @@ impl<'a> ParserContext<'a> { /// Create a `ParserContext` with extra data. pub fn new_with_extra_data(stylesheet_origin: Origin, base_url: &'a ServoUrl, - error_reporter: Box<ParseErrorReporter + Send>, + error_reporter: &'a ParseErrorReporter, extra_data: ParserContextExtraData) -> ParserContext<'a> { ParserContext { @@ -90,22 +90,27 @@ impl<'a> ParserContext<'a> { /// Create a parser context with the default extra data. pub fn new(stylesheet_origin: Origin, base_url: &'a ServoUrl, - error_reporter: Box<ParseErrorReporter + Send>) + error_reporter: &'a ParseErrorReporter) -> ParserContext<'a> { let extra_data = ParserContextExtraData::default(); Self::new_with_extra_data(stylesheet_origin, base_url, error_reporter, extra_data) } /// Create a parser context for on-the-fly parsing in CSSOM - pub fn new_for_cssom(base_url: &'a ServoUrl) -> ParserContext<'a> { - Self::new(Origin::User, base_url, Box::new(MemoryHoleReporter)) + pub fn new_for_cssom(base_url: &'a ServoUrl, + error_reporter: &'a ParseErrorReporter) + -> ParserContext<'a> { + Self::new(Origin::User, base_url, error_reporter) } } /// Defaults to a no-op. /// Set a `RUST_LOG=style::errors` environment variable /// to log CSS parse errors to stderr. -pub fn log_css_error(input: &mut Parser, position: SourcePosition, message: &str, parsercontext: &ParserContext) { +pub fn log_css_error(input: &mut Parser, + position: SourcePosition, + message: &str, + parsercontext: &ParserContext) { let servo_url = parsercontext.base_url; parsercontext.error_reporter.report_error(input, position, message, servo_url); } diff --git a/components/style/properties/declaration_block.rs b/components/style/properties/declaration_block.rs index f10da7a7cb4..721396e8b3a 100644 --- a/components/style/properties/declaration_block.rs +++ b/components/style/properties/declaration_block.rs @@ -11,7 +11,6 @@ use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter}; use error_reporting::ParseErrorReporter; use parser::{ParserContext, ParserContextExtraData, log_css_error}; use servo_url::ServoUrl; -use std::boxed::Box as StdBox; use std::fmt; use style_traits::ToCss; use stylesheets::Origin; @@ -570,10 +569,13 @@ pub fn append_serialization<'a, W, I, N>(dest: &mut W, /// shared between Servo and Gecko. pub fn parse_style_attribute(input: &str, base_url: &ServoUrl, - error_reporter: StdBox<ParseErrorReporter + Send>, + error_reporter: &ParseErrorReporter, extra_data: ParserContextExtraData) -> PropertyDeclarationBlock { - let context = ParserContext::new_with_extra_data(Origin::Author, base_url, error_reporter, extra_data); + let context = ParserContext::new_with_extra_data(Origin::Author, + base_url, + error_reporter, + extra_data); parse_property_declaration_list(&context, &mut Parser::new(input)) } @@ -585,10 +587,13 @@ pub fn parse_style_attribute(input: &str, pub fn parse_one_declaration(id: PropertyId, input: &str, base_url: &ServoUrl, - error_reporter: StdBox<ParseErrorReporter + Send>, + error_reporter: &ParseErrorReporter, extra_data: ParserContextExtraData) -> Result<ParsedDeclaration, ()> { - let context = ParserContext::new_with_extra_data(Origin::Author, base_url, error_reporter, extra_data); + let context = ParserContext::new_with_extra_data(Origin::Author, + base_url, + error_reporter, + extra_data); Parser::new(input).parse_entirely(|parser| { ParsedDeclaration::parse(id, &context, parser, false) .map_err(|_| ()) diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index aa059acb258..691f5cb5641 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -83,7 +83,7 @@ pub struct ComputedValues { } impl ComputedValues { - pub fn inherit_from(parent: &Arc<Self>, default: &Arc<Self>) -> Arc<Self> { + pub fn inherit_from(parent: &Self, default: &Self) -> Arc<Self> { Arc::new(ComputedValues { custom_properties: parent.custom_properties.clone(), shareable: parent.shareable, diff --git a/components/style/properties/helpers.mako.rs b/components/style/properties/helpers.mako.rs index cd88ae26a86..48214966928 100644 --- a/components/style/properties/helpers.mako.rs +++ b/components/style/properties/helpers.mako.rs @@ -233,7 +233,7 @@ context: &mut computed::Context, cacheable: &mut bool, cascade_info: &mut Option<<&mut CascadeInfo>, - error_reporter: &mut StdBox<ParseErrorReporter + Send>) { + error_reporter: &ParseErrorReporter) { let declared_value = match *declaration { PropertyDeclaration::${property.camel_case}(ref declared_value) => { declared_value diff --git a/components/style/properties/longhand/box.mako.rs b/components/style/properties/longhand/box.mako.rs index e57ce3aca34..55d348b6ceb 100644 --- a/components/style/properties/longhand/box.mako.rs +++ b/components/style/properties/longhand/box.mako.rs @@ -85,7 +85,7 @@ _inherited_style: &ComputedValues, context: &mut computed::Context, _cacheable: &mut bool, - _error_reporter: &mut StdBox<ParseErrorReporter + Send>) { + _error_reporter: &ParseErrorReporter) { longhands::_servo_display_for_hypothetical_box::derive_from_display(context); longhands::_servo_text_decorations_in_effect::derive_from_display(context); longhands::_servo_under_display_none::derive_from_display(context); diff --git a/components/style/properties/longhand/color.mako.rs b/components/style/properties/longhand/color.mako.rs index 136546e2e70..9fbdaac287a 100644 --- a/components/style/properties/longhand/color.mako.rs +++ b/components/style/properties/longhand/color.mako.rs @@ -8,28 +8,24 @@ <%helpers:longhand name="color" need_clone="True" animatable="True" spec="https://drafts.csswg.org/css-color/#color"> - use cssparser::Color as CSSParserColor; use cssparser::RGBA; use std::fmt; use style_traits::ToCss; use values::HasViewportPercentage; - use values::specified::{CSSColor, CSSRGBA}; + use values::specified::{Color, CSSColor, CSSRGBA}; impl ToComputedValue for SpecifiedValue { type ComputedValue = computed_value::T; #[inline] fn to_computed_value(&self, context: &Context) -> computed_value::T { - match self.0.parsed { - CSSParserColor::RGBA(rgba) => rgba, - CSSParserColor::CurrentColor => context.inherited_style.get_color().clone_color(), - } + self.0.parsed.to_computed_value(context) } #[inline] fn from_computed_value(computed: &computed_value::T) -> Self { SpecifiedValue(CSSColor { - parsed: CSSParserColor::RGBA(*computed), + parsed: Color::RGBA(*computed), authored: None, }) } diff --git a/components/style/properties/longhand/inherited_text.mako.rs b/components/style/properties/longhand/inherited_text.mako.rs index 516ff2855ad..145b0e61ab7 100644 --- a/components/style/properties/longhand/inherited_text.mako.rs +++ b/components/style/properties/longhand/inherited_text.mako.rs @@ -792,7 +792,7 @@ ${helpers.single_keyword("text-align-last", blur_radius: value.blur_radius.to_computed_value(context), color: value.color .as_ref() - .map(|color| color.parsed) + .map(|color| color.to_computed_value(context)) .unwrap_or(cssparser::Color::CurrentColor), } }).collect()) diff --git a/components/style/properties/longhand/outline.mako.rs b/components/style/properties/longhand/outline.mako.rs index 65be748c187..a599c436174 100644 --- a/components/style/properties/longhand/outline.mako.rs +++ b/components/style/properties/longhand/outline.mako.rs @@ -10,7 +10,7 @@ additional_methods=[Method("outline_has_nonzero_width", "bool")]) %> // TODO(pcwalton): `invert` -${helpers.predefined_type("outline-color", "CSSColor", "::cssparser::Color::CurrentColor", +${helpers.predefined_type("outline-color", "CSSColor", "computed::CSSColor::CurrentColor", initial_specified_value="specified::CSSColor::currentcolor()", animatable=True, complex_color=True, need_clone=True, spec="https://drafts.csswg.org/css-ui/#propdef-outline-color")} diff --git a/components/style/properties/longhand/text.mako.rs b/components/style/properties/longhand/text.mako.rs index f5769fa26be..00b7b3fb346 100644 --- a/components/style/properties/longhand/text.mako.rs +++ b/components/style/properties/longhand/text.mako.rs @@ -210,7 +210,7 @@ ${helpers.single_keyword("unicode-bidi", _inherited_style: &ComputedValues, context: &mut computed::Context, _cacheable: &mut bool, - _error_reporter: &mut StdBox<ParseErrorReporter + Send>) { + _error_reporter: &ParseErrorReporter) { longhands::_servo_text_decorations_in_effect::derive_from_text_decoration(context); } % endif @@ -224,7 +224,7 @@ ${helpers.single_keyword("text-decoration-style", ${helpers.predefined_type( "text-decoration-color", "CSSColor", - "::cssparser::Color::CurrentColor", + "computed::CSSColor::CurrentColor", initial_specified_value="specified::CSSColor::currentcolor()", complex_color=True, products="gecko", diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index 656b2b9294c..7855b3e1c79 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -11,7 +11,6 @@ <%namespace name="helpers" file="/helpers.mako.rs" /> use std::borrow::Cow; -use std::boxed::Box as StdBox; use std::collections::HashSet; use std::fmt; use std::sync::Arc; @@ -21,13 +20,13 @@ use app_units::Au; use cssparser::{Parser, TokenSerializationType}; use error_reporting::ParseErrorReporter; #[cfg(feature = "servo")] use euclid::side_offsets::SideOffsets2D; -use euclid::size::Size2D; use computed_values; use font_metrics::FontMetricsProvider; #[cfg(feature = "gecko")] use gecko_bindings::bindings; #[cfg(feature = "gecko")] use gecko_bindings::structs::{self, nsCSSPropertyID}; #[cfg(feature = "servo")] use logical_geometry::{LogicalMargin, PhysicalSide}; use logical_geometry::WritingMode; +use media_queries::Device; use parser::{Parse, ParserContext, ParserContextExtraData}; use properties::animated_properties::TransitionProperty; #[cfg(feature = "servo")] use servo_config::prefs::PREFS; @@ -288,7 +287,7 @@ impl PropertyDeclarationIdSet { % endif custom_properties: &Option<Arc<::custom_properties::ComputedValuesMap>>, f: F, - error_reporter: &mut StdBox<ParseErrorReporter + Send>) + error_reporter: &ParseErrorReporter) % if property.boxed: where F: FnOnce(&DeclaredValue<Box<longhands::${property.ident}::SpecifiedValue>>) % else: @@ -322,7 +321,7 @@ impl PropertyDeclarationIdSet { from_shorthand: Option<ShorthandId>, custom_properties: &Option<Arc<::custom_properties::ComputedValuesMap>>, f: F, - error_reporter: &mut StdBox<ParseErrorReporter + Send>, + error_reporter: &ParseErrorReporter, extra_data: ParserContextExtraData) % if property.boxed: where F: FnOnce(&DeclaredValue<Box<longhands::${property.ident}::SpecifiedValue>>) @@ -338,7 +337,7 @@ impl PropertyDeclarationIdSet { // FIXME(pcwalton): Cloning the error reporter is slow! But so are custom // properties, so whatever... let context = ParserContext::new_with_extra_data( - ::stylesheets::Origin::Author, base_url, (*error_reporter).clone(), + ::stylesheets::Origin::Author, base_url, error_reporter, extra_data); Parser::new(&css).parse_entirely(|input| { match from_shorthand { @@ -1764,7 +1763,7 @@ pub type CascadePropertyFn = context: &mut computed::Context, cacheable: &mut bool, cascade_info: &mut Option<<&mut CascadeInfo>, - error_reporter: &mut StdBox<ParseErrorReporter + Send>); + error_reporter: &ParseErrorReporter); /// A per-longhand array of functions to perform the CSS cascade on each of /// them, effectively doing virtual dispatch. @@ -1793,7 +1792,7 @@ bitflags! { /// /// The arguments are: /// -/// * `viewport_size`: The size of the initial viewport. +/// * `device`: Used to get the initial viewport and other external state. /// /// * `rule_node`: The rule node in the tree that represent the CSS rules that /// matched. @@ -1803,20 +1802,28 @@ bitflags! { /// Returns the computed values. /// * `flags`: Various flags. /// -pub fn cascade(viewport_size: Size2D<Au>, +pub fn cascade(device: &Device, rule_node: &StrongRuleNode, parent_style: Option<<&ComputedValues>, layout_parent_style: Option<<&ComputedValues>, - default_style: &ComputedValues, cascade_info: Option<<&mut CascadeInfo>, - error_reporter: StdBox<ParseErrorReporter + Send>, + error_reporter: &ParseErrorReporter, flags: CascadeFlags) -> ComputedValues { debug_assert_eq!(parent_style.is_some(), layout_parent_style.is_some()); let (is_root_element, inherited_style, layout_parent_style) = match parent_style { - Some(parent_style) => (false, parent_style, layout_parent_style.unwrap()), - None => (true, &*default_style, &*default_style), + Some(parent_style) => { + (false, + parent_style, + layout_parent_style.unwrap()) + }, + None => { + (true, + device.default_computed_values(), + device.default_computed_values()) + } }; + // Hold locks until after the apply_declarations() call returns. // Use filter_map because the root node has no style source. let lock_guards = rule_node.self_and_ancestors().filter_map(|node| { @@ -1836,12 +1843,11 @@ pub fn cascade(viewport_size: Size2D<Au>, }) }) }; - apply_declarations(viewport_size, + apply_declarations(device, is_root_element, iter_declarations, inherited_style, layout_parent_style, - default_style, cascade_info, error_reporter, None, @@ -1850,20 +1856,20 @@ pub fn cascade(viewport_size: Size2D<Au>, /// NOTE: This function expects the declaration with more priority to appear /// first. -pub fn apply_declarations<'a, F, I>(viewport_size: Size2D<Au>, +pub fn apply_declarations<'a, F, I>(device: &Device, is_root_element: bool, iter_declarations: F, inherited_style: &ComputedValues, layout_parent_style: &ComputedValues, - default_style: &ComputedValues, mut cascade_info: Option<<&mut CascadeInfo>, - mut error_reporter: StdBox<ParseErrorReporter + Send>, + error_reporter: &ParseErrorReporter, font_metrics_provider: Option<<&FontMetricsProvider>, flags: CascadeFlags) -> ComputedValues where F: Fn() -> I, I: Iterator<Item = &'a PropertyDeclaration>, { + let default_style = device.default_computed_values(); let inherited_custom_properties = inherited_style.custom_properties(); let mut custom_properties = None; let mut seen_custom = HashSet::new(); @@ -1905,7 +1911,7 @@ pub fn apply_declarations<'a, F, I>(viewport_size: Size2D<Au>, let mut context = computed::Context { is_root_element: is_root_element, - viewport_size: viewport_size, + device: device, inherited_style: inherited_style, layout_parent_style: layout_parent_style, style: starting_style, @@ -1984,7 +1990,7 @@ pub fn apply_declarations<'a, F, I>(viewport_size: Size2D<Au>, &mut context, &mut cacheable, &mut cascade_info, - &mut error_reporter); + error_reporter); } % if category_to_cascade_now == "early": let writing_mode = get_writing_mode(context.style.get_inheritedbox()); diff --git a/components/style/properties/shorthand/serialize.mako.rs b/components/style/properties/shorthand/serialize.mako.rs index 5c265f16c9e..f990ca81df3 100644 --- a/components/style/properties/shorthand/serialize.mako.rs +++ b/components/style/properties/shorthand/serialize.mako.rs @@ -2,9 +2,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use cssparser::Color; use style_traits::ToCss; -use values::specified::{BorderStyle, CSSColor}; +use values::specified::{BorderStyle, Color, CSSColor}; use std::fmt; #[allow(missing_docs)] diff --git a/components/style/properties/shorthand/text.mako.rs b/components/style/properties/shorthand/text.mako.rs index 00860c91887..c035158a511 100644 --- a/components/style/properties/shorthand/text.mako.rs +++ b/components/style/properties/shorthand/text.mako.rs @@ -10,13 +10,12 @@ spec="https://drafts.csswg.org/css-text-decor/#propdef-text-decoration"> % if product == "gecko" or data.testing: - use cssparser::Color as CSSParserColor; + use values::specified; use properties::longhands::{text_decoration_line, text_decoration_style, text_decoration_color}; % else: use properties::longhands::text_decoration_line; % endif - pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result<Longhands, ()> { % if product == "gecko" or data.testing: let (mut line, mut style, mut color, mut any) = (None, None, None, false); @@ -71,7 +70,7 @@ self.text_decoration_style.to_css(dest)?; } - if self.text_decoration_color.parsed != CSSParserColor::CurrentColor { + if self.text_decoration_color.parsed != specified::Color::CurrentColor { dest.write_str(" ")?; self.text_decoration_color.to_css(dest)?; } diff --git a/components/style/servo/media_queries.rs b/components/style/servo/media_queries.rs index 99b30494483..75bd789766f 100644 --- a/components/style/servo/media_queries.rs +++ b/components/style/servo/media_queries.rs @@ -39,7 +39,10 @@ impl Device { } /// Return the default computed values for this device. - pub fn default_values(&self) -> &ComputedValues { + pub fn default_computed_values(&self) -> &ComputedValues { + // FIXME(bz): This isn't really right, but it's no more wrong + // than what we used to do. See + // https://github.com/servo/servo/issues/14773 for fixing it properly. ComputedValues::initial_values() } @@ -128,7 +131,7 @@ impl Expression { let value = viewport_size.width; match self.0 { ExpressionKind::Width(ref range) => { - match range.to_computed_range(viewport_size, device.default_values()) { + match range.to_computed_range(device) { Range::Min(ref width) => { value >= *width }, Range::Max(ref width) => { value <= *width }, Range::Eq(ref width) => { value == *width }, @@ -170,15 +173,13 @@ pub enum Range<T> { } impl Range<specified::Length> { - fn to_computed_range(&self, - viewport_size: Size2D<Au>, - default_values: &ComputedValues) - -> Range<Au> { + fn to_computed_range(&self, device: &Device) -> Range<Au> { + let default_values = device.default_computed_values(); // http://dev.w3.org/csswg/mediaqueries3/#units // em units are relative to the initial font-size. let context = computed::Context { is_root_element: false, - viewport_size: viewport_size, + device: device, inherited_style: default_values, layout_parent_style: default_values, // This cloning business is kind of dumb.... It's because Context diff --git a/components/style/stylesheets.rs b/components/style/stylesheets.rs index cc72acd4c15..9145e761a4b 100644 --- a/components/style/stylesheets.rs +++ b/components/style/stylesheets.rs @@ -255,9 +255,6 @@ impl ParseErrorReporter for MemoryHoleReporter { _: &ServoUrl) { // do nothing } - fn clone(&self) -> Box<ParseErrorReporter + Send + Sync> { - Box::new(MemoryHoleReporter) - } } #[allow(missing_docs)] @@ -341,11 +338,11 @@ impl CssRule { extra_data: ParserContextExtraData, state: Option<State>) -> Result<(Self, State), SingleRuleParseError> { - let error_reporter = Box::new(MemoryHoleReporter); + let error_reporter = MemoryHoleReporter; let mut namespaces = parent_stylesheet.namespaces.write(); let context = ParserContext::new_with_extra_data(parent_stylesheet.origin, &parent_stylesheet.base_url, - error_reporter.clone(), + &error_reporter, extra_data); let mut input = Parser::new(css); @@ -583,7 +580,7 @@ impl Stylesheet { origin: Origin, media: MediaList, stylesheet_loader: Option<&StylesheetLoader>, - error_reporter: Box<ParseErrorReporter + Send>, + error_reporter: &ParseErrorReporter, extra_data: ParserContextExtraData) -> Stylesheet { let (string, _) = decode_stylesheet_bytes( @@ -604,7 +601,7 @@ impl Stylesheet { protocol_encoding_label: Option<&str>, environment_encoding: Option<EncodingRef>, stylesheet_loader: Option<&StylesheetLoader>, - error_reporter: Box<ParseErrorReporter + Send>, + error_reporter: &ParseErrorReporter, extra_data: ParserContextExtraData) { let (string, _) = decode_stylesheet_bytes( bytes, protocol_encoding_label, environment_encoding); @@ -619,7 +616,7 @@ impl Stylesheet { pub fn update_from_str(existing: &Stylesheet, css: &str, stylesheet_loader: Option<&StylesheetLoader>, - error_reporter: Box<ParseErrorReporter + Send>, + error_reporter: &ParseErrorReporter, extra_data: ParserContextExtraData) { let mut rules = existing.rules.write(); let mut namespaces = existing.namespaces.write(); @@ -668,7 +665,7 @@ impl Stylesheet { origin: Origin, media: MediaList, stylesheet_loader: Option<&StylesheetLoader>, - error_reporter: Box<ParseErrorReporter + Send>, + error_reporter: &ParseErrorReporter, extra_data: ParserContextExtraData) -> Stylesheet { let s = Stylesheet { origin: origin, diff --git a/components/style/stylist.rs b/components/style/stylist.rs index 61b9826f8d0..79044cd1fb5 100644 --- a/components/style/stylist.rs +++ b/components/style/stylist.rs @@ -295,7 +295,6 @@ impl Stylist { pub fn precomputed_values_for_pseudo(&self, pseudo: &PseudoElement, parent: Option<&Arc<ComputedValues>>, - default: &ComputedValues, cascade_flags: CascadeFlags) -> ComputedStyle { debug_assert!(SelectorImpl::pseudo_element_cascade_type(pseudo).is_precomputed()); @@ -325,13 +324,12 @@ impl Stylist { // the actual used value, and the computed value of it would need // blockification. let computed = - properties::cascade(self.device.au_viewport_size(), + properties::cascade(&self.device, &rule_node, parent.map(|p| &**p), parent.map(|p| &**p), - default, None, - Box::new(StdoutErrorReporter), + &StdoutErrorReporter, cascade_flags); ComputedStyle::new(rule_node, Arc::new(computed)) } @@ -340,8 +338,7 @@ impl Stylist { #[cfg(feature = "servo")] pub fn style_for_anonymous_box(&self, pseudo: &PseudoElement, - parent_style: &Arc<ComputedValues>, - default_style: &ComputedValues) + parent_style: &Arc<ComputedValues>) -> Arc<ComputedValues> { // For most (but not all) pseudo-elements, we inherit all values from the parent. let inherit_all = match *pseudo { @@ -364,7 +361,7 @@ impl Stylist { if inherit_all { cascade_flags.insert(INHERIT_ALL); } - self.precomputed_values_for_pseudo(&pseudo, Some(parent_style), default_style, cascade_flags) + self.precomputed_values_for_pseudo(&pseudo, Some(parent_style), cascade_flags) .values.unwrap() } @@ -378,8 +375,7 @@ impl Stylist { pub fn lazily_compute_pseudo_element_style<E>(&self, element: &E, pseudo: &PseudoElement, - parent: &Arc<ComputedValues>, - default: &Arc<ComputedValues>) + parent: &Arc<ComputedValues>) -> Option<ComputedStyle> where E: TElement + fmt::Debug + @@ -410,13 +406,12 @@ impl Stylist { // (tl;dr: It doesn't apply for replaced elements and such, but the // computed value is still "contents"). let computed = - properties::cascade(self.device.au_viewport_size(), + properties::cascade(&self.device, &rule_node, Some(&**parent), Some(&**parent), - default, None, - Box::new(StdoutErrorReporter), + &StdoutErrorReporter, CascadeFlags::empty()); // Apply the selector flags. We should be in sequential mode already, diff --git a/components/style/values/computed/image.rs b/components/style/values/computed/image.rs index 9eb0bbc7f14..8441ab62c05 100644 --- a/components/style/values/computed/image.rs +++ b/components/style/values/computed/image.rs @@ -250,7 +250,7 @@ impl ToComputedValue for specified::ColorStop { #[inline] fn to_computed_value(&self, context: &Context) -> ColorStop { ColorStop { - color: self.color.parsed, + color: self.color.to_computed_value(context), position: match self.position { None => None, Some(ref value) => Some(value.to_computed_value(context)), diff --git a/components/style/values/computed/length.rs b/components/style/values/computed/length.rs index e512a623492..a65768ea2a1 100644 --- a/components/style/values/computed/length.rs +++ b/components/style/values/computed/length.rs @@ -12,7 +12,6 @@ use super::{Number, ToComputedValue, Context}; use values::{Auto, CSSFloat, Either, ExtremumLength, None_, Normal, specified}; use values::specified::length::{FontRelativeLength, ViewportPercentageLength}; -pub use cssparser::Color as CSSColor; pub use super::image::{EndingShape as GradientShape, Gradient, GradientKind, Image}; pub use super::image::{LengthOrKeyword, LengthOrPercentageOrKeyword}; pub use values::specified::{Angle, BorderStyle, Time, UrlOrNone}; diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index 9f3c827b944..22f9e5e0996 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -7,6 +7,7 @@ use app_units::Au; use euclid::size::Size2D; use font_metrics::FontMetricsProvider; +use media_queries::Device; use properties::ComputedValues; use std::fmt; use style_traits::ToCss; @@ -37,8 +38,8 @@ pub struct Context<'a> { /// Whether the current element is the root element. pub is_root_element: bool, - /// The current viewport size. - pub viewport_size: Size2D<Au>, + /// The Device holds the viewport and other external state. + pub device: &'a Device, /// The style we're inheriting from. pub inherited_style: &'a ComputedValues, @@ -65,7 +66,7 @@ impl<'a> Context<'a> { /// Whether the current element is the root element. pub fn is_root_element(&self) -> bool { self.is_root_element } /// The current viewport size. - pub fn viewport_size(&self) -> Size2D<Au> { self.viewport_size } + pub fn viewport_size(&self) -> Size2D<Au> { self.device.au_viewport_size() } /// The style we're inheriting from. pub fn inherited_style(&self) -> &ComputedValues { &self.inherited_style } /// The current style. Note that only "eager" properties should be accessed @@ -113,18 +114,65 @@ impl<T> ToComputedValue for T } } +impl ToComputedValue for specified::Color { + type ComputedValue = RGBA; + + #[cfg(not(feature = "gecko"))] + fn to_computed_value(&self, context: &Context) -> RGBA { + match *self { + specified::Color::RGBA(rgba) => rgba, + specified::Color::CurrentColor => context.inherited_style.get_color().clone_color(), + } + } + + #[cfg(feature = "gecko")] + fn to_computed_value(&self, context: &Context) -> RGBA { + use gecko::values::convert_nscolor_to_rgba as to_rgba; + // It's safe to access the nsPresContext immutably during style computation. + let pres_context = unsafe { &*context.device.pres_context }; + match *self { + specified::Color::RGBA(rgba) => rgba, + specified::Color::CurrentColor => context.inherited_style.get_color().clone_color(), + specified::Color::MozDefaultColor => to_rgba(pres_context.mDefaultColor), + specified::Color::MozDefaultBackgroundColor => to_rgba(pres_context.mBackgroundColor), + specified::Color::MozHyperlinktext => to_rgba(pres_context.mLinkColor), + specified::Color::MozActiveHyperlinktext => to_rgba(pres_context.mActiveLinkColor), + specified::Color::MozVisitedHyperlinktext => to_rgba(pres_context.mVisitedLinkColor), + } + } + + fn from_computed_value(computed: &RGBA) -> Self { + specified::Color::RGBA(*computed) + } +} + impl ToComputedValue for specified::CSSColor { type ComputedValue = CSSColor; + #[cfg(not(feature = "gecko"))] #[inline] fn to_computed_value(&self, _context: &Context) -> CSSColor { self.parsed } + #[cfg(feature = "gecko")] + #[inline] + fn to_computed_value(&self, context: &Context) -> CSSColor { + match self.parsed { + specified::Color::RGBA(rgba) => CSSColor::RGBA(rgba), + specified::Color::CurrentColor => CSSColor::CurrentColor, + // Resolve non-standard -moz keywords to RGBA: + non_standard => CSSColor::RGBA(non_standard.to_computed_value(context)), + } + } + #[inline] fn from_computed_value(computed: &CSSColor) -> Self { specified::CSSColor { - parsed: *computed, + parsed: match *computed { + CSSColor::RGBA(rgba) => specified::Color::RGBA(rgba), + CSSColor::CurrentColor => specified::Color::CurrentColor, + }, authored: None, } } diff --git a/components/style/values/specified/color.rs b/components/style/values/specified/color.rs new file mode 100644 index 00000000000..88063803d31 --- /dev/null +++ b/components/style/values/specified/color.rs @@ -0,0 +1,90 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//! Non-standard CSS color values + +#[cfg(not(feature = "gecko"))] pub use self::servo::Color; +#[cfg(feature = "gecko")] pub use self::gecko::Color; + +#[cfg(not(feature = "gecko"))] +mod servo { + pub use cssparser::Color; + use cssparser::Parser; + use parser::{Parse, ParserContext}; + + impl Parse for Color { + fn parse(_: &ParserContext, input: &mut Parser) -> Result<Self, ()> { + Color::parse(input) + } + } +} + +#[cfg(feature = "gecko")] +mod gecko { + use cssparser::{Color as CSSParserColor, Parser, RGBA}; + use parser::{Parse, ParserContext}; + use std::fmt; + use style_traits::ToCss; + use values::HasViewportPercentage; + + /// Color value including non-standard -moz prefixed values. + #[derive(Clone, Copy, PartialEq, Debug)] + pub enum Color { + /// The 'currentColor' keyword + CurrentColor, + /// A specific RGBA color + RGBA(RGBA), + + /// -moz-default-color + MozDefaultColor, + /// -moz-default-background-color + MozDefaultBackgroundColor, + /// -moz-hyperlinktext + MozHyperlinktext, + /// -moz-activehyperlinktext + MozActiveHyperlinktext, + /// -moz-visitedhyperlinktext + MozVisitedHyperlinktext, + } + + no_viewport_percentage!(Color); + + impl Parse for Color { + fn parse(_: &ParserContext, input: &mut Parser) -> Result<Self, ()> { + if let Ok(value) = input.try(CSSParserColor::parse) { + match value { + CSSParserColor::CurrentColor => Ok(Color::CurrentColor), + CSSParserColor::RGBA(x) => Ok(Color::RGBA(x)), + } + } else { + let ident = input.expect_ident()?; + match_ignore_ascii_case! { &ident, + "-moz-default-color" => Ok(Color::MozDefaultColor), + "-moz-default-background-color" => Ok(Color::MozDefaultBackgroundColor), + "-moz-hyperlinktext" => Ok(Color::MozHyperlinktext), + "-moz-activehyperlinktext" => Ok(Color::MozActiveHyperlinktext), + "-moz-visitedhyperlinktext" => Ok(Color::MozVisitedHyperlinktext), + _ => Err(()) + } + } + } + } + + impl ToCss for Color { + fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + match *self { + // Standard values: + Color::CurrentColor => CSSParserColor::CurrentColor.to_css(dest), + Color::RGBA(rgba) => rgba.to_css(dest), + + // Non-standard values: + Color::MozDefaultColor => dest.write_str("-moz-default-color"), + Color::MozDefaultBackgroundColor => dest.write_str("-moz-default-background-color"), + Color::MozHyperlinktext => dest.write_str("-moz-hyperlinktext"), + Color::MozActiveHyperlinktext => dest.write_str("-moz-activehyperlinktext"), + Color::MozVisitedHyperlinktext => dest.write_str("-moz-visitedhyperlinktext"), + } + } + } +} diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index 60c169c55be..0e7ec2eb34a 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -18,11 +18,12 @@ use std::fmt; use std::ops::Mul; use style_traits::ToCss; use super::{Auto, CSSFloat, HasViewportPercentage, Either, None_}; -use super::computed::{ComputedValueAsSpecified, Context, ToComputedValue}; -use super::computed::Shadow as ComputedShadow; +use super::computed::{ComputedValueAsSpecified, Context}; +use super::computed::{Shadow as ComputedShadow, ToComputedValue}; #[cfg(feature = "gecko")] pub use self::align::{AlignItems, AlignJustifyContent, AlignJustifySelf, JustifyItems}; +pub use self::color::Color; pub use self::grid::{GridLine, TrackKeyword}; pub use self::image::{AngleOrCorner, ColorStop, EndingShape as GradientEndingShape, Gradient}; pub use self::image::{GradientKind, HorizontalDirection, Image, LengthOrKeyword, LengthOrPercentageOrKeyword}; @@ -36,6 +37,7 @@ pub use self::position::{HorizontalPosition, Position, VerticalPosition}; #[cfg(feature = "gecko")] pub mod align; pub mod basic_shape; +pub mod color; pub mod grid; pub mod image; pub mod length; @@ -48,12 +50,12 @@ no_viewport_percentage!(i32); // For PropertyDeclaration::Order #[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[allow(missing_docs)] pub struct CSSColor { - pub parsed: cssparser::Color, + pub parsed: Color, pub authored: Option<Box<str>>, } impl Parse for CSSColor { - fn parse(_context: &ParserContext, input: &mut Parser) -> Result<Self, ()> { + fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> { let start_position = input.position(); let authored = match input.next() { Ok(Token::Ident(s)) => Some(s.into_owned().into_boxed_str()), @@ -61,7 +63,7 @@ impl Parse for CSSColor { }; input.reset(start_position); Ok(CSSColor { - parsed: try!(cssparser::Color::parse(input)), + parsed: try!(Parse::parse(context, input)), authored: authored, }) } @@ -83,7 +85,7 @@ impl CSSColor { /// Returns currentcolor value. pub fn currentcolor() -> CSSColor { CSSColor { - parsed: cssparser::Color::CurrentColor, + parsed: Color::CurrentColor, authored: None, } } @@ -92,7 +94,7 @@ impl CSSColor { /// Returns transparent value. pub fn transparent() -> CSSColor { CSSColor { - parsed: cssparser::Color::RGBA(cssparser::RGBA::transparent()), + parsed: Color::RGBA(cssparser::RGBA::transparent()), // This should probably be "transparent", but maybe it doesn't matter. authored: None, } @@ -616,7 +618,7 @@ impl ToComputedValue for Shadow { spread_radius: self.spread_radius.to_computed_value(context), color: self.color .as_ref() - .map(|color| color.parsed) + .map(|color| color.to_computed_value(context)) .unwrap_or(cssparser::Color::CurrentColor), inset: self.inset, } diff --git a/components/style/viewport.rs b/components/style/viewport.rs index f15f4553c0e..9c364dc7249 100644 --- a/components/style/viewport.rs +++ b/components/style/viewport.rs @@ -687,10 +687,10 @@ impl MaybeNew for ViewportConstraints { // TODO(emilio): Stop cloning `ComputedValues` around! let context = Context { is_root_element: false, - viewport_size: initial_viewport, - inherited_style: device.default_values(), - layout_parent_style: device.default_values(), - style: device.default_values().clone(), + device: device, + inherited_style: device.default_computed_values(), + layout_parent_style: device.default_computed_values(), + style: device.default_computed_values().clone(), font_metrics_provider: None, // TODO: Should have! }; diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index eb51eb7ea09..0bc09c30e68 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -166,12 +166,12 @@ fn create_shared_context(per_doc_data: &PerDocumentStyleDataImpl) -> SharedStyle stylist: per_doc_data.stylist.clone(), running_animations: per_doc_data.running_animations.clone(), expired_animations: per_doc_data.expired_animations.clone(), + // FIXME(emilio): Stop boxing here. error_reporter: Box::new(StdoutErrorReporter), local_context_creation_data: Mutex::new(local_context_data), timer: Timer::new(), // FIXME Find the real QuirksMode information for this document quirks_mode: QuirksMode::NoQuirks, - default_computed_values: per_doc_data.default_computed_values().clone(), } } @@ -337,7 +337,7 @@ pub extern "C" fn Servo_StyleSheet_Empty(mode: SheetParsingMode) -> RawServoStyl }; Arc::new(Stylesheet::from_str( "", url, origin, Default::default(), None, - Box::new(StdoutErrorReporter), extra_data) + &StdoutErrorReporter, extra_data) ).into_strong() } @@ -380,7 +380,7 @@ pub extern "C" fn Servo_StyleSheet_FromUTF8Bytes(loader: *mut Loader, Arc::new(Stylesheet::from_str( input, url, origin, Default::default(), loader, - Box::new(StdoutErrorReporter), extra_data) + &StdoutErrorReporter, extra_data) ).into_strong() } @@ -416,7 +416,7 @@ pub extern "C" fn Servo_StyleSheet_ClearAndUpdate(stylesheet: RawServoStyleSheet sheet.rules.write().0.clear(); Stylesheet::update_from_str(&sheet, input, loader, - Box::new(StdoutErrorReporter), extra_data); + &StdoutErrorReporter, extra_data); } #[no_mangle] @@ -634,7 +634,6 @@ pub extern "C" fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null: cascade_flags.insert(SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP); } data.stylist.precomputed_values_for_pseudo(&pseudo, maybe_parent, - data.default_computed_values(), cascade_flags) .values.unwrap() .into_strong() @@ -680,8 +679,7 @@ fn get_pseudo_style(element: GeckoElement, pseudo_tag: *mut nsIAtom, let base = styles.primary.values(); d.stylist.lazily_compute_pseudo_element_style(&element, &pseudo, - base, - &d.default_computed_values()) + base) .map(|s| s.values().clone()) }, } @@ -749,9 +747,10 @@ pub extern "C" fn Servo_ParseProperty(property: *const nsACString, value: *const make_context!((base, data) => (base_url, extra_data)); + let reporter = StdoutErrorReporter; let context = ParserContext::new_with_extra_data(Origin::Author, &base_url, - Box::new(StdoutErrorReporter), + &reporter, extra_data); match ParsedDeclaration::parse(id, &context, &mut Parser::new(value), false) { @@ -877,7 +876,7 @@ fn set_property(declarations: RawServoDeclarationBlockBorrowed, property_id: Pro make_context!((base, data) => (base_url, extra_data)); if let Ok(parsed) = parse_one_declaration(property_id, value, &base_url, - Box::new(StdoutErrorReporter), extra_data) { + &StdoutErrorReporter, extra_data) { let mut declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations).write(); let importance = if is_important { Importance::Important } else { Importance::Normal }; let mut changed = false; @@ -1173,9 +1172,8 @@ pub extern "C" fn Servo_DeclarationBlock_SetAutoValue(declarations: pub extern "C" fn Servo_DeclarationBlock_SetCurrentColor(declarations: RawServoDeclarationBlockBorrowed, property: nsCSSPropertyID) { - use cssparser::Color; use style::properties::{DeclaredValue, PropertyDeclaration, LonghandId}; - use style::values::specified::CSSColor; + use style::values::specified::{Color, CSSColor}; let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations); let long = get_longhand_from_id!(property); @@ -1195,11 +1193,10 @@ pub extern "C" fn Servo_DeclarationBlock_SetColorValue(declarations: RawServoDeclarationBlockBorrowed, property: nsCSSPropertyID, value: structs::nscolor) { - use cssparser::Color; use style::gecko::values::convert_nscolor_to_rgba; use style::properties::{DeclaredValue, PropertyDeclaration, LonghandId}; use style::properties::longhands; - use style::values::specified::CSSColor; + use style::values::specified::{Color, CSSColor}; let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations); let long = get_longhand_from_id!(property); @@ -1262,7 +1259,7 @@ pub extern "C" fn Servo_CSSSupports2(property: *const nsACString, value: *const let base_url = &*DUMMY_BASE_URL; let extra_data = ParserContextExtraData::default(); - parse_one_declaration(id, &value, &base_url, Box::new(StdoutErrorReporter), extra_data).is_ok() + parse_one_declaration(id, &value, &base_url, &StdoutErrorReporter, extra_data).is_ok() } #[no_mangle] @@ -1272,7 +1269,8 @@ pub extern "C" fn Servo_CSSSupports(cond: *const nsACString) -> bool { let cond = parse_condition_or_declaration(&mut input); if let Ok(cond) = cond { let url = ServoUrl::parse("about:blank").unwrap(); - let context = ParserContext::new_for_cssom(&url); + let reporter = StdoutErrorReporter; + let context = ParserContext::new_for_cssom(&url, &reporter); cond.eval(&context) } else { false @@ -1440,11 +1438,11 @@ pub extern "C" fn Servo_GetComputedKeyframeValues(keyframes: RawGeckoKeyframeLis let style = ComputedValues::as_arc(&style); let parent_style = parent_style.as_ref().map(|r| &**ComputedValues::as_arc(&r)); - let default_values = data.stylist.device.default_values(); + let default_values = data.default_computed_values(); let context = Context { is_root_element: false, - viewport_size: data.stylist.device.au_viewport_size(), + device: &data.stylist.device, inherited_style: parent_style.unwrap_or(default_values), layout_parent_style: parent_style.unwrap_or(default_values), style: (**style).clone(), diff --git a/tests/unit/style/media_queries.rs b/tests/unit/style/media_queries.rs index b2fe60ea91e..4d3cf9e98a2 100644 --- a/tests/unit/style/media_queries.rs +++ b/tests/unit/style/media_queries.rs @@ -21,10 +21,6 @@ impl ParseErrorReporter for CSSErrorReporterTest { fn report_error(&self, _input: &mut Parser, _position: SourcePosition, _message: &str, _url: &ServoUrl) { } - - fn clone(&self) -> Box<ParseErrorReporter + Send + Sync> { - Box::new(CSSErrorReporterTest) - } } fn test_media_rule<F>(css: &str, callback: F) @@ -34,7 +30,7 @@ fn test_media_rule<F>(css: &str, callback: F) let css_str = css.to_owned(); let stylesheet = Stylesheet::from_str( css, url, Origin::Author, Default::default(), - None, Box::new(CSSErrorReporterTest), + None, &CSSErrorReporterTest, ParserContextExtraData::default()); let mut rule_count = 0; media_queries(&stylesheet.rules.read().0, &mut |mq| { @@ -61,7 +57,7 @@ fn media_query_test(device: &Device, css: &str, expected_rule_count: usize) { let url = ServoUrl::parse("http://localhost").unwrap(); let ss = Stylesheet::from_str( css, url, Origin::Author, Default::default(), - None, Box::new(CSSErrorReporterTest), + None, &CSSErrorReporterTest, ParserContextExtraData::default()); let mut rule_count = 0; ss.effective_style_rules(device, |_| rule_count += 1); diff --git a/tests/unit/style/parsing/background.rs b/tests/unit/style/parsing/background.rs index 6d1c1f0e954..084c2e10201 100644 --- a/tests/unit/style/parsing/background.rs +++ b/tests/unit/style/parsing/background.rs @@ -15,7 +15,8 @@ use style::stylesheets::Origin; #[test] fn background_shorthand_should_parse_all_available_properties_when_specified() { let url = ServoUrl::parse("http://localhost").unwrap(); - let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest)); + let reporter = CSSErrorReporterTest; + let context = ParserContext::new(Origin::Author, &url, &reporter); let mut parser = Parser::new("url(\"http://servo/test.png\") top center / 200px 200px repeat-x fixed padding-box \ content-box red"); let result = background::parse_value(&context, &mut parser).unwrap(); @@ -34,7 +35,8 @@ fn background_shorthand_should_parse_all_available_properties_when_specified() { #[test] fn background_shorthand_should_parse_when_some_fields_set() { let url = ServoUrl::parse("http://localhost").unwrap(); - let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest)); + let reporter = CSSErrorReporterTest; + let context = ParserContext::new(Origin::Author, &url, &reporter); let mut parser = Parser::new("14px 40px repeat-y"); let result = background::parse_value(&context, &mut parser).unwrap(); @@ -64,7 +66,8 @@ fn background_shorthand_should_parse_when_some_fields_set() { #[test] fn background_shorthand_should_parse_comma_separated_declarations() { let url = ServoUrl::parse("http://localhost").unwrap(); - let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest)); + let reporter = CSSErrorReporterTest; + let context = ParserContext::new(Origin::Author, &url, &reporter); let mut parser = Parser::new("url(\"http://servo/test.png\") top left no-repeat, url(\"http://servo/test.png\") \ center / 100% 100% no-repeat, white"); let result = background::parse_value(&context, &mut parser).unwrap(); @@ -85,7 +88,8 @@ fn background_shorthand_should_parse_comma_separated_declarations() { #[test] fn background_shorthand_should_parse_position_and_size_correctly() { let url = ServoUrl::parse("http://localhost").unwrap(); - let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest)); + let reporter = CSSErrorReporterTest; + let context = ParserContext::new(Origin::Author, &url, &reporter); let mut parser = Parser::new("7px 4px"); let result = background::parse_value(&context, &mut parser).unwrap(); @@ -109,7 +113,8 @@ fn background_shorthand_should_parse_position_and_size_correctly() { #[test] fn background_shorthand_should_parse_origin_and_clip_correctly() { let url = ServoUrl::parse("http://localhost").unwrap(); - let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest)); + let reporter = CSSErrorReporterTest; + let context = ParserContext::new(Origin::Author, &url, &reporter); let mut parser = Parser::new("padding-box content-box"); let result = background::parse_value(&context, &mut parser).unwrap(); diff --git a/tests/unit/style/parsing/border.rs b/tests/unit/style/parsing/border.rs index ced526dea95..94a4d8f6ff3 100644 --- a/tests/unit/style/parsing/border.rs +++ b/tests/unit/style/parsing/border.rs @@ -15,7 +15,8 @@ use style_traits::ToCss; #[test] fn border_image_shorthand_should_parse_when_all_properties_specified() { let url = ServoUrl::parse("http://localhost").unwrap(); - let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest)); + let reporter = CSSErrorReporterTest; + let context = ParserContext::new(Origin::Author, &url, &reporter); let mut parser = Parser::new("linear-gradient(red, blue) 30 30% 45 fill / 20px 40px / 10px \ round stretch"); let result = border_image::parse_value(&context, &mut parser).unwrap(); @@ -31,7 +32,8 @@ fn border_image_shorthand_should_parse_when_all_properties_specified() { #[test] fn border_image_shorthand_should_parse_without_width() { let url = ServoUrl::parse("http://localhost").unwrap(); - let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest)); + let reporter = CSSErrorReporterTest; + let context = ParserContext::new(Origin::Author, &url, &reporter); let mut parser = Parser::new("linear-gradient(red, blue) 30 30% 45 fill / / 10px round stretch"); let result = border_image::parse_value(&context, &mut parser).unwrap(); @@ -46,7 +48,8 @@ fn border_image_shorthand_should_parse_without_width() { #[test] fn border_image_shorthand_should_parse_without_outset() { let url = ServoUrl::parse("http://localhost").unwrap(); - let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest)); + let reporter = CSSErrorReporterTest; + let context = ParserContext::new(Origin::Author, &url, &reporter); let mut parser = Parser::new("linear-gradient(red, blue) 30 30% 45 fill / 20px 40px round"); let result = border_image::parse_value(&context, &mut parser).unwrap(); @@ -61,7 +64,8 @@ fn border_image_shorthand_should_parse_without_outset() { #[test] fn border_image_shorthand_should_parse_without_width_or_outset() { let url = ServoUrl::parse("http://localhost").unwrap(); - let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest)); + let reporter = CSSErrorReporterTest; + let context = ParserContext::new(Origin::Author, &url, &reporter); let mut parser = Parser::new("linear-gradient(red, blue) 30 30% 45 fill round"); let result = border_image::parse_value(&context, &mut parser).unwrap(); @@ -76,7 +80,8 @@ fn border_image_shorthand_should_parse_without_width_or_outset() { #[test] fn border_image_shorthand_should_parse_with_just_source() { let url = ServoUrl::parse("http://localhost").unwrap(); - let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest)); + let reporter = CSSErrorReporterTest; + let context = ParserContext::new(Origin::Author, &url, &reporter); let mut parser = Parser::new("linear-gradient(red, blue)"); let result = border_image::parse_value(&context, &mut parser).unwrap(); @@ -91,7 +96,8 @@ fn border_image_shorthand_should_parse_with_just_source() { #[test] fn border_image_outset_should_error_on_negative_length() { let url = ServoUrl::parse("http://localhost").unwrap(); - let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest)); + let reporter = CSSErrorReporterTest; + let context = ParserContext::new(Origin::Author, &url, &reporter); let mut parser = Parser::new("-1em"); let result = border_image_outset::parse(&context, &mut parser); assert_eq!(result, Err(())); @@ -100,7 +106,8 @@ fn border_image_outset_should_error_on_negative_length() { #[test] fn border_image_outset_should_error_on_negative_number() { let url = ServoUrl::parse("http://localhost").unwrap(); - let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest)); + let reporter = CSSErrorReporterTest; + let context = ParserContext::new(Origin::Author, &url, &reporter); let mut parser = Parser::new("-15"); let result = border_image_outset::parse(&context, &mut parser); assert_eq!(result, Err(())); @@ -109,7 +116,8 @@ fn border_image_outset_should_error_on_negative_number() { #[test] fn border_image_outset_should_return_number_on_plain_zero() { let url = ServoUrl::parse("http://localhost").unwrap(); - let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest)); + let reporter = CSSErrorReporterTest; + let context = ParserContext::new(Origin::Author, &url, &reporter); let mut parser = Parser::new("0"); let result = border_image_outset::parse(&context, &mut parser); assert_eq!(result.unwrap(), parse_longhand!(border_image_outset, "0")); @@ -118,7 +126,8 @@ fn border_image_outset_should_return_number_on_plain_zero() { #[test] fn border_image_outset_should_return_length_on_length_zero() { let url = ServoUrl::parse("http://localhost").unwrap(); - let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest)); + let reporter = CSSErrorReporterTest; + let context = ParserContext::new(Origin::Author, &url, &reporter); let mut parser = Parser::new("0em"); let result = border_image_outset::parse(&context, &mut parser); assert_eq!(result.unwrap(), parse_longhand!(border_image_outset, "0em")); diff --git a/tests/unit/style/parsing/column.rs b/tests/unit/style/parsing/column.rs index 5de0d773329..f8aff1e04b7 100644 --- a/tests/unit/style/parsing/column.rs +++ b/tests/unit/style/parsing/column.rs @@ -19,7 +19,8 @@ fn test_column_width() { assert_roundtrip_with_context!(column_width::parse, "0.3vw"); let url = ServoUrl::parse("http://localhost").unwrap(); - let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest)); + let reporter = CSSErrorReporterTest; + let context = ParserContext::new(Origin::Author, &url, &reporter); let mut negative = Parser::new("-6px"); assert!(column_width::parse(&context, &mut negative).is_err()); @@ -35,7 +36,8 @@ fn test_column_gap() { assert_roundtrip_with_context!(column_gap::parse, "0.3vw"); let url = ServoUrl::parse("http://localhost").unwrap(); - let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest)); + let reporter = CSSErrorReporterTest; + let context = ParserContext::new(Origin::Author, &url, &reporter); let mut negative = Parser::new("-6px"); assert!(column_gap::parse(&context, &mut negative).is_err()); diff --git a/tests/unit/style/parsing/effects.rs b/tests/unit/style/parsing/effects.rs index 7453d423635..2b8ef18c2e5 100644 --- a/tests/unit/style/parsing/effects.rs +++ b/tests/unit/style/parsing/effects.rs @@ -38,7 +38,8 @@ fn test_clip() { #[test] fn test_longhands_parse_origin() { let url = ServoUrl::parse("http://localhost").unwrap(); - let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest)); + let reporter = CSSErrorReporterTest; + let context = ParserContext::new(Origin::Author, &url, &reporter); let mut parser = Parser::new("1px some-rubbish"); let parsed = longhands::parse_origin(&context, &mut parser); diff --git a/tests/unit/style/parsing/font.rs b/tests/unit/style/parsing/font.rs index 7fdd3565e5c..6d44e1f532f 100644 --- a/tests/unit/style/parsing/font.rs +++ b/tests/unit/style/parsing/font.rs @@ -53,7 +53,8 @@ fn font_feature_settings_should_parse_properly() { #[test] fn font_feature_settings_should_throw_on_bad_input() { let url = ServoUrl::parse("http://localhost").unwrap(); - let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest)); + let reporter = CSSErrorReporterTest; + let context = ParserContext::new(Origin::Author, &url, &reporter); let mut empty = Parser::new(""); assert!(font_feature_settings::parse(&context, &mut empty).is_err()); @@ -103,7 +104,8 @@ fn font_weight_keyword_should_preserve_keyword() { use style::properties::longhands::font_weight::SpecifiedValue; let url = ServoUrl::parse("http://localhost").unwrap(); - let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest)); + let reporter = CSSErrorReporterTest; + let context = ParserContext::new(Origin::Author, &url, &reporter); let mut parser = Parser::new("normal"); let result = font_weight::parse(&context, &mut parser); assert_eq!(result.unwrap(), SpecifiedValue::Normal); diff --git a/tests/unit/style/parsing/image.rs b/tests/unit/style/parsing/image.rs index b68d61fb2ed..15e53e1007f 100644 --- a/tests/unit/style/parsing/image.rs +++ b/tests/unit/style/parsing/image.rs @@ -2,11 +2,11 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use app_units::Au; use cssparser::Parser; -use euclid::size::Size2D; +use euclid::size::TypedSize2D; use media_queries::CSSErrorReporterTest; use std::f32::consts::PI; +use style::media_queries::{Device, MediaType}; use style::parser::ParserContext; use style::properties::ComputedValues; use style::stylesheets::Origin; @@ -43,11 +43,12 @@ fn test_linear_gradient() { // AngleOrCorner::None should become AngleOrCorner::Angle(Angle(PI)) when parsed // Note that Angle(PI) is correct for top-to-bottom rendering, whereas Angle(0) would render bottom-to-top. // ref: https://developer.mozilla.org/en-US/docs/Web/CSS/angle - let container = Size2D::new(Au::default(), Au::default()); + let viewport_size = TypedSize2D::new(0., 0.); let initial_style = ComputedValues::initial_values(); + let device = Device::new(MediaType::Screen, viewport_size); let specified_context = Context { is_root_element: true, - viewport_size: container, + device: &device, inherited_style: initial_style, layout_parent_style: initial_style, style: initial_style.clone(), diff --git a/tests/unit/style/parsing/inherited_text.rs b/tests/unit/style/parsing/inherited_text.rs index a9604f8dc09..b0d474b6024 100644 --- a/tests/unit/style/parsing/inherited_text.rs +++ b/tests/unit/style/parsing/inherited_text.rs @@ -111,7 +111,8 @@ fn webkit_text_stroke_shorthand_should_parse_properly() { use style::properties::shorthands::_webkit_text_stroke; let url = ServoUrl::parse("http://localhost").unwrap(); - let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest)); + let reporter = CSSErrorReporterTest; + let context = ParserContext::new(Origin::Author, &url, &reporter); let mut parser = Parser::new("thin red"); let result = _webkit_text_stroke::parse_value(&context, &mut parser).unwrap(); @@ -132,7 +133,8 @@ fn line_height_should_return_number_on_plain_zero() { use style::properties::longhands::line_height; let url = ServoUrl::parse("http://localhost").unwrap(); - let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest)); + let reporter = CSSErrorReporterTest; + let context = ParserContext::new(Origin::Author, &url, &reporter); let mut parser = Parser::new("0"); let result = line_height::parse(&context, &mut parser); assert_eq!(result.unwrap(), parse_longhand!(line_height, "0")); @@ -145,7 +147,8 @@ fn line_height_should_return_length_on_length_zero() { use style::properties::longhands::line_height; let url = ServoUrl::parse("http://localhost").unwrap(); - let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest)); + let reporter = CSSErrorReporterTest; + let context = ParserContext::new(Origin::Author, &url, &reporter); let mut parser = Parser::new("0px"); let result = line_height::parse(&context, &mut parser); assert_eq!(result.unwrap(), parse_longhand!(line_height, "0px")); diff --git a/tests/unit/style/parsing/mask.rs b/tests/unit/style/parsing/mask.rs index b57f8a2b4b4..09ea57c0686 100644 --- a/tests/unit/style/parsing/mask.rs +++ b/tests/unit/style/parsing/mask.rs @@ -14,7 +14,8 @@ use style::stylesheets::Origin; #[test] fn mask_shorthand_should_parse_all_available_properties_when_specified() { let url = ServoUrl::parse("http://localhost").unwrap(); - let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest)); + let reporter = CSSErrorReporterTest; + let context = ParserContext::new(Origin::Author, &url, &reporter); let mut parser = Parser::new("url(\"http://servo/test.png\") luminance 7px 4px / 70px 50px \ repeat-x padding-box border-box subtract"); let result = mask::parse_value(&context, &mut parser).unwrap(); @@ -33,7 +34,8 @@ fn mask_shorthand_should_parse_all_available_properties_when_specified() { #[test] fn mask_shorthand_should_parse_when_some_fields_set() { let url = ServoUrl::parse("http://localhost").unwrap(); - let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest)); + let reporter = CSSErrorReporterTest; + let context = ParserContext::new(Origin::Author, &url, &reporter); let mut parser = Parser::new("14px 40px repeat-y"); let result = mask::parse_value(&context, &mut parser).unwrap(); @@ -62,7 +64,8 @@ fn mask_shorthand_should_parse_when_some_fields_set() { #[test] fn mask_shorthand_should_parse_position_and_size_correctly() { let url = ServoUrl::parse("http://localhost").unwrap(); - let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest)); + let reporter = CSSErrorReporterTest; + let context = ParserContext::new(Origin::Author, &url, &reporter); let mut parser = Parser::new("7px 4px"); let result = mask::parse_value(&context, &mut parser).unwrap(); @@ -86,7 +89,8 @@ fn mask_shorthand_should_parse_position_and_size_correctly() { #[test] fn mask_shorthand_should_parse_origin_and_clip_correctly() { let url = ServoUrl::parse("http://localhost").unwrap(); - let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest)); + let reporter = CSSErrorReporterTest; + let context = ParserContext::new(Origin::Author, &url, &reporter); let mut parser = Parser::new("padding-box content-box"); let result = mask::parse_value(&context, &mut parser).unwrap(); @@ -109,7 +113,8 @@ fn mask_shorthand_should_parse_origin_and_clip_correctly() { #[test] fn mask_shorthand_should_parse_mode_everywhere() { let url = ServoUrl::parse("http://localhost").unwrap(); - let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest)); + let reporter = CSSErrorReporterTest; + let context = ParserContext::new(Origin::Author, &url, &reporter); let mut parser = Parser::new("luminance 7px 4px repeat-x padding-box"); assert!(mask::parse_value(&context, &mut parser).is_ok()); diff --git a/tests/unit/style/parsing/mod.rs b/tests/unit/style/parsing/mod.rs index 83cb6d1d1f7..e4a9ce985a3 100644 --- a/tests/unit/style/parsing/mod.rs +++ b/tests/unit/style/parsing/mod.rs @@ -11,7 +11,8 @@ use style::stylesheets::Origin; fn parse<T, F: Fn(&ParserContext, &mut Parser) -> Result<T, ()>>(f: F, s: &str) -> Result<T, ()> { let url = ::servo_url::ServoUrl::parse("http://localhost").unwrap(); - let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest)); + let reporter = CSSErrorReporterTest; + let context = ParserContext::new(Origin::Author, &url, &reporter); let mut parser = Parser::new(s); f(&context, &mut parser) } @@ -24,7 +25,8 @@ macro_rules! assert_roundtrip_with_context { }; ($fun:expr,$input:expr, $output:expr) => { let url = ::servo_url::ServoUrl::parse("http://localhost").unwrap(); - let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest)); + let reporter = CSSErrorReporterTest; + let context = ParserContext::new(Origin::Author, &url, &reporter); let mut parser = Parser::new($input); let parsed = $fun(&context, &mut parser) .expect(&format!("Failed to parse {}", $input)); @@ -61,7 +63,8 @@ macro_rules! assert_roundtrip { macro_rules! assert_parser_exhausted { ($name:ident, $string:expr, $should_exhausted:expr) => {{ let url = ::servo_url::ServoUrl::parse("http://localhost").unwrap(); - let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest)); + let reporter = CSSErrorReporterTest; + let context = ParserContext::new(Origin::Author, &url, &reporter); let mut parser = Parser::new($string); let parsed = $name::parse(&context, &mut parser); assert_eq!(parsed.is_ok(), true); @@ -72,7 +75,8 @@ macro_rules! assert_parser_exhausted { macro_rules! parse_longhand { ($name:ident, $s:expr) => {{ let url = ::servo_url::ServoUrl::parse("http://localhost").unwrap(); - let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest)); + let reporter = CSSErrorReporterTest; + let context = ParserContext::new(Origin::Author, &url, &reporter); $name::parse(&context, &mut Parser::new($s)).unwrap() }}; } diff --git a/tests/unit/style/parsing/outline.rs b/tests/unit/style/parsing/outline.rs index 7ffa5eeee5b..3603ccda1db 100644 --- a/tests/unit/style/parsing/outline.rs +++ b/tests/unit/style/parsing/outline.rs @@ -28,7 +28,8 @@ fn test_outline_style() { // except that 'hidden' is not a legal outline style. let url = ::servo_url::ServoUrl::parse("http://localhost").unwrap(); - let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest)); + let reporter = CSSErrorReporterTest; + let context = ParserContext::new(Origin::Author, &url, &reporter); let mut parser = Parser::new(r#"hidden"#); let parsed = outline_style::parse(&context, &mut parser); assert!(parsed.is_err()); diff --git a/tests/unit/style/parsing/ui.rs b/tests/unit/style/parsing/ui.rs index 1687df84848..a0b5367e9c2 100644 --- a/tests/unit/style/parsing/ui.rs +++ b/tests/unit/style/parsing/ui.rs @@ -27,7 +27,8 @@ fn test_moz_user_select() { assert_roundtrip_with_context!(_moz_user_select::parse, "-moz-text"); let url = ServoUrl::parse("http://localhost").unwrap(); - let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest)); + let reporter = CSSErrorReporterTest; + let context = ParserContext::new(Origin::Author, &url, &reporter); let mut negative = Parser::new("potato"); assert!(_moz_user_select::parse(&context, &mut negative).is_err()); diff --git a/tests/unit/style/properties/background.rs b/tests/unit/style/properties/background.rs index 493e12e3dcf..4640845ae85 100644 --- a/tests/unit/style/properties/background.rs +++ b/tests/unit/style/properties/background.rs @@ -11,7 +11,8 @@ use style::stylesheets::Origin; #[test] fn background_size_should_reject_negative_values() { let url = ::servo_url::ServoUrl::parse("http://localhost").unwrap(); - let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest)); + let reporter = CSSErrorReporterTest; + let context = ParserContext::new(Origin::Author, &url, &reporter); let parse_result = background_size::parse(&context, &mut Parser::new("-40% -40%")); diff --git a/tests/unit/style/properties/serialization.rs b/tests/unit/style/properties/serialization.rs index d197a52b9cd..26a8c9d0191 100644 --- a/tests/unit/style/properties/serialization.rs +++ b/tests/unit/style/properties/serialization.rs @@ -21,7 +21,8 @@ use stylesheets::block_from; fn parse_declaration_block(css_properties: &str) -> PropertyDeclarationBlock { let url = ServoUrl::parse("http://localhost").unwrap(); - let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest)); + let reporter = CSSErrorReporterTest; + let context = ParserContext::new(Origin::Author, &url, &reporter); let mut parser = Parser::new(css_properties); parse_property_declaration_list(&context, &mut parser) } @@ -963,7 +964,8 @@ mod shorthand_serialization { let mut s = String::new(); let url = ::servo_url::ServoUrl::parse("http://localhost").unwrap(); - let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest)); + let reporter = CSSErrorReporterTest; + let context = ParserContext::new(Origin::Author, &url, &reporter); let parsed = transform::parse(&context, &mut Parser::new("none")).unwrap(); let try_serialize = parsed.to_css(&mut s); @@ -986,7 +988,8 @@ mod shorthand_serialization { let mut s = String::new(); let url = ::servo_url::ServoUrl::parse("http://localhost").unwrap(); - let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest)); + let reporter = CSSErrorReporterTest; + let context = ParserContext::new(Origin::Author, &url, &reporter); let parsed = quotes::parse(&context, &mut Parser::new("none")).unwrap(); let try_serialize = parsed.to_css(&mut s); diff --git a/tests/unit/style/rule_tree/bench.rs b/tests/unit/style/rule_tree/bench.rs index 74242967766..bec7018215f 100644 --- a/tests/unit/style/rule_tree/bench.rs +++ b/tests/unit/style/rule_tree/bench.rs @@ -21,10 +21,6 @@ impl ParseErrorReporter for ErrorringErrorReporter { url: &ServoUrl) { panic!("CSS error: {}\t\n{:?} {}", url.as_str(), position, message); } - - fn clone(&self) -> Box<ParseErrorReporter + Send + Sync> { - Box::new(ErrorringErrorReporter) - } } struct AutoGCRuleTree<'a>(&'a RuleTree); @@ -49,7 +45,7 @@ fn parse_rules(css: &str) -> Vec<(StyleSource, CascadeLevel)> { media_queries: vec![], }, None, - Box::new(ErrorringErrorReporter), + &ErrorringErrorReporter, ParserContextExtraData {}); let rules = s.rules.read(); rules.0.iter().filter_map(|rule| { diff --git a/tests/unit/style/stylesheets.rs b/tests/unit/style/stylesheets.rs index a85e5e36fb0..892bcb53980 100644 --- a/tests/unit/style/stylesheets.rs +++ b/tests/unit/style/stylesheets.rs @@ -63,7 +63,7 @@ fn test_parse_stylesheet() { let url = ServoUrl::parse("about::test").unwrap(); let stylesheet = Stylesheet::from_str(css, url.clone(), Origin::UserAgent, Default::default(), None, - Box::new(CSSErrorReporterTest), + &CSSErrorReporterTest, ParserContextExtraData::default()); let mut namespaces = Namespaces::default(); namespaces.default = Some(ns!(html)); @@ -289,13 +289,15 @@ impl CSSInvalidErrorReporterTest { } impl ParseErrorReporter for CSSInvalidErrorReporterTest { - fn report_error(&self, input: &mut CssParser, position: SourcePosition, message: &str, - url: &ServoUrl) { + fn report_error(&self, + input: &mut CssParser, + position: SourcePosition, + message: &str, + url: &ServoUrl) { let location = input.source_location(position); - let errors = self.errors.clone(); - let mut errors = errors.lock().unwrap(); + let mut errors = self.errors.lock().unwrap(); errors.push( CSSError{ @@ -306,14 +308,6 @@ impl ParseErrorReporter for CSSInvalidErrorReporterTest { } ); } - - fn clone(&self) -> Box<ParseErrorReporter + Send + Sync> { - return Box::new( - CSSInvalidErrorReporterTest{ - errors: self.errors.clone() - } - ); - } } @@ -327,13 +321,13 @@ fn test_report_error_stylesheet() { } "; let url = ServoUrl::parse("about::test").unwrap(); - let error_reporter = Box::new(CSSInvalidErrorReporterTest::new()); + let error_reporter = CSSInvalidErrorReporterTest::new(); let errors = error_reporter.errors.clone(); Stylesheet::from_str(css, url.clone(), Origin::UserAgent, Default::default(), None, - error_reporter, + &error_reporter, ParserContextExtraData::default()); let mut errors = errors.lock().unwrap(); diff --git a/tests/unit/style/viewport.rs b/tests/unit/style/viewport.rs index d4ef14536d8..166094ebdc1 100644 --- a/tests/unit/style/viewport.rs +++ b/tests/unit/style/viewport.rs @@ -7,7 +7,6 @@ use euclid::size::TypedSize2D; use media_queries::CSSErrorReporterTest; use servo_config::prefs::{PREFS, PrefValue}; use servo_url::ServoUrl; -use style::error_reporting::ParseErrorReporter; use style::media_queries::{Device, MediaType}; use style::parser::{ParserContext, ParserContextExtraData}; use style::stylesheets::{Stylesheet, Origin}; @@ -26,7 +25,7 @@ macro_rules! stylesheet { Origin::$origin, Default::default(), None, - $error_reporter, + &$error_reporter, ParserContextExtraData::default() )) } @@ -38,7 +37,7 @@ fn test_viewport_rule<F>(css: &str, where F: Fn(&Vec<ViewportDescriptorDeclaration>, &str) { PREFS.set("layout.viewport.enabled", PrefValue::Boolean(true)); - let stylesheet = stylesheet!(css, Author, Box::new(CSSErrorReporterTest)); + let stylesheet = stylesheet!(css, Author, CSSErrorReporterTest); let mut rule_count = 0; stylesheet.effective_viewport_rules(&device, |rule| { rule_count += 1; @@ -253,9 +252,9 @@ fn multiple_stylesheets_cascading() { let device = Device::new(MediaType::Screen, TypedSize2D::new(800., 600.)); let error_reporter = CSSErrorReporterTest; let stylesheets = vec![ - stylesheet!("@viewport { min-width: 100px; min-height: 100px; zoom: 1; }", UserAgent, error_reporter.clone()), - stylesheet!("@viewport { min-width: 200px; min-height: 200px; }", User, error_reporter.clone()), - stylesheet!("@viewport { min-width: 300px; }", Author, error_reporter.clone())]; + stylesheet!("@viewport { min-width: 100px; min-height: 100px; zoom: 1; }", UserAgent, error_reporter), + stylesheet!("@viewport { min-width: 200px; min-height: 200px; }", User, error_reporter), + stylesheet!("@viewport { min-width: 300px; }", Author, error_reporter)]; let declarations = Cascade::from_stylesheets(&stylesheets, &device).finish(); assert_decl_len!(declarations == 3); @@ -264,11 +263,11 @@ fn multiple_stylesheets_cascading() { assert_decl_eq!(&declarations[2], Author, MinWidth: viewport_length!(300., px)); let stylesheets = vec![ - stylesheet!("@viewport { min-width: 100px !important; }", UserAgent, error_reporter.clone()), + stylesheet!("@viewport { min-width: 100px !important; }", UserAgent, error_reporter), stylesheet!("@viewport { min-width: 200px !important; min-height: 200px !important; }", - User, error_reporter.clone()), + User, error_reporter), stylesheet!("@viewport { min-width: 300px !important; min-height: 300px !important; zoom: 3 !important; }", - Author, error_reporter.clone())]; + Author, error_reporter)]; let declarations = Cascade::from_stylesheets(&stylesheets, &device).finish(); assert_decl_len!(declarations == 3); assert_decl_eq!(&declarations[0], UserAgent, MinWidth: viewport_length!(100., px), !important); @@ -279,7 +278,8 @@ fn multiple_stylesheets_cascading() { #[test] fn constrain_viewport() { let url = ServoUrl::parse("http://localhost").unwrap(); - let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest)); + let reporter = CSSErrorReporterTest; + let context = ParserContext::new(Origin::Author, &url, &reporter); macro_rules! from_css { ($css:expr) => { |