mirror of
https://github.com/servo/servo.git
synced 2025-07-23 15:23:42 +01:00
Defined new trait ParseErrorReporter and added error_reporter member to ParserContext
This commit is contained in:
parent
8efc954531
commit
996e9e06b2
24 changed files with 194 additions and 69 deletions
|
@ -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"
|
||||||
|
|
||||||
|
|
|
@ -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> {
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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"
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
25
components/script/reporter.rs
Normal file
25
components/script/reporter.rs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
2
components/servo/Cargo.lock
generated
2
components/servo/Cargo.lock
generated
|
@ -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)",
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -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'!");
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
2
ports/cef/Cargo.lock
generated
|
@ -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
2
ports/gonk/Cargo.lock
generated
|
@ -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)",
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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) => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue