Refactor style to be completely backend-independent

This commit refactors the style crate to be completely independent of
the actual implementation and pseudo-elements supported.

This also adds a gecko backend which introduces parsing for the
anonymous box pseudo-elements[1], although there's still no way of
querying them.

https://mxr.mozilla.org/mozilla-central/source/layout/style/nsCSSAnonBoxList.h
This commit is contained in:
Emilio Cobos Álvarez 2016-02-08 02:53:22 +01:00
parent a164176876
commit dd503dfacb
41 changed files with 767 additions and 310 deletions

View file

@ -64,7 +64,7 @@ heapsize_plugin = "0.1.2"
libc = "0.2" libc = "0.2"
log = "0.3" log = "0.3"
rustc-serialize = "0.3" rustc-serialize = "0.3"
selectors = {version = "0.4.2", features = ["heap_size"]} selectors = {version = "0.5", features = ["heap_size"]}
serde = "0.6" serde = "0.6"
serde_json = "0.5" serde_json = "0.5"
serde_macros = "0.6" serde_macros = "0.6"

View file

@ -25,8 +25,10 @@ use std::hash::BuildHasherDefault;
use std::rc::Rc; use std::rc::Rc;
use std::sync::mpsc::Sender; use std::sync::mpsc::Sender;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use style::context::{LocalStyleContext, SharedStyleContext, StyleContext}; use style::context::{LocalStyleContext, StyleContext};
use style::matching::{ApplicableDeclarationsCache, StyleSharingCandidateCache}; use style::matching::{ApplicableDeclarationsCache, StyleSharingCandidateCache};
use style::selector_impl::ServoSelectorImpl;
use style::servo::SharedStyleContext;
use url::Url; use url::Url;
use util::opts; use util::opts;
@ -104,7 +106,7 @@ pub struct LayoutContext<'a> {
cached_local_layout_context: Rc<LocalLayoutContext>, cached_local_layout_context: Rc<LocalLayoutContext>,
} }
impl<'a> StyleContext<'a> for LayoutContext<'a> { impl<'a> StyleContext<'a, ServoSelectorImpl> for LayoutContext<'a> {
fn shared_context(&self) -> &'a SharedStyleContext { fn shared_context(&self) -> &'a SharedStyleContext {
&self.shared.style_context &self.shared.style_context
} }

View file

@ -4,7 +4,7 @@
use construct::ConstructionResult; use construct::ConstructionResult;
use incremental::RestyleDamage; use incremental::RestyleDamage;
use style::data::PrivateStyleData; use style::servo::PrivateStyleData;
/// Data that layout associates with a node. /// Data that layout associates with a node.
pub struct PrivateLayoutData { pub struct PrivateLayoutData {

View file

@ -62,13 +62,15 @@ use std::sync::mpsc::{channel, Sender, Receiver};
use std::sync::{Arc, Mutex, MutexGuard, RwLock}; use std::sync::{Arc, Mutex, MutexGuard, RwLock};
use style::animation::Animation; use style::animation::Animation;
use style::computed_values::{filter, mix_blend_mode}; use style::computed_values::{filter, mix_blend_mode};
use style::context::{SharedStyleContext, StylistWrapper, ReflowGoal}; use style::context::{ReflowGoal, StylistWrapper};
use style::dom::{TDocument, TElement, TNode}; use style::dom::{TDocument, TElement, TNode};
use style::error_reporting::ParseErrorReporter; use style::error_reporting::ParseErrorReporter;
use style::media_queries::{Device, MediaType}; use style::media_queries::{Device, MediaType};
use style::parallel::WorkQueueData; use style::parallel::WorkQueueData;
use style::selector_matching::{Stylist, USER_OR_USER_AGENT_STYLESHEETS}; use style::selector_impl::ServoSelectorImpl;
use style::stylesheets::{CSSRuleIteratorExt, Stylesheet}; use style::selector_matching::USER_OR_USER_AGENT_STYLESHEETS;
use style::servo::{SharedStyleContext, Stylesheet, Stylist};
use style::stylesheets::CSSRuleIteratorExt;
use traversal::RecalcStyleAndConstructFlows; use traversal::RecalcStyleAndConstructFlows;
use url::Url; use url::Url;
use util::geometry::MAX_RECT; use util::geometry::MAX_RECT;
@ -477,7 +479,7 @@ impl LayoutThread {
style_context: SharedStyleContext { style_context: SharedStyleContext {
viewport_size: self.viewport_size.clone(), viewport_size: self.viewport_size.clone(),
screen_size_changed: screen_size_changed, screen_size_changed: screen_size_changed,
stylist: StylistWrapper(&*rw_data.stylist), stylist: StylistWrapper::<ServoSelectorImpl>(&*rw_data.stylist),
generation: self.generation, generation: self.generation,
goal: goal, goal: goal,
new_animations_sender: Mutex::new(self.new_animations_sender.clone()), new_animations_sender: Mutex::new(self.new_animations_sender.clone()),

View file

@ -16,6 +16,7 @@ use incremental::{BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, RestyleDam
use std::mem; use std::mem;
use style::context::{StyleContext, ReflowGoal}; use style::context::{StyleContext, ReflowGoal};
use style::matching::MatchMethods; use style::matching::MatchMethods;
use style::selector_impl::ServoSelectorImpl;
use style::traversal::{DomTraversalContext, STYLE_BLOOM}; use style::traversal::{DomTraversalContext, STYLE_BLOOM};
use style::traversal::{put_thread_local_bloom_filter, recalc_style_at}; use style::traversal::{put_thread_local_bloom_filter, recalc_style_at};
use util::opts; use util::opts;
@ -27,7 +28,8 @@ pub struct RecalcStyleAndConstructFlows<'lc> {
root: OpaqueNode, root: OpaqueNode,
} }
impl<'lc, 'ln, N: LayoutNode<'ln>> DomTraversalContext<'ln, N> for RecalcStyleAndConstructFlows<'lc> { impl<'lc, 'ln, N: LayoutNode<'ln>> DomTraversalContext<'ln, N> for RecalcStyleAndConstructFlows<'lc>
where N::ConcreteElement: ::selectors::Element<Impl=ServoSelectorImpl> {
type SharedContext = SharedLayoutContext; type SharedContext = SharedLayoutContext;
#[allow(unsafe_code)] #[allow(unsafe_code)]
fn new<'a>(shared: &'a Self::SharedContext, root: OpaqueNode) -> Self { fn new<'a>(shared: &'a Self::SharedContext, root: OpaqueNode) -> Self {

View file

@ -64,13 +64,13 @@ use std::sync::Arc;
use string_cache::{Atom, Namespace}; use string_cache::{Atom, Namespace};
use style::computed_values::content::ContentItem; use style::computed_values::content::ContentItem;
use style::computed_values::{content, display}; use style::computed_values::{content, display};
use style::data::PrivateStyleData;
use style::dom::{TDocument, TElement, TNode, UnsafeNode}; use style::dom::{TDocument, TElement, TNode, UnsafeNode};
use style::element_state::*; use style::element_state::*;
use style::properties::ComputedValues; use style::properties::ComputedValues;
use style::properties::{PropertyDeclaration, PropertyDeclarationBlock}; use style::properties::{PropertyDeclaration, PropertyDeclarationBlock};
use style::restyle_hints::ElementSnapshot; use style::restyle_hints::ElementSnapshot;
use style::selector_impl::{NonTSPseudoClass, ServoSelectorImpl}; use style::selector_impl::{NonTSPseudoClass, PseudoElement, ServoSelectorImpl};
use style::servo::PrivateStyleData;
use url::Url; use url::Url;
use util::str::{is_whitespace, search_index}; use util::str::{is_whitespace, search_index};
@ -664,14 +664,18 @@ pub trait ThreadSafeLayoutNode<'ln> : Clone + Copy + Sized {
#[inline] #[inline]
fn get_before_pseudo(&self) -> Option<Self> { fn get_before_pseudo(&self) -> Option<Self> {
self.borrow_layout_data().unwrap().style_data.before_style.as_ref().map(|style| { self.borrow_layout_data().unwrap()
.style_data.per_pseudo
.get(&PseudoElement::Before).unwrap_or(&None).as_ref().map(|style| {
self.with_pseudo(PseudoElementType::Before(style.get_box().display)) self.with_pseudo(PseudoElementType::Before(style.get_box().display))
}) })
} }
#[inline] #[inline]
fn get_after_pseudo(&self) -> Option<Self> { fn get_after_pseudo(&self) -> Option<Self> {
self.borrow_layout_data().unwrap().style_data.after_style.as_ref().map(|style| { self.borrow_layout_data().unwrap()
.style_data.per_pseudo
.get(&PseudoElement::After).unwrap_or(&None).as_ref().map(|style| {
self.with_pseudo(PseudoElementType::After(style.get_box().display)) self.with_pseudo(PseudoElementType::After(style.get_box().display))
}) })
} }
@ -696,8 +700,8 @@ pub trait ThreadSafeLayoutNode<'ln> : Clone + Copy + Sized {
fn style(&self) -> Ref<Arc<ComputedValues>> { fn style(&self) -> Ref<Arc<ComputedValues>> {
Ref::map(self.borrow_layout_data().unwrap(), |data| { Ref::map(self.borrow_layout_data().unwrap(), |data| {
let style = match self.get_pseudo_element_type() { let style = match self.get_pseudo_element_type() {
PseudoElementType::Before(_) => &data.style_data.before_style, PseudoElementType::Before(_) => data.style_data.per_pseudo.get(&PseudoElement::Before).unwrap(),
PseudoElementType::After(_) => &data.style_data.after_style, PseudoElementType::After(_) => data.style_data.per_pseudo.get(&PseudoElement::After).unwrap(),
PseudoElementType::Normal => &data.style_data.style, PseudoElementType::Normal => &data.style_data.style,
}; };
style.as_ref().unwrap() style.as_ref().unwrap()
@ -711,8 +715,18 @@ pub trait ThreadSafeLayoutNode<'ln> : Clone + Copy + Sized {
let mut data = self.mutate_layout_data().unwrap(); let mut data = self.mutate_layout_data().unwrap();
let style = let style =
match self.get_pseudo_element_type() { match self.get_pseudo_element_type() {
PseudoElementType::Before(_) => &mut data.style_data.before_style, PseudoElementType::Before(_) => {
PseudoElementType::After (_) => &mut data.style_data.after_style, match data.style_data.per_pseudo.get_mut(&PseudoElement::Before) {
None => return,
Some(style) => style,
}
}
PseudoElementType::After(_) => {
match data.style_data.per_pseudo.get_mut(&PseudoElement::After) {
None => return,
Some(style) => style,
}
}
PseudoElementType::Normal => &mut data.style_data.style, PseudoElementType::Normal => &mut data.style_data.style,
}; };
@ -934,10 +948,11 @@ impl<'ln> ThreadSafeLayoutNode<'ln> for ServoThreadSafeLayoutNode<'ln> {
let data = &self.borrow_layout_data().unwrap().style_data; let data = &self.borrow_layout_data().unwrap().style_data;
let style = if self.pseudo.is_before() { let style = if self.pseudo.is_before() {
&data.before_style data.per_pseudo.get(&PseudoElement::Before).unwrap()
} else { } else {
&data.after_style data.per_pseudo.get(&PseudoElement::After).unwrap()
}; };
return match style.as_ref().unwrap().get_box().content { return match style.as_ref().unwrap().get_box().content {
content::T::Content(ref value) if !value.is_empty() => { content::T::Content(ref value) if !value.is_empty() => {
TextContent::GeneratedContent((*value).clone()) TextContent::GeneratedContent((*value).clone())

View file

@ -81,7 +81,7 @@ num = "0.1.24"
rand = "0.3" rand = "0.3"
ref_slice = "0.1.0" ref_slice = "0.1.0"
rustc-serialize = "0.3" rustc-serialize = "0.3"
selectors = {version = "0.4.2", features = ["heap_size"]} selectors = {version = "0.5", features = ["heap_size"]}
serde = "0.6" serde = "0.6"
smallvec = "0.1" smallvec = "0.1"
string_cache = {version = "0.2.9", features = ["heap_size", "unstable"]} string_cache = {version = "0.2.9", features = ["heap_size", "unstable"]}

View file

@ -105,7 +105,7 @@ use std::sync::Arc;
use string_cache::{Atom, QualName}; use string_cache::{Atom, QualName};
use style::context::ReflowGoal; use style::context::ReflowGoal;
use style::restyle_hints::ElementSnapshot; use style::restyle_hints::ElementSnapshot;
use style::stylesheets::Stylesheet; use style::servo::Stylesheet;
use time; use time;
use url::{Host, Url}; use url::{Host, Url};
use util::str::{DOMString, split_html_space_chars, str_join}; use util::str::{DOMString, split_html_space_chars, str_join};

View file

@ -36,7 +36,8 @@ use std::mem;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use string_cache::Atom; use string_cache::Atom;
use style::media_queries::{MediaQueryList, parse_media_query_list}; use style::media_queries::{MediaQueryList, parse_media_query_list};
use style::stylesheets::{Origin, Stylesheet}; use style::servo::Stylesheet;
use style::stylesheets::Origin;
use url::Url; use url::Url;
use util::str::{DOMString, HTML_SPACE_CHARACTERS}; use util::str::{DOMString, HTML_SPACE_CHARACTERS};

View file

@ -15,7 +15,8 @@ use dom::virtualmethods::VirtualMethods;
use std::ascii::AsciiExt; use std::ascii::AsciiExt;
use std::sync::Arc; use std::sync::Arc;
use string_cache::Atom; use string_cache::Atom;
use style::stylesheets::{CSSRule, Origin, Stylesheet}; use style::servo::Stylesheet;
use style::stylesheets::{CSSRule, Origin};
use style::viewport::ViewportRule; use style::viewport::ViewportRule;
use util::str::{DOMString, HTML_SPACE_CHARACTERS}; use util::str::{DOMString, HTML_SPACE_CHARACTERS};

View file

@ -17,7 +17,8 @@ use layout_interface::{LayoutChan, Msg};
use std::sync::Arc; use std::sync::Arc;
use string_cache::Atom; use string_cache::Atom;
use style::media_queries::parse_media_query_list; use style::media_queries::parse_media_query_list;
use style::stylesheets::{Origin, Stylesheet}; use style::servo::Stylesheet;
use style::stylesheets::Origin;
use util::str::DOMString; use util::str::DOMString;
#[dom_struct] #[dom_struct]

View file

@ -24,7 +24,7 @@ use std::sync::mpsc::{Receiver, Sender, channel};
use string_cache::Atom; use string_cache::Atom;
use style::context::ReflowGoal; use style::context::ReflowGoal;
use style::selector_impl::PseudoElement; use style::selector_impl::PseudoElement;
use style::stylesheets::Stylesheet; use style::servo::Stylesheet;
use url::Url; use url::Url;
use util::ipc::OptionalOpaqueIpcSender; use util::ipc::OptionalOpaqueIpcSender;

View file

@ -1003,7 +1003,7 @@ dependencies = [
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"script 0.0.1", "script 0.0.1",
"script_traits 0.0.1", "script_traits 0.0.1",
"selectors 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "selectors 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1590,7 +1590,7 @@ dependencies = [
"ref_slice 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "ref_slice 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"script_traits 0.0.1", "script_traits 0.0.1",
"selectors 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "selectors 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"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.9 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1641,7 +1641,7 @@ dependencies = [
[[package]] [[package]]
name = "selectors" name = "selectors"
version = "0.4.2" version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1850,7 +1850,7 @@ dependencies = [
"num 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "num 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
"plugins 0.0.1", "plugins 0.0.1",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"selectors 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "selectors 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"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)",
@ -1870,7 +1870,7 @@ dependencies = [
"euclid 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1", "msg 0.0.1",
"plugins 0.0.1", "plugins 0.0.1",
"selectors 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "selectors 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
"style 0.0.1", "style 0.0.1",
"style_traits 0.0.1", "style_traits 0.0.1",
@ -1891,7 +1891,7 @@ dependencies = [
"num 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "num 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
"plugins 0.0.1", "plugins 0.0.1",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"selectors 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "selectors 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "url 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2049,7 +2049,7 @@ dependencies = [
"plugins 0.0.1", "plugins 0.0.1",
"rand 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"selectors 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "selectors 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"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)",

View file

@ -32,7 +32,7 @@ log = "0.3"
matches = "0.1" matches = "0.1"
num = "0.1.24" num = "0.1.24"
rustc-serialize = "0.3" rustc-serialize = "0.3"
selectors = {version = "0.4.2", features = ["heap_size", "unstable"]} selectors = {version = "0.5", features = ["heap_size", "unstable"]}
serde = "0.6" serde = "0.6"
serde_macros = "0.6" serde_macros = "0.6"
smallvec = "0.1" smallvec = "0.1"

View file

@ -8,19 +8,20 @@ use dom::OpaqueNode;
use error_reporting::ParseErrorReporter; use error_reporting::ParseErrorReporter;
use euclid::Size2D; use euclid::Size2D;
use matching::{ApplicableDeclarationsCache, StyleSharingCandidateCache}; use matching::{ApplicableDeclarationsCache, StyleSharingCandidateCache};
use selector_impl::SelectorImplExt;
use selector_matching::Stylist; use selector_matching::Stylist;
use std::cell::RefCell; use std::cell::RefCell;
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::mpsc::Sender; use std::sync::mpsc::Sender;
use std::sync::{Arc, Mutex, RwLock}; use std::sync::{Arc, Mutex, RwLock};
pub struct StylistWrapper(pub *const Stylist); pub struct StylistWrapper<Impl: SelectorImplExt>(pub *const Stylist<Impl>);
// FIXME(#6569) This implementation is unsound. // FIXME(#6569) This implementation is unsound.
#[allow(unsafe_code)] #[allow(unsafe_code)]
unsafe impl Sync for StylistWrapper {} unsafe impl<Impl: SelectorImplExt> Sync for StylistWrapper<Impl> {}
pub struct SharedStyleContext { pub struct SharedStyleContext<Impl: SelectorImplExt> {
/// The current viewport size. /// The current viewport size.
pub viewport_size: Size2D<Au>, pub viewport_size: Size2D<Au>,
@ -30,7 +31,7 @@ pub struct SharedStyleContext {
/// The CSS selector stylist. /// The CSS selector stylist.
/// ///
/// FIXME(#2604): Make this no longer an unsafe pointer once we have fast `RWArc`s. /// FIXME(#2604): Make this no longer an unsafe pointer once we have fast `RWArc`s.
pub stylist: StylistWrapper, pub stylist: StylistWrapper<Impl>,
/// Starts at zero, and increased by one every time a layout completes. /// Starts at zero, and increased by one every time a layout completes.
/// This can be used to easily check for invalid stale data. /// This can be used to easily check for invalid stale data.
@ -58,8 +59,9 @@ pub struct LocalStyleContext {
pub style_sharing_candidate_cache: RefCell<StyleSharingCandidateCache>, pub style_sharing_candidate_cache: RefCell<StyleSharingCandidateCache>,
} }
pub trait StyleContext<'a> { pub trait StyleContext<'a, Impl: SelectorImplExt> {
fn shared_context(&self) -> &'a SharedStyleContext;
fn shared_context(&self) -> &'a SharedStyleContext<Impl>;
fn local_context(&self) -> &LocalStyleContext; fn local_context(&self) -> &LocalStyleContext;
} }

View file

@ -3,29 +3,27 @@
* 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 properties::ComputedValues; use properties::ComputedValues;
use selectors::parser::SelectorImpl;
use std::collections::HashMap;
use std::sync::Arc; use std::sync::Arc;
use std::sync::atomic::AtomicIsize; use std::sync::atomic::AtomicIsize;
pub struct PrivateStyleData { pub struct PrivateStyleData<Impl: SelectorImpl> {
/// The results of CSS styling for this node. /// The results of CSS styling for this node.
pub style: Option<Arc<ComputedValues>>, pub style: Option<Arc<ComputedValues>>,
/// The results of CSS styling for this node's `before` pseudo-element, if any. /// The results of CSS styling for each pseudo-element (if any).
pub before_style: Option<Arc<ComputedValues>>, pub per_pseudo: HashMap<Impl::PseudoElement, Option<Arc<ComputedValues>>>,
/// The results of CSS styling for this node's `after` pseudo-element, if any.
pub after_style: Option<Arc<ComputedValues>>,
/// Information needed during parallel traversals. /// Information needed during parallel traversals.
pub parallel: DomParallelInfo, pub parallel: DomParallelInfo,
} }
impl PrivateStyleData { impl<Impl: SelectorImpl> PrivateStyleData<Impl> {
pub fn new() -> PrivateStyleData { pub fn new() -> PrivateStyleData<Impl> {
PrivateStyleData { PrivateStyleData {
style: None, style: None,
before_style: None, per_pseudo: HashMap::new(),
after_style: None,
parallel: DomParallelInfo::new(), parallel: DomParallelInfo::new(),
} }
} }

View file

@ -8,7 +8,8 @@ use data::PrivateStyleData;
use element_state::ElementState; use element_state::ElementState;
use properties::{ComputedValues, PropertyDeclaration, PropertyDeclarationBlock}; use properties::{ComputedValues, PropertyDeclaration, PropertyDeclarationBlock};
use restyle_hints::{ElementSnapshot, RESTYLE_DESCENDANTS, RESTYLE_LATER_SIBLINGS, RESTYLE_SELF, RestyleHint}; use restyle_hints::{ElementSnapshot, RESTYLE_DESCENDANTS, RESTYLE_LATER_SIBLINGS, RESTYLE_SELF, RestyleHint};
use selector_impl::ServoSelectorImpl; use selector_impl::ElementExt;
use selectors::Element;
use selectors::matching::DeclarationBlock; use selectors::matching::DeclarationBlock;
use smallvec::VecLike; use smallvec::VecLike;
use std::cell::{Ref, RefMut}; use std::cell::{Ref, RefMut};
@ -136,15 +137,18 @@ pub trait TNode<'ln> : Sized + Copy + Clone {
/// Borrows the PrivateStyleData without checks. /// Borrows the PrivateStyleData without checks.
#[inline(always)] #[inline(always)]
unsafe fn borrow_data_unchecked(&self) -> Option<*const PrivateStyleData>; unsafe fn borrow_data_unchecked(&self)
-> Option<*const PrivateStyleData<<Self::ConcreteElement as Element>::Impl>>;
/// Borrows the PrivateStyleData immutably. Fails on a conflicting borrow. /// Borrows the PrivateStyleData immutably. Fails on a conflicting borrow.
#[inline(always)] #[inline(always)]
fn borrow_data(&self) -> Option<Ref<PrivateStyleData>>; fn borrow_data(&self)
-> Option<Ref<PrivateStyleData<<Self::ConcreteElement as Element>::Impl>>>;
/// Borrows the PrivateStyleData mutably. Fails on a conflicting borrow. /// Borrows the PrivateStyleData mutably. Fails on a conflicting borrow.
#[inline(always)] #[inline(always)]
fn mutate_data(&self) -> Option<RefMut<PrivateStyleData>>; fn mutate_data(&self)
-> Option<RefMut<PrivateStyleData<<Self::ConcreteElement as Element>::Impl>>>;
/// Get the description of how to account for recent style changes. /// Get the description of how to account for recent style changes.
fn restyle_damage(self) -> Self::ConcreteRestyleDamage; fn restyle_damage(self) -> Self::ConcreteRestyleDamage;
@ -165,7 +169,7 @@ pub trait TNode<'ln> : Sized + Copy + Clone {
/// Returns the style results for the given node. If CSS selector matching /// Returns the style results for the given node. If CSS selector matching
/// has not yet been performed, fails. /// has not yet been performed, fails.
fn style(&self) -> Ref<Arc<ComputedValues>> { fn style(&'ln self) -> Ref<Arc<ComputedValues>> {
Ref::map(self.borrow_data().unwrap(), |data| data.style.as_ref().unwrap()) Ref::map(self.borrow_data().unwrap(), |data| data.style.as_ref().unwrap())
} }
@ -186,7 +190,7 @@ pub trait TDocument<'ld> : Sized + Copy + Clone {
fn drain_modified_elements(&self) -> Vec<(Self::ConcreteElement, ElementSnapshot)>; fn drain_modified_elements(&self) -> Vec<(Self::ConcreteElement, ElementSnapshot)>;
} }
pub trait TElement<'le> : Sized + Copy + Clone + ::selectors::Element<Impl=ServoSelectorImpl> { pub trait TElement<'le> : Sized + Copy + Clone + ElementExt {
type ConcreteNode: TNode<'le, ConcreteElement = Self, ConcreteDocument = Self::ConcreteDocument>; type ConcreteNode: TNode<'le, ConcreteElement = Self, ConcreteDocument = Self::ConcreteDocument>;
type ConcreteDocument: TDocument<'le, ConcreteNode = Self::ConcreteNode, ConcreteElement = Self>; type ConcreteDocument: TDocument<'le, ConcreteNode = Self::ConcreteNode, ConcreteElement = Self>;

View file

@ -62,6 +62,7 @@ pub mod restyle_hints;
pub mod selector_impl; pub mod selector_impl;
pub mod selector_matching; pub mod selector_matching;
pub mod sequential; pub mod sequential;
pub mod servo;
pub mod stylesheets; pub mod stylesheets;
pub mod traversal; pub mod traversal;
#[macro_use] #[macro_use]

View file

@ -9,13 +9,14 @@ use context::SharedStyleContext;
use data::PrivateStyleData; use data::PrivateStyleData;
use dom::{TElement, TNode, TRestyleDamage}; use dom::{TElement, TNode, TRestyleDamage};
use properties::{ComputedValues, PropertyDeclaration, cascade}; use properties::{ComputedValues, PropertyDeclaration, cascade};
use selector_impl::{NonTSPseudoClass, PseudoElement}; use selector_impl::SelectorImplExt;
use selector_matching::{DeclarationBlock, Stylist}; use selector_matching::{DeclarationBlock, Stylist};
use selectors::Element; use selectors::Element;
use selectors::bloom::BloomFilter; use selectors::bloom::BloomFilter;
use selectors::matching::{CommonStyleAffectingAttributeMode, CommonStyleAffectingAttributes}; use selectors::matching::{CommonStyleAffectingAttributeMode, CommonStyleAffectingAttributes};
use selectors::matching::{common_style_affecting_attributes, rare_style_affecting_attributes}; use selectors::matching::{common_style_affecting_attributes, rare_style_affecting_attributes};
use smallvec::SmallVec; use smallvec::SmallVec;
use std::collections::HashMap;
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
use std::slice::Iter; use std::slice::Iter;
use std::sync::mpsc::Sender; use std::sync::mpsc::Sender;
@ -51,23 +52,27 @@ fn create_common_style_affecting_attributes_from_element<'le, E: TElement<'le>>(
flags flags
} }
pub struct ApplicableDeclarations { pub struct ApplicableDeclarations<Impl: SelectorImplExt> {
pub normal: SmallVec<[DeclarationBlock; 16]>, pub normal: SmallVec<[DeclarationBlock; 16]>,
pub before: Vec<DeclarationBlock>, pub per_pseudo: HashMap<Impl::PseudoElement, Vec<DeclarationBlock>>,
pub after: Vec<DeclarationBlock>,
/// Whether the `normal` declarations are shareable with other nodes. /// Whether the `normal` declarations are shareable with other nodes.
pub normal_shareable: bool, pub normal_shareable: bool,
} }
impl ApplicableDeclarations { impl<Impl: SelectorImplExt> ApplicableDeclarations<Impl> {
pub fn new() -> ApplicableDeclarations { pub fn new() -> ApplicableDeclarations<Impl> {
ApplicableDeclarations { let mut applicable_declarations = ApplicableDeclarations {
normal: SmallVec::new(), normal: SmallVec::new(),
before: Vec::new(), per_pseudo: HashMap::new(),
after: Vec::new(),
normal_shareable: false, normal_shareable: false,
} };
Impl::each_eagerly_cascaded_pseudo_element(|pseudo| {
applicable_declarations.per_pseudo.insert(pseudo, vec![]);
});
applicable_declarations
} }
} }
@ -246,7 +251,7 @@ impl StyleSharingCandidate {
local_name: element.get_local_name().clone(), local_name: element.get_local_name().clone(),
class: element.get_attr(&ns!(), &atom!("class")) class: element.get_attr(&ns!(), &atom!("class"))
.map(|string| string.to_owned()), .map(|string| string.to_owned()),
link: element.match_non_ts_pseudo_class(NonTSPseudoClass::AnyLink), link: element.is_link(),
namespace: (*element.get_namespace()).clone(), namespace: (*element.get_namespace()).clone(),
common_style_affecting_attributes: common_style_affecting_attributes:
create_common_style_affecting_attributes_from_element::<'le, E>(&element) create_common_style_affecting_attributes_from_element::<'le, E>(&element)
@ -314,7 +319,7 @@ impl StyleSharingCandidate {
} }
} }
if element.match_non_ts_pseudo_class(NonTSPseudoClass::AnyLink) != self.link { if element.is_link() != self.link {
return false return false
} }
@ -359,9 +364,10 @@ pub enum StyleSharingResult<ConcreteRestyleDamage: TRestyleDamage> {
StyleWasShared(usize, ConcreteRestyleDamage), StyleWasShared(usize, ConcreteRestyleDamage),
} }
trait PrivateMatchMethods<'ln>: TNode<'ln> { trait PrivateMatchMethods<'ln>: TNode<'ln>
where <Self::ConcreteElement as Element>::Impl: SelectorImplExt {
fn cascade_node_pseudo_element(&self, fn cascade_node_pseudo_element(&self,
context: &SharedStyleContext, context: &SharedStyleContext<<Self::ConcreteElement as Element>::Impl>,
parent_style: Option<&Arc<ComputedValues>>, parent_style: Option<&Arc<ComputedValues>>,
applicable_declarations: &[DeclarationBlock], applicable_declarations: &[DeclarationBlock],
style: &mut Option<Arc<ComputedValues>>, style: &mut Option<Arc<ComputedValues>>,
@ -434,7 +440,7 @@ trait PrivateMatchMethods<'ln>: TNode<'ln> {
} }
fn update_animations_for_cascade(&self, fn update_animations_for_cascade(&self,
context: &SharedStyleContext, context: &SharedStyleContext<<Self::ConcreteElement as Element>::Impl>,
style: &mut Option<Arc<ComputedValues>>) style: &mut Option<Arc<ComputedValues>>)
-> bool { -> bool {
let style = match *style { let style = match *style {
@ -478,7 +484,8 @@ trait PrivateMatchMethods<'ln>: TNode<'ln> {
} }
} }
impl<'ln, N: TNode<'ln>> PrivateMatchMethods<'ln> for N {} impl<'ln, N: TNode<'ln>> PrivateMatchMethods<'ln> for N
where <N::ConcreteElement as Element>::Impl: SelectorImplExt {}
trait PrivateElementMatchMethods<'le>: TElement<'le> { trait PrivateElementMatchMethods<'le>: TElement<'le> {
fn share_style_with_candidate_if_possible(&self, fn share_style_with_candidate_if_possible(&self,
@ -490,7 +497,7 @@ trait PrivateElementMatchMethods<'le>: TElement<'le> {
Some(_) | None => return None, Some(_) | None => return None,
}; };
let parent_data: Option<&PrivateStyleData> = unsafe { let parent_data: Option<&PrivateStyleData<_>> = unsafe {
parent_node.borrow_data_unchecked().map(|d| &*d) parent_node.borrow_data_unchecked().map(|d| &*d)
}; };
@ -512,11 +519,12 @@ trait PrivateElementMatchMethods<'le>: TElement<'le> {
impl<'le, E: TElement<'le>> PrivateElementMatchMethods<'le> for E {} impl<'le, E: TElement<'le>> PrivateElementMatchMethods<'le> for E {}
pub trait ElementMatchMethods<'le> : TElement<'le> { pub trait ElementMatchMethods<'le> : TElement<'le>
where Self::Impl: SelectorImplExt {
fn match_element(&self, fn match_element(&self,
stylist: &Stylist, stylist: &Stylist<Self::Impl>,
parent_bf: Option<&BloomFilter>, parent_bf: Option<&BloomFilter>,
applicable_declarations: &mut ApplicableDeclarations) applicable_declarations: &mut ApplicableDeclarations<Self::Impl>)
-> bool { -> bool {
let style_attribute = self.style_attribute().as_ref(); let style_attribute = self.style_attribute().as_ref();
@ -526,20 +534,16 @@ pub trait ElementMatchMethods<'le> : TElement<'le> {
style_attribute, style_attribute,
None, None,
&mut applicable_declarations.normal); &mut applicable_declarations.normal);
Self::Impl::each_eagerly_cascaded_pseudo_element(|pseudo| {
stylist.push_applicable_declarations(self, stylist.push_applicable_declarations(self,
parent_bf, parent_bf,
None, None,
Some(PseudoElement::Before), Some(pseudo.clone()),
&mut applicable_declarations.before); applicable_declarations.per_pseudo.entry(pseudo).or_insert(vec![]));
stylist.push_applicable_declarations(self, });
parent_bf,
None,
Some(PseudoElement::After),
&mut applicable_declarations.after);
applicable_declarations.normal_shareable && applicable_declarations.normal_shareable &&
applicable_declarations.before.is_empty() && applicable_declarations.per_pseudo.values().all(|v| v.is_empty())
applicable_declarations.after.is_empty()
} }
/// Attempts to share a style with another node. This method is unsafe because it depends on /// Attempts to share a style with another node. This method is unsafe because it depends on
@ -580,7 +584,8 @@ pub trait ElementMatchMethods<'le> : TElement<'le> {
} }
} }
impl<'le, E: TElement<'le>> ElementMatchMethods<'le> for E {} impl<'le, E: TElement<'le>> ElementMatchMethods<'le> for E
where E::Impl: SelectorImplExt {}
pub trait MatchMethods<'ln> : TNode<'ln> { pub trait MatchMethods<'ln> : TNode<'ln> {
// The below two functions are copy+paste because I can't figure out how to // The below two functions are copy+paste because I can't figure out how to
@ -632,11 +637,12 @@ pub trait MatchMethods<'ln> : TNode<'ln> {
} }
unsafe fn cascade_node(&self, unsafe fn cascade_node(&self,
context: &SharedStyleContext, context: &SharedStyleContext<<Self::ConcreteElement as Element>::Impl>,
parent: Option<Self>, parent: Option<Self>,
applicable_declarations: &ApplicableDeclarations, applicable_declarations: &ApplicableDeclarations<<Self::ConcreteElement as Element>::Impl>,
applicable_declarations_cache: &mut ApplicableDeclarationsCache, applicable_declarations_cache: &mut ApplicableDeclarationsCache,
new_animations_sender: &Mutex<Sender<Animation>>) { new_animations_sender: &Mutex<Sender<Animation>>)
where <Self::ConcreteElement as Element>::Impl: SelectorImplExt {
// Get our parent's style. This must be unsafe so that we don't touch the parent's // Get our parent's style. This must be unsafe so that we don't touch the parent's
// borrow flags. // borrow flags.
// //
@ -673,28 +679,24 @@ pub trait MatchMethods<'ln> : TNode<'ln> {
new_animations_sender, new_animations_sender,
applicable_declarations.normal_shareable, applicable_declarations.normal_shareable,
true); true);
if !applicable_declarations.before.is_empty() {
<Self::ConcreteElement as Element>::Impl::each_eagerly_cascaded_pseudo_element(|pseudo| {
let applicable_declarations_for_this_pseudo =
applicable_declarations.per_pseudo.get(&pseudo).unwrap();
if !applicable_declarations_for_this_pseudo.is_empty() {
damage = damage | self.cascade_node_pseudo_element( damage = damage | self.cascade_node_pseudo_element(
context, context,
Some(data.style.as_ref().unwrap()), Some(data.style.as_ref().unwrap()),
&*applicable_declarations.before, &*applicable_declarations_for_this_pseudo,
&mut data.before_style, data.per_pseudo.entry(pseudo).or_insert(None),
applicable_declarations_cache,
new_animations_sender,
false,
false);
}
if !applicable_declarations.after.is_empty() {
damage = damage | self.cascade_node_pseudo_element(
context,
Some(data.style.as_ref().unwrap()),
&*applicable_declarations.after,
&mut data.after_style,
applicable_declarations_cache, applicable_declarations_cache,
new_animations_sender, new_animations_sender,
false, false,
false); false);
} }
});
} }
// This method needs to borrow the data as mutable, so make sure data_ref goes out of // This method needs to borrow the data as mutable, so make sure data_ref goes out of

View file

@ -4,10 +4,10 @@
use attr::{AttrIdentifier, AttrValue}; use attr::{AttrIdentifier, AttrValue};
use element_state::*; use element_state::*;
use selector_impl::{NonTSPseudoClass, ServoSelectorImpl}; use selector_impl::SelectorImplExt;
use selectors::Element; use selectors::Element;
use selectors::matching::matches_compound_selector; use selectors::matching::matches_compound_selector;
use selectors::parser::{AttrSelector, Combinator, CompoundSelector, NamespaceConstraint, SimpleSelector}; use selectors::parser::{AttrSelector, Combinator, CompoundSelector, NamespaceConstraint, SelectorImpl, SimpleSelector};
use std::clone::Clone; use std::clone::Clone;
use std::sync::Arc; use std::sync::Arc;
use string_cache::{Atom, Namespace}; use string_cache::{Atom, Namespace};
@ -78,12 +78,16 @@ impl ElementSnapshot {
static EMPTY_SNAPSHOT: ElementSnapshot = ElementSnapshot { state: None, attrs: None }; static EMPTY_SNAPSHOT: ElementSnapshot = ElementSnapshot { state: None, attrs: None };
struct ElementWrapper<'a, E> where E: Element { struct ElementWrapper<'a, E>
where E: Element,
E::Impl: SelectorImplExt {
element: E, element: E,
snapshot: &'a ElementSnapshot, snapshot: &'a ElementSnapshot,
} }
impl<'a, E> ElementWrapper<'a, E> where E: Element { impl<'a, E> ElementWrapper<'a, E>
where E: Element,
E::Impl: SelectorImplExt {
pub fn new(el: E) -> ElementWrapper<'a, E> { pub fn new(el: E) -> ElementWrapper<'a, E> {
ElementWrapper { element: el, snapshot: &EMPTY_SNAPSHOT } ElementWrapper { element: el, snapshot: &EMPTY_SNAPSHOT }
} }
@ -93,16 +97,19 @@ impl<'a, E> ElementWrapper<'a, E> where E: Element {
} }
} }
impl<'a, E> Element for ElementWrapper<'a, E> where E: Element<Impl=ServoSelectorImpl> { impl<'a, E> Element for ElementWrapper<'a, E>
where E: Element,
E::Impl: SelectorImplExt {
type Impl = E::Impl; type Impl = E::Impl;
fn match_non_ts_pseudo_class(&self, pseudo_class: NonTSPseudoClass) -> bool { fn match_non_ts_pseudo_class(&self,
let flag = pseudo_class.state_flag(); pseudo_class: <Self::Impl as SelectorImpl>::NonTSPseudoClass) -> bool {
let flag = Self::Impl::pseudo_class_state_flag(&pseudo_class);
if flag == ElementState::empty() { if flag == ElementState::empty() {
self.element.match_non_ts_pseudo_class(pseudo_class) self.element.match_non_ts_pseudo_class(pseudo_class)
} else { } else {
match self.snapshot.state { match self.snapshot.state {
Some(s) => s.contains(pseudo_class.state_flag()), Some(s) => s.contains(flag),
None => self.element.match_non_ts_pseudo_class(pseudo_class) None => self.element.match_non_ts_pseudo_class(pseudo_class)
} }
} }
@ -177,14 +184,14 @@ impl<'a, E> Element for ElementWrapper<'a, E> where E: Element<Impl=ServoSelecto
} }
} }
fn selector_to_state(sel: &SimpleSelector<ServoSelectorImpl>) -> ElementState { fn selector_to_state<Impl: SelectorImplExt>(sel: &SimpleSelector<Impl>) -> ElementState {
match *sel { match *sel {
SimpleSelector::NonTSPseudoClass(ref pc) => pc.state_flag(), SimpleSelector::NonTSPseudoClass(ref pc) => Impl::pseudo_class_state_flag(pc),
_ => ElementState::empty(), _ => ElementState::empty(),
} }
} }
fn is_attr_selector(sel: &SimpleSelector<ServoSelectorImpl>) -> bool { fn is_attr_selector<Impl: SelectorImpl>(sel: &SimpleSelector<Impl>) -> bool {
match *sel { match *sel {
SimpleSelector::ID(_) | SimpleSelector::ID(_) |
SimpleSelector::Class(_) | SimpleSelector::Class(_) |
@ -249,25 +256,25 @@ impl Sensitivities {
// maximum effect that a given state or attribute change may have on the style of // maximum effect that a given state or attribute change may have on the style of
// elements in the document. // elements in the document.
#[derive(Debug)] #[derive(Debug)]
struct Dependency { struct Dependency<Impl: SelectorImplExt> {
selector: Arc<CompoundSelector<ServoSelectorImpl>>, selector: Arc<CompoundSelector<Impl>>,
combinator: Option<Combinator>, combinator: Option<Combinator>,
sensitivities: Sensitivities, sensitivities: Sensitivities,
} }
#[derive(Debug)] #[derive(Debug)]
pub struct DependencySet { pub struct DependencySet<Impl: SelectorImplExt> {
deps: Vec<Dependency>, deps: Vec<Dependency<Impl>>,
} }
impl DependencySet { impl<Impl: SelectorImplExt> DependencySet<Impl> {
pub fn new() -> DependencySet { pub fn new() -> DependencySet<Impl> {
DependencySet { deps: Vec::new() } DependencySet { deps: Vec::new() }
} }
pub fn compute_hint<E>(&self, el: &E, snapshot: &ElementSnapshot, current_state: ElementState) pub fn compute_hint<E>(&self, el: &E, snapshot: &ElementSnapshot, current_state: ElementState)
-> RestyleHint -> RestyleHint
where E: Element<Impl=ServoSelectorImpl> + Clone { where E: Element<Impl=Impl> + Clone {
let state_changes = snapshot.state.map_or(ElementState::empty(), |old_state| current_state ^ old_state); let state_changes = snapshot.state.map_or(ElementState::empty(), |old_state| current_state ^ old_state);
let attrs_changed = snapshot.attrs.is_some(); let attrs_changed = snapshot.attrs.is_some();
let mut hint = RestyleHint::empty(); let mut hint = RestyleHint::empty();
@ -287,7 +294,7 @@ impl DependencySet {
hint hint
} }
pub fn note_selector(&mut self, selector: Arc<CompoundSelector<ServoSelectorImpl>>) { pub fn note_selector(&mut self, selector: Arc<CompoundSelector<Impl>>) {
let mut cur = selector; let mut cur = selector;
let mut combinator: Option<Combinator> = None; let mut combinator: Option<Combinator> = None;
loop { loop {

View file

@ -2,15 +2,33 @@
* 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 element_state::ElementState; use element_state::ElementState;
use selector_matching::{USER_OR_USER_AGENT_STYLESHEETS, QUIRKS_MODE_STYLESHEET};
use selectors::Element;
use selectors::parser::{ParserContext, SelectorImpl}; use selectors::parser::{ParserContext, SelectorImpl};
use stylesheets::Stylesheet;
#[derive(Clone, Debug, PartialEq, HeapSizeOf)] pub trait ElementExt: Element {
fn is_link(&self) -> bool;
}
pub trait SelectorImplExt : SelectorImpl + Sized {
fn each_eagerly_cascaded_pseudo_element<F>(mut fun: F)
where F: FnMut(<Self as SelectorImpl>::PseudoElement);
fn pseudo_class_state_flag(pc: &Self::NonTSPseudoClass) -> ElementState;
fn get_user_or_user_agent_stylesheets() -> &'static [Stylesheet<Self>];
fn get_quirks_mode_stylesheet() -> &'static Stylesheet<Self>;
}
#[derive(Clone, Debug, PartialEq, Eq, HeapSizeOf, Hash)]
pub enum PseudoElement { pub enum PseudoElement {
Before, Before,
After, After,
} }
#[derive(Clone, Debug, PartialEq, HeapSizeOf)] #[derive(Clone, Debug, PartialEq, Eq, HeapSizeOf, Hash)]
pub enum NonTSPseudoClass { pub enum NonTSPseudoClass {
AnyLink, AnyLink,
Link, Link,
@ -82,10 +100,42 @@ impl SelectorImpl for ServoSelectorImpl {
fn parse_pseudo_element(_context: &ParserContext, fn parse_pseudo_element(_context: &ParserContext,
name: &str) -> Result<PseudoElement, ()> { name: &str) -> Result<PseudoElement, ()> {
use self::PseudoElement::*; use self::PseudoElement::*;
match_ignore_ascii_case! { name, let pseudo_element = match_ignore_ascii_case! { name,
"before" => Ok(Before), "before" => Before,
"after" => Ok(After), "after" => After,
_ => Err(()) _ => return Err(())
} };
Ok(pseudo_element)
}
}
impl<E: Element<Impl=ServoSelectorImpl>> ElementExt for E {
fn is_link(&self) -> bool {
self.match_non_ts_pseudo_class(NonTSPseudoClass::AnyLink)
}
}
impl SelectorImplExt for ServoSelectorImpl {
#[inline]
fn each_eagerly_cascaded_pseudo_element<F>(mut fun: F)
where F: FnMut(PseudoElement) {
fun(PseudoElement::Before);
fun(PseudoElement::After);
}
#[inline]
fn pseudo_class_state_flag(pc: &NonTSPseudoClass) -> ElementState {
pc.state_flag()
}
#[inline]
fn get_user_or_user_agent_stylesheets() -> &'static [Stylesheet<Self>] {
&*USER_OR_USER_AGENT_STYLESHEETS
}
#[inline]
fn get_quirks_mode_stylesheet() -> &'static Stylesheet<Self> {
&*QUIRKS_MODE_STYLESHEET
} }
} }

View file

@ -11,12 +11,14 @@ use error_reporting::{ParseErrorReporter, StdoutErrorReporter};
use media_queries::{Device, MediaType}; use media_queries::{Device, MediaType};
use properties::{PropertyDeclaration, PropertyDeclarationBlock}; use properties::{PropertyDeclaration, PropertyDeclarationBlock};
use restyle_hints::{ElementSnapshot, RestyleHint, DependencySet}; use restyle_hints::{ElementSnapshot, RestyleHint, DependencySet};
use selector_impl::{PseudoElement, ServoSelectorImpl}; use selector_impl::{SelectorImplExt, ServoSelectorImpl};
use selectors::Element; use selectors::Element;
use selectors::bloom::BloomFilter; use selectors::bloom::BloomFilter;
use selectors::matching::DeclarationBlock as GenericDeclarationBlock; use selectors::matching::DeclarationBlock as GenericDeclarationBlock;
use selectors::matching::{Rule, SelectorMap}; use selectors::matching::{Rule, SelectorMap};
use selectors::parser::SelectorImpl;
use smallvec::VecLike; use smallvec::VecLike;
use std::collections::HashMap;
use std::process; use std::process;
use std::sync::Arc; use std::sync::Arc;
use style_traits::viewport::ViewportConstraints; use style_traits::viewport::ViewportConstraints;
@ -30,7 +32,7 @@ use viewport::{MaybeNew, ViewportRuleCascade};
pub type DeclarationBlock = GenericDeclarationBlock<Vec<PropertyDeclaration>>; pub type DeclarationBlock = GenericDeclarationBlock<Vec<PropertyDeclaration>>;
lazy_static! { lazy_static! {
pub static ref USER_OR_USER_AGENT_STYLESHEETS: Vec<Stylesheet> = { pub static ref USER_OR_USER_AGENT_STYLESHEETS: Vec<Stylesheet<ServoSelectorImpl>> = {
let mut stylesheets = vec!(); let mut stylesheets = vec!();
// FIXME: presentational-hints.css should be at author origin with zero specificity. // FIXME: presentational-hints.css should be at author origin with zero specificity.
// (Does it make a difference?) // (Does it make a difference?)
@ -61,7 +63,7 @@ lazy_static! {
} }
lazy_static! { lazy_static! {
pub static ref QUIRKS_MODE_STYLESHEET: Stylesheet = { pub static ref QUIRKS_MODE_STYLESHEET: Stylesheet<ServoSelectorImpl> = {
match read_resource_file(&["quirks-mode.css"]) { match read_resource_file(&["quirks-mode.css"]) {
Ok(res) => { Ok(res) => {
Stylesheet::from_bytes( Stylesheet::from_bytes(
@ -80,7 +82,7 @@ lazy_static! {
}; };
} }
pub struct Stylist { pub struct Stylist<Impl: SelectorImplExt> {
// Device that the stylist is currently evaluating against. // Device that the stylist is currently evaluating against.
pub device: Device, pub device: Device,
@ -95,50 +97,55 @@ pub struct Stylist {
// The current selector maps, after evaluating media // The current selector maps, after evaluating media
// rules against the current device. // rules against the current device.
element_map: PerPseudoElementSelectorMap, element_map: PerPseudoElementSelectorMap<Impl>,
before_map: PerPseudoElementSelectorMap, pseudos_map: HashMap<Impl::PseudoElement, PerPseudoElementSelectorMap<Impl>>,
after_map: PerPseudoElementSelectorMap,
rules_source_order: usize, rules_source_order: usize,
// Selector dependencies used to compute restyle hints. // Selector dependencies used to compute restyle hints.
state_deps: DependencySet, state_deps: DependencySet<Impl>,
} }
impl Stylist { impl<Impl: SelectorImplExt> Stylist<Impl> {
#[inline] #[inline]
pub fn new(device: Device) -> Stylist { pub fn new(device: Device) -> Stylist<Impl> {
Stylist { let mut stylist = Stylist {
viewport_constraints: None, viewport_constraints: None,
device: device, device: device,
is_device_dirty: true, is_device_dirty: true,
quirks_mode: false, quirks_mode: false,
element_map: PerPseudoElementSelectorMap::new(), element_map: PerPseudoElementSelectorMap::new(),
before_map: PerPseudoElementSelectorMap::new(), pseudos_map: HashMap::new(),
after_map: PerPseudoElementSelectorMap::new(),
rules_source_order: 0, rules_source_order: 0,
state_deps: DependencySet::new(), state_deps: DependencySet::new(),
} };
Impl::each_eagerly_cascaded_pseudo_element(|pseudo| {
stylist.pseudos_map.insert(pseudo, PerPseudoElementSelectorMap::new());
});
// FIXME: Add iso-8859-9.css when the documents encoding is ISO-8859-8. // FIXME: Add iso-8859-9.css when the documents encoding is ISO-8859-8.
stylist
} }
pub fn update(&mut self, doc_stylesheets: &[Arc<Stylesheet>], pub fn update(&mut self, doc_stylesheets: &[Arc<Stylesheet<Impl>>],
stylesheets_changed: bool) -> bool { stylesheets_changed: bool) -> bool
where Impl: 'static {
if !(self.is_device_dirty || stylesheets_changed) { if !(self.is_device_dirty || stylesheets_changed) {
return false; return false;
} }
self.element_map = PerPseudoElementSelectorMap::new(); self.element_map = PerPseudoElementSelectorMap::new();
self.before_map = PerPseudoElementSelectorMap::new(); self.pseudos_map = HashMap::new();
self.after_map = PerPseudoElementSelectorMap::new();
self.rules_source_order = 0; self.rules_source_order = 0;
self.state_deps.clear(); self.state_deps.clear();
for ref stylesheet in USER_OR_USER_AGENT_STYLESHEETS.iter() { for ref stylesheet in Impl::get_user_or_user_agent_stylesheets().iter() {
self.add_stylesheet(&stylesheet); self.add_stylesheet(&stylesheet);
} }
if self.quirks_mode { if self.quirks_mode {
self.add_stylesheet(&QUIRKS_MODE_STYLESHEET); self.add_stylesheet(&Impl::get_quirks_mode_stylesheet());
} }
for ref stylesheet in doc_stylesheets.iter() { for ref stylesheet in doc_stylesheets.iter() {
@ -149,28 +156,12 @@ impl Stylist {
true true
} }
fn add_stylesheet(&mut self, stylesheet: &Stylesheet) { fn add_stylesheet(&mut self, stylesheet: &Stylesheet<Impl>) {
let device = &self.device; let device = &self.device;
if !stylesheet.is_effective_for_device(device) { if !stylesheet.is_effective_for_device(device) {
return; return;
} }
let (mut element_map, mut before_map, mut after_map) = match stylesheet.origin {
Origin::UserAgent => (
&mut self.element_map.user_agent,
&mut self.before_map.user_agent,
&mut self.after_map.user_agent,
),
Origin::Author => (
&mut self.element_map.author,
&mut self.before_map.author,
&mut self.after_map.author,
),
Origin::User => (
&mut self.element_map.user,
&mut self.before_map.user,
&mut self.after_map.user,
),
};
let mut rules_source_order = self.rules_source_order; let mut rules_source_order = self.rules_source_order;
// Take apart the StyleRule into individual Rules and insert // Take apart the StyleRule into individual Rules and insert
@ -179,11 +170,14 @@ impl Stylist {
($style_rule: ident, $priority: ident) => { ($style_rule: ident, $priority: ident) => {
if $style_rule.declarations.$priority.len() > 0 { if $style_rule.declarations.$priority.len() > 0 {
for selector in &$style_rule.selectors { for selector in &$style_rule.selectors {
let map = match selector.pseudo_element { let map = if let Some(ref pseudo) = selector.pseudo_element {
None => &mut element_map, self.pseudos_map.entry(pseudo.clone())
Some(PseudoElement::Before) => &mut before_map, .or_insert_with(PerPseudoElementSelectorMap::new)
Some(PseudoElement::After) => &mut after_map, .borrow_for_origin(&stylesheet.origin)
} else {
self.element_map.borrow_for_origin(&stylesheet.origin)
}; };
map.$priority.insert(Rule { map.$priority.insert(Rule {
selector: selector.compound_selectors.clone(), selector: selector.compound_selectors.clone(),
declarations: DeclarationBlock { declarations: DeclarationBlock {
@ -216,11 +210,11 @@ impl Stylist {
// more expensive than getting it directly from the caller. // more expensive than getting it directly from the caller.
current_state: ElementState) current_state: ElementState)
-> RestyleHint -> RestyleHint
where E: Element<Impl=ServoSelectorImpl> + Clone { where E: Element<Impl=Impl> + Clone {
self.state_deps.compute_hint(element, snapshot, current_state) self.state_deps.compute_hint(element, snapshot, current_state)
} }
pub fn set_device(&mut self, mut device: Device, stylesheets: &[Arc<Stylesheet>]) { pub fn set_device(&mut self, mut device: Device, stylesheets: &[Arc<Stylesheet<Impl>>]) {
let cascaded_rule = stylesheets.iter() let cascaded_rule = stylesheets.iter()
.flat_map(|s| s.effective_rules(&self.device).viewport()) .flat_map(|s| s.effective_rules(&self.device).viewport())
.cascade(); .cascade();
@ -256,19 +250,18 @@ impl Stylist {
element: &E, element: &E,
parent_bf: Option<&BloomFilter>, parent_bf: Option<&BloomFilter>,
style_attribute: Option<&PropertyDeclarationBlock>, style_attribute: Option<&PropertyDeclarationBlock>,
pseudo_element: Option<PseudoElement>, pseudo_element: Option<Impl::PseudoElement>,
applicable_declarations: &mut V) applicable_declarations: &mut V)
-> bool -> bool
where E: Element + TElement<'le>, where E: Element<Impl=Impl> + TElement<'le>,
V: VecLike<DeclarationBlock> { V: VecLike<DeclarationBlock> {
assert!(!self.is_device_dirty); assert!(!self.is_device_dirty);
assert!(style_attribute.is_none() || pseudo_element.is_none(), assert!(style_attribute.is_none() || pseudo_element.is_none(),
"Style attributes do not apply to pseudo-elements"); "Style attributes do not apply to pseudo-elements");
let map = match pseudo_element { let map = match pseudo_element {
Some(ref pseudo) => self.pseudos_map.get(pseudo).unwrap(),
None => &self.element_map, None => &self.element_map,
Some(PseudoElement::Before) => &self.before_map,
Some(PseudoElement::After) => &self.after_map,
}; };
let mut shareable = true; let mut shareable = true;
@ -336,14 +329,14 @@ impl Stylist {
} }
} }
struct PerOriginSelectorMap { struct PerOriginSelectorMap<Impl: SelectorImpl> {
normal: SelectorMap<Vec<PropertyDeclaration>, ServoSelectorImpl>, normal: SelectorMap<Vec<PropertyDeclaration>, Impl>,
important: SelectorMap<Vec<PropertyDeclaration>, ServoSelectorImpl>, important: SelectorMap<Vec<PropertyDeclaration>, Impl>,
} }
impl PerOriginSelectorMap { impl<Impl: SelectorImpl> PerOriginSelectorMap<Impl> {
#[inline] #[inline]
fn new() -> PerOriginSelectorMap { fn new() -> PerOriginSelectorMap<Impl> {
PerOriginSelectorMap { PerOriginSelectorMap {
normal: SelectorMap::new(), normal: SelectorMap::new(),
important: SelectorMap::new(), important: SelectorMap::new(),
@ -351,19 +344,28 @@ impl PerOriginSelectorMap {
} }
} }
struct PerPseudoElementSelectorMap { struct PerPseudoElementSelectorMap<Impl: SelectorImpl> {
user_agent: PerOriginSelectorMap, user_agent: PerOriginSelectorMap<Impl>,
author: PerOriginSelectorMap, author: PerOriginSelectorMap<Impl>,
user: PerOriginSelectorMap, user: PerOriginSelectorMap<Impl>,
} }
impl PerPseudoElementSelectorMap { impl<Impl: SelectorImpl> PerPseudoElementSelectorMap<Impl> {
#[inline] #[inline]
fn new() -> PerPseudoElementSelectorMap { fn new() -> PerPseudoElementSelectorMap<Impl> {
PerPseudoElementSelectorMap { PerPseudoElementSelectorMap {
user_agent: PerOriginSelectorMap::new(), user_agent: PerOriginSelectorMap::new(),
author: PerOriginSelectorMap::new(), author: PerOriginSelectorMap::new(),
user: PerOriginSelectorMap::new(), user: PerOriginSelectorMap::new(),
} }
} }
#[inline]
fn borrow_for_origin(&mut self, origin: &Origin) -> &mut PerOriginSelectorMap<Impl> {
match *origin {
Origin::UserAgent => &mut self.user_agent,
Origin::Author => &mut self.author,
Origin::User => &mut self.user,
}
}
} }

15
components/style/servo.rs Normal file
View file

@ -0,0 +1,15 @@
/* 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 context;
use data;
use selector_impl::ServoSelectorImpl;
use selector_matching;
use stylesheets;
/// Concrete types for servo Style implementation
pub type Stylesheet = stylesheets::Stylesheet<ServoSelectorImpl>;
pub type PrivateStyleData = data::PrivateStyleData<ServoSelectorImpl>;
pub type Stylist = selector_matching::Stylist<ServoSelectorImpl>;
pub type StylistWrapper = context::StylistWrapper<ServoSelectorImpl>;
pub type SharedStyleContext = context::SharedStyleContext<ServoSelectorImpl>;

View file

@ -10,12 +10,12 @@ use font_face::{FontFaceRule, parse_font_face_block};
use media_queries::{Device, MediaQueryList, parse_media_query_list}; use media_queries::{Device, MediaQueryList, parse_media_query_list};
use parser::{ParserContext, log_css_error}; use parser::{ParserContext, log_css_error};
use properties::{PropertyDeclarationBlock, parse_property_declaration_list}; use properties::{PropertyDeclarationBlock, parse_property_declaration_list};
use selector_impl::ServoSelectorImpl; use selectors::parser::{Selector, SelectorImpl, parse_selector_list};
use selectors::parser::{Selector, parse_selector_list};
use smallvec::SmallVec; use smallvec::SmallVec;
use std::ascii::AsciiExt; use std::ascii::AsciiExt;
use std::cell::Cell; use std::cell::Cell;
use std::iter::Iterator; use std::iter::Iterator;
use std::marker::PhantomData;
use std::slice; use std::slice;
use string_cache::{Atom, Namespace}; use string_cache::{Atom, Namespace};
use url::Url; use url::Url;
@ -39,10 +39,10 @@ pub enum Origin {
#[derive(Debug, HeapSizeOf, PartialEq)] #[derive(Debug, HeapSizeOf, PartialEq)]
pub struct Stylesheet { pub struct Stylesheet<Impl: SelectorImpl> {
/// List of rules in the order they were found (important for /// List of rules in the order they were found (important for
/// cascading order) /// cascading order)
pub rules: Vec<CSSRule>, pub rules: Vec<CSSRule<Impl>>,
/// List of media associated with the Stylesheet, if any. /// List of media associated with the Stylesheet, if any.
pub media: Option<MediaQueryList>, pub media: Option<MediaQueryList>,
pub origin: Origin, pub origin: Origin,
@ -50,22 +50,22 @@ pub struct Stylesheet {
#[derive(Debug, HeapSizeOf, PartialEq)] #[derive(Debug, HeapSizeOf, PartialEq)]
pub enum CSSRule { pub enum CSSRule<Impl: SelectorImpl> {
Charset(String), Charset(String),
Namespace(Option<String>, Namespace), Namespace(Option<String>, Namespace),
Style(StyleRule), Style(StyleRule<Impl>),
Media(MediaRule), Media(MediaRule<Impl>),
FontFace(FontFaceRule), FontFace(FontFaceRule),
Viewport(ViewportRule), Viewport(ViewportRule),
} }
#[derive(Debug, HeapSizeOf, PartialEq)] #[derive(Debug, HeapSizeOf, PartialEq)]
pub struct MediaRule { pub struct MediaRule<Impl: SelectorImpl> {
pub media_queries: MediaQueryList, pub media_queries: MediaQueryList,
pub rules: Vec<CSSRule>, pub rules: Vec<CSSRule<Impl>>,
} }
impl MediaRule { impl<Impl: SelectorImpl> MediaRule<Impl> {
#[inline] #[inline]
pub fn evaluate(&self, device: &Device) -> bool { pub fn evaluate(&self, device: &Device) -> bool {
self.media_queries.evaluate(device) self.media_queries.evaluate(device)
@ -73,17 +73,17 @@ impl MediaRule {
} }
#[derive(Debug, HeapSizeOf, PartialEq)] #[derive(Debug, HeapSizeOf, PartialEq)]
pub struct StyleRule { pub struct StyleRule<Impl: SelectorImpl> {
pub selectors: Vec<Selector<ServoSelectorImpl>>, pub selectors: Vec<Selector<Impl>>,
pub declarations: PropertyDeclarationBlock, pub declarations: PropertyDeclarationBlock,
} }
impl Stylesheet { impl<Impl: SelectorImpl> Stylesheet<Impl> {
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, environment_encoding: Option<EncodingRef>, origin: Origin,
error_reporter: Box<ParseErrorReporter + Send>) -> Stylesheet { error_reporter: Box<ParseErrorReporter + Send>) -> Stylesheet<Impl> {
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 {
@ -98,7 +98,7 @@ impl Stylesheet {
protocol_encoding_label: Option<&str>, protocol_encoding_label: Option<&str>,
environment_encoding: Option<EncodingRef>, environment_encoding: Option<EncodingRef>,
origin: Origin, error_reporter: Box<ParseErrorReporter + Send>) origin: Origin, error_reporter: Box<ParseErrorReporter + Send>)
-> Stylesheet { -> Stylesheet<Impl> {
// 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);
@ -106,10 +106,11 @@ impl Stylesheet {
} }
pub fn from_str(css: &str, base_url: Url, origin: Origin, pub fn from_str(css: &str, base_url: Url, origin: Origin,
error_reporter: Box<ParseErrorReporter + Send>) -> Stylesheet { error_reporter: Box<ParseErrorReporter + Send>) -> Stylesheet<Impl> {
let rule_parser = TopLevelRuleParser { let rule_parser = TopLevelRuleParser {
context: ParserContext::new(origin, &base_url, error_reporter.clone()), context: ParserContext::new(origin, &base_url, error_reporter.clone()),
state: Cell::new(State::Start), state: Cell::new(State::Start),
_impl: PhantomData,
}; };
let mut input = Parser::new(css); let mut input = Parser::new(css);
let mut iter = RuleListParser::new_for_stylesheet(&mut input, rule_parser); let mut iter = RuleListParser::new_for_stylesheet(&mut input, rule_parser);
@ -158,7 +159,7 @@ impl Stylesheet {
/// Return an iterator over all the rules within the style-sheet. /// Return an iterator over all the rules within the style-sheet.
#[inline] #[inline]
pub fn rules(&self) -> Rules { pub fn rules(&self) -> Rules<Impl> {
Rules::new(self.rules.iter(), None) Rules::new(self.rules.iter(), None)
} }
@ -169,7 +170,7 @@ impl Stylesheet {
/// nested rules will be skipped. Use `rules` if all rules need to be /// nested rules will be skipped. Use `rules` if all rules need to be
/// examined. /// examined.
#[inline] #[inline]
pub fn effective_rules<'a>(&'a self, device: &'a Device) -> Rules<'a> { pub fn effective_rules<'a>(&'a self, device: &'a Device) -> Rules<'a, Impl> {
Rules::new(self.rules.iter(), Some(device)) Rules::new(self.rules.iter(), Some(device))
} }
} }
@ -178,25 +179,25 @@ impl Stylesheet {
/// ///
/// The iteration order is pre-order. Specifically, this implies that a /// The iteration order is pre-order. Specifically, this implies that a
/// conditional group rule will come before its nested rules. /// conditional group rule will come before its nested rules.
pub struct Rules<'a> { pub struct Rules<'a, Impl: SelectorImpl + 'a> {
// 2 because normal case is likely to be just one level of nesting (@media) // 2 because normal case is likely to be just one level of nesting (@media)
stack: SmallVec<[slice::Iter<'a, CSSRule>; 2]>, stack: SmallVec<[slice::Iter<'a, CSSRule<Impl>>; 2]>,
device: Option<&'a Device> device: Option<&'a Device>
} }
impl<'a> Rules<'a> { impl<'a, Impl: SelectorImpl + 'a> Rules<'a, Impl> {
fn new(iter: slice::Iter<'a, CSSRule>, device: Option<&'a Device>) -> Rules<'a> { fn new(iter: slice::Iter<'a, CSSRule<Impl>>, device: Option<&'a Device>) -> Rules<'a, Impl> {
let mut stack: SmallVec<[slice::Iter<'a, CSSRule>; 2]> = SmallVec::new(); let mut stack: SmallVec<[slice::Iter<'a, CSSRule<Impl>>; 2]> = SmallVec::new();
stack.push(iter); stack.push(iter);
Rules { stack: stack, device: device } Rules { stack: stack, device: device }
} }
} }
impl<'a> Iterator for Rules<'a> { impl<'a, Impl: SelectorImpl + 'a> Iterator for Rules<'a, Impl> {
type Item = &'a CSSRule; type Item = &'a CSSRule<Impl>;
fn next(&mut self) -> Option<&'a CSSRule> { fn next(&mut self) -> Option<&'a CSSRule<Impl>> {
while !self.stack.is_empty() { while !self.stack.is_empty() {
let top = self.stack.len() - 1; let top = self.stack.len() - 1;
while let Some(rule) = self.stack[top].next() { while let Some(rule) = self.stack[top].next() {
@ -231,6 +232,7 @@ impl<'a> Iterator for Rules<'a> {
pub mod rule_filter { pub mod rule_filter {
//! Specific `CSSRule` variant iterators. //! Specific `CSSRule` variant iterators.
use selectors::parser::SelectorImpl;
use std::marker::PhantomData; use std::marker::PhantomData;
use super::super::font_face::FontFaceRule; use super::super::font_face::FontFaceRule;
use super::super::viewport::ViewportRule; use super::super::viewport::ViewportRule;
@ -245,7 +247,8 @@ pub mod rule_filter {
_lifetime: PhantomData<&'a ()> _lifetime: PhantomData<&'a ()>
} }
impl<'a, I> $variant<'a, I> where I: Iterator<Item=&'a CSSRule> { impl<'a, I, Impl: SelectorImpl + 'a> $variant<'a, I>
where I: Iterator<Item=&'a CSSRule<Impl>> {
pub fn new(iter: I) -> $variant<'a, I> { pub fn new(iter: I) -> $variant<'a, I> {
$variant { $variant {
iter: iter, iter: iter,
@ -254,7 +257,8 @@ pub mod rule_filter {
} }
} }
impl<'a, I> Iterator for $variant<'a, I> where I: Iterator<Item=&'a CSSRule> { impl<'a, I, Impl: SelectorImpl + 'a> Iterator for $variant<'a, I>
where I: Iterator<Item=&'a CSSRule<Impl>> {
type Item = &'a $value; type Item = &'a $value;
fn next(&mut self) -> Option<&'a $value> { fn next(&mut self) -> Option<&'a $value> {
@ -275,14 +279,14 @@ pub mod rule_filter {
} }
} }
rule_filter!(Media -> MediaRule<Impl>);
rule_filter!(Style -> StyleRule<Impl>);
rule_filter!(FontFace -> FontFaceRule); rule_filter!(FontFace -> FontFaceRule);
rule_filter!(Media -> MediaRule);
rule_filter!(Style -> StyleRule);
rule_filter!(Viewport -> ViewportRule); rule_filter!(Viewport -> ViewportRule);
} }
/// Extension methods for `CSSRule` iterators. /// Extension methods for `CSSRule` iterators.
pub trait CSSRuleIteratorExt<'a>: Iterator<Item=&'a CSSRule> + Sized { pub trait CSSRuleIteratorExt<'a, Impl: SelectorImpl + 'a>: Iterator<Item=&'a CSSRule<Impl>> + Sized {
/// Yield only @font-face rules. /// Yield only @font-face rules.
fn font_face(self) -> rule_filter::FontFace<'a, Self>; fn font_face(self) -> rule_filter::FontFace<'a, Self>;
@ -296,7 +300,7 @@ pub trait CSSRuleIteratorExt<'a>: Iterator<Item=&'a CSSRule> + Sized {
fn viewport(self) -> rule_filter::Viewport<'a, Self>; fn viewport(self) -> rule_filter::Viewport<'a, Self>;
} }
impl<'a, I> CSSRuleIteratorExt<'a> for I where I: Iterator<Item=&'a CSSRule> { impl<'a, I, Impl: SelectorImpl + 'a> CSSRuleIteratorExt<'a, Impl> for I where I: Iterator<Item=&'a CSSRule<Impl>> {
#[inline] #[inline]
fn font_face(self) -> rule_filter::FontFace<'a, I> { fn font_face(self) -> rule_filter::FontFace<'a, I> {
rule_filter::FontFace::new(self) rule_filter::FontFace::new(self)
@ -318,8 +322,12 @@ impl<'a, I> CSSRuleIteratorExt<'a> for I where I: Iterator<Item=&'a CSSRule> {
} }
} }
fn parse_nested_rules(context: &ParserContext, input: &mut Parser) -> Vec<CSSRule> { fn parse_nested_rules<Impl: SelectorImpl>(context: &ParserContext, input: &mut Parser) -> Vec<CSSRule<Impl>> {
let mut iter = RuleListParser::new_for_nested_rule(input, NestedRuleParser { context: context }); let mut iter = RuleListParser::new_for_nested_rule(input,
NestedRuleParser {
context: context,
_impl: PhantomData
});
let mut rules = Vec::new(); let mut rules = Vec::new();
while let Some(result) = iter.next() { while let Some(result) = iter.next() {
match result { match result {
@ -335,9 +343,10 @@ fn parse_nested_rules(context: &ParserContext, input: &mut Parser) -> Vec<CSSRul
} }
struct TopLevelRuleParser<'a> { struct TopLevelRuleParser<'a, Impl: SelectorImpl> {
context: ParserContext<'a>, context: ParserContext<'a>,
state: Cell<State>, state: Cell<State>,
_impl: PhantomData<Impl>
} }
#[derive(Eq, PartialEq, Ord, PartialOrd, Copy, Clone)] #[derive(Eq, PartialEq, Ord, PartialOrd, Copy, Clone)]
@ -356,12 +365,12 @@ enum AtRulePrelude {
} }
impl<'a> AtRuleParser for TopLevelRuleParser<'a> { impl<'a, Impl: SelectorImpl> AtRuleParser for TopLevelRuleParser<'a, Impl> {
type Prelude = AtRulePrelude; type Prelude = AtRulePrelude;
type AtRule = CSSRule; type AtRule = CSSRule<Impl>;
fn parse_prelude(&self, name: &str, input: &mut Parser) fn parse_prelude(&self, name: &str, input: &mut Parser)
-> Result<AtRuleType<AtRulePrelude, CSSRule>, ()> { -> Result<AtRuleType<AtRulePrelude, CSSRule<Impl>>, ()> {
match_ignore_ascii_case! { name, match_ignore_ascii_case! { name,
"charset" => { "charset" => {
if self.state.get() <= State::Start { if self.state.get() <= State::Start {
@ -397,45 +406,46 @@ impl<'a> AtRuleParser for TopLevelRuleParser<'a> {
} }
self.state.set(State::Body); self.state.set(State::Body);
AtRuleParser::parse_prelude(&NestedRuleParser { context: &self.context }, name, input) AtRuleParser::parse_prelude(&NestedRuleParser { context: &self.context, _impl: PhantomData }, name, input)
} }
#[inline] #[inline]
fn parse_block(&self, prelude: AtRulePrelude, input: &mut Parser) -> Result<CSSRule, ()> { fn parse_block(&self, prelude: AtRulePrelude, input: &mut Parser) -> Result<CSSRule<Impl>, ()> {
AtRuleParser::parse_block(&NestedRuleParser { context: &self.context }, prelude, input) AtRuleParser::parse_block(&NestedRuleParser { context: &self.context, _impl: PhantomData }, prelude, input)
} }
} }
impl<'a> QualifiedRuleParser for TopLevelRuleParser<'a> { impl<'a, Impl: SelectorImpl> QualifiedRuleParser for TopLevelRuleParser<'a, Impl> {
type Prelude = Vec<Selector<ServoSelectorImpl>>; type Prelude = Vec<Selector<Impl>>;
type QualifiedRule = CSSRule; type QualifiedRule = CSSRule<Impl>;
#[inline] #[inline]
fn parse_prelude(&self, input: &mut Parser) -> Result<Vec<Selector<ServoSelectorImpl>>, ()> { fn parse_prelude(&self, input: &mut Parser) -> Result<Vec<Selector<Impl>>, ()> {
self.state.set(State::Body); self.state.set(State::Body);
QualifiedRuleParser::parse_prelude(&NestedRuleParser { context: &self.context }, input) QualifiedRuleParser::parse_prelude(&NestedRuleParser { context: &self.context, _impl: PhantomData }, input)
} }
#[inline] #[inline]
fn parse_block(&self, prelude: Vec<Selector<ServoSelectorImpl>>, input: &mut Parser) -> Result<CSSRule, ()> { fn parse_block(&self, prelude: Vec<Selector<Impl>>, input: &mut Parser) -> Result<CSSRule<Impl>, ()> {
QualifiedRuleParser::parse_block(&NestedRuleParser { context: &self.context }, QualifiedRuleParser::parse_block(&NestedRuleParser { context: &self.context, _impl: PhantomData },
prelude, input) prelude, input)
} }
} }
struct NestedRuleParser<'a, 'b: 'a> { struct NestedRuleParser<'a, 'b: 'a, Impl: SelectorImpl> {
context: &'a ParserContext<'b>, context: &'a ParserContext<'b>,
_impl: PhantomData<Impl>,
} }
impl<'a, 'b> AtRuleParser for NestedRuleParser<'a, 'b> { impl<'a, 'b, Impl: SelectorImpl> AtRuleParser for NestedRuleParser<'a, 'b, Impl> {
type Prelude = AtRulePrelude; type Prelude = AtRulePrelude;
type AtRule = CSSRule; type AtRule = CSSRule<Impl>;
fn parse_prelude(&self, name: &str, input: &mut Parser) fn parse_prelude(&self, name: &str, input: &mut Parser)
-> Result<AtRuleType<AtRulePrelude, CSSRule>, ()> { -> Result<AtRuleType<AtRulePrelude, CSSRule<Impl>>, ()> {
match_ignore_ascii_case! { name, match_ignore_ascii_case! { name,
"media" => { "media" => {
let media_queries = parse_media_query_list(input); let media_queries = parse_media_query_list(input);
@ -455,7 +465,7 @@ impl<'a, 'b> AtRuleParser for NestedRuleParser<'a, 'b> {
} }
} }
fn parse_block(&self, prelude: AtRulePrelude, input: &mut Parser) -> Result<CSSRule, ()> { fn parse_block(&self, prelude: AtRulePrelude, input: &mut Parser) -> Result<CSSRule<Impl>, ()> {
match prelude { match prelude {
AtRulePrelude::FontFace => { AtRulePrelude::FontFace => {
parse_font_face_block(self.context, input).map(CSSRule::FontFace) parse_font_face_block(self.context, input).map(CSSRule::FontFace)
@ -474,15 +484,15 @@ impl<'a, 'b> AtRuleParser for NestedRuleParser<'a, 'b> {
} }
impl<'a, 'b> QualifiedRuleParser for NestedRuleParser<'a, 'b> { impl<'a, 'b, Impl: SelectorImpl> QualifiedRuleParser for NestedRuleParser<'a, 'b, Impl> {
type Prelude = Vec<Selector<ServoSelectorImpl>>; type Prelude = Vec<Selector<Impl>>;
type QualifiedRule = CSSRule; type QualifiedRule = CSSRule<Impl>;
fn parse_prelude(&self, input: &mut Parser) -> Result<Vec<Selector<ServoSelectorImpl>>, ()> { fn parse_prelude(&self, input: &mut Parser) -> Result<Vec<Selector<Impl>>, ()> {
parse_selector_list(&self.context.selector_context, input) parse_selector_list(&self.context.selector_context, input)
} }
fn parse_block(&self, prelude: Vec<Selector<ServoSelectorImpl>>, input: &mut Parser) -> Result<CSSRule, ()> { fn parse_block(&self, prelude: Vec<Selector<Impl>>, input: &mut Parser) -> Result<CSSRule<Impl>, ()> {
Ok(CSSRule::Style(StyleRule { Ok(CSSRule::Style(StyleRule {
selectors: prelude, selectors: prelude,
declarations: parse_property_declaration_list(self.context, input) declarations: parse_property_declaration_list(self.context, input)

View file

@ -5,6 +5,8 @@
use context::{SharedStyleContext, StyleContext}; use context::{SharedStyleContext, StyleContext};
use dom::{OpaqueNode, TNode, TRestyleDamage, UnsafeNode}; use dom::{OpaqueNode, TNode, TRestyleDamage, UnsafeNode};
use matching::{ApplicableDeclarations, ElementMatchMethods, MatchMethods, StyleSharingResult}; use matching::{ApplicableDeclarations, ElementMatchMethods, MatchMethods, StyleSharingResult};
use selector_impl::SelectorImplExt;
use selectors::Element;
use selectors::bloom::BloomFilter; use selectors::bloom::BloomFilter;
use std::cell::RefCell; use std::cell::RefCell;
use util::opts; use util::opts;
@ -41,9 +43,9 @@ thread_local!(
/// ///
/// If one does not exist, a new one will be made for you. If it is out of date, /// If one does not exist, a new one will be made for you. If it is out of date,
/// it will be cleared and reused. /// it will be cleared and reused.
fn take_thread_local_bloom_filter<'ln, N>(parent_node: Option<N>, fn take_thread_local_bloom_filter<'ln, N, Impl: SelectorImplExt>(parent_node: Option<N>,
root: OpaqueNode, root: OpaqueNode,
context: &SharedStyleContext) context: &SharedStyleContext<Impl>)
-> Box<BloomFilter> -> Box<BloomFilter>
where N: TNode<'ln> { where N: TNode<'ln> {
STYLE_BLOOM.with(|style_bloom| { STYLE_BLOOM.with(|style_bloom| {
@ -77,9 +79,9 @@ fn take_thread_local_bloom_filter<'ln, N>(parent_node: Option<N>,
}) })
} }
pub fn put_thread_local_bloom_filter(bf: Box<BloomFilter>, pub fn put_thread_local_bloom_filter<Impl: SelectorImplExt>(bf: Box<BloomFilter>,
unsafe_node: &UnsafeNode, unsafe_node: &UnsafeNode,
context: &SharedStyleContext) { context: &SharedStyleContext<Impl>) {
STYLE_BLOOM.with(move |style_bloom| { STYLE_BLOOM.with(move |style_bloom| {
assert!(style_bloom.borrow().is_none(), assert!(style_bloom.borrow().is_none(),
"Putting into a never-taken thread-local bloom filter"); "Putting into a never-taken thread-local bloom filter");
@ -117,7 +119,12 @@ pub trait DomTraversalContext<'ln, N: TNode<'ln>> {
/// layout computation. This computes the styles applied to each node. /// layout computation. This computes the styles applied to each node.
#[inline] #[inline]
#[allow(unsafe_code)] #[allow(unsafe_code)]
pub fn recalc_style_at<'a, 'ln, N: TNode<'ln>, C: StyleContext<'a>> (context: &'a C, root: OpaqueNode, node: N) { pub fn recalc_style_at<'a, 'ln, N, C>(context: &'a C,
root: OpaqueNode,
node: N)
where N: TNode<'ln>,
C: StyleContext<'a, <N::ConcreteElement as Element>::Impl>,
<N::ConcreteElement as Element>::Impl: SelectorImplExt + 'a {
// Initialize layout data. // Initialize layout data.
// //
// FIXME(pcwalton): Stop allocating here. Ideally this should just be done by the HTML // FIXME(pcwalton): Stop allocating here. Ideally this should just be done by the HTML

View file

@ -22,7 +22,7 @@ lazy_static = "0.1.10"
log = "0.3" log = "0.3"
num = "0.1.24" num = "0.1.24"
rustc-serialize = "0.3" rustc-serialize = "0.3"
selectors = {version = "0.4.2", features = ["heap_size"]} selectors = {version = "0.5", features = ["heap_size"]}
serde = "0.6" serde = "0.6"
serde_macros = "0.6" serde_macros = "0.6"
url = {version = "0.5.5", features = ["heap_size"]} url = {version = "0.5.5", features = ["heap_size"]}

View file

@ -41,7 +41,7 @@ num = "0.1.24"
num_cpus = "0.2.2" num_cpus = "0.2.2"
rand = "0.3" rand = "0.3"
rustc-serialize = "0.3" rustc-serialize = "0.3"
selectors = {version = "0.4.2", features = ["heap_size"]} selectors = {version = "0.5", features = ["heap_size"]}
serde = "0.6" serde = "0.6"
serde_macros = "0.6" serde_macros = "0.6"
smallvec = "0.1" smallvec = "0.1"

12
ports/cef/Cargo.lock generated
View file

@ -934,7 +934,7 @@ dependencies = [
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"script 0.0.1", "script 0.0.1",
"script_traits 0.0.1", "script_traits 0.0.1",
"selectors 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "selectors 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1477,7 +1477,7 @@ dependencies = [
"ref_slice 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "ref_slice 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"script_traits 0.0.1", "script_traits 0.0.1",
"selectors 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "selectors 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"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.9 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1519,7 +1519,7 @@ dependencies = [
[[package]] [[package]]
name = "selectors" name = "selectors"
version = "0.4.2" version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1763,7 +1763,7 @@ dependencies = [
"num 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "num 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
"plugins 0.0.1", "plugins 0.0.1",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"selectors 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "selectors 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"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)",
@ -1787,7 +1787,7 @@ dependencies = [
"num 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "num 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
"plugins 0.0.1", "plugins 0.0.1",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"selectors 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "selectors 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "url 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1945,7 +1945,7 @@ dependencies = [
"plugins 0.0.1", "plugins 0.0.1",
"rand 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"selectors 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "selectors 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"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)",

View file

@ -6,10 +6,14 @@ dependencies = [
"bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
"selectors 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "plugins 0.0.1",
"selectors 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"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.9 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
"style 0.0.1", "style 0.0.1",
@ -312,7 +316,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "selectors" name = "selectors"
version = "0.4.2" version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
@ -389,7 +393,7 @@ dependencies = [
"num 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "num 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
"plugins 0.0.1", "plugins 0.0.1",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"selectors 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "selectors 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"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)",
@ -413,7 +417,7 @@ dependencies = [
"num 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "num 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
"plugins 0.0.1", "plugins 0.0.1",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"selectors 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "selectors 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "url 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
@ -492,7 +496,7 @@ dependencies = [
"plugins 0.0.1", "plugins 0.0.1",
"rand 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"selectors 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "selectors 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"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)",

View file

@ -13,14 +13,20 @@ app_units = {version = "0.2.1", features = ["plugins"]}
bitflags = "0.3" bitflags = "0.3"
cssparser = {version = "0.5.3", features = ["heap_size", "serde-serialization"]} cssparser = {version = "0.5.3", features = ["heap_size", "serde-serialization"]}
euclid = {version = "0.6.2", features = ["plugins"]} euclid = {version = "0.6.2", features = ["plugins"]}
heapsize = "0.3.0"
heapsize_plugin = "0.1.2"
lazy_static = "0.1"
libc = "0.2" libc = "0.2"
log = "0.3" log = "0.3"
num_cpus = "0.2.2" num_cpus = "0.2.2"
selectors = {version = "0.4.2", features = ["heap_size"]} selectors = {version = "0.5", features = ["heap_size"]}
smallvec = "0.1" smallvec = "0.1"
string_cache = {version = "0.2.9", features = ["heap_size"]} string_cache = {version = "0.2.9", features = ["heap_size"]}
url = {version = "0.5.5", features = ["heap_size"]} url = {version = "0.5.5", features = ["heap_size"]}
[dependencies.plugins]
path = "../../components/plugins"
[dependencies.util] [dependencies.util]
path = "../../components/util" path = "../../components/util"

View file

@ -6,17 +6,15 @@ use bindings::ServoStyleSetData;
use euclid::Size2D; use euclid::Size2D;
use euclid::size::TypedSize2D; use euclid::size::TypedSize2D;
use num_cpus; use num_cpus;
use selector_impl::{Stylist, Stylesheet, SharedStyleContext};
use std::cmp; use std::cmp;
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::mpsc::{channel, Receiver, Sender}; use std::sync::mpsc::{channel, Receiver, Sender};
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
use style::animation::Animation; use style::animation::Animation;
use style::context::SharedStyleContext;
use style::dom::OpaqueNode; use style::dom::OpaqueNode;
use style::media_queries::{Device, MediaType}; use style::media_queries::{Device, MediaType};
use style::parallel::WorkQueueData; use style::parallel::WorkQueueData;
use style::selector_matching::Stylist;
use style::stylesheets::Stylesheet;
use util::geometry::ViewportPx; use util::geometry::ViewportPx;
use util::thread_state; use util::thread_state;
use util::workqueue::WorkQueue; use util::workqueue::WorkQueue;

View file

@ -9,15 +9,16 @@ use bindings::RawGeckoDocument;
use bindings::{ServoArcStyleSheet, ServoNodeData, ServoStyleSetData, uint8_t, uint32_t}; use bindings::{ServoArcStyleSheet, ServoNodeData, ServoStyleSetData, uint8_t, uint32_t};
use data::PerDocumentStyleData; use data::PerDocumentStyleData;
use euclid::Size2D; use euclid::Size2D;
use selector_impl::{SharedStyleContext, Stylesheet};
use std::mem::{forget, transmute}; use std::mem::{forget, transmute};
use std::slice; use std::slice;
use std::str::from_utf8_unchecked; use std::str::from_utf8_unchecked;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use style::context::{ReflowGoal, SharedStyleContext, StylistWrapper}; use style::context::{ReflowGoal, StylistWrapper};
use style::dom::{TDocument, TNode}; use style::dom::{TDocument, TNode};
use style::error_reporting::StdoutErrorReporter; use style::error_reporting::StdoutErrorReporter;
use style::parallel; use style::parallel;
use style::stylesheets::{Origin, Stylesheet}; use style::stylesheets::Origin;
use traversal::RecalcStyleOnly; use traversal::RecalcStyleOnly;
use url::Url; use url::Url;
use util::arc_ptr_eq; use util::arc_ptr_eq;

View file

@ -5,13 +5,24 @@
#![feature(as_unsafe_cell)] #![feature(as_unsafe_cell)]
#![feature(box_syntax)] #![feature(box_syntax)]
#![feature(ptr_as_ref)] #![feature(ptr_as_ref)]
#![feature(custom_derive)]
#![feature(plugin)]
#![plugin(heapsize_plugin)]
#![plugin(plugins)]
extern crate app_units; extern crate app_units;
#[macro_use] #[macro_use]
extern crate bitflags; extern crate bitflags;
#[macro_use]
extern crate cssparser; extern crate cssparser;
extern crate euclid; extern crate euclid;
extern crate heapsize;
#[macro_use]
extern crate lazy_static;
extern crate libc; extern crate libc;
#[macro_use]
extern crate log;
extern crate num_cpus; extern crate num_cpus;
extern crate selectors; extern crate selectors;
extern crate smallvec; extern crate smallvec;
@ -26,5 +37,6 @@ mod bindings;
mod data; mod data;
#[allow(non_snake_case)] #[allow(non_snake_case)]
pub mod glue; pub mod glue;
mod selector_impl;
mod traversal; mod traversal;
mod wrapper; mod wrapper;

View file

@ -0,0 +1,307 @@
/* 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 selectors::parser::{ParserContext, SelectorImpl};
use std::process;
use style;
use style::element_state::ElementState;
use style::error_reporting::StdoutErrorReporter;
use style::selector_impl::SelectorImplExt;
use style::stylesheets::Origin;
use url::Url;
use util::resource_files::read_resource_file;
pub type Stylist = style::selector_matching::Stylist<GeckoSelectorImpl>;
pub type Stylesheet = style::stylesheets::Stylesheet<GeckoSelectorImpl>;
pub type SharedStyleContext = style::context::SharedStyleContext<GeckoSelectorImpl>;
pub type PrivateStyleData = style::data::PrivateStyleData<GeckoSelectorImpl>;
pub struct GeckoSelectorImpl;
// TODO: Replace this with Gecko's stylesheets
lazy_static! {
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:///{:?}", filename)).unwrap(),
None,
None,
Origin::UserAgent,
box StdoutErrorReporter);
stylesheets.push(ua_stylesheet);
}
Err(..) => {
error!("Failed to load UA stylesheet {}!", filename);
process::exit(1);
}
}
}
stylesheets
};
}
lazy_static! {
static ref QUIRKS_MODE_STYLESHEET: Stylesheet = {
match read_resource_file(&["quirks-mode.css"]) {
Ok(res) => {
Stylesheet::from_bytes(
&res,
url!("chrome:///quirks-mode.css"),
None,
None,
Origin::UserAgent,
box StdoutErrorReporter)
},
Err(..) => {
error!("Stylist failed to load 'quirks-mode.css'!");
process::exit(1);
}
}
};
}
#[derive(Clone, Debug, PartialEq, Eq, HeapSizeOf, Hash)]
pub enum PseudoElement {
Before,
After,
FirstLine,
// TODO: Probably a few more are missing here
// https://mxr.mozilla.org/mozilla-central/source/layout/style/nsCSSAnonBoxList.h
MozNonElement,
MozAnonymousBlock,
MozAnonymousPositionedBlock,
MozMathMLAnonymousBlock,
MozXULAnonymousBlock,
MozHorizontalFramesetBorder,
MozVerticalFramesetBorder,
MozLineFrame,
MozButtonContent,
MozButtonLabel,
MozCellContent,
MozDropdownList,
MozFieldsetContent,
MozFramesetBlank,
MozDisplayComboboxControlFrame,
MozHTMLCanvasContent,
MozInlineTable,
MozTable,
MozTableCell,
MozTableColumnGroup,
MozTableColumn,
MozTableOuter,
MozTableRowGroup,
MozTableRow,
MozCanvas,
MozPageBreak,
MozPage,
MozPageContent,
MozPageSequence,
MozScrolledContent,
MozScrolledCanvas,
MozScrolledPageSequence,
MozColumnContent,
MozViewport,
MozViewportScroll,
MozAnonymousFlexItem,
MozAnonymousGridItem,
MozRuby,
MozRubyBase,
MozRubyBaseContainer,
MozRubyText,
MozRubyTextContainer,
MozTreeColumn,
MozTreeRow,
MozTreeSeparator,
MozTreeCell,
MozTreeIndentation,
MozTreeLine,
MozTreeTwisty,
MozTreeImage,
MozTreeCellText,
MozTreeCheckbox,
MozTreeProgressMeter,
MozTreeDropFeedback,
MozSVGMarkerAnonChild,
MozSVGOuterSVGAnonChild,
MozSVGForeignContent,
MozSVGText,
}
#[derive(Clone, Debug, PartialEq, Eq, HeapSizeOf, Hash)]
pub enum NonTSPseudoClass {
AnyLink,
Link,
Visited,
Active,
Focus,
Hover,
Enabled,
Disabled,
Checked,
Indeterminate,
}
impl NonTSPseudoClass {
pub fn state_flag(&self) -> ElementState {
use self::NonTSPseudoClass::*;
use style::element_state::*;
match *self {
Active => IN_ACTIVE_STATE,
Focus => IN_FOCUS_STATE,
Hover => IN_HOVER_STATE,
Enabled => IN_ENABLED_STATE,
Disabled => IN_DISABLED_STATE,
Checked => IN_CHECKED_STATE,
Indeterminate => IN_INDETERMINATE_STATE,
AnyLink |
Link |
Visited => ElementState::empty(),
}
}
}
impl SelectorImpl for GeckoSelectorImpl {
type PseudoElement = PseudoElement;
type NonTSPseudoClass = NonTSPseudoClass;
fn parse_non_ts_pseudo_class(_context: &ParserContext,
name: &str) -> Result<NonTSPseudoClass, ()> {
use self::NonTSPseudoClass::*;
let pseudo_class = match_ignore_ascii_case! { name,
"any-link" => AnyLink,
"link" => Link,
"visited" => Visited,
"active" => Active,
"focus" => Focus,
"hover" => Hover,
"enabled" => Enabled,
"disabled" => Disabled,
"checked" => Checked,
"indeterminate" => Indeterminate,
_ => return Err(())
};
Ok(pseudo_class)
}
fn parse_pseudo_element(_context: &ParserContext,
name: &str) -> Result<PseudoElement, ()> {
use self::PseudoElement::*;
let pseudo_element = match_ignore_ascii_case! { name,
"before" => Before,
"after" => After,
"first-line" => FirstLine,
"-moz-non-element" => MozNonElement,
"-moz-anonymous-block" => MozAnonymousBlock,
"-moz-anonymous-positioned-block" => MozAnonymousPositionedBlock,
"-moz-mathml-anonymous-block" => MozMathMLAnonymousBlock,
"-moz-xul-anonymous-block" => MozXULAnonymousBlock,
"-moz-hframeset-border" => MozHorizontalFramesetBorder,
"-moz-vframeset-border" => MozVerticalFramesetBorder,
"-moz-line-frame" => MozLineFrame,
"-moz-button-content" => MozButtonContent,
"-moz-buttonlabel" => MozButtonLabel,
"-moz-cell-content" => MozCellContent,
"-moz-dropdown-list" => MozDropdownList,
"-moz-fieldset-content" => MozFieldsetContent,
"-moz-frameset-blank" => MozFramesetBlank,
"-moz-display-comboboxcontrol-frame" => MozDisplayComboboxControlFrame,
"-moz-html-canvas-content" => MozHTMLCanvasContent,
"-moz-inline-table" => MozInlineTable,
"-moz-table" => MozTable,
"-moz-table-cell" => MozTableCell,
"-moz-table-column-group" => MozTableColumnGroup,
"-moz-table-column" => MozTableColumn,
"-moz-table-outer" => MozTableOuter,
"-moz-table-row-group" => MozTableRowGroup,
"-moz-table-row" => MozTableRow,
"-moz-canvas" => MozCanvas,
"-moz-pagebreak" => MozPageBreak,
"-moz-page" => MozPage,
"-moz-pagecontent" => MozPageContent,
"-moz-page-sequence" => MozPageSequence,
"-moz-scrolled-content" => MozScrolledContent,
"-moz-scrolled-canvas" => MozScrolledCanvas,
"-moz-scrolled-page-sequence" => MozScrolledPageSequence,
"-moz-column-content" => MozColumnContent,
"-moz-viewport" => MozViewport,
"-moz-viewport-scroll" => MozViewportScroll,
"-moz-anonymous-flex-item" => MozAnonymousFlexItem,
"-moz-anonymous-grid-item" => MozAnonymousGridItem,
"-moz-ruby" => MozRuby,
"-moz-ruby-base" => MozRubyBase,
"-moz-ruby-base-container" => MozRubyBaseContainer,
"-moz-ruby-text" => MozRubyText,
"-moz-ruby-text-container" => MozRubyTextContainer,
"-moz-tree-column" => MozTreeColumn,
"-moz-tree-row" => MozTreeRow,
"-moz-tree-separator" => MozTreeSeparator,
"-moz-tree-cell" => MozTreeCell,
"-moz-tree-indentation" => MozTreeIndentation,
"-moz-tree-line" => MozTreeLine,
"-moz-tree-twisty" => MozTreeTwisty,
"-moz-tree-image" => MozTreeImage,
"-moz-tree-cell-text" => MozTreeCellText,
"-moz-tree-checkbox" => MozTreeCheckbox,
"-moz-tree-progressmeter" => MozTreeProgressMeter,
"-moz-tree-drop-feedback" => MozTreeDropFeedback,
"-moz-svg-marker-anon-child" => MozSVGMarkerAnonChild,
"-moz-svg-outer-svg-anon-child" => MozSVGOuterSVGAnonChild,
"-moz-svg-foreign-content" => MozSVGForeignContent,
"-moz-svg-text" => MozSVGText,
_ => return Err(())
};
Ok(pseudo_element)
}
}
impl SelectorImplExt for GeckoSelectorImpl {
#[inline]
fn each_eagerly_cascaded_pseudo_element<F>(mut fun: F)
where F: FnMut(PseudoElement) {
fun(PseudoElement::Before);
fun(PseudoElement::After);
// TODO: probably a lot more are missing here
}
#[inline]
fn pseudo_class_state_flag(pc: &NonTSPseudoClass) -> ElementState {
pc.state_flag()
}
// FIXME: Don't use Servo's UA stylesheets, use Gecko's instead
#[inline]
fn get_user_or_user_agent_stylesheets() -> &'static [Stylesheet] {
&*USER_OR_USER_AGENT_STYLESHEETS
}
#[inline]
fn get_quirks_mode_stylesheet() -> &'static Stylesheet {
&*QUIRKS_MODE_STYLESHEET
}
}

View file

@ -2,10 +2,11 @@
* 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 selector_impl::{GeckoSelectorImpl, SharedStyleContext};
use std::cell::RefCell; use std::cell::RefCell;
use std::mem; use std::mem;
use std::rc::Rc; use std::rc::Rc;
use style::context::{LocalStyleContext, SharedStyleContext, StyleContext}; use style::context::{LocalStyleContext, StyleContext};
use style::dom::{OpaqueNode, TNode}; use style::dom::{OpaqueNode, TNode};
use style::matching::{ApplicableDeclarationsCache, StyleSharingCandidateCache}; use style::matching::{ApplicableDeclarationsCache, StyleSharingCandidateCache};
use style::traversal::{DomTraversalContext, recalc_style_at}; use style::traversal::{DomTraversalContext, recalc_style_at};
@ -48,7 +49,7 @@ impl<'a> StandaloneStyleContext<'a> {
} }
} }
impl<'a> StyleContext<'a> for StandaloneStyleContext<'a> { impl<'a> StyleContext<'a, GeckoSelectorImpl> for StandaloneStyleContext<'a> {
fn shared_context(&self) -> &'a SharedStyleContext { fn shared_context(&self) -> &'a SharedStyleContext {
&self.shared &self.shared
} }
@ -63,7 +64,8 @@ pub struct RecalcStyleOnly<'lc> {
root: OpaqueNode, root: OpaqueNode,
} }
impl<'lc, 'ln, N: TNode<'ln>> DomTraversalContext<'ln, N> for RecalcStyleOnly<'lc> { impl<'lc, 'ln, N: TNode<'ln>> DomTraversalContext<'ln, N> for RecalcStyleOnly<'lc>
where N::ConcreteElement: ::selectors::Element<Impl=GeckoSelectorImpl> {
type SharedContext = SharedStyleContext; type SharedContext = SharedStyleContext;
#[allow(unsafe_code)] #[allow(unsafe_code)]
fn new<'a>(shared: &'a Self::SharedContext, root: OpaqueNode) -> Self { fn new<'a>(shared: &'a Self::SharedContext, root: OpaqueNode) -> Self {

View file

@ -19,6 +19,8 @@ use bindings::{Gecko_LocalName, Gecko_Namespace, Gecko_NodeIsElement, Gecko_SetN
use bindings::{RawGeckoDocument, RawGeckoElement, RawGeckoNode}; use bindings::{RawGeckoDocument, RawGeckoElement, RawGeckoNode};
use bindings::{ServoNodeData}; use bindings::{ServoNodeData};
use libc::uintptr_t; use libc::uintptr_t;
use selector_impl::{GeckoSelectorImpl, NonTSPseudoClass, PrivateStyleData};
use selectors::Element;
use selectors::matching::DeclarationBlock; use selectors::matching::DeclarationBlock;
use selectors::parser::{AttrSelector, NamespaceConstraint}; use selectors::parser::{AttrSelector, NamespaceConstraint};
use smallvec::VecLike; use smallvec::VecLike;
@ -29,7 +31,6 @@ use std::slice;
use std::str::from_utf8_unchecked; use std::str::from_utf8_unchecked;
use std::sync::Arc; use std::sync::Arc;
use string_cache::{Atom, Namespace}; use string_cache::{Atom, Namespace};
use style::data::PrivateStyleData;
use style::dom::{OpaqueNode, TDocument, TElement, TNode, TRestyleDamage, UnsafeNode}; use style::dom::{OpaqueNode, TDocument, TElement, TNode, TRestyleDamage, UnsafeNode};
use style::element_state::ElementState; use style::element_state::ElementState;
#[allow(unused_imports)] // Used in commented-out code. #[allow(unused_imports)] // Used in commented-out code.
@ -38,7 +39,7 @@ use style::properties::{ComputedValues, PropertyDeclaration, PropertyDeclaration
#[allow(unused_imports)] // Used in commented-out code. #[allow(unused_imports)] // Used in commented-out code.
use style::properties::{parse_style_attribute}; use style::properties::{parse_style_attribute};
use style::restyle_hints::ElementSnapshot; use style::restyle_hints::ElementSnapshot;
use style::selector_impl::{NonTSPseudoClass, ServoSelectorImpl}; use style::selector_impl::ElementExt;
#[allow(unused_imports)] // Used in commented-out code. #[allow(unused_imports)] // Used in commented-out code.
use url::Url; use url::Url;
@ -357,7 +358,7 @@ impl<'le> TElement<'le> for GeckoElement<'le> {
} }
impl<'le> ::selectors::Element for GeckoElement<'le> { impl<'le> ::selectors::Element for GeckoElement<'le> {
type Impl = ServoSelectorImpl; type Impl = GeckoSelectorImpl;
fn parent_element(&self) -> Option<Self> { fn parent_element(&self) -> Option<Self> {
unsafe { unsafe {
@ -427,11 +428,6 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
NonTSPseudoClass::Link => unsafe { Gecko_IsLink(self.element) != 0 }, NonTSPseudoClass::Link => unsafe { Gecko_IsLink(self.element) != 0 },
NonTSPseudoClass::AnyLink => unsafe { Gecko_IsUnvisitedLink(self.element) != 0 }, NonTSPseudoClass::AnyLink => unsafe { Gecko_IsUnvisitedLink(self.element) != 0 },
NonTSPseudoClass::Visited => unsafe { Gecko_IsVisitedLink(self.element) != 0 }, NonTSPseudoClass::Visited => unsafe { Gecko_IsVisitedLink(self.element) != 0 },
NonTSPseudoClass::ServoNonZeroBorder => {
unimplemented!()
},
NonTSPseudoClass::Active | NonTSPseudoClass::Active |
NonTSPseudoClass::Focus | NonTSPseudoClass::Focus |
NonTSPseudoClass::Hover | NonTSPseudoClass::Hover |
@ -489,6 +485,12 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
} }
} }
impl<'le> ElementExt for GeckoElement<'le> {
fn is_link(&self) -> bool {
self.match_non_ts_pseudo_class(NonTSPseudoClass::AnyLink)
}
}
unsafe fn reinterpret_string<'a>(ptr: *const ::libc::c_char, length: u32) -> Option<&'a str> { unsafe fn reinterpret_string<'a>(ptr: *const ::libc::c_char, length: u32) -> Option<&'a str> {
(ptr as *const u8).as_ref().map(|p| from_utf8_unchecked(slice::from_raw_parts(p, length as usize))) (ptr as *const u8).as_ref().map(|p| from_utf8_unchecked(slice::from_raw_parts(p, length as usize)))
} }

12
ports/gonk/Cargo.lock generated
View file

@ -916,7 +916,7 @@ dependencies = [
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"script 0.0.1", "script 0.0.1",
"script_traits 0.0.1", "script_traits 0.0.1",
"selectors 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "selectors 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1459,7 +1459,7 @@ dependencies = [
"ref_slice 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "ref_slice 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"script_traits 0.0.1", "script_traits 0.0.1",
"selectors 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "selectors 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"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.9 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1501,7 +1501,7 @@ dependencies = [
[[package]] [[package]]
name = "selectors" name = "selectors"
version = "0.4.2" version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1743,7 +1743,7 @@ dependencies = [
"num 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "num 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
"plugins 0.0.1", "plugins 0.0.1",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"selectors 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "selectors 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"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)",
@ -1767,7 +1767,7 @@ dependencies = [
"num 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "num 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
"plugins 0.0.1", "plugins 0.0.1",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"selectors 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "selectors 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "url 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1925,7 +1925,7 @@ dependencies = [
"plugins 0.0.1", "plugins 0.0.1",
"rand 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"selectors 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "selectors 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"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)",

View file

@ -27,6 +27,6 @@ path = "../../../components/util"
app_units = {version = "0.2.1", features = ["plugins"]} app_units = {version = "0.2.1", features = ["plugins"]}
cssparser = {version = "0.5.3", features = ["heap_size"]} cssparser = {version = "0.5.3", features = ["heap_size"]}
euclid = {version = "0.6.2", features = ["plugins"]} euclid = {version = "0.6.2", features = ["plugins"]}
selectors = {version = "0.4.2", features = ["heap_size"]} selectors = {version = "0.5", features = ["heap_size"]}
string_cache = {version = "0.2.9", features = ["heap_size"]} string_cache = {version = "0.2.9", features = ["heap_size"]}
url = {version = "0.5.5", features = ["heap_size"]} url = {version = "0.5.5", features = ["heap_size"]}

View file

@ -8,7 +8,8 @@ use euclid::size::Size2D;
use std::borrow::ToOwned; use std::borrow::ToOwned;
use style::error_reporting::ParseErrorReporter; use style::error_reporting::ParseErrorReporter;
use style::media_queries::*; use style::media_queries::*;
use style::stylesheets::{Origin, Stylesheet, CSSRuleIteratorExt}; use style::servo::Stylesheet;
use style::stylesheets::{Origin, CSSRuleIteratorExt};
use style::values::specified; use style::values::specified;
pub struct CSSErrorReporterTest; pub struct CSSErrorReporterTest;

View file

@ -10,8 +10,9 @@ use std::sync::Arc;
use std::sync::Mutex; use std::sync::Mutex;
use string_cache::Atom; 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};
use style::error_reporting::ParseErrorReporter; use style::error_reporting::ParseErrorReporter;
use style::servo::Stylesheet;
#[test] #[test]
fn test_parse_stylesheet() { fn test_parse_stylesheet() {

View file

@ -9,7 +9,8 @@ use media_queries::CSSErrorReporterTest;
use style::error_reporting::ParseErrorReporter; use style::error_reporting::ParseErrorReporter;
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::servo::Stylesheet;
use style::stylesheets::{Origin, CSSRuleIteratorExt};
use style::values::specified::Length::{self, ViewportPercentage}; 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;