diff options
-rw-r--r-- | components/layout_thread/Cargo.toml | 1 | ||||
-rw-r--r-- | components/layout_thread/lib.rs | 60 | ||||
-rw-r--r-- | components/servo/Cargo.lock | 1 | ||||
-rw-r--r-- | components/style/gecko_selector_impl.rs | 11 | ||||
-rw-r--r-- | components/style/selector_matching.rs | 19 | ||||
-rw-r--r-- | components/style/servo_selector_impl.rs | 71 | ||||
-rw-r--r-- | components/style/stylesheets.rs | 7 | ||||
-rw-r--r-- | ports/cef/Cargo.lock | 1 | ||||
-rw-r--r-- | ports/geckolib/data.rs | 2 |
9 files changed, 78 insertions, 95 deletions
diff --git a/components/layout_thread/Cargo.toml b/components/layout_thread/Cargo.toml index f97e632d26c..2dcf5ce7455 100644 --- a/components/layout_thread/Cargo.toml +++ b/components/layout_thread/Cargo.toml @@ -21,6 +21,7 @@ heapsize_plugin = "0.1.2" ipc-channel = "0.5" layout = {path = "../layout"} layout_traits = {path = "../layout_traits"} +lazy_static = "0.2" log = "0.3.5" msg = {path = "../msg"} net_traits = {path = "../net_traits"} diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs index 3fcdaa7c986..8d01b9b0a74 100644 --- a/components/layout_thread/lib.rs +++ b/components/layout_thread/lib.rs @@ -25,6 +25,9 @@ extern crate ipc_channel; #[macro_use] extern crate layout; extern crate layout_traits; +#[allow(unused_extern_crates)] +#[macro_use] +extern crate lazy_static; #[macro_use] extern crate log; extern crate msg; @@ -95,6 +98,7 @@ use std::borrow::ToOwned; use std::collections::HashMap; use std::hash::BuildHasherDefault; use std::ops::{Deref, DerefMut}; +use std::process; use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::mpsc::{channel, Sender, Receiver}; use std::sync::{Arc, Mutex, MutexGuard, RwLock}; @@ -102,14 +106,14 @@ use style::animation::Animation; use style::computed_values::{filter, mix_blend_mode}; use style::context::{ReflowGoal, LocalStyleContextCreationInfo, SharedStyleContext}; use style::dom::{TDocument, TElement, TNode}; -use style::error_reporting::ParseErrorReporter; +use style::error_reporting::{ParseErrorReporter, StdoutErrorReporter}; use style::logical_geometry::LogicalPoint; use style::media_queries::{Device, MediaType}; use style::parallel::WorkQueueData; +use style::parser::ParserContextExtraData; use style::refcell::RefCell; use style::selector_matching::Stylist; -use style::servo_selector_impl::USER_OR_USER_AGENT_STYLESHEETS; -use style::stylesheets::{Stylesheet, CSSRuleIteratorExt}; +use style::stylesheets::{Stylesheet, UserAgentStylesheets, CSSRuleIteratorExt, Origin}; use style::thread_state; use style::timer::Timer; use style::workqueue::WorkQueue; @@ -118,6 +122,7 @@ use util::geometry::max_rect; use util::ipc::OptionalIpcSender; use util::opts; use util::prefs::PREFS; +use util::resource_files::read_resource_file; use util::thread; /// The number of screens we have to traverse before we decide to generate new display lists. @@ -417,7 +422,7 @@ impl LayoutThread { let stylist = Arc::new(Stylist::new(device)); let outstanding_web_fonts_counter = Arc::new(AtomicUsize::new(0)); - for stylesheet in &*USER_OR_USER_AGENT_STYLESHEETS { + for stylesheet in &*UA_STYLESHEETS.user_or_user_agent_stylesheets { add_font_face_rules(stylesheet, &stylist.device, &font_cache_thread, @@ -1132,6 +1137,7 @@ impl LayoutThread { // If the entire flow tree is invalid, then it will be reflowed anyhow. needs_dirtying |= Arc::get_mut(&mut rw_data.stylist).unwrap().update(&data.document_stylesheets, + Some(&*UA_STYLESHEETS), data.stylesheets_changed); let needs_reflow = viewport_size_changed && !needs_dirtying; unsafe { @@ -1575,3 +1581,49 @@ fn get_root_flow_background_color(flow: &mut Flow) -> AzColor { .resolve_color(kid_block_flow.fragment.style.get_background().background_color) .to_gfx_color() } + +fn get_ua_stylesheets() -> Result<UserAgentStylesheets, &'static str> { + fn parse_ua_stylesheet(filename: &'static str) -> Result<Stylesheet, &'static str> { + let res = try!(read_resource_file(filename).map_err(|_| filename)); + Ok(Stylesheet::from_bytes( + &res, + Url::parse(&format!("chrome://resources/{:?}", filename)).unwrap(), + None, + None, + Origin::UserAgent, + Box::new(StdoutErrorReporter), + ParserContextExtraData::default())) + } + + let mut user_or_user_agent_stylesheets = vec!(); + // FIXME: presentational-hints.css should be at author origin with zero specificity. + // (Does it make a difference?) + for &filename in &["user-agent.css", "servo.css", "presentational-hints.css"] { + user_or_user_agent_stylesheets.push(try!(parse_ua_stylesheet(filename))); + } + for &(ref contents, ref url) in &opts::get().user_stylesheets { + user_or_user_agent_stylesheets.push(Stylesheet::from_bytes( + &contents, url.clone(), None, None, Origin::User, Box::new(StdoutErrorReporter), + ParserContextExtraData::default())); + } + + let quirks_mode_stylesheet = try!(parse_ua_stylesheet("quirks-mode.css")); + + Ok(UserAgentStylesheets { + user_or_user_agent_stylesheets: user_or_user_agent_stylesheets, + quirks_mode_stylesheet: quirks_mode_stylesheet, + }) +} + + +lazy_static! { + static ref UA_STYLESHEETS: UserAgentStylesheets = { + match get_ua_stylesheets() { + Ok(stylesheets) => stylesheets, + Err(filename) => { + error!("Failed to load UA stylesheet {}!", filename); + process::exit(1); + } + } + }; +} diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock index 4bdc0dab852..8e38d89fc98 100644 --- a/components/servo/Cargo.lock +++ b/components/servo/Cargo.lock @@ -1199,6 +1199,7 @@ dependencies = [ "ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "layout 0.0.1", "layout_traits 0.0.1", + "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", "net_traits 0.0.1", diff --git a/components/style/gecko_selector_impl.rs b/components/style/gecko_selector_impl.rs index 611e79eddcc..86de0ad4938 100644 --- a/components/style/gecko_selector_impl.rs +++ b/components/style/gecko_selector_impl.rs @@ -9,7 +9,6 @@ use selector_impl::{attr_exists_selector_is_shareable, attr_equals_selector_is_s use selectors::parser::{ParserContext, SelectorImpl, AttrSelector}; use std::fmt; use string_cache::{Atom, WeakAtom, Namespace, WeakNamespace}; -use stylesheets::Stylesheet; #[derive(Debug, Clone, PartialEq, Eq)] pub struct GeckoSelectorImpl; @@ -252,14 +251,4 @@ impl GeckoSelectorImpl { pub fn pseudo_class_state_flag(pc: &NonTSPseudoClass) -> ElementState { pc.state_flag() } - - #[inline] - pub fn get_user_or_user_agent_stylesheets() -> &'static [Stylesheet] { - &[] - } - - #[inline] - pub fn get_quirks_mode_stylesheet() -> Option<&'static Stylesheet> { - None - } } diff --git a/components/style/selector_matching.rs b/components/style/selector_matching.rs index a6457ccf574..66f533d174b 100644 --- a/components/style/selector_matching.rs +++ b/components/style/selector_matching.rs @@ -29,7 +29,7 @@ use std::slice; use std::sync::Arc; use string_cache::Atom; use style_traits::viewport::ViewportConstraints; -use stylesheets::{CSSRule, CSSRuleIteratorExt, Origin, Stylesheet}; +use stylesheets::{CSSRule, CSSRuleIteratorExt, Origin, Stylesheet, UserAgentStylesheets}; use viewport::{MaybeNew, ViewportRuleCascade}; pub type FnvHashMap<K, V> = HashMap<K, V, BuildHasherDefault<::fnv::FnvHasher>>; @@ -116,7 +116,10 @@ impl Stylist { stylist } - pub fn update(&mut self, doc_stylesheets: &[Arc<Stylesheet>], stylesheets_changed: bool) -> bool { + pub fn update(&mut self, + doc_stylesheets: &[Arc<Stylesheet>], + ua_stylesheets: Option<&UserAgentStylesheets>, + stylesheets_changed: bool) -> bool { if !(self.is_device_dirty || stylesheets_changed) { return false; } @@ -135,13 +138,13 @@ impl Stylist { self.sibling_affecting_selectors.clear(); self.non_common_style_affecting_attributes_selectors.clear(); - for ref stylesheet in TheSelectorImpl::get_user_or_user_agent_stylesheets().iter() { - self.add_stylesheet(&stylesheet); - } + if let Some(ua_stylesheets) = ua_stylesheets { + for stylesheet in &ua_stylesheets.user_or_user_agent_stylesheets { + self.add_stylesheet(&stylesheet); + } - if self.quirks_mode { - if let Some(s) = TheSelectorImpl::get_quirks_mode_stylesheet() { - self.add_stylesheet(s); + if self.quirks_mode { + self.add_stylesheet(&ua_stylesheets.quirks_mode_stylesheet); } } diff --git a/components/style/servo_selector_impl.rs b/components/style/servo_selector_impl.rs index f69b1cb9e12..81079f4a416 100644 --- a/components/style/servo_selector_impl.rs +++ b/components/style/servo_selector_impl.rs @@ -5,20 +5,13 @@ use attr::{AttrIdentifier, AttrValue}; use cssparser::ToCss; use element_state::ElementState; -use error_reporting::StdoutErrorReporter; -use parser::ParserContextExtraData; use restyle_hints::ElementSnapshot; use selector_impl::{ElementExt, PseudoElementCascadeType, TheSelectorImpl}; use selector_impl::{attr_exists_selector_is_shareable, attr_equals_selector_is_shareable}; use selectors::parser::{AttrSelector, ParserContext, SelectorImpl}; use selectors::{Element, MatchAttrGeneric}; use std::fmt; -use std::process; use string_cache::{Atom, Namespace}; -use stylesheets::{Stylesheet, Origin}; -use url::Url; -use util::opts; -use util::resource_files::read_resource_file; #[derive(Clone, Debug, PartialEq, Eq, Hash)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] @@ -240,16 +233,6 @@ impl ServoSelectorImpl { pub fn pseudo_is_before_or_after(pseudo: &PseudoElement) -> bool { pseudo.is_before_or_after() } - - #[inline] - pub fn get_user_or_user_agent_stylesheets() -> &'static [Stylesheet] { - &*USER_OR_USER_AGENT_STYLESHEETS - } - - #[inline] - pub fn get_quirks_mode_stylesheet() -> Option<&'static Stylesheet> { - Some(&*QUIRKS_MODE_STYLESHEET) - } } /// Servo's version of an element snapshot. @@ -336,57 +319,3 @@ impl<E: Element<Impl=TheSelectorImpl>> ElementExt for E { self.match_non_ts_pseudo_class(NonTSPseudoClass::AnyLink) } } - -lazy_static! { - pub static ref USER_OR_USER_AGENT_STYLESHEETS: Vec<Stylesheet> = { - let mut stylesheets = vec!(); - // FIXME: presentational-hints.css should be at author origin with zero specificity. - // (Does it make a difference?) - for &filename in &["user-agent.css", "servo.css", "presentational-hints.css"] { - match read_resource_file(filename) { - Ok(res) => { - let ua_stylesheet = Stylesheet::from_bytes( - &res, - Url::parse(&format!("chrome://resources/{:?}", filename)).unwrap(), - None, - None, - Origin::UserAgent, - Box::new(StdoutErrorReporter), - ParserContextExtraData::default()); - stylesheets.push(ua_stylesheet); - } - Err(..) => { - error!("Failed to load UA stylesheet {}!", filename); - process::exit(1); - } - } - } - for &(ref contents, ref url) in &opts::get().user_stylesheets { - stylesheets.push(Stylesheet::from_bytes( - &contents, url.clone(), None, None, Origin::User, Box::new(StdoutErrorReporter), - ParserContextExtraData::default())); - } - stylesheets - }; -} - -lazy_static! { - pub static ref QUIRKS_MODE_STYLESHEET: Stylesheet = { - match read_resource_file("quirks-mode.css") { - Ok(res) => { - Stylesheet::from_bytes( - &res, - Url::parse("chrome://resources/quirks-mode.css").unwrap(), - None, - None, - Origin::UserAgent, - Box::new(StdoutErrorReporter), - ParserContextExtraData::default()) - }, - Err(..) => { - error!("Stylist failed to load 'quirks-mode.css'!"); - process::exit(1); - } - } - }; -} diff --git a/components/style/stylesheets.rs b/components/style/stylesheets.rs index 8d234540adc..e622679fee5 100644 --- a/components/style/stylesheets.rs +++ b/components/style/stylesheets.rs @@ -54,6 +54,13 @@ pub struct Stylesheet { } +/// This structure holds the user-agent and user stylesheets. +pub struct UserAgentStylesheets { + pub user_or_user_agent_stylesheets: Vec<Stylesheet>, + pub quirks_mode_stylesheet: Stylesheet, +} + + #[derive(Debug, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub enum CSSRule { diff --git a/ports/cef/Cargo.lock b/ports/cef/Cargo.lock index 6dbc3320f5f..da5a3bc841a 100644 --- a/ports/cef/Cargo.lock +++ b/ports/cef/Cargo.lock @@ -1100,6 +1100,7 @@ dependencies = [ "ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "layout 0.0.1", "layout_traits 0.0.1", + "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", "net_traits 0.0.1", diff --git a/ports/geckolib/data.rs b/ports/geckolib/data.rs index d87baab86d1..836090bbbe5 100644 --- a/ports/geckolib/data.rs +++ b/ports/geckolib/data.rs @@ -83,7 +83,7 @@ impl PerDocumentStyleData { // need to detect the latter case and trigger a flush as well. if self.stylesheets_changed { let _ = Arc::get_mut(&mut self.stylist).unwrap() - .update(&self.stylesheets, true); + .update(&self.stylesheets, None, true); self.stylesheets_changed = false; } } |