mirror of
https://github.com/servo/servo.git
synced 2025-06-17 21:04:28 +00:00
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:
parent
a164176876
commit
dd503dfacb
41 changed files with 767 additions and 310 deletions
|
@ -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"
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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()),
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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())
|
||||||
|
|
|
@ -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"]}
|
||||||
|
|
|
@ -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};
|
||||||
|
|
|
@ -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};
|
||||||
|
|
||||||
|
|
|
@ -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};
|
||||||
|
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
14
components/servo/Cargo.lock
generated
14
components/servo/Cargo.lock
generated
|
@ -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)",
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>;
|
||||||
|
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 document’s encoding is ISO-8859-8.
|
// FIXME: Add iso-8859-9.css when the document’s 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
15
components/style/servo.rs
Normal 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>;
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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"]}
|
||||||
|
|
|
@ -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
12
ports/cef/Cargo.lock
generated
|
@ -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)",
|
||||||
|
|
14
ports/geckolib/Cargo.lock
generated
14
ports/geckolib/Cargo.lock
generated
|
@ -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)",
|
||||||
|
|
|
@ -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"
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
307
ports/geckolib/selector_impl.rs
Normal file
307
ports/geckolib/selector_impl.rs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 {
|
||||||
|
|
|
@ -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
12
ports/gonk/Cargo.lock
generated
|
@ -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)",
|
||||||
|
|
|
@ -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"]}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue