Defined new trait ParseErrorReporter and added error_reporter member to ParserContext

This commit is contained in:
GauriGNaik 2015-10-26 11:31:28 -04:00 committed by Josh Matthews
parent 8efc954531
commit 996e9e06b2
24 changed files with 194 additions and 69 deletions

View file

@ -38,6 +38,9 @@ path = "../script_traits"
[dependencies.style] [dependencies.style]
path = "../style" path = "../style"
[dependencies.style_traits]
path = "../style_traits"
[dependencies.plugins] [dependencies.plugins]
path = "../plugins" path = "../plugins"

View file

@ -27,6 +27,7 @@ use std::rc::Rc;
use std::sync::mpsc::{Sender, channel}; use std::sync::mpsc::{Sender, channel};
use std::sync::{Arc, Mutex, RwLock}; use std::sync::{Arc, Mutex, RwLock};
use style::selector_matching::Stylist; use style::selector_matching::Stylist;
use style_traits::ParseErrorReporter;
use url::Url; use url::Url;
use util::mem::HeapSizeOf; use util::mem::HeapSizeOf;
use util::opts; use util::opts;
@ -127,6 +128,9 @@ pub struct SharedLayoutContext {
/// Why is this reflow occurring /// Why is this reflow occurring
pub goal: ReflowGoal, pub goal: ReflowGoal,
///The CSS error reporter for all CSS loaded in this layout thread
pub error_reporter: Box<ParseErrorReporter + Sync>
} }
pub struct LayoutContext<'a> { pub struct LayoutContext<'a> {

View file

@ -27,6 +27,7 @@ use string_cache::{Atom, Namespace};
use style::node::TElementAttributes; use style::node::TElementAttributes;
use style::properties::{ComputedValues, PropertyDeclaration, cascade}; use style::properties::{ComputedValues, PropertyDeclaration, cascade};
use style::selector_matching::{DeclarationBlock, Stylist}; use style::selector_matching::{DeclarationBlock, Stylist};
use style_traits::ParseErrorReporter;
use util::arc_ptr_eq; use util::arc_ptr_eq;
use util::cache::{LRUCache, SimpleHashCache}; use util::cache::{LRUCache, SimpleHashCache};
use util::opts; use util::opts;
@ -456,7 +457,8 @@ impl<'ln> PrivateMatchMethods for ServoLayoutNode<'ln> {
applicable_declarations, applicable_declarations,
shareable, shareable,
Some(&***parent_style), Some(&***parent_style),
cached_computed_values); cached_computed_values,
layout_context.error_reporter.clone());
cacheable = cacheable && is_cacheable; cacheable = cacheable && is_cacheable;
this_style = the_style this_style = the_style
} }
@ -465,7 +467,8 @@ impl<'ln> PrivateMatchMethods for ServoLayoutNode<'ln> {
applicable_declarations, applicable_declarations,
shareable, shareable,
None, None,
None); None,
layout_context.error_reporter.clone());
cacheable = cacheable && is_cacheable; cacheable = cacheable && is_cacheable;
this_style = the_style this_style = the_style
} }

View file

@ -49,6 +49,7 @@ use script::layout_interface::Animation;
use script::layout_interface::{LayoutRPC, OffsetParentResponse}; use script::layout_interface::{LayoutRPC, OffsetParentResponse};
use script::layout_interface::{Msg, NewLayoutTaskInfo, Reflow, ReflowGoal, ReflowQueryType}; use script::layout_interface::{Msg, NewLayoutTaskInfo, Reflow, ReflowGoal, ReflowQueryType};
use script::layout_interface::{ScriptLayoutChan, ScriptReflow}; use script::layout_interface::{ScriptLayoutChan, ScriptReflow};
use script::reporter::CSSErrorReporter;
use script_traits::{ConstellationControlMsg, LayoutControlMsg, OpaqueScriptLayoutChannel}; use script_traits::{ConstellationControlMsg, LayoutControlMsg, OpaqueScriptLayoutChannel};
use sequential; use sequential;
use serde_json; use serde_json;
@ -64,6 +65,7 @@ use style::computed_values::{filter, mix_blend_mode};
use style::media_queries::{Device, MediaType}; use style::media_queries::{Device, MediaType};
use style::selector_matching::{Stylist, USER_OR_USER_AGENT_STYLESHEETS}; use style::selector_matching::{Stylist, USER_OR_USER_AGENT_STYLESHEETS};
use style::stylesheets::{CSSRuleIteratorExt, Stylesheet}; use style::stylesheets::{CSSRuleIteratorExt, Stylesheet};
use style_traits::ParseErrorReporter;
use url::Url; use url::Url;
use util::geometry::MAX_RECT; use util::geometry::MAX_RECT;
use util::ipc::OptionalIpcSender; use util::ipc::OptionalIpcSender;
@ -211,6 +213,10 @@ pub struct LayoutTask {
/// ///
/// All the other elements of this struct are read-only. /// All the other elements of this struct are read-only.
rw_data: Arc<Mutex<LayoutTaskData>>, rw_data: Arc<Mutex<LayoutTaskData>>,
/// The CSS error reporter for all CSS loaded in this layout thread
error_reporter: CSSErrorReporter,
} }
impl LayoutTaskFactory for LayoutTask { impl LayoutTaskFactory for LayoutTask {
@ -438,6 +444,7 @@ impl LayoutTask {
resolved_style_response: None, resolved_style_response: None,
offset_parent_response: OffsetParentResponse::empty(), offset_parent_response: OffsetParentResponse::empty(),
})), })),
error_reporter: CSSErrorReporter,
} }
} }
@ -476,6 +483,7 @@ impl LayoutTask {
goal: goal, goal: goal,
running_animations: self.running_animations.clone(), running_animations: self.running_animations.clone(),
expired_animations: self.expired_animations.clone(), expired_animations: self.expired_animations.clone(),
error_reporter: self.error_reporter.clone(),
} }
} }
@ -557,7 +565,6 @@ impl LayoutTask {
goal: ReflowGoal::ForDisplay, goal: ReflowGoal::ForDisplay,
page_clip_rect: MAX_RECT, page_clip_rect: MAX_RECT,
}; };
let mut layout_context = self.build_shared_layout_context(&*rw_data, let mut layout_context = self.build_shared_layout_context(&*rw_data,
false, false,
&self.url, &self.url,

View file

@ -53,6 +53,7 @@ extern crate serde_json;
extern crate smallvec; extern crate smallvec;
#[macro_use(atom, ns)] extern crate string_cache; #[macro_use(atom, ns)] extern crate string_cache;
extern crate style; extern crate style;
extern crate style_traits;
extern crate unicode_bidi; extern crate unicode_bidi;
extern crate unicode_script; extern crate unicode_script;
extern crate url; extern crate url;

View file

@ -36,6 +36,9 @@ path = "../devtools_traits"
[dependencies.style] [dependencies.style]
path = "../style" path = "../style"
[dependencies.style_traits]
path = "../style_traits"
[dependencies.canvas] [dependencies.canvas]
path = "../canvas" path = "../canvas"

View file

@ -18,6 +18,7 @@ use std::cell::Ref;
use string_cache::Atom; use string_cache::Atom;
use style::properties::{PropertyDeclaration, Shorthand}; use style::properties::{PropertyDeclaration, Shorthand};
use style::properties::{is_supported_property, parse_one_declaration}; use style::properties::{is_supported_property, parse_one_declaration};
use style_traits::ParseErrorReporter;
use util::str::{DOMString, str_join}; use util::str::{DOMString, str_join};
// http://dev.w3.org/csswg/cssom/#the-cssstyledeclaration-interface // http://dev.w3.org/csswg/cssom/#the-cssstyledeclaration-interface
@ -240,7 +241,7 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
// Step 6 // Step 6
let window = window_from_node(&*self.owner); let window = window_from_node(&*self.owner);
let declarations = parse_one_declaration(&property, &value, &window.get_url()); let declarations = parse_one_declaration(&property, &value, &window.get_url(), window.css_error_reporter());
// Step 7 // Step 7
let declarations = if let Ok(declarations) = declarations { let declarations = if let Ok(declarations) = declarations {

View file

@ -80,6 +80,7 @@ use style::properties::longhands::{self, background_image, border_spacing, font_
use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, parse_style_attribute}; use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, parse_style_attribute};
use style::values::CSSFloat; use style::values::CSSFloat;
use style::values::specified::{self, CSSColor, CSSRGBA, LengthOrPercentage}; use style::values::specified::{self, CSSColor, CSSRGBA, LengthOrPercentage};
use style_traits::ParseErrorReporter;
use url::UrlParser; use url::UrlParser;
use util::mem::HeapSizeOf; use util::mem::HeapSizeOf;
use util::str::{DOMString, LengthOrPercentageOrAuto}; use util::str::{DOMString, LengthOrPercentageOrAuto};
@ -1514,7 +1515,8 @@ impl VirtualMethods for Element {
// Modifying the `style` attribute might change style. // Modifying the `style` attribute might change style.
*self.style_attribute.borrow_mut() = *self.style_attribute.borrow_mut() =
mutation.new_value(attr).map(|value| { mutation.new_value(attr).map(|value| {
parse_style_attribute(&value, &doc.base_url()) let win = window_from_node(self);
parse_style_attribute(&value, &doc.base_url(), win.css_error_reporter())
}); });
if node.is_in_doc() { if node.is_in_doc() {
doc.content_changed(node, NodeDamage::NodeStyleDamaged); doc.content_changed(node, NodeDamage::NodeStyleDamaged);

View file

@ -281,13 +281,17 @@ impl AsyncResponseListener for StylesheetContext {
let environment_encoding = UTF_8 as EncodingRef; let environment_encoding = UTF_8 as EncodingRef;
let protocol_encoding_label = metadata.charset.as_ref().map(|s| &**s); let protocol_encoding_label = metadata.charset.as_ref().map(|s| &**s);
let final_url = metadata.final_url; let final_url = metadata.final_url;
let elem = self.elem.root();
let win = window_from_node(&*elem);
let mut sheet = Stylesheet::from_bytes(&data, final_url, protocol_encoding_label, let mut sheet = Stylesheet::from_bytes(&data, final_url, protocol_encoding_label,
Some(environment_encoding), Origin::Author); Some(environment_encoding), Origin::Author,
win.css_error_reporter());
let media = self.media.take().unwrap(); let media = self.media.take().unwrap();
sheet.set_media(Some(media)); sheet.set_media(Some(media));
let sheet = Arc::new(sheet); let sheet = Arc::new(sheet);
let elem = self.elem.root();
let elem = elem.r(); let elem = elem.r();
let document = document_from_node(elem); let document = document_from_node(elem);
let document = document.r(); let document = document.r();

View file

@ -58,7 +58,7 @@ impl HTMLStyleElement {
}; };
let data = node.GetTextContent().expect("Element.textContent must be a string"); let data = node.GetTextContent().expect("Element.textContent must be a string");
let mut sheet = Stylesheet::from_str(&data, url, Origin::Author); let mut sheet = Stylesheet::from_str(&data, url, Origin::Author, win.css_error_reporter());
let mut css_parser = CssParser::new(&mq_str); let mut css_parser = CssParser::new(&mq_str);
let media = parse_media_query_list(&mut css_parser); let media = parse_media_query_list(&mut css_parser);
sheet.set_media(Some(media)); sheet.set_media(Some(media));

View file

@ -52,6 +52,7 @@ use net_traits::storage_task::{StorageTask, StorageType};
use num::traits::ToPrimitive; use num::traits::ToPrimitive;
use page::Page; use page::Page;
use profile_traits::mem; use profile_traits::mem;
use reporter::CSSErrorReporter;
use rustc_serialize::base64::{FromBase64, STANDARD, ToBase64}; use rustc_serialize::base64::{FromBase64, STANDARD, ToBase64};
use script_task::{ScriptChan, ScriptPort, MainThreadScriptMsg, RunnableWrapper}; use script_task::{ScriptChan, ScriptPort, MainThreadScriptMsg, RunnableWrapper};
use script_task::{SendableMainThreadScriptChan, MainThreadScriptChan}; use script_task::{SendableMainThreadScriptChan, MainThreadScriptChan};
@ -70,6 +71,7 @@ use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc::TryRecvError::{Disconnected, Empty}; use std::sync::mpsc::TryRecvError::{Disconnected, Empty};
use std::sync::mpsc::{Sender, channel}; use std::sync::mpsc::{Sender, channel};
use string_cache::Atom; use string_cache::Atom;
use style_traits::ParseErrorReporter;
use time; use time;
use timers::{ActiveTimers, IsInterval, ScheduledCallback, TimerCallback, TimerHandle}; use timers::{ActiveTimers, IsInterval, ScheduledCallback, TimerCallback, TimerHandle};
use url::Url; use url::Url;
@ -216,6 +218,8 @@ pub struct Window {
/// A flag to prevent async events from attempting to interact with this window. /// A flag to prevent async events from attempting to interact with this window.
#[ignore_heap_size_of = "defined in std"] #[ignore_heap_size_of = "defined in std"]
ignore_further_async_events: Arc<AtomicBool>, ignore_further_async_events: Arc<AtomicBool>,
error_reporter: CSSErrorReporter,
} }
impl Window { impl Window {
@ -289,6 +293,10 @@ impl Window {
pub fn storage_task(&self) -> StorageTask { pub fn storage_task(&self) -> StorageTask {
self.storage_task.clone() self.storage_task.clone()
} }
pub fn css_error_reporter(&self) -> Box<ParseErrorReporter + Send> {
return self.error_reporter.clone();
}
} }
// https://html.spec.whatwg.org/multipage/#atob // https://html.spec.whatwg.org/multipage/#atob
@ -1243,7 +1251,7 @@ impl Window {
lchan.send(Msg::GetRPC(rpc_send)).unwrap(); lchan.send(Msg::GetRPC(rpc_send)).unwrap();
rpc_recv.recv().unwrap() rpc_recv.recv().unwrap()
}; };
let error_reporter = CSSErrorReporter;
let win = box Window { let win = box Window {
eventtarget: EventTarget::new_inherited(), eventtarget: EventTarget::new_inherited(),
script_chan: script_chan, script_chan: script_chan,
@ -1288,8 +1296,8 @@ impl Window {
devtools_markers: DOMRefCell::new(HashSet::new()), devtools_markers: DOMRefCell::new(HashSet::new()),
devtools_wants_updates: Cell::new(false), devtools_wants_updates: Cell::new(false),
webdriver_script_chan: DOMRefCell::new(None), webdriver_script_chan: DOMRefCell::new(None),
ignore_further_async_events: Arc::new(AtomicBool::new(false)), ignore_further_async_events: Arc::new(AtomicBool::new(false)),
error_reporter: error_reporter
}; };
WindowBinding::Wrap(runtime.cx(), win) WindowBinding::Wrap(runtime.cx(), win)

View file

@ -42,6 +42,7 @@ extern crate log;
extern crate profile_traits; extern crate profile_traits;
#[macro_use] #[macro_use]
extern crate style; extern crate style;
extern crate style_traits;
#[macro_use] #[macro_use]
extern crate util; extern crate util;
extern crate angle; extern crate angle;
@ -90,6 +91,7 @@ mod mem;
mod network_listener; mod network_listener;
pub mod page; pub mod page;
pub mod parse; pub mod parse;
pub mod reporter;
#[allow(unsafe_code)] #[allow(unsafe_code)]
pub mod script_task; pub mod script_task;
pub mod textinput; pub mod textinput;

View file

@ -0,0 +1,25 @@
/* 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/. */
use cssparser::{Parser, SourcePosition};
use log;
use style_traits::ParseErrorReporter;
#[derive(JSTraceable, HeapSizeOf)]
pub struct CSSErrorReporter;
impl ParseErrorReporter for CSSErrorReporter {
fn report_error(&self, input: &mut Parser, position: SourcePosition, message: &str) {
if log_enabled!(log::LogLevel::Info) {
let location = input.source_location(position);
// TODO eventually this will got into a "web console" or something.
info!("{}:{} {}", location.line, location.column, message)
}
}
fn clone(&self) -> Box<ParseErrorReporter + Send + Sync> {
let error_reporter = box CSSErrorReporter;
return error_reporter;
}
}

View file

@ -1028,6 +1028,7 @@ dependencies = [
"smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"style 0.0.1", "style 0.0.1",
"style_traits 0.0.1",
"unicode-bidi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-bidi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-script 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-script 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)", "url 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1550,6 +1551,7 @@ dependencies = [
"smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"style 0.0.1", "style 0.0.1",
"style_traits 0.0.1",
"tendril 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "tendril 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"unicase 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",

View file

@ -6,6 +6,7 @@
use cssparser::{Parser, SourcePosition}; use cssparser::{Parser, SourcePosition};
use log; use log;
use selectors::parser::ParserContext as SelectorParserContext; use selectors::parser::ParserContext as SelectorParserContext;
use style_traits::ParseErrorReporter;
use stylesheets::Origin; use stylesheets::Origin;
use url::{Url, UrlParser}; use url::{Url, UrlParser};
@ -13,16 +14,19 @@ pub struct ParserContext<'a> {
pub stylesheet_origin: Origin, pub stylesheet_origin: Origin,
pub base_url: &'a Url, pub base_url: &'a Url,
pub selector_context: SelectorParserContext, pub selector_context: SelectorParserContext,
pub error_reporter: Box<ParseErrorReporter + Send>
} }
impl<'a> ParserContext<'a> { impl<'a> ParserContext<'a> {
pub fn new(stylesheet_origin: Origin, base_url: &'a Url) -> ParserContext<'a> { pub fn new(stylesheet_origin: Origin, base_url: &'a Url, error_reporter: Box<ParseErrorReporter + Send>)
-> ParserContext<'a> {
let mut selector_context = SelectorParserContext::new(); let mut selector_context = SelectorParserContext::new();
selector_context.in_user_agent_stylesheet = stylesheet_origin == Origin::UserAgent; selector_context.in_user_agent_stylesheet = stylesheet_origin == Origin::UserAgent;
ParserContext { ParserContext {
stylesheet_origin: stylesheet_origin, stylesheet_origin: stylesheet_origin,
base_url: base_url, base_url: base_url,
selector_context: selector_context, selector_context: selector_context,
error_reporter: error_reporter,
} }
} }
} }

View file

@ -22,7 +22,7 @@ use euclid::SideOffsets2D;
use euclid::size::Size2D; use euclid::size::Size2D;
use fnv::FnvHasher; use fnv::FnvHasher;
use string_cache::Atom; use string_cache::Atom;
use style_traits::ParseErrorReporter;
use computed_values; use computed_values;
use parser::{ParserContext, log_css_error}; use parser::{ParserContext, log_css_error};
use selectors::matching::DeclarationBlock; use selectors::matching::DeclarationBlock;
@ -135,6 +135,7 @@ pub mod longhands {
use properties::{ComputedValues, PropertyDeclaration}; use properties::{ComputedValues, PropertyDeclaration};
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::Arc; use std::sync::Arc;
use style_traits::ParseErrorReporter;
use values::computed::ToComputedValue; use values::computed::ToComputedValue;
use values::{computed, specified}; use values::{computed, specified};
use string_cache::Atom; use string_cache::Atom;
@ -145,7 +146,8 @@ pub mod longhands {
inherited_style: &ComputedValues, inherited_style: &ComputedValues,
context: &computed::Context, context: &computed::Context,
seen: &mut PropertyBitField, seen: &mut PropertyBitField,
cacheable: &mut bool) { cacheable: &mut bool,
error_reporter: Box<ParseErrorReporter + Send>) {
let declared_value = match *declaration { let declared_value = match *declaration {
PropertyDeclaration::${property.camel_case}(ref declared_value) => { PropertyDeclaration::${property.camel_case}(ref declared_value) => {
declared_value declared_value
@ -174,7 +176,7 @@ pub mod longhands {
.${property.ident} .${property.ident}
.clone() .clone()
} }
} }, error_reporter.clone()
); );
Arc::make_mut(&mut style.${THIS_STYLE_STRUCT.ident}).${property.ident} = Arc::make_mut(&mut style.${THIS_STYLE_STRUCT.ident}).${property.ident} =
computed_value; computed_value;
@ -186,7 +188,8 @@ pub mod longhands {
inherited_style, inherited_style,
context, context,
seen, seen,
cacheable); cacheable,
error_reporter);
% endif % endif
% else: % else:
// Do not allow stylesheets to set derived properties. // Do not allow stylesheets to set derived properties.
@ -533,7 +536,8 @@ pub mod longhands {
_inherited_style: &ComputedValues, _inherited_style: &ComputedValues,
context: &computed::Context, context: &computed::Context,
_seen: &mut PropertyBitField, _seen: &mut PropertyBitField,
_cacheable: &mut bool) { _cacheable: &mut bool,
_error_reporter: Box<ParseErrorReporter + Send>) {
Arc::make_mut(&mut style.box_)._servo_display_for_hypothetical_box = Arc::make_mut(&mut style.box_)._servo_display_for_hypothetical_box =
longhands::_servo_display_for_hypothetical_box::derive_from_display( longhands::_servo_display_for_hypothetical_box::derive_from_display(
*computed_value, *computed_value,
@ -2234,7 +2238,8 @@ pub mod longhands {
_inherited_style: &ComputedValues, _inherited_style: &ComputedValues,
context: &computed::Context, context: &computed::Context,
_seen: &mut PropertyBitField, _seen: &mut PropertyBitField,
_cacheable: &mut bool) { _cacheable: &mut bool,
_error_reporter: Box<ParseErrorReporter + Send>) {
Arc::make_mut(&mut style.inheritedtext)._servo_text_decorations_in_effect = Arc::make_mut(&mut style.inheritedtext)._servo_text_decorations_in_effect =
longhands::_servo_text_decorations_in_effect::derive_from_text_decoration( longhands::_servo_text_decorations_in_effect::derive_from_text_decoration(
*computed_value, *computed_value,
@ -5613,7 +5618,7 @@ mod property_bit_field {
fn substitute_variables_${property.ident}<F, R>( fn substitute_variables_${property.ident}<F, R>(
value: &DeclaredValue<longhands::${property.ident}::SpecifiedValue>, value: &DeclaredValue<longhands::${property.ident}::SpecifiedValue>,
custom_properties: &Option<Arc<::custom_properties::ComputedValuesMap>>, custom_properties: &Option<Arc<::custom_properties::ComputedValuesMap>>,
f: F) f: F, error_reporter: Box<ParseErrorReporter + Send>)
-> R -> R
where F: FnOnce(&DeclaredValue<longhands::${property.ident}::SpecifiedValue>) -> R where F: FnOnce(&DeclaredValue<longhands::${property.ident}::SpecifiedValue>) -> R
{ {
@ -5625,7 +5630,7 @@ mod property_bit_field {
.and_then(|css| { .and_then(|css| {
// As of this writing, only the base URL is used for property values: // As of this writing, only the base URL is used for property values:
let context = ParserContext::new( let context = ParserContext::new(
::stylesheets::Origin::Author, base_url); ::stylesheets::Origin::Author, base_url, error_reporter);
Parser::new(&css).parse_entirely(|input| { Parser::new(&css).parse_entirely(|input| {
match from_shorthand { match from_shorthand {
None => { None => {
@ -5668,15 +5673,15 @@ pub struct PropertyDeclarationBlock {
pub normal: Arc<Vec<PropertyDeclaration>>, pub normal: Arc<Vec<PropertyDeclaration>>,
} }
pub fn parse_style_attribute(input: &str, base_url: &Url, error_reporter: Box<ParseErrorReporter + Send>)
pub fn parse_style_attribute(input: &str, base_url: &Url) -> PropertyDeclarationBlock { -> PropertyDeclarationBlock {
let context = ParserContext::new(Origin::Author, base_url); let context = ParserContext::new(Origin::Author, base_url, error_reporter);
parse_property_declaration_list(&context, &mut Parser::new(input)) parse_property_declaration_list(&context, &mut Parser::new(input))
} }
pub fn parse_one_declaration(name: &str, input: &str, base_url: &Url) pub fn parse_one_declaration(name: &str, input: &str, base_url: &Url, error_reporter: Box<ParseErrorReporter + Send>)
-> Result<Vec<PropertyDeclaration>, ()> { -> Result<Vec<PropertyDeclaration>, ()> {
let context = ParserContext::new(Origin::Author, base_url); let context = ParserContext::new(Origin::Author, base_url, error_reporter);
let mut results = vec![]; let mut results = vec![];
match PropertyDeclaration::parse(name, &context, &mut Parser::new(input), &mut results) { match PropertyDeclaration::parse(name, &context, &mut Parser::new(input), &mut results) {
PropertyDeclarationParseResult::ValidOrIgnoredDeclaration => Ok(results), PropertyDeclarationParseResult::ValidOrIgnoredDeclaration => Ok(results),
@ -6389,7 +6394,8 @@ fn cascade_with_cached_declarations(
parent_style: &ComputedValues, parent_style: &ComputedValues,
cached_style: &ComputedValues, cached_style: &ComputedValues,
custom_properties: Option<Arc<::custom_properties::ComputedValuesMap>>, custom_properties: Option<Arc<::custom_properties::ComputedValuesMap>>,
context: &computed::Context) context: &computed::Context,
error_reporter: Box<ParseErrorReporter + Send>)
-> ComputedValues { -> ComputedValues {
% for style_struct in STYLE_STRUCTS: % for style_struct in STYLE_STRUCTS:
% if style_struct.inherited: % if style_struct.inherited:
@ -6433,7 +6439,7 @@ fn cascade_with_cached_declarations(
.clone() .clone()
} }
DeclaredValue::WithVariables { .. } => unreachable!() DeclaredValue::WithVariables { .. } => unreachable!()
} }, error_reporter.clone()
); );
Arc::make_mut(&mut style_${style_struct.ident}) Arc::make_mut(&mut style_${style_struct.ident})
.${property.ident} = computed_value; .${property.ident} = computed_value;
@ -6488,7 +6494,8 @@ type CascadePropertyFn = extern "Rust" fn(declaration: &PropertyDeclaration,
inherited_style: &ComputedValues, inherited_style: &ComputedValues,
context: &computed::Context, context: &computed::Context,
seen: &mut PropertyBitField, seen: &mut PropertyBitField,
cacheable: &mut bool); cacheable: &mut bool,
error_reporter: Box<ParseErrorReporter + Send>);
// This is a thread-local rather than a lazy static to avoid atomic operations when cascading // This is a thread-local rather than a lazy static to avoid atomic operations when cascading
// properties. // properties.
@ -6533,7 +6540,8 @@ pub fn cascade(viewport_size: Size2D<Au>,
applicable_declarations: &[DeclarationBlock<Vec<PropertyDeclaration>>], applicable_declarations: &[DeclarationBlock<Vec<PropertyDeclaration>>],
shareable: bool, shareable: bool,
parent_style: Option< &ComputedValues >, parent_style: Option< &ComputedValues >,
cached_style: Option< &ComputedValues >) cached_style: Option< &ComputedValues >,
error_reporter: Box<ParseErrorReporter + Send>)
-> (ComputedValues, bool) { -> (ComputedValues, bool) {
let initial_values = &*INITIAL_VALUES; let initial_values = &*INITIAL_VALUES;
let (is_root_element, inherited_style) = match parent_style { let (is_root_element, inherited_style) = match parent_style {
@ -6588,7 +6596,7 @@ pub fn cascade(viewport_size: Size2D<Au>,
// This assumes that the computed and specified values have the same Rust type. // This assumes that the computed and specified values have the same Rust type.
macro_rules! get_specified( macro_rules! get_specified(
($style_struct_getter: ident, $property: ident, $declared_value: expr) => { ($style_struct_getter: ident, $property: ident, $declared_value: expr, $error_reporter: expr) => {
concat_idents!(substitute_variables_, $property)( concat_idents!(substitute_variables_, $property)(
$declared_value, &custom_properties, |value| match *value { $declared_value, &custom_properties, |value| match *value {
DeclaredValue::Value(specified_value) => specified_value, DeclaredValue::Value(specified_value) => specified_value,
@ -6597,7 +6605,7 @@ pub fn cascade(viewport_size: Size2D<Au>,
inherited_style.$style_struct_getter().$property.clone() inherited_style.$style_struct_getter().$property.clone()
} }
DeclaredValue::WithVariables { .. } => unreachable!() DeclaredValue::WithVariables { .. } => unreachable!()
} }, $error_reporter.clone()
) )
}; };
); );
@ -6636,7 +6644,7 @@ pub fn cascade(viewport_size: Size2D<Au>,
DeclaredValue::Initial => longhands::font_size::get_initial_value(), DeclaredValue::Initial => longhands::font_size::get_initial_value(),
DeclaredValue::Inherit => context.inherited_font_size, DeclaredValue::Inherit => context.inherited_font_size,
DeclaredValue::WithVariables { .. } => unreachable!(), DeclaredValue::WithVariables { .. } => unreachable!(),
} }, error_reporter.clone()
); );
} }
PropertyDeclaration::Color(ref value) => { PropertyDeclaration::Color(ref value) => {
@ -6648,35 +6656,35 @@ pub fn cascade(viewport_size: Size2D<Au>,
DeclaredValue::Initial => longhands::color::get_initial_value(), DeclaredValue::Initial => longhands::color::get_initial_value(),
DeclaredValue::Inherit => inherited_style.get_color().color.clone(), DeclaredValue::Inherit => inherited_style.get_color().color.clone(),
DeclaredValue::WithVariables { .. } => unreachable!(), DeclaredValue::WithVariables { .. } => unreachable!(),
} }, error_reporter.clone()
); );
} }
PropertyDeclaration::Display(ref value) => { PropertyDeclaration::Display(ref value) => {
context.display = get_specified!(get_box, display, value); context.display = get_specified!(get_box, display, value, error_reporter.clone());
} }
PropertyDeclaration::Position(ref value) => { PropertyDeclaration::Position(ref value) => {
context.positioned = match get_specified!(get_box, position, value) { context.positioned = match get_specified!(get_box, position, value, error_reporter.clone()) {
longhands::position::SpecifiedValue::absolute | longhands::position::SpecifiedValue::absolute |
longhands::position::SpecifiedValue::fixed => true, longhands::position::SpecifiedValue::fixed => true,
_ => false, _ => false,
} }
} }
PropertyDeclaration::OverflowX(ref value) => { PropertyDeclaration::OverflowX(ref value) => {
context.overflow_x = get_specified!(get_box, overflow_x, value); context.overflow_x = get_specified!(get_box, overflow_x, value, error_reporter.clone());
} }
PropertyDeclaration::OverflowY(ref value) => { PropertyDeclaration::OverflowY(ref value) => {
context.overflow_y = get_specified!(get_box, overflow_y, value); context.overflow_y = get_specified!(get_box, overflow_y, value, error_reporter.clone());
} }
PropertyDeclaration::Float(ref value) => { PropertyDeclaration::Float(ref value) => {
context.floated = get_specified!(get_box, float, value) context.floated = get_specified!(get_box, float, value, error_reporter.clone())
!= longhands::float::SpecifiedValue::none; != longhands::float::SpecifiedValue::none;
} }
PropertyDeclaration::TextDecoration(ref value) => { PropertyDeclaration::TextDecoration(ref value) => {
context.text_decoration = get_specified!(get_text, text_decoration, value); context.text_decoration = get_specified!(get_text, text_decoration, value, error_reporter.clone());
} }
PropertyDeclaration::OutlineStyle(ref value) => { PropertyDeclaration::OutlineStyle(ref value) => {
context.outline_style_present = context.outline_style_present =
match get_specified!(get_outline, outline_style, value) { match get_specified!(get_outline, outline_style, value, error_reporter.clone()) {
BorderStyle::none => false, BorderStyle::none => false,
_ => true, _ => true,
}; };
@ -6684,7 +6692,7 @@ pub fn cascade(viewport_size: Size2D<Au>,
% for side in ["top", "right", "bottom", "left"]: % for side in ["top", "right", "bottom", "left"]:
PropertyDeclaration::Border${side.capitalize()}Style(ref value) => { PropertyDeclaration::Border${side.capitalize()}Style(ref value) => {
context.border_${side}_present = context.border_${side}_present =
match get_specified!(get_border, border_${side}_style, value) { match get_specified!(get_border, border_${side}_style, value, error_reporter.clone()) {
BorderStyle::none | BorderStyle::hidden => false, BorderStyle::none | BorderStyle::hidden => false,
_ => true, _ => true,
}; };
@ -6702,7 +6710,8 @@ pub fn cascade(viewport_size: Size2D<Au>,
parent_style, parent_style,
cached_style, cached_style,
custom_properties, custom_properties,
&context), false) &context,
error_reporter), false)
} }
(_, _) => {} (_, _) => {}
} }
@ -6746,7 +6755,8 @@ pub fn cascade(viewport_size: Size2D<Au>,
inherited_style, inherited_style,
&context, &context,
&mut seen, &mut seen,
&mut cacheable); &mut cacheable,
error_reporter.clone());
} }
} }
}); });

View file

@ -2,6 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use cssparser::{Parser, SourcePosition};
use log;
use media_queries::{Device, MediaType}; use media_queries::{Device, MediaType};
use node::TElementAttributes; use node::TElementAttributes;
use properties::{PropertyDeclaration, PropertyDeclarationBlock}; use properties::{PropertyDeclaration, PropertyDeclarationBlock};
@ -14,6 +16,7 @@ use selectors::parser::PseudoElement;
use selectors::states::*; use selectors::states::*;
use smallvec::VecLike; use smallvec::VecLike;
use std::process; use std::process;
use style_traits::ParseErrorReporter;
use style_traits::viewport::ViewportConstraints; use style_traits::viewport::ViewportConstraints;
use stylesheets::{CSSRuleIteratorExt, Origin, Stylesheet}; use stylesheets::{CSSRuleIteratorExt, Origin, Stylesheet};
use url::Url; use url::Url;
@ -24,6 +27,20 @@ use viewport::{MaybeNew, ViewportRuleCascade};
pub type DeclarationBlock = GenericDeclarationBlock<Vec<PropertyDeclaration>>; pub type DeclarationBlock = GenericDeclarationBlock<Vec<PropertyDeclaration>>;
struct StdoutErrorReporter;
impl ParseErrorReporter for StdoutErrorReporter {
fn report_error(&self, input: &mut Parser, position: SourcePosition, message: &str) {
if log_enabled!(log::LogLevel::Info) {
let location = input.source_location(position);
info!("{}:{} {}", location.line, location.column, message)
}
}
fn clone(&self) -> Box<ParseErrorReporter + Send + Sync> {
box StdoutErrorReporter
}
}
lazy_static! { lazy_static! {
pub static ref USER_OR_USER_AGENT_STYLESHEETS: Vec<Stylesheet> = { pub static ref USER_OR_USER_AGENT_STYLESHEETS: Vec<Stylesheet> = {
@ -38,7 +55,8 @@ lazy_static! {
Url::parse(&format!("chrome:///{:?}", filename)).unwrap(), Url::parse(&format!("chrome:///{:?}", filename)).unwrap(),
None, None,
None, None,
Origin::UserAgent); Origin::UserAgent,
box StdoutErrorReporter);
stylesheets.push(ua_stylesheet); stylesheets.push(ua_stylesheet);
} }
Err(..) => { Err(..) => {
@ -49,7 +67,7 @@ lazy_static! {
} }
for &(ref contents, ref url) in &opts::get().user_stylesheets { for &(ref contents, ref url) in &opts::get().user_stylesheets {
stylesheets.push(Stylesheet::from_bytes( stylesheets.push(Stylesheet::from_bytes(
&contents, url.clone(), None, None, Origin::User)); &contents, url.clone(), None, None, Origin::User, box StdoutErrorReporter));
} }
stylesheets stylesheets
}; };
@ -64,7 +82,8 @@ lazy_static! {
url!("chrome:///quirks-mode.css"), url!("chrome:///quirks-mode.css"),
None, None,
None, None,
Origin::UserAgent) Origin::UserAgent,
box StdoutErrorReporter)
}, },
Err(..) => { Err(..) => {
error!("Stylist failed to load 'quirks-mode.css'!"); error!("Stylist failed to load 'quirks-mode.css'!");

View file

@ -16,10 +16,12 @@ use std::cell::Cell;
use std::iter::Iterator; use std::iter::Iterator;
use std::slice; use std::slice;
use string_cache::{Atom, Namespace}; use string_cache::{Atom, Namespace};
use style_traits::ParseErrorReporter;
use url::Url; use url::Url;
use util::mem::HeapSizeOf; use util::mem::HeapSizeOf;
use viewport::ViewportRule; use viewport::ViewportRule;
/// Each style rule has an origin, which determines where it enters the cascade. /// Each style rule has an origin, which determines where it enters the cascade.
/// ///
/// http://dev.w3.org/csswg/css-cascade/#cascading-origins /// http://dev.w3.org/csswg/css-cascade/#cascading-origins
@ -80,31 +82,33 @@ pub struct StyleRule {
impl Stylesheet { impl Stylesheet {
pub fn from_bytes_iter<I: Iterator<Item=Vec<u8>>>( pub fn from_bytes_iter<I: Iterator<Item=Vec<u8>>>(
input: I, base_url: Url, protocol_encoding_label: Option<&str>, input: I, base_url: Url, protocol_encoding_label: Option<&str>,
environment_encoding: Option<EncodingRef>, origin: Origin) -> Stylesheet { environment_encoding: Option<EncodingRef>, origin: Origin,
error_reporter: Box<ParseErrorReporter + Send>) -> Stylesheet {
let mut bytes = vec![]; let mut bytes = vec![];
// TODO: incremental decoding and tokenization/parsing // TODO: incremental decoding and tokenization/parsing
for chunk in input { for chunk in input {
bytes.push_all(&chunk) bytes.push_all(&chunk)
} }
Stylesheet::from_bytes(&bytes, base_url, protocol_encoding_label, Stylesheet::from_bytes(&bytes, base_url, protocol_encoding_label,
environment_encoding, origin) environment_encoding, origin, error_reporter)
} }
pub fn from_bytes(bytes: &[u8], pub fn from_bytes(bytes: &[u8],
base_url: Url, base_url: Url,
protocol_encoding_label: Option<&str>, protocol_encoding_label: Option<&str>,
environment_encoding: Option<EncodingRef>, environment_encoding: Option<EncodingRef>,
origin: Origin) origin: Origin, error_reporter: Box<ParseErrorReporter + Send>)
-> Stylesheet { -> Stylesheet {
// TODO: bytes.as_slice could be bytes.container_as_bytes() // TODO: bytes.as_slice could be bytes.container_as_bytes()
let (string, _) = decode_stylesheet_bytes( let (string, _) = decode_stylesheet_bytes(
bytes, protocol_encoding_label, environment_encoding); bytes, protocol_encoding_label, environment_encoding);
Stylesheet::from_str(&string, base_url, origin) Stylesheet::from_str(&string, base_url, origin, error_reporter)
} }
pub fn from_str(css: &str, base_url: Url, origin: Origin) -> Stylesheet { pub fn from_str(css: &str, base_url: Url, origin: Origin,
error_reporter: Box<ParseErrorReporter + Send>) -> Stylesheet {
let rule_parser = TopLevelRuleParser { let rule_parser = TopLevelRuleParser {
context: ParserContext::new(origin, &base_url), context: ParserContext::new(origin, &base_url, error_reporter),
state: Cell::new(State::Start), state: Cell::new(State::Start),
}; };
let mut input = Parser::new(css); let mut input = Parser::new(css);

View file

@ -24,3 +24,9 @@ extern crate util;
#[macro_use] #[macro_use]
pub mod values; pub mod values;
pub mod viewport; pub mod viewport;
use cssparser::{Parser, SourcePosition};
pub trait ParseErrorReporter {
fn report_error(&self, input: &mut Parser, position: SourcePosition, message: &str);
fn clone(&self) -> Box<ParseErrorReporter + Send + Sync>;
}

2
ports/cef/Cargo.lock generated
View file

@ -977,6 +977,7 @@ dependencies = [
"smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"style 0.0.1", "style 0.0.1",
"style_traits 0.0.1",
"unicode-bidi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-bidi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-script 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-script 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)", "url 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1464,6 +1465,7 @@ dependencies = [
"smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"style 0.0.1", "style 0.0.1",
"style_traits 0.0.1",
"tendril 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "tendril 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"unicase 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",

2
ports/gonk/Cargo.lock generated
View file

@ -957,6 +957,7 @@ dependencies = [
"smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"style 0.0.1", "style 0.0.1",
"style_traits 0.0.1",
"unicode-bidi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-bidi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-script 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-script 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)", "url 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1444,6 +1445,7 @@ dependencies = [
"smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"style 0.0.1", "style 0.0.1",
"style_traits 0.0.1",
"tendril 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "tendril 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"unicase 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",

View file

@ -3,16 +3,28 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use app_units::Au; use app_units::Au;
use cssparser::{Parser, SourcePosition};
use euclid::size::Size2D; use euclid::size::Size2D;
use std::borrow::ToOwned; use std::borrow::ToOwned;
use style::media_queries::*; use style::media_queries::*;
use style::stylesheets::{Origin, Stylesheet, CSSRuleIteratorExt}; use style::stylesheets::{Origin, Stylesheet, CSSRuleIteratorExt};
use style::values::specified; use style::values::specified;
use style_traits::ParseErrorReporter;
pub struct CSSErrorReporterTest;
impl ParseErrorReporter for CSSErrorReporterTest {
fn report_error(&self, _input: &mut Parser, _position: SourcePosition, _message: &str) {
}
fn clone(&self) -> Box<ParseErrorReporter + Send + Sync> {
let error_reporter = Box::new(CSSErrorReporterTest);
return error_reporter;
}
}
fn test_media_rule<F>(css: &str, callback: F) where F: Fn(&MediaQueryList, &str) { fn test_media_rule<F>(css: &str, callback: F) where F: Fn(&MediaQueryList, &str) {
let url = url!("http://localhost"); let url = url!("http://localhost");
let stylesheet = Stylesheet::from_str(css, url, Origin::Author); let stylesheet = Stylesheet::from_str(css, url, Origin::Author, Box::new(CSSErrorReporterTest));
let mut rule_count = 0; let mut rule_count = 0;
for rule in stylesheet.rules().media() { for rule in stylesheet.rules().media() {
rule_count += 1; rule_count += 1;
@ -23,7 +35,7 @@ fn test_media_rule<F>(css: &str, callback: F) where F: Fn(&MediaQueryList, &str)
fn media_query_test(device: &Device, css: &str, expected_rule_count: usize) { fn media_query_test(device: &Device, css: &str, expected_rule_count: usize) {
let url = url!("http://localhost"); let url = url!("http://localhost");
let ss = Stylesheet::from_str(css, url, Origin::Author); let ss = Stylesheet::from_str(css, url, Origin::Author, Box::new(CSSErrorReporterTest));
let rule_count = ss.effective_rules(device).style().count(); let rule_count = ss.effective_rules(device).style().count();
assert!(rule_count == expected_rule_count, css.to_owned()); assert!(rule_count == expected_rule_count, css.to_owned());
} }

View file

@ -3,6 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use cssparser; use cssparser;
use media_queries::CSSErrorReporterTest;
use selectors::parser::*; use selectors::parser::*;
use std::borrow::ToOwned; use std::borrow::ToOwned;
use std::sync::Arc; use std::sync::Arc;
@ -10,7 +11,6 @@ use string_cache::Atom;
use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, DeclaredValue, longhands}; use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, DeclaredValue, longhands};
use style::stylesheets::{CSSRule, StyleRule, Origin, Stylesheet}; use style::stylesheets::{CSSRule, StyleRule, Origin, Stylesheet};
#[test] #[test]
fn test_parse_stylesheet() { fn test_parse_stylesheet() {
let css = r" let css = r"
@ -21,7 +21,7 @@ fn test_parse_stylesheet() {
#d1 > .ok { background: blue; } #d1 > .ok { background: blue; }
"; ";
let url = url!("about::test"); let url = url!("about::test");
let stylesheet = Stylesheet::from_str(css, url, Origin::UserAgent); let stylesheet = Stylesheet::from_str(css, url, Origin::UserAgent, Box::new(CSSErrorReporterTest));
assert_eq!(stylesheet, Stylesheet { assert_eq!(stylesheet, Stylesheet {
origin: Origin::UserAgent, origin: Origin::UserAgent,
media: None, media: None,

View file

@ -5,6 +5,7 @@
use cssparser::Parser; use cssparser::Parser;
use euclid::scale_factor::ScaleFactor; use euclid::scale_factor::ScaleFactor;
use euclid::size::Size2D; use euclid::size::Size2D;
use media_queries::CSSErrorReporterTest;
use style::media_queries::{Device, MediaType}; use style::media_queries::{Device, MediaType};
use style::parser::ParserContext; use style::parser::ParserContext;
use style::stylesheets::{Origin, Stylesheet, CSSRuleIteratorExt}; use style::stylesheets::{Origin, Stylesheet, CSSRuleIteratorExt};
@ -12,11 +13,12 @@ use style::values::specified::Length::{self, ViewportPercentage};
use style::values::specified::LengthOrPercentageOrAuto::{self, Auto}; use style::values::specified::LengthOrPercentageOrAuto::{self, Auto};
use style::values::specified::ViewportPercentageLength::Vw; use style::values::specified::ViewportPercentageLength::Vw;
use style::viewport::*; use style::viewport::*;
use style_traits::ParseErrorReporter;
use style_traits::viewport::*; use style_traits::viewport::*;
macro_rules! stylesheet { macro_rules! stylesheet {
($css:expr, $origin:ident) => { ($css:expr, $origin:ident, $error_reporter:expr) => {
Stylesheet::from_str($css, url!("http://localhost"), Origin::$origin); Stylesheet::from_str($css, url!("http://localhost"), Origin::$origin, $error_reporter);
} }
} }
@ -27,8 +29,7 @@ fn test_viewport_rule<F>(css: &str,
{ {
::util::prefs::set_pref("layout.viewport.enabled", ::util::prefs::set_pref("layout.viewport.enabled",
::util::prefs::PrefValue::Boolean(true)); ::util::prefs::PrefValue::Boolean(true));
let stylesheet = stylesheet!(css, Author, Box::new(CSSErrorReporterTest));
let stylesheet = stylesheet!(css, Author);
let mut rule_count = 0; let mut rule_count = 0;
for rule in stylesheet.effective_rules(&device).viewport() { for rule in stylesheet.effective_rules(&device).viewport() {
rule_count += 1; rule_count += 1;
@ -244,11 +245,11 @@ fn multiple_stylesheets_cascading() {
::util::prefs::set_pref("layout.viewport.enabled", ::util::prefs::set_pref("layout.viewport.enabled",
::util::prefs::PrefValue::Boolean(true)); ::util::prefs::PrefValue::Boolean(true));
let device = Device::new(MediaType::Screen, Size2D::typed(800., 600.)); let device = Device::new(MediaType::Screen, Size2D::typed(800., 600.));
let error_reporter = CSSErrorReporterTest;
let stylesheets = vec![ let stylesheets = vec![
stylesheet!("@viewport { min-width: 100px; min-height: 100px; zoom: 1; }", UserAgent), stylesheet!("@viewport { min-width: 100px; min-height: 100px; zoom: 1; }", UserAgent, error_reporter.clone()),
stylesheet!("@viewport { min-width: 200px; min-height: 200px; }", User), stylesheet!("@viewport { min-width: 200px; min-height: 200px; }", User, error_reporter.clone()),
stylesheet!("@viewport { min-width: 300px; }", Author)]; stylesheet!("@viewport { min-width: 300px; }", Author, error_reporter.clone())];
let declarations = stylesheets.iter() let declarations = stylesheets.iter()
.flat_map(|s| s.effective_rules(&device).viewport()) .flat_map(|s| s.effective_rules(&device).viewport())
@ -260,11 +261,11 @@ fn multiple_stylesheets_cascading() {
assert_decl_eq!(&declarations[2], Author, MinWidth: viewport_length!(300., px)); assert_decl_eq!(&declarations[2], Author, MinWidth: viewport_length!(300., px));
let stylesheets = vec![ let stylesheets = vec![
stylesheet!("@viewport { min-width: 100px !important; }", UserAgent), stylesheet!("@viewport { min-width: 100px !important; }", UserAgent, error_reporter.clone()),
stylesheet!("@viewport { min-width: 200px !important; min-height: 200px !important; }", User), stylesheet!("@viewport { min-width: 200px !important; min-height: 200px !important; }",
stylesheet!( User, error_reporter.clone()),
"@viewport { min-width: 300px !important; min-height: 300px !important; zoom: 3 !important; }", Author)]; stylesheet!("@viewport { min-width: 300px !important; min-height: 300px !important; zoom: 3 !important; }",
Author, error_reporter.clone())];
let declarations = stylesheets.iter() let declarations = stylesheets.iter()
.flat_map(|s| s.effective_rules(&device).viewport()) .flat_map(|s| s.effective_rules(&device).viewport())
.cascade() .cascade()
@ -278,7 +279,7 @@ fn multiple_stylesheets_cascading() {
#[test] #[test]
fn constrain_viewport() { fn constrain_viewport() {
let url = url!("http://localhost"); let url = url!("http://localhost");
let context = ParserContext::new(Origin::Author, &url); let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest));
macro_rules! from_css { macro_rules! from_css {
($css:expr) => { ($css:expr) => {