mirror of
https://github.com/servo/servo.git
synced 2025-07-23 07:13:52 +01:00
Have a concrete SelectorImpl type everywhere in the style crate.
It is conditionally compiled to one implementation or the other (Gecko or Servo) with `#[cfg(…)]`.
This commit is contained in:
parent
4b7060554b
commit
5c70dfab01
16 changed files with 236 additions and 232 deletions
|
@ -25,7 +25,6 @@ use std::hash::BuildHasherDefault;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::{Arc, Mutex, RwLock};
|
use std::sync::{Arc, Mutex, RwLock};
|
||||||
use style::context::{LocalStyleContext, StyleContext};
|
use style::context::{LocalStyleContext, StyleContext};
|
||||||
use style::selector_impl::ServoSelectorImpl;
|
|
||||||
use style::servo::SharedStyleContext;
|
use style::servo::SharedStyleContext;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use util::opts;
|
use util::opts;
|
||||||
|
@ -103,7 +102,7 @@ pub struct LayoutContext<'a> {
|
||||||
cached_local_layout_context: Rc<LocalLayoutContext>,
|
cached_local_layout_context: Rc<LocalLayoutContext>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> StyleContext<'a, ServoSelectorImpl> for LayoutContext<'a> {
|
impl<'a> StyleContext<'a> for LayoutContext<'a> {
|
||||||
fn shared_context(&self) -> &'a SharedStyleContext {
|
fn shared_context(&self) -> &'a SharedStyleContext {
|
||||||
&self.shared.style_context
|
&self.shared.style_context
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@ use properties::longhands::animation_play_state::computed_value::AnimationPlaySt
|
||||||
use properties::longhands::transition_timing_function::computed_value::StartEnd;
|
use properties::longhands::transition_timing_function::computed_value::StartEnd;
|
||||||
use properties::longhands::transition_timing_function::computed_value::TransitionTimingFunction;
|
use properties::longhands::transition_timing_function::computed_value::TransitionTimingFunction;
|
||||||
use properties::{self, ComputedValues};
|
use properties::{self, ComputedValues};
|
||||||
use selector_impl::SelectorImplExt;
|
|
||||||
use selectors::matching::DeclarationBlock;
|
use selectors::matching::DeclarationBlock;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::mpsc::Sender;
|
use std::sync::mpsc::Sender;
|
||||||
|
@ -339,11 +338,11 @@ impl PropertyAnimation {
|
||||||
//
|
//
|
||||||
// TODO(emilio): Take rid of this mutex splitting SharedLayoutContex into a
|
// TODO(emilio): Take rid of this mutex splitting SharedLayoutContex into a
|
||||||
// cloneable part and a non-cloneable part..
|
// cloneable part and a non-cloneable part..
|
||||||
pub fn start_transitions_if_applicable<Impl: SelectorImplExt>(new_animations_sender: &Sender<Animation>,
|
pub fn start_transitions_if_applicable(new_animations_sender: &Sender<Animation>,
|
||||||
node: OpaqueNode,
|
node: OpaqueNode,
|
||||||
old_style: &ComputedValues,
|
old_style: &ComputedValues,
|
||||||
new_style: &mut Arc<ComputedValues>)
|
new_style: &mut Arc<ComputedValues>)
|
||||||
-> bool {
|
-> bool {
|
||||||
let mut had_animations = false;
|
let mut had_animations = false;
|
||||||
for i in 0..new_style.get_box().transition_property_count() {
|
for i in 0..new_style.get_box().transition_property_count() {
|
||||||
// Create any property animations, if applicable.
|
// Create any property animations, if applicable.
|
||||||
|
@ -372,11 +371,11 @@ pub fn start_transitions_if_applicable<Impl: SelectorImplExt>(new_animations_sen
|
||||||
had_animations
|
had_animations
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compute_style_for_animation_step<Impl: SelectorImplExt>(context: &SharedStyleContext<Impl>,
|
fn compute_style_for_animation_step(context: &SharedStyleContext,
|
||||||
step: &KeyframesStep,
|
step: &KeyframesStep,
|
||||||
previous_style: &ComputedValues,
|
previous_style: &ComputedValues,
|
||||||
style_from_cascade: &ComputedValues)
|
style_from_cascade: &ComputedValues)
|
||||||
-> ComputedValues {
|
-> ComputedValues {
|
||||||
match step.value {
|
match step.value {
|
||||||
// TODO: avoiding this spurious clone might involve having to create
|
// TODO: avoiding this spurious clone might involve having to create
|
||||||
// an Arc in the below (more common case).
|
// an Arc in the below (more common case).
|
||||||
|
@ -398,11 +397,11 @@ fn compute_style_for_animation_step<Impl: SelectorImplExt>(context: &SharedStyle
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn maybe_start_animations<Impl: SelectorImplExt>(context: &SharedStyleContext<Impl>,
|
pub fn maybe_start_animations(context: &SharedStyleContext,
|
||||||
new_animations_sender: &Sender<Animation>,
|
new_animations_sender: &Sender<Animation>,
|
||||||
node: OpaqueNode,
|
node: OpaqueNode,
|
||||||
new_style: &Arc<ComputedValues>) -> bool
|
new_style: &Arc<ComputedValues>)
|
||||||
{
|
-> bool {
|
||||||
let mut had_animations = false;
|
let mut had_animations = false;
|
||||||
|
|
||||||
let box_style = new_style.get_box();
|
let box_style = new_style.get_box();
|
||||||
|
@ -488,12 +487,11 @@ pub fn update_style_for_animation_frame(mut new_style: &mut Arc<ComputedValues>,
|
||||||
}
|
}
|
||||||
/// Updates a single animation and associated style based on the current time.
|
/// Updates a single animation and associated style based on the current time.
|
||||||
/// If `damage` is provided, inserts the appropriate restyle damage.
|
/// If `damage` is provided, inserts the appropriate restyle damage.
|
||||||
pub fn update_style_for_animation<Damage, Impl>(context: &SharedStyleContext<Impl>,
|
pub fn update_style_for_animation<Damage>(context: &SharedStyleContext,
|
||||||
animation: &Animation,
|
animation: &Animation,
|
||||||
style: &mut Arc<ComputedValues>,
|
style: &mut Arc<ComputedValues>,
|
||||||
damage: Option<&mut Damage>)
|
damage: Option<&mut Damage>)
|
||||||
where Impl: SelectorImplExt,
|
where Damage: TRestyleDamage {
|
||||||
Damage: TRestyleDamage {
|
|
||||||
debug!("update_style_for_animation: entering");
|
debug!("update_style_for_animation: entering");
|
||||||
debug_assert!(!animation.is_expired());
|
debug_assert!(!animation.is_expired());
|
||||||
match *animation {
|
match *animation {
|
||||||
|
|
|
@ -10,7 +10,6 @@ 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;
|
||||||
|
@ -30,7 +29,7 @@ impl LocalStyleContextCreationInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SharedStyleContext<Impl: SelectorImplExt> {
|
pub struct SharedStyleContext {
|
||||||
/// The current viewport size.
|
/// The current viewport size.
|
||||||
pub viewport_size: Size2D<Au>,
|
pub viewport_size: Size2D<Au>,
|
||||||
|
|
||||||
|
@ -38,7 +37,7 @@ pub struct SharedStyleContext<Impl: SelectorImplExt> {
|
||||||
pub screen_size_changed: bool,
|
pub screen_size_changed: bool,
|
||||||
|
|
||||||
/// The CSS selector stylist.
|
/// The CSS selector stylist.
|
||||||
pub stylist: Arc<Stylist<Impl>>,
|
pub stylist: Arc<Stylist>,
|
||||||
|
|
||||||
/// 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.
|
||||||
|
@ -78,8 +77,8 @@ impl LocalStyleContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait StyleContext<'a, Impl: SelectorImplExt> {
|
pub trait StyleContext<'a> {
|
||||||
fn shared_context(&self) -> &'a SharedStyleContext<Impl>;
|
fn shared_context(&self) -> &'a SharedStyleContext;
|
||||||
fn local_context(&self) -> &LocalStyleContext;
|
fn local_context(&self) -> &LocalStyleContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,26 +5,25 @@
|
||||||
//! Per-node data used in style calculation.
|
//! Per-node data used in style calculation.
|
||||||
|
|
||||||
use properties::ComputedValues;
|
use properties::ComputedValues;
|
||||||
use selectors::parser::SelectorImpl;
|
use selector_impl::PseudoElement;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::hash::BuildHasherDefault;
|
use std::hash::BuildHasherDefault;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::atomic::AtomicIsize;
|
use std::sync::atomic::AtomicIsize;
|
||||||
|
|
||||||
pub struct PrivateStyleData<Impl: SelectorImpl> {
|
pub struct PrivateStyleData {
|
||||||
/// 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 each pseudo-element (if any).
|
/// The results of CSS styling for each pseudo-element (if any).
|
||||||
pub per_pseudo: HashMap<Impl::PseudoElement, Arc<ComputedValues>,
|
pub per_pseudo: HashMap<PseudoElement, Arc<ComputedValues>,
|
||||||
BuildHasherDefault<::fnv::FnvHasher>>,
|
BuildHasherDefault<::fnv::FnvHasher>>,
|
||||||
|
|
||||||
/// Information needed during parallel traversals.
|
/// Information needed during parallel traversals.
|
||||||
pub parallel: DomParallelInfo,
|
pub parallel: DomParallelInfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Impl> PrivateStyleData<Impl>
|
impl PrivateStyleData {
|
||||||
where Impl: SelectorImpl {
|
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
PrivateStyleData {
|
PrivateStyleData {
|
||||||
style: None,
|
style: None,
|
||||||
|
|
|
@ -144,18 +144,15 @@ pub trait TNode : Sized + Copy + Clone {
|
||||||
|
|
||||||
/// Borrows the PrivateStyleData without checks.
|
/// Borrows the PrivateStyleData without checks.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
unsafe fn borrow_data_unchecked(&self)
|
unsafe fn borrow_data_unchecked(&self) -> Option<*const PrivateStyleData>;
|
||||||
-> 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)
|
fn borrow_data(&self) -> Option<Ref<PrivateStyleData>>;
|
||||||
-> 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)
|
fn mutate_data(&self) -> Option<RefMut<PrivateStyleData>>;
|
||||||
-> 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;
|
||||||
|
@ -176,9 +173,7 @@ pub trait TNode : 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,
|
fn style(&self, _context: &SharedStyleContext) -> Ref<Arc<ComputedValues>>
|
||||||
_context: &SharedStyleContext<<Self::ConcreteElement as Element>::Impl>)
|
|
||||||
-> Ref<Arc<ComputedValues>>
|
|
||||||
where <Self::ConcreteElement as Element>::Impl: SelectorImplExt {
|
where <Self::ConcreteElement as Element>::Impl: SelectorImplExt {
|
||||||
Ref::map(self.borrow_data().unwrap(), |data| data.style.as_ref().unwrap())
|
Ref::map(self.borrow_data().unwrap(), |data| data.style.as_ref().unwrap())
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,13 +7,13 @@ use selector_impl::{PseudoElementCascadeType, SelectorImplExt};
|
||||||
use selectors::parser::{ParserContext, SelectorImpl};
|
use selectors::parser::{ParserContext, SelectorImpl};
|
||||||
use string_cache::Atom;
|
use string_cache::Atom;
|
||||||
|
|
||||||
pub type Stylist = ::selector_matching::Stylist<GeckoSelectorImpl>;
|
pub type Stylist = ::selector_matching::Stylist;
|
||||||
pub type Stylesheet = ::stylesheets::Stylesheet<GeckoSelectorImpl>;
|
pub type Stylesheet = ::stylesheets::Stylesheet;
|
||||||
pub type SharedStyleContext = ::context::SharedStyleContext<GeckoSelectorImpl>;
|
pub type SharedStyleContext = ::context::SharedStyleContext;
|
||||||
pub type PrivateStyleData = ::data::PrivateStyleData<GeckoSelectorImpl>;
|
pub type PrivateStyleData = ::data::PrivateStyleData;
|
||||||
pub type Animation = ::animation::Animation;
|
pub type Animation = ::animation::Animation;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct GeckoSelectorImpl;
|
pub struct GeckoSelectorImpl;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
|
|
|
@ -97,7 +97,7 @@ pub mod selector_impl;
|
||||||
pub mod selector_matching;
|
pub mod selector_matching;
|
||||||
pub mod sequential;
|
pub mod sequential;
|
||||||
pub mod servo;
|
pub mod servo;
|
||||||
pub mod servo_selector_impl;
|
#[cfg(feature = "servo")] pub mod servo_selector_impl;
|
||||||
pub mod sink;
|
pub mod sink;
|
||||||
pub mod str;
|
pub mod str;
|
||||||
pub mod stylesheets;
|
pub mod stylesheets;
|
||||||
|
|
|
@ -13,7 +13,7 @@ use context::{StyleContext, 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::{ElementExt, SelectorImplExt};
|
use selector_impl::{ElementExt, SelectorImplExt, TheSelectorImpl, PseudoElement};
|
||||||
use selector_matching::{DeclarationBlock, Stylist};
|
use selector_matching::{DeclarationBlock, Stylist};
|
||||||
use selectors::Element;
|
use selectors::Element;
|
||||||
use selectors::bloom::BloomFilter;
|
use selectors::bloom::BloomFilter;
|
||||||
|
@ -48,9 +48,9 @@ fn create_common_style_affecting_attributes_from_element<E: TElement>(element: &
|
||||||
flags
|
flags
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ApplicableDeclarations<Impl: SelectorImplExt> {
|
pub struct ApplicableDeclarations {
|
||||||
pub normal: SmallVec<[DeclarationBlock; 16]>,
|
pub normal: SmallVec<[DeclarationBlock; 16]>,
|
||||||
pub per_pseudo: HashMap<Impl::PseudoElement,
|
pub per_pseudo: HashMap<PseudoElement,
|
||||||
Vec<DeclarationBlock>,
|
Vec<DeclarationBlock>,
|
||||||
BuildHasherDefault<::fnv::FnvHasher>>,
|
BuildHasherDefault<::fnv::FnvHasher>>,
|
||||||
|
|
||||||
|
@ -58,15 +58,15 @@ pub struct ApplicableDeclarations<Impl: SelectorImplExt> {
|
||||||
pub normal_shareable: bool,
|
pub normal_shareable: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Impl: SelectorImplExt> ApplicableDeclarations<Impl> {
|
impl ApplicableDeclarations {
|
||||||
pub fn new() -> ApplicableDeclarations<Impl> {
|
pub fn new() -> Self {
|
||||||
let mut applicable_declarations = ApplicableDeclarations {
|
let mut applicable_declarations = ApplicableDeclarations {
|
||||||
normal: SmallVec::new(),
|
normal: SmallVec::new(),
|
||||||
per_pseudo: HashMap::with_hasher(Default::default()),
|
per_pseudo: HashMap::with_hasher(Default::default()),
|
||||||
normal_shareable: false,
|
normal_shareable: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
Impl::each_eagerly_cascaded_pseudo_element(|pseudo| {
|
TheSelectorImpl::each_eagerly_cascaded_pseudo_element(|pseudo| {
|
||||||
applicable_declarations.per_pseudo.insert(pseudo, vec![]);
|
applicable_declarations.per_pseudo.insert(pseudo, vec![]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -377,7 +377,7 @@ trait PrivateMatchMethods: TNode
|
||||||
shareable: bool,
|
shareable: bool,
|
||||||
animate_properties: bool)
|
animate_properties: bool)
|
||||||
-> (Self::ConcreteRestyleDamage, Arc<ComputedValues>)
|
-> (Self::ConcreteRestyleDamage, Arc<ComputedValues>)
|
||||||
where Ctx: StyleContext<'a, <Self::ConcreteElement as Element>::Impl> {
|
where Ctx: StyleContext<'a> {
|
||||||
let mut cacheable = true;
|
let mut cacheable = true;
|
||||||
let shared_context = context.shared_context();
|
let shared_context = context.shared_context();
|
||||||
if animate_properties {
|
if animate_properties {
|
||||||
|
@ -421,7 +421,7 @@ trait PrivateMatchMethods: TNode
|
||||||
let new_animations_sender = &context.local_context().new_animations_sender;
|
let new_animations_sender = &context.local_context().new_animations_sender;
|
||||||
let this_opaque = self.opaque();
|
let this_opaque = self.opaque();
|
||||||
// Trigger any present animations if necessary.
|
// Trigger any present animations if necessary.
|
||||||
let mut animations_started = animation::maybe_start_animations::<<Self::ConcreteElement as Element>::Impl>(
|
let mut animations_started = animation::maybe_start_animations(
|
||||||
&shared_context,
|
&shared_context,
|
||||||
new_animations_sender,
|
new_animations_sender,
|
||||||
this_opaque,
|
this_opaque,
|
||||||
|
@ -431,7 +431,7 @@ trait PrivateMatchMethods: TNode
|
||||||
// to its old value if it did trigger a transition.
|
// to its old value if it did trigger a transition.
|
||||||
if let Some(ref style) = style {
|
if let Some(ref style) = style {
|
||||||
animations_started |=
|
animations_started |=
|
||||||
animation::start_transitions_if_applicable::<<Self::ConcreteElement as Element>::Impl>(
|
animation::start_transitions_if_applicable(
|
||||||
new_animations_sender,
|
new_animations_sender,
|
||||||
this_opaque,
|
this_opaque,
|
||||||
&**style,
|
&**style,
|
||||||
|
@ -455,7 +455,7 @@ trait PrivateMatchMethods: TNode
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_animations_for_cascade(&self,
|
fn update_animations_for_cascade(&self,
|
||||||
context: &SharedStyleContext<<Self::ConcreteElement as Element>::Impl>,
|
context: &SharedStyleContext,
|
||||||
style: &mut Option<&mut Arc<ComputedValues>>)
|
style: &mut Option<&mut Arc<ComputedValues>>)
|
||||||
-> bool {
|
-> bool {
|
||||||
let style = match *style {
|
let style = match *style {
|
||||||
|
@ -506,8 +506,8 @@ trait PrivateMatchMethods: TNode
|
||||||
// See #12171 and the associated PR for an example where this
|
// See #12171 and the associated PR for an example where this
|
||||||
// happened while debugging other release panic.
|
// happened while debugging other release panic.
|
||||||
if !running_animation.is_expired() {
|
if !running_animation.is_expired() {
|
||||||
animation::update_style_for_animation::<Self::ConcreteRestyleDamage,
|
animation::update_style_for_animation::<Self::ConcreteRestyleDamage>(
|
||||||
<Self::ConcreteElement as Element>::Impl>(context, running_animation, style, None);
|
context, running_animation, style, None);
|
||||||
running_animation.mark_as_expired();
|
running_animation.mark_as_expired();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -530,7 +530,7 @@ trait PrivateElementMatchMethods: TElement {
|
||||||
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)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -552,12 +552,11 @@ trait PrivateElementMatchMethods: TElement {
|
||||||
|
|
||||||
impl<E: TElement> PrivateElementMatchMethods for E {}
|
impl<E: TElement> PrivateElementMatchMethods for E {}
|
||||||
|
|
||||||
pub trait ElementMatchMethods : TElement
|
pub trait ElementMatchMethods : TElement {
|
||||||
where Self::Impl: SelectorImplExt {
|
|
||||||
fn match_element(&self,
|
fn match_element(&self,
|
||||||
stylist: &Stylist<Self::Impl>,
|
stylist: &Stylist,
|
||||||
parent_bf: Option<&BloomFilter>,
|
parent_bf: Option<&BloomFilter>,
|
||||||
applicable_declarations: &mut ApplicableDeclarations<Self::Impl>)
|
applicable_declarations: &mut ApplicableDeclarations)
|
||||||
-> bool {
|
-> bool {
|
||||||
let style_attribute = self.style_attribute().as_ref();
|
let style_attribute = self.style_attribute().as_ref();
|
||||||
|
|
||||||
|
@ -567,7 +566,7 @@ pub trait ElementMatchMethods : TElement
|
||||||
style_attribute,
|
style_attribute,
|
||||||
None,
|
None,
|
||||||
&mut applicable_declarations.normal);
|
&mut applicable_declarations.normal);
|
||||||
Self::Impl::each_eagerly_cascaded_pseudo_element(|pseudo| {
|
TheSelectorImpl::each_eagerly_cascaded_pseudo_element(|pseudo| {
|
||||||
stylist.push_applicable_declarations(self,
|
stylist.push_applicable_declarations(self,
|
||||||
parent_bf,
|
parent_bf,
|
||||||
None,
|
None,
|
||||||
|
@ -669,11 +668,8 @@ pub trait MatchMethods : TNode {
|
||||||
unsafe fn cascade_node<'a, Ctx>(&self,
|
unsafe fn cascade_node<'a, Ctx>(&self,
|
||||||
context: &Ctx,
|
context: &Ctx,
|
||||||
parent: Option<Self>,
|
parent: Option<Self>,
|
||||||
applicable_declarations:
|
applicable_declarations: &ApplicableDeclarations)
|
||||||
&ApplicableDeclarations<<Self::ConcreteElement as Element>::Impl>)
|
where Ctx: StyleContext<'a> {
|
||||||
where <Self::ConcreteElement as Element>::Impl: SelectorImplExt,
|
|
||||||
Ctx: StyleContext<'a, <Self::ConcreteElement as Element>::Impl>
|
|
||||||
{
|
|
||||||
// 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.
|
||||||
//
|
//
|
||||||
|
|
|
@ -6,10 +6,11 @@
|
||||||
|
|
||||||
use attr::{AttrIdentifier, AttrValue};
|
use attr::{AttrIdentifier, AttrValue};
|
||||||
use element_state::*;
|
use element_state::*;
|
||||||
use selector_impl::SelectorImplExt;
|
use selector_impl::{SelectorImplExt, TheSelectorImpl, AttrString};
|
||||||
use selectors::matching::matches_compound_selector;
|
use selectors::matching::matches_compound_selector;
|
||||||
use selectors::parser::{AttrSelector, Combinator, CompoundSelector, SelectorImpl, SimpleSelector};
|
use selectors::parser::{AttrSelector, Combinator, CompoundSelector, SelectorImpl, SimpleSelector};
|
||||||
use selectors::{Element, MatchAttrGeneric};
|
use selectors::{Element, MatchAttrGeneric};
|
||||||
|
#[cfg(feature = "gecko")] use selectors::MatchAttr;
|
||||||
use std::clone::Clone;
|
use std::clone::Clone;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use string_cache::{Atom, BorrowedAtom, BorrowedNamespace, Namespace};
|
use string_cache::{Atom, BorrowedAtom, BorrowedNamespace, Namespace};
|
||||||
|
@ -88,14 +89,14 @@ static EMPTY_SNAPSHOT: ElementSnapshot = ElementSnapshot { state: None, attrs: N
|
||||||
// geckolib, but in the mean time we can just use the trait parameters to
|
// geckolib, but in the mean time we can just use the trait parameters to
|
||||||
// specialize it to the Servo configuration.
|
// specialize it to the Servo configuration.
|
||||||
struct ElementWrapper<'a, E>
|
struct ElementWrapper<'a, E>
|
||||||
where E: Element<AttrString=String>,
|
where E: Element<AttrString=AttrString>,
|
||||||
E::Impl: SelectorImplExt {
|
E::Impl: SelectorImplExt {
|
||||||
element: E,
|
element: E,
|
||||||
snapshot: &'a ElementSnapshot,
|
snapshot: &'a ElementSnapshot,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, E> ElementWrapper<'a, E>
|
impl<'a, E> ElementWrapper<'a, E>
|
||||||
where E: Element<AttrString=String>,
|
where E: Element<AttrString=AttrString>,
|
||||||
E::Impl: SelectorImplExt {
|
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 }
|
||||||
|
@ -108,7 +109,7 @@ impl<'a, E> ElementWrapper<'a, E>
|
||||||
|
|
||||||
#[cfg(not(feature = "gecko"))]
|
#[cfg(not(feature = "gecko"))]
|
||||||
impl<'a, E> MatchAttrGeneric for ElementWrapper<'a, E>
|
impl<'a, E> MatchAttrGeneric for ElementWrapper<'a, E>
|
||||||
where E: Element<AttrString=String>,
|
where E: Element<AttrString=AttrString>,
|
||||||
E: MatchAttrGeneric,
|
E: MatchAttrGeneric,
|
||||||
E::Impl: SelectorImplExt {
|
E::Impl: SelectorImplExt {
|
||||||
fn match_attr<F>(&self, attr: &AttrSelector, test: F) -> bool
|
fn match_attr<F>(&self, attr: &AttrSelector, test: F) -> bool
|
||||||
|
@ -129,18 +130,46 @@ impl<'a, E> MatchAttrGeneric for ElementWrapper<'a, E>
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
impl<'a, E> MatchAttrGeneric for ElementWrapper<'a, E>
|
impl<'a, E> MatchAttr for ElementWrapper<'a, E>
|
||||||
where E: Element<AttrString=String>,
|
where E: Element<AttrString=AttrString>,
|
||||||
E: MatchAttrGeneric,
|
|
||||||
E::Impl: SelectorImplExt {
|
E::Impl: SelectorImplExt {
|
||||||
fn match_attr<F>(&self, _: &AttrSelector, _: F) -> bool
|
type AttrString = AttrString;
|
||||||
where F: Fn(&str) -> bool {
|
|
||||||
|
fn match_attr_has(&self, _attr: &AttrSelector) -> bool {
|
||||||
|
panic!("Not implemented for Gecko - this system will need to be redesigned");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn match_attr_equals(&self, _attr: &AttrSelector, _value: &Self::AttrString) -> bool {
|
||||||
|
panic!("Not implemented for Gecko - this system will need to be redesigned");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn match_attr_equals_ignore_ascii_case(&self, _attr: &AttrSelector, _value: &Self::AttrString) -> bool {
|
||||||
|
panic!("Not implemented for Gecko - this system will need to be redesigned");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn match_attr_includes(&self, _attr: &AttrSelector, _value: &Self::AttrString) -> bool {
|
||||||
|
panic!("Not implemented for Gecko - this system will need to be redesigned");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn match_attr_dash(&self, _attr: &AttrSelector, _value: &Self::AttrString) -> bool {
|
||||||
|
panic!("Not implemented for Gecko - this system will need to be redesigned");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn match_attr_prefix(&self, _attr: &AttrSelector, _value: &Self::AttrString) -> bool {
|
||||||
|
panic!("Not implemented for Gecko - this system will need to be redesigned");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn match_attr_substring(&self, _attr: &AttrSelector, _value: &Self::AttrString) -> bool {
|
||||||
|
panic!("Not implemented for Gecko - this system will need to be redesigned");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn match_attr_suffix(&self, _attr: &AttrSelector, _value: &Self::AttrString) -> bool {
|
||||||
panic!("Not implemented for Gecko - this system will need to be redesigned");
|
panic!("Not implemented for Gecko - this system will need to be redesigned");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, E> Element for ElementWrapper<'a, E>
|
impl<'a, E> Element for ElementWrapper<'a, E>
|
||||||
where E: Element<AttrString=String>,
|
where E: Element<AttrString=AttrString>,
|
||||||
E: MatchAttrGeneric,
|
E: MatchAttrGeneric,
|
||||||
E::Impl: SelectorImplExt {
|
E::Impl: SelectorImplExt {
|
||||||
type Impl = E::Impl;
|
type Impl = E::Impl;
|
||||||
|
@ -213,14 +242,14 @@ impl<'a, E> Element for ElementWrapper<'a, E>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn selector_to_state<Impl: SelectorImplExt>(sel: &SimpleSelector<Impl>) -> ElementState {
|
fn selector_to_state(sel: &SimpleSelector<TheSelectorImpl>) -> ElementState {
|
||||||
match *sel {
|
match *sel {
|
||||||
SimpleSelector::NonTSPseudoClass(ref pc) => Impl::pseudo_class_state_flag(pc),
|
SimpleSelector::NonTSPseudoClass(ref pc) => TheSelectorImpl::pseudo_class_state_flag(pc),
|
||||||
_ => ElementState::empty(),
|
_ => ElementState::empty(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_attr_selector<Impl: SelectorImpl>(sel: &SimpleSelector<Impl>) -> bool {
|
fn is_attr_selector(sel: &SimpleSelector<TheSelectorImpl>) -> bool {
|
||||||
match *sel {
|
match *sel {
|
||||||
SimpleSelector::ID(_) |
|
SimpleSelector::ID(_) |
|
||||||
SimpleSelector::Class(_) |
|
SimpleSelector::Class(_) |
|
||||||
|
@ -287,24 +316,24 @@ impl Sensitivities {
|
||||||
// elements in the document.
|
// elements in the document.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
struct Dependency<Impl: SelectorImplExt> {
|
struct Dependency {
|
||||||
selector: Arc<CompoundSelector<Impl>>,
|
selector: Arc<CompoundSelector<TheSelectorImpl>>,
|
||||||
combinator: Option<Combinator>,
|
combinator: Option<Combinator>,
|
||||||
sensitivities: Sensitivities,
|
sensitivities: Sensitivities,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
pub struct DependencySet<Impl: SelectorImplExt> {
|
pub struct DependencySet {
|
||||||
deps: Vec<Dependency<Impl>>,
|
deps: Vec<Dependency>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Impl: SelectorImplExt> DependencySet<Impl> {
|
impl DependencySet {
|
||||||
pub fn new() -> DependencySet<Impl> {
|
pub fn new() -> Self {
|
||||||
DependencySet { deps: Vec::new() }
|
DependencySet { deps: Vec::new() }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn note_selector(&mut self, selector: Arc<CompoundSelector<Impl>>) {
|
pub fn note_selector(&mut self, selector: Arc<CompoundSelector<TheSelectorImpl>>) {
|
||||||
let mut cur = selector;
|
let mut cur = selector;
|
||||||
let mut combinator: Option<Combinator> = None;
|
let mut combinator: Option<Combinator> = None;
|
||||||
loop {
|
loop {
|
||||||
|
@ -338,10 +367,10 @@ impl<Impl: SelectorImplExt> DependencySet<Impl> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Impl: SelectorImplExt<AttrString=String>> DependencySet<Impl> {
|
impl DependencySet {
|
||||||
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=Impl, AttrString=Impl::AttrString> + Clone + MatchAttrGeneric {
|
where E: Element<Impl=TheSelectorImpl, AttrString=AttrString> + Clone + MatchAttrGeneric {
|
||||||
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();
|
||||||
|
|
|
@ -10,6 +10,8 @@ use selectors::parser::SelectorImpl;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use stylesheets::Stylesheet;
|
use stylesheets::Stylesheet;
|
||||||
|
|
||||||
|
pub type AttrString = <TheSelectorImpl as SelectorImpl>::AttrString;
|
||||||
|
|
||||||
#[cfg(feature = "servo")]
|
#[cfg(feature = "servo")]
|
||||||
pub use servo_selector_impl::ServoSelectorImpl;
|
pub use servo_selector_impl::ServoSelectorImpl;
|
||||||
|
|
||||||
|
@ -66,7 +68,7 @@ impl PseudoElementCascadeType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ElementExt: Element {
|
pub trait ElementExt: Element<Impl=TheSelectorImpl, AttrString=<TheSelectorImpl as SelectorImpl>::AttrString> {
|
||||||
fn is_link(&self) -> bool;
|
fn is_link(&self) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +104,7 @@ pub trait SelectorImplExt : SelectorImpl + Clone + Debug + Sized + 'static {
|
||||||
|
|
||||||
fn pseudo_class_state_flag(pc: &Self::NonTSPseudoClass) -> ElementState;
|
fn pseudo_class_state_flag(pc: &Self::NonTSPseudoClass) -> ElementState;
|
||||||
|
|
||||||
fn get_user_or_user_agent_stylesheets() -> &'static [Stylesheet<Self>];
|
fn get_user_or_user_agent_stylesheets() -> &'static [Stylesheet];
|
||||||
|
|
||||||
fn get_quirks_mode_stylesheet() -> Option<&'static Stylesheet<Self>>;
|
fn get_quirks_mode_stylesheet() -> Option<&'static Stylesheet>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,11 +11,10 @@ use keyframes::KeyframesAnimation;
|
||||||
use media_queries::{Device, MediaType};
|
use media_queries::{Device, MediaType};
|
||||||
use properties::{self, PropertyDeclaration, PropertyDeclarationBlock, ComputedValues};
|
use properties::{self, PropertyDeclaration, PropertyDeclarationBlock, ComputedValues};
|
||||||
use restyle_hints::{ElementSnapshot, RestyleHint, DependencySet};
|
use restyle_hints::{ElementSnapshot, RestyleHint, DependencySet};
|
||||||
use selector_impl::SelectorImplExt;
|
use selector_impl::{SelectorImplExt, TheSelectorImpl, PseudoElement, AttrString};
|
||||||
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 selectors::{Element, MatchAttrGeneric};
|
use selectors::{Element, MatchAttrGeneric};
|
||||||
use sink::Push;
|
use sink::Push;
|
||||||
use smallvec::VecLike;
|
use smallvec::VecLike;
|
||||||
|
@ -47,7 +46,7 @@ pub type DeclarationBlock = GenericDeclarationBlock<Vec<PropertyDeclaration>>;
|
||||||
/// regular builds, or `GeckoSelectorImpl`, the implementation used in the
|
/// regular builds, or `GeckoSelectorImpl`, the implementation used in the
|
||||||
/// geckolib port.
|
/// geckolib port.
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
pub struct Stylist<Impl: SelectorImplExt> {
|
pub struct Stylist {
|
||||||
/// Device that the stylist is currently evaluating against.
|
/// Device that the stylist is currently evaluating against.
|
||||||
pub device: Device,
|
pub device: Device,
|
||||||
|
|
||||||
|
@ -62,12 +61,12 @@ pub struct Stylist<Impl: SelectorImplExt> {
|
||||||
|
|
||||||
/// 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<Impl>,
|
element_map: PerPseudoElementSelectorMap,
|
||||||
|
|
||||||
/// The selector maps corresponding to a given pseudo-element
|
/// The selector maps corresponding to a given pseudo-element
|
||||||
/// (depending on the implementation)
|
/// (depending on the implementation)
|
||||||
pseudos_map: HashMap<Impl::PseudoElement,
|
pseudos_map: HashMap<PseudoElement,
|
||||||
PerPseudoElementSelectorMap<Impl>,
|
PerPseudoElementSelectorMap,
|
||||||
BuildHasherDefault<::fnv::FnvHasher>>,
|
BuildHasherDefault<::fnv::FnvHasher>>,
|
||||||
|
|
||||||
/// A map with all the animations indexed by name.
|
/// A map with all the animations indexed by name.
|
||||||
|
@ -76,19 +75,19 @@ pub struct Stylist<Impl: SelectorImplExt> {
|
||||||
/// Applicable declarations for a given non-eagerly cascaded pseudo-element.
|
/// Applicable declarations for a given non-eagerly cascaded pseudo-element.
|
||||||
/// These are eagerly computed once, and then used to resolve the new
|
/// These are eagerly computed once, and then used to resolve the new
|
||||||
/// computed values on the fly on layout.
|
/// computed values on the fly on layout.
|
||||||
precomputed_pseudo_element_decls: HashMap<Impl::PseudoElement,
|
precomputed_pseudo_element_decls: HashMap<PseudoElement,
|
||||||
Vec<DeclarationBlock>,
|
Vec<DeclarationBlock>,
|
||||||
BuildHasherDefault<::fnv::FnvHasher>>,
|
BuildHasherDefault<::fnv::FnvHasher>>,
|
||||||
|
|
||||||
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<Impl>,
|
state_deps: DependencySet,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Impl: SelectorImplExt> Stylist<Impl> {
|
impl Stylist {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(device: Device) -> Stylist<Impl> {
|
pub fn new(device: Device) -> Self {
|
||||||
let mut stylist = Stylist {
|
let mut stylist = Stylist {
|
||||||
viewport_constraints: None,
|
viewport_constraints: None,
|
||||||
device: device,
|
device: device,
|
||||||
|
@ -103,7 +102,7 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
|
||||||
state_deps: DependencySet::new(),
|
state_deps: DependencySet::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
Impl::each_eagerly_cascaded_pseudo_element(|pseudo| {
|
TheSelectorImpl::each_eagerly_cascaded_pseudo_element(|pseudo| {
|
||||||
stylist.pseudos_map.insert(pseudo, PerPseudoElementSelectorMap::new());
|
stylist.pseudos_map.insert(pseudo, PerPseudoElementSelectorMap::new());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -112,9 +111,7 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
|
||||||
stylist
|
stylist
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self, doc_stylesheets: &[Arc<Stylesheet<Impl>>],
|
pub fn update(&mut self, doc_stylesheets: &[Arc<Stylesheet>], 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;
|
||||||
}
|
}
|
||||||
|
@ -122,7 +119,7 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
|
||||||
self.element_map = PerPseudoElementSelectorMap::new();
|
self.element_map = PerPseudoElementSelectorMap::new();
|
||||||
self.pseudos_map = HashMap::with_hasher(Default::default());
|
self.pseudos_map = HashMap::with_hasher(Default::default());
|
||||||
self.animations = HashMap::with_hasher(Default::default());
|
self.animations = HashMap::with_hasher(Default::default());
|
||||||
Impl::each_eagerly_cascaded_pseudo_element(|pseudo| {
|
TheSelectorImpl::each_eagerly_cascaded_pseudo_element(|pseudo| {
|
||||||
self.pseudos_map.insert(pseudo, PerPseudoElementSelectorMap::new());
|
self.pseudos_map.insert(pseudo, PerPseudoElementSelectorMap::new());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -130,12 +127,12 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
|
||||||
self.rules_source_order = 0;
|
self.rules_source_order = 0;
|
||||||
self.state_deps.clear();
|
self.state_deps.clear();
|
||||||
|
|
||||||
for ref stylesheet in Impl::get_user_or_user_agent_stylesheets().iter() {
|
for ref stylesheet in TheSelectorImpl::get_user_or_user_agent_stylesheets().iter() {
|
||||||
self.add_stylesheet(&stylesheet);
|
self.add_stylesheet(&stylesheet);
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.quirks_mode {
|
if self.quirks_mode {
|
||||||
if let Some(s) = Impl::get_quirks_mode_stylesheet() {
|
if let Some(s) = TheSelectorImpl::get_quirks_mode_stylesheet() {
|
||||||
self.add_stylesheet(s);
|
self.add_stylesheet(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -148,7 +145,7 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_stylesheet(&mut self, stylesheet: &Stylesheet<Impl>) {
|
fn add_stylesheet(&mut self, stylesheet: &Stylesheet) {
|
||||||
if !stylesheet.is_effective_for_device(&self.device) {
|
if !stylesheet.is_effective_for_device(&self.device) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -212,7 +209,7 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Impl::each_precomputed_pseudo_element(|pseudo| {
|
TheSelectorImpl::each_precomputed_pseudo_element(|pseudo| {
|
||||||
// TODO: Consider not doing this and just getting the rules on the
|
// TODO: Consider not doing this and just getting the rules on the
|
||||||
// fly. It should be a bit slower, but we'd take rid of the
|
// fly. It should be a bit slower, but we'd take rid of the
|
||||||
// extra field, and avoid this precomputation entirely.
|
// extra field, and avoid this precomputation entirely.
|
||||||
|
@ -230,10 +227,10 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
|
||||||
/// Computes the style for a given "precomputed" pseudo-element, taking the
|
/// Computes the style for a given "precomputed" pseudo-element, taking the
|
||||||
/// universal rules and applying them.
|
/// universal rules and applying them.
|
||||||
pub fn precomputed_values_for_pseudo(&self,
|
pub fn precomputed_values_for_pseudo(&self,
|
||||||
pseudo: &Impl::PseudoElement,
|
pseudo: &PseudoElement,
|
||||||
parent: Option<&Arc<ComputedValues>>)
|
parent: Option<&Arc<ComputedValues>>)
|
||||||
-> Option<Arc<ComputedValues>> {
|
-> Option<Arc<ComputedValues>> {
|
||||||
debug_assert!(Impl::pseudo_element_cascade_type(pseudo).is_precomputed());
|
debug_assert!(TheSelectorImpl::pseudo_element_cascade_type(pseudo).is_precomputed());
|
||||||
if let Some(declarations) = self.precomputed_pseudo_element_decls.get(pseudo) {
|
if let Some(declarations) = self.precomputed_pseudo_element_decls.get(pseudo) {
|
||||||
let (computed, _) =
|
let (computed, _) =
|
||||||
properties::cascade(self.device.au_viewport_size(),
|
properties::cascade(self.device.au_viewport_size(),
|
||||||
|
@ -249,12 +246,12 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
|
||||||
|
|
||||||
pub fn lazily_compute_pseudo_element_style<E>(&self,
|
pub fn lazily_compute_pseudo_element_style<E>(&self,
|
||||||
element: &E,
|
element: &E,
|
||||||
pseudo: &Impl::PseudoElement,
|
pseudo: &PseudoElement,
|
||||||
parent: &Arc<ComputedValues>)
|
parent: &Arc<ComputedValues>)
|
||||||
-> Option<Arc<ComputedValues>>
|
-> Option<Arc<ComputedValues>>
|
||||||
where E: Element<Impl=Impl, AttrString=Impl::AttrString> +
|
where E: Element<Impl=TheSelectorImpl, AttrString=AttrString> +
|
||||||
PresentationalHintsSynthetizer {
|
PresentationalHintsSynthetizer {
|
||||||
debug_assert!(Impl::pseudo_element_cascade_type(pseudo).is_lazy());
|
debug_assert!(TheSelectorImpl::pseudo_element_cascade_type(pseudo).is_lazy());
|
||||||
if self.pseudos_map.get(pseudo).is_none() {
|
if self.pseudos_map.get(pseudo).is_none() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -277,7 +274,7 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
|
||||||
Some(Arc::new(computed))
|
Some(Arc::new(computed))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_device(&mut self, mut device: Device, stylesheets: &[Arc<Stylesheet<Impl>>]) {
|
pub fn set_device(&mut self, mut device: Device, stylesheets: &[Arc<Stylesheet>]) {
|
||||||
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();
|
||||||
|
@ -315,17 +312,18 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
|
||||||
element: &E,
|
element: &E,
|
||||||
parent_bf: Option<&BloomFilter>,
|
parent_bf: Option<&BloomFilter>,
|
||||||
style_attribute: Option<&PropertyDeclarationBlock>,
|
style_attribute: Option<&PropertyDeclarationBlock>,
|
||||||
pseudo_element: Option<&Impl::PseudoElement>,
|
pseudo_element: Option<&PseudoElement>,
|
||||||
applicable_declarations: &mut V)
|
applicable_declarations: &mut V)
|
||||||
-> bool
|
-> bool
|
||||||
where E: Element<Impl=Impl, AttrString=Impl::AttrString> +
|
where E: Element<Impl=TheSelectorImpl, AttrString=AttrString> +
|
||||||
PresentationalHintsSynthetizer,
|
PresentationalHintsSynthetizer,
|
||||||
V: Push<DeclarationBlock> + VecLike<DeclarationBlock> {
|
V: Push<DeclarationBlock> + 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");
|
||||||
debug_assert!(pseudo_element.is_none() ||
|
debug_assert!(pseudo_element.is_none() ||
|
||||||
!Impl::pseudo_element_cascade_type(pseudo_element.as_ref().unwrap()).is_precomputed());
|
!TheSelectorImpl::pseudo_element_cascade_type(pseudo_element.as_ref().unwrap())
|
||||||
|
.is_precomputed());
|
||||||
|
|
||||||
let map = match pseudo_element {
|
let map = match pseudo_element {
|
||||||
Some(ref pseudo) => self.pseudos_map.get(pseudo).unwrap(),
|
Some(ref pseudo) => self.pseudos_map.get(pseudo).unwrap(),
|
||||||
|
@ -402,9 +400,7 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
|
||||||
pub fn animations(&self) -> &HashMap<Atom, KeyframesAnimation> {
|
pub fn animations(&self) -> &HashMap<Atom, KeyframesAnimation> {
|
||||||
&self.animations
|
&self.animations
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl<Impl: SelectorImplExt<AttrString=String>> Stylist<Impl> {
|
|
||||||
pub fn compute_restyle_hint<E>(&self, element: &E,
|
pub fn compute_restyle_hint<E>(&self, element: &E,
|
||||||
snapshot: &ElementSnapshot,
|
snapshot: &ElementSnapshot,
|
||||||
// NB: We need to pass current_state as an argument because
|
// NB: We need to pass current_state as an argument because
|
||||||
|
@ -413,7 +409,8 @@ impl<Impl: SelectorImplExt<AttrString=String>> Stylist<Impl> {
|
||||||
// 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=Impl, AttrString=String> + Clone + MatchAttrGeneric {
|
where E: Element<Impl=TheSelectorImpl, AttrString=AttrString>
|
||||||
|
+ Clone + MatchAttrGeneric {
|
||||||
self.state_deps.compute_hint(element, snapshot, current_state)
|
self.state_deps.compute_hint(element, snapshot, current_state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -421,18 +418,18 @@ impl<Impl: SelectorImplExt<AttrString=String>> Stylist<Impl> {
|
||||||
|
|
||||||
/// Map that contains the CSS rules for a given origin.
|
/// Map that contains the CSS rules for a given origin.
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
struct PerOriginSelectorMap<Impl: SelectorImpl> {
|
struct PerOriginSelectorMap {
|
||||||
/// Rules that contains at least one property declararion with
|
/// Rules that contains at least one property declararion with
|
||||||
/// normal importance.
|
/// normal importance.
|
||||||
normal: SelectorMap<Vec<PropertyDeclaration>, Impl>,
|
normal: SelectorMap<Vec<PropertyDeclaration>, TheSelectorImpl>,
|
||||||
/// Rules that contains at least one property declararion with
|
/// Rules that contains at least one property declararion with
|
||||||
/// !important.
|
/// !important.
|
||||||
important: SelectorMap<Vec<PropertyDeclaration>, Impl>,
|
important: SelectorMap<Vec<PropertyDeclaration>, TheSelectorImpl>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Impl: SelectorImpl> PerOriginSelectorMap<Impl> {
|
impl PerOriginSelectorMap {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn new() -> PerOriginSelectorMap<Impl> {
|
fn new() -> Self {
|
||||||
PerOriginSelectorMap {
|
PerOriginSelectorMap {
|
||||||
normal: SelectorMap::new(),
|
normal: SelectorMap::new(),
|
||||||
important: SelectorMap::new(),
|
important: SelectorMap::new(),
|
||||||
|
@ -443,18 +440,18 @@ impl<Impl: SelectorImpl> PerOriginSelectorMap<Impl> {
|
||||||
/// Map that contains the CSS rules for a specific PseudoElement
|
/// Map that contains the CSS rules for a specific PseudoElement
|
||||||
/// (or lack of PseudoElement).
|
/// (or lack of PseudoElement).
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
struct PerPseudoElementSelectorMap<Impl: SelectorImpl> {
|
struct PerPseudoElementSelectorMap {
|
||||||
/// Rules from user agent stylesheets
|
/// Rules from user agent stylesheets
|
||||||
user_agent: PerOriginSelectorMap<Impl>,
|
user_agent: PerOriginSelectorMap,
|
||||||
/// Rules from author stylesheets
|
/// Rules from author stylesheets
|
||||||
author: PerOriginSelectorMap<Impl>,
|
author: PerOriginSelectorMap,
|
||||||
/// Rules from user stylesheets
|
/// Rules from user stylesheets
|
||||||
user: PerOriginSelectorMap<Impl>,
|
user: PerOriginSelectorMap,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Impl: SelectorImpl> PerPseudoElementSelectorMap<Impl> {
|
impl PerPseudoElementSelectorMap {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn new() -> PerPseudoElementSelectorMap<Impl> {
|
fn new() -> Self {
|
||||||
PerPseudoElementSelectorMap {
|
PerPseudoElementSelectorMap {
|
||||||
user_agent: PerOriginSelectorMap::new(),
|
user_agent: PerOriginSelectorMap::new(),
|
||||||
author: PerOriginSelectorMap::new(),
|
author: PerOriginSelectorMap::new(),
|
||||||
|
@ -463,7 +460,7 @@ impl<Impl: SelectorImpl> PerPseudoElementSelectorMap<Impl> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn borrow_for_origin(&mut self, origin: &Origin) -> &mut PerOriginSelectorMap<Impl> {
|
fn borrow_for_origin(&mut self, origin: &Origin) -> &mut PerOriginSelectorMap {
|
||||||
match *origin {
|
match *origin {
|
||||||
Origin::UserAgent => &mut self.user_agent,
|
Origin::UserAgent => &mut self.user_agent,
|
||||||
Origin::Author => &mut self.author,
|
Origin::Author => &mut self.author,
|
||||||
|
|
|
@ -7,12 +7,11 @@ use animation;
|
||||||
use context;
|
use context;
|
||||||
use data;
|
use data;
|
||||||
use selector_matching;
|
use selector_matching;
|
||||||
use servo_selector_impl::ServoSelectorImpl;
|
|
||||||
use stylesheets;
|
use stylesheets;
|
||||||
|
|
||||||
pub type Stylesheet = stylesheets::Stylesheet<ServoSelectorImpl>;
|
pub type Stylesheet = stylesheets::Stylesheet;
|
||||||
pub type PrivateStyleData = data::PrivateStyleData<ServoSelectorImpl>;
|
pub type PrivateStyleData = data::PrivateStyleData;
|
||||||
pub type Stylist = selector_matching::Stylist<ServoSelectorImpl>;
|
pub type Stylist = selector_matching::Stylist;
|
||||||
pub type SharedStyleContext = context::SharedStyleContext<ServoSelectorImpl>;
|
pub type SharedStyleContext = context::SharedStyleContext;
|
||||||
pub type LocalStyleContextCreationInfo = context::LocalStyleContextCreationInfo;
|
pub type LocalStyleContextCreationInfo = context::LocalStyleContextCreationInfo;
|
||||||
pub type Animation = animation::Animation;
|
pub type Animation = animation::Animation;
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
use element_state::ElementState;
|
use element_state::ElementState;
|
||||||
use error_reporting::StdoutErrorReporter;
|
use error_reporting::StdoutErrorReporter;
|
||||||
use parser::ParserContextExtraData;
|
use parser::ParserContextExtraData;
|
||||||
use selector_impl::{SelectorImplExt, ElementExt, PseudoElementCascadeType};
|
use selector_impl::{SelectorImplExt, ElementExt, PseudoElementCascadeType, TheSelectorImpl};
|
||||||
use selectors::Element;
|
use selectors::Element;
|
||||||
use selectors::parser::{ParserContext, SelectorImpl};
|
use selectors::parser::{ParserContext, SelectorImpl};
|
||||||
use std::process;
|
use std::process;
|
||||||
|
@ -179,24 +179,24 @@ impl SelectorImplExt for ServoSelectorImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_user_or_user_agent_stylesheets() -> &'static [Stylesheet<Self>] {
|
fn get_user_or_user_agent_stylesheets() -> &'static [Stylesheet] {
|
||||||
&*USER_OR_USER_AGENT_STYLESHEETS
|
&*USER_OR_USER_AGENT_STYLESHEETS
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_quirks_mode_stylesheet() -> Option<&'static Stylesheet<Self>> {
|
fn get_quirks_mode_stylesheet() -> Option<&'static Stylesheet> {
|
||||||
Some(&*QUIRKS_MODE_STYLESHEET)
|
Some(&*QUIRKS_MODE_STYLESHEET)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: Element<Impl=ServoSelectorImpl, AttrString=String>> ElementExt for E {
|
impl<E: Element<Impl=TheSelectorImpl, AttrString=String>> ElementExt for E {
|
||||||
fn is_link(&self) -> bool {
|
fn is_link(&self) -> bool {
|
||||||
self.match_non_ts_pseudo_class(NonTSPseudoClass::AnyLink)
|
self.match_non_ts_pseudo_class(NonTSPseudoClass::AnyLink)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref USER_OR_USER_AGENT_STYLESHEETS: Vec<Stylesheet<ServoSelectorImpl>> = {
|
pub static ref USER_OR_USER_AGENT_STYLESHEETS: Vec<Stylesheet> = {
|
||||||
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?)
|
||||||
|
@ -229,7 +229,7 @@ lazy_static! {
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref QUIRKS_MODE_STYLESHEET: Stylesheet<ServoSelectorImpl> = {
|
pub static ref QUIRKS_MODE_STYLESHEET: Stylesheet = {
|
||||||
match read_resource_file("quirks-mode.css") {
|
match read_resource_file("quirks-mode.css") {
|
||||||
Ok(res) => {
|
Ok(res) => {
|
||||||
Stylesheet::from_bytes(
|
Stylesheet::from_bytes(
|
||||||
|
|
|
@ -13,11 +13,11 @@ use keyframes::{Keyframe, parse_keyframe_list};
|
||||||
use media_queries::{Device, MediaQueryList, parse_media_query_list};
|
use media_queries::{Device, MediaQueryList, parse_media_query_list};
|
||||||
use parser::{ParserContext, ParserContextExtraData, log_css_error};
|
use parser::{ParserContext, ParserContextExtraData, log_css_error};
|
||||||
use properties::{PropertyDeclarationBlock, parse_property_declaration_list};
|
use properties::{PropertyDeclarationBlock, parse_property_declaration_list};
|
||||||
use selectors::parser::{Selector, SelectorImpl, parse_selector_list};
|
use selector_impl::TheSelectorImpl;
|
||||||
|
use selectors::parser::{Selector, parse_selector_list};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
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;
|
||||||
|
@ -43,10 +43,10 @@ pub enum Origin {
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
pub struct Stylesheet<Impl: SelectorImpl> {
|
pub struct Stylesheet {
|
||||||
/// 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<Impl>>,
|
pub rules: Vec<CSSRule>,
|
||||||
/// 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,
|
||||||
|
@ -56,11 +56,11 @@ pub struct Stylesheet<Impl: SelectorImpl> {
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
pub enum CSSRule<Impl: SelectorImpl> {
|
pub enum CSSRule {
|
||||||
Charset(String),
|
Charset(String),
|
||||||
Namespace(Option<String>, Namespace),
|
Namespace(Option<String>, Namespace),
|
||||||
Style(StyleRule<Impl>),
|
Style(StyleRule),
|
||||||
Media(MediaRule<Impl>),
|
Media(MediaRule),
|
||||||
FontFace(FontFaceRule),
|
FontFace(FontFaceRule),
|
||||||
Viewport(ViewportRule),
|
Viewport(ViewportRule),
|
||||||
Keyframes(KeyframesRule),
|
Keyframes(KeyframesRule),
|
||||||
|
@ -76,13 +76,13 @@ pub struct KeyframesRule {
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
pub struct MediaRule<Impl: SelectorImpl> {
|
pub struct MediaRule {
|
||||||
pub media_queries: MediaQueryList,
|
pub media_queries: MediaQueryList,
|
||||||
pub rules: Vec<CSSRule<Impl>>,
|
pub rules: Vec<CSSRule>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<Impl: SelectorImpl> MediaRule<Impl> {
|
impl MediaRule {
|
||||||
#[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)
|
||||||
|
@ -91,18 +91,18 @@ impl<Impl: SelectorImpl> MediaRule<Impl> {
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
pub struct StyleRule<Impl: SelectorImpl> {
|
pub struct StyleRule {
|
||||||
pub selectors: Vec<Selector<Impl>>,
|
pub selectors: Vec<Selector<TheSelectorImpl>>,
|
||||||
pub declarations: PropertyDeclarationBlock,
|
pub declarations: PropertyDeclarationBlock,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<Impl: SelectorImpl> Stylesheet<Impl> {
|
impl Stylesheet {
|
||||||
pub fn from_bytes_iter<I: Iterator<Item=Vec<u8>>>(
|
pub fn from_bytes_iter<I: Iterator<Item=Vec<u8>>>(
|
||||||
input: I, base_url: Url, protocol_encoding_label: Option<&str>,
|
input: I, base_url: Url, protocol_encoding_label: Option<&str>,
|
||||||
environment_encoding: Option<EncodingRef>, origin: Origin,
|
environment_encoding: Option<EncodingRef>, origin: Origin,
|
||||||
error_reporter: Box<ParseErrorReporter + Send>,
|
error_reporter: Box<ParseErrorReporter + Send>,
|
||||||
extra_data: ParserContextExtraData) -> Stylesheet<Impl> {
|
extra_data: ParserContextExtraData) -> Stylesheet {
|
||||||
let mut bytes = vec![];
|
let mut bytes = vec![];
|
||||||
// TODO: incremental decoding and tokenization/parsing
|
// TODO: incremental decoding and tokenization/parsing
|
||||||
for chunk in input {
|
for chunk in input {
|
||||||
|
@ -119,7 +119,7 @@ impl<Impl: SelectorImpl> Stylesheet<Impl> {
|
||||||
environment_encoding: Option<EncodingRef>,
|
environment_encoding: Option<EncodingRef>,
|
||||||
origin: Origin, error_reporter: Box<ParseErrorReporter + Send>,
|
origin: Origin, error_reporter: Box<ParseErrorReporter + Send>,
|
||||||
extra_data: ParserContextExtraData)
|
extra_data: ParserContextExtraData)
|
||||||
-> Stylesheet<Impl> {
|
-> Stylesheet {
|
||||||
// TODO: bytes.as_slice could be bytes.container_as_bytes()
|
// TODO: bytes.as_slice could be bytes.container_as_bytes()
|
||||||
let (string, _) = decode_stylesheet_bytes(
|
let (string, _) = decode_stylesheet_bytes(
|
||||||
bytes, protocol_encoding_label, environment_encoding);
|
bytes, protocol_encoding_label, environment_encoding);
|
||||||
|
@ -128,12 +128,11 @@ impl<Impl: SelectorImpl> Stylesheet<Impl> {
|
||||||
|
|
||||||
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>,
|
error_reporter: Box<ParseErrorReporter + Send>,
|
||||||
extra_data: ParserContextExtraData) -> Stylesheet<Impl> {
|
extra_data: ParserContextExtraData) -> Stylesheet {
|
||||||
let rule_parser = TopLevelRuleParser {
|
let rule_parser = TopLevelRuleParser {
|
||||||
context: ParserContext::new_with_extra_data(origin, &base_url, error_reporter.clone(),
|
context: ParserContext::new_with_extra_data(origin, &base_url, error_reporter.clone(),
|
||||||
extra_data),
|
extra_data),
|
||||||
state: Cell::new(State::Start),
|
state: Cell::new(State::Start),
|
||||||
_impl: PhantomData,
|
|
||||||
};
|
};
|
||||||
let mut input = Parser::new(css);
|
let mut input = Parser::new(css);
|
||||||
input.look_for_viewport_percentages();
|
input.look_for_viewport_percentages();
|
||||||
|
@ -189,7 +188,7 @@ impl<Impl: SelectorImpl> Stylesheet<Impl> {
|
||||||
|
|
||||||
/// 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<Impl> {
|
pub fn rules(&self) -> Rules {
|
||||||
Rules::new(self.rules.iter(), None)
|
Rules::new(self.rules.iter(), None)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,7 +199,7 @@ impl<Impl: SelectorImpl> Stylesheet<Impl> {
|
||||||
/// 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, Impl> {
|
pub fn effective_rules<'a>(&'a self, device: &'a Device) -> Rules<'a> {
|
||||||
Rules::new(self.rules.iter(), Some(device))
|
Rules::new(self.rules.iter(), Some(device))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -209,25 +208,25 @@ impl<Impl: SelectorImpl> Stylesheet<Impl> {
|
||||||
///
|
///
|
||||||
/// 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, Impl: SelectorImpl + 'a> {
|
pub struct Rules<'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<Impl>>; 2]>,
|
stack: SmallVec<[slice::Iter<'a, CSSRule>; 2]>,
|
||||||
device: Option<&'a Device>
|
device: Option<&'a Device>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Impl: SelectorImpl + 'a> Rules<'a, Impl> {
|
impl<'a> Rules<'a> {
|
||||||
fn new(iter: slice::Iter<'a, CSSRule<Impl>>, device: Option<&'a Device>) -> Rules<'a, Impl> {
|
fn new(iter: slice::Iter<'a, CSSRule>, device: Option<&'a Device>) -> Rules<'a> {
|
||||||
let mut stack: SmallVec<[slice::Iter<'a, CSSRule<Impl>>; 2]> = SmallVec::new();
|
let mut stack: SmallVec<[slice::Iter<'a, CSSRule>; 2]> = SmallVec::new();
|
||||||
stack.push(iter);
|
stack.push(iter);
|
||||||
|
|
||||||
Rules { stack: stack, device: device }
|
Rules { stack: stack, device: device }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Impl: SelectorImpl + 'a> Iterator for Rules<'a, Impl> {
|
impl<'a> Iterator for Rules<'a> {
|
||||||
type Item = &'a CSSRule<Impl>;
|
type Item = &'a CSSRule;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<&'a CSSRule<Impl>> {
|
fn next(&mut self) -> Option<&'a CSSRule> {
|
||||||
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() {
|
||||||
|
@ -262,7 +261,6 @@ impl<'a, Impl: SelectorImpl + 'a> Iterator for Rules<'a, Impl> {
|
||||||
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;
|
||||||
|
@ -277,8 +275,8 @@ pub mod rule_filter {
|
||||||
_lifetime: PhantomData<&'a ()>
|
_lifetime: PhantomData<&'a ()>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, I, Impl: SelectorImpl + 'a> $variant<'a, I>
|
impl<'a, I> $variant<'a, I>
|
||||||
where I: Iterator<Item=&'a CSSRule<Impl>> {
|
where I: Iterator<Item=&'a CSSRule> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(iter: I) -> $variant<'a, I> {
|
pub fn new(iter: I) -> $variant<'a, I> {
|
||||||
$variant {
|
$variant {
|
||||||
|
@ -288,8 +286,8 @@ pub mod rule_filter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, I, Impl: SelectorImpl + 'a> Iterator for $variant<'a, I>
|
impl<'a, I> Iterator for $variant<'a, I>
|
||||||
where I: Iterator<Item=&'a CSSRule<Impl>> {
|
where I: Iterator<Item=&'a CSSRule> {
|
||||||
type Item = &'a $value;
|
type Item = &'a $value;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<&'a $value> {
|
fn next(&mut self) -> Option<&'a $value> {
|
||||||
|
@ -310,15 +308,15 @@ pub mod rule_filter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rule_filter!(Media -> MediaRule<Impl>);
|
rule_filter!(Media -> MediaRule);
|
||||||
rule_filter!(Style -> StyleRule<Impl>);
|
rule_filter!(Style -> StyleRule);
|
||||||
rule_filter!(FontFace -> FontFaceRule);
|
rule_filter!(FontFace -> FontFaceRule);
|
||||||
rule_filter!(Viewport -> ViewportRule);
|
rule_filter!(Viewport -> ViewportRule);
|
||||||
rule_filter!(Keyframes -> KeyframesRule);
|
rule_filter!(Keyframes -> KeyframesRule);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extension methods for `CSSRule` iterators.
|
/// Extension methods for `CSSRule` iterators.
|
||||||
pub trait CSSRuleIteratorExt<'a, Impl: SelectorImpl + 'a>: Iterator<Item=&'a CSSRule<Impl>> + Sized {
|
pub trait CSSRuleIteratorExt<'a>: Iterator<Item=&'a CSSRule> + 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>;
|
||||||
|
|
||||||
|
@ -335,7 +333,7 @@ pub trait CSSRuleIteratorExt<'a, Impl: SelectorImpl + 'a>: Iterator<Item=&'a CSS
|
||||||
fn keyframes(self) -> rule_filter::Keyframes<'a, Self>;
|
fn keyframes(self) -> rule_filter::Keyframes<'a, Self>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, I, Impl: SelectorImpl + 'a> CSSRuleIteratorExt<'a, Impl> for I where I: Iterator<Item=&'a CSSRule<Impl>> {
|
impl<'a, I> CSSRuleIteratorExt<'a> for I where I: Iterator<Item=&'a CSSRule> {
|
||||||
#[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)
|
||||||
|
@ -362,12 +360,9 @@ impl<'a, I, Impl: SelectorImpl + 'a> CSSRuleIteratorExt<'a, Impl> for I where I:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_nested_rules<Impl: SelectorImpl>(context: &ParserContext, input: &mut Parser) -> Vec<CSSRule<Impl>> {
|
fn parse_nested_rules(context: &ParserContext, input: &mut Parser) -> Vec<CSSRule> {
|
||||||
let mut iter = RuleListParser::new_for_nested_rule(input,
|
let mut iter = RuleListParser::new_for_nested_rule(input,
|
||||||
NestedRuleParser {
|
NestedRuleParser { context: context });
|
||||||
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 {
|
||||||
|
@ -383,10 +378,9 @@ fn parse_nested_rules<Impl: SelectorImpl>(context: &ParserContext, input: &mut P
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct TopLevelRuleParser<'a, Impl: SelectorImpl> {
|
struct TopLevelRuleParser<'a> {
|
||||||
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)]
|
||||||
|
@ -410,12 +404,12 @@ enum AtRulePrelude {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<'a, Impl: SelectorImpl> AtRuleParser for TopLevelRuleParser<'a, Impl> {
|
impl<'a> AtRuleParser for TopLevelRuleParser<'a> {
|
||||||
type Prelude = AtRulePrelude;
|
type Prelude = AtRulePrelude;
|
||||||
type AtRule = CSSRule<Impl>;
|
type AtRule = CSSRule;
|
||||||
|
|
||||||
fn parse_prelude(&self, name: &str, input: &mut Parser)
|
fn parse_prelude(&self, name: &str, input: &mut Parser)
|
||||||
-> Result<AtRuleType<AtRulePrelude, CSSRule<Impl>>, ()> {
|
-> Result<AtRuleType<AtRulePrelude, CSSRule>, ()> {
|
||||||
match_ignore_ascii_case! { name,
|
match_ignore_ascii_case! { name,
|
||||||
"charset" => {
|
"charset" => {
|
||||||
if self.state.get() <= State::Start {
|
if self.state.get() <= State::Start {
|
||||||
|
@ -451,46 +445,45 @@ impl<'a, Impl: SelectorImpl> AtRuleParser for TopLevelRuleParser<'a, Impl> {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.state.set(State::Body);
|
self.state.set(State::Body);
|
||||||
AtRuleParser::parse_prelude(&NestedRuleParser { context: &self.context, _impl: PhantomData }, name, input)
|
AtRuleParser::parse_prelude(&NestedRuleParser { context: &self.context }, name, input)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn parse_block(&self, prelude: AtRulePrelude, input: &mut Parser) -> Result<CSSRule<Impl>, ()> {
|
fn parse_block(&self, prelude: AtRulePrelude, input: &mut Parser) -> Result<CSSRule, ()> {
|
||||||
AtRuleParser::parse_block(&NestedRuleParser { context: &self.context, _impl: PhantomData }, prelude, input)
|
AtRuleParser::parse_block(&NestedRuleParser { context: &self.context }, prelude, input)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<'a, Impl: SelectorImpl> QualifiedRuleParser for TopLevelRuleParser<'a, Impl> {
|
impl<'a> QualifiedRuleParser for TopLevelRuleParser<'a> {
|
||||||
type Prelude = Vec<Selector<Impl>>;
|
type Prelude = Vec<Selector<TheSelectorImpl>>;
|
||||||
type QualifiedRule = CSSRule<Impl>;
|
type QualifiedRule = CSSRule;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn parse_prelude(&self, input: &mut Parser) -> Result<Vec<Selector<Impl>>, ()> {
|
fn parse_prelude(&self, input: &mut Parser) -> Result<Vec<Selector<TheSelectorImpl>>, ()> {
|
||||||
self.state.set(State::Body);
|
self.state.set(State::Body);
|
||||||
QualifiedRuleParser::parse_prelude(&NestedRuleParser { context: &self.context, _impl: PhantomData }, input)
|
QualifiedRuleParser::parse_prelude(&NestedRuleParser { context: &self.context }, input)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn parse_block(&self, prelude: Vec<Selector<Impl>>, input: &mut Parser) -> Result<CSSRule<Impl>, ()> {
|
fn parse_block(&self, prelude: Vec<Selector<TheSelectorImpl>>, input: &mut Parser) -> Result<CSSRule, ()> {
|
||||||
QualifiedRuleParser::parse_block(&NestedRuleParser { context: &self.context, _impl: PhantomData },
|
QualifiedRuleParser::parse_block(&NestedRuleParser { context: &self.context },
|
||||||
prelude, input)
|
prelude, input)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct NestedRuleParser<'a, 'b: 'a, Impl: SelectorImpl> {
|
struct NestedRuleParser<'a, 'b: 'a> {
|
||||||
context: &'a ParserContext<'b>,
|
context: &'a ParserContext<'b>,
|
||||||
_impl: PhantomData<Impl>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<'a, 'b, Impl: SelectorImpl> AtRuleParser for NestedRuleParser<'a, 'b, Impl> {
|
impl<'a, 'b> AtRuleParser for NestedRuleParser<'a, 'b> {
|
||||||
type Prelude = AtRulePrelude;
|
type Prelude = AtRulePrelude;
|
||||||
type AtRule = CSSRule<Impl>;
|
type AtRule = CSSRule;
|
||||||
|
|
||||||
fn parse_prelude(&self, name: &str, input: &mut Parser)
|
fn parse_prelude(&self, name: &str, input: &mut Parser)
|
||||||
-> Result<AtRuleType<AtRulePrelude, CSSRule<Impl>>, ()> {
|
-> Result<AtRuleType<AtRulePrelude, CSSRule>, ()> {
|
||||||
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);
|
||||||
|
@ -519,7 +512,7 @@ impl<'a, 'b, Impl: SelectorImpl> AtRuleParser for NestedRuleParser<'a, 'b, Impl>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_block(&self, prelude: AtRulePrelude, input: &mut Parser) -> Result<CSSRule<Impl>, ()> {
|
fn parse_block(&self, prelude: AtRulePrelude, input: &mut Parser) -> Result<CSSRule, ()> {
|
||||||
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)
|
||||||
|
@ -543,15 +536,15 @@ impl<'a, 'b, Impl: SelectorImpl> AtRuleParser for NestedRuleParser<'a, 'b, Impl>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b, Impl: SelectorImpl> QualifiedRuleParser for NestedRuleParser<'a, 'b, Impl> {
|
impl<'a, 'b> QualifiedRuleParser for NestedRuleParser<'a, 'b> {
|
||||||
type Prelude = Vec<Selector<Impl>>;
|
type Prelude = Vec<Selector<TheSelectorImpl>>;
|
||||||
type QualifiedRule = CSSRule<Impl>;
|
type QualifiedRule = CSSRule;
|
||||||
|
|
||||||
fn parse_prelude(&self, input: &mut Parser) -> Result<Vec<Selector<Impl>>, ()> {
|
fn parse_prelude(&self, input: &mut Parser) -> Result<Vec<Selector<TheSelectorImpl>>, ()> {
|
||||||
parse_selector_list(&self.context.selector_context, input)
|
parse_selector_list(&self.context.selector_context, input)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_block(&self, prelude: Vec<Selector<Impl>>, input: &mut Parser) -> Result<CSSRule<Impl>, ()> {
|
fn parse_block(&self, prelude: Vec<Selector<TheSelectorImpl>>, input: &mut Parser) -> Result<CSSRule, ()> {
|
||||||
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)
|
||||||
|
|
|
@ -46,11 +46,11 @@ 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<N, Impl: SelectorImplExt>(parent_node: Option<N>,
|
fn take_thread_local_bloom_filter<N>(parent_node: Option<N>,
|
||||||
root: OpaqueNode,
|
root: OpaqueNode,
|
||||||
context: &SharedStyleContext<Impl>)
|
context: &SharedStyleContext)
|
||||||
-> Box<BloomFilter>
|
-> Box<BloomFilter>
|
||||||
where N: TNode {
|
where N: TNode {
|
||||||
STYLE_BLOOM.with(|style_bloom| {
|
STYLE_BLOOM.with(|style_bloom| {
|
||||||
match (parent_node, style_bloom.borrow_mut().take()) {
|
match (parent_node, style_bloom.borrow_mut().take()) {
|
||||||
// Root node. Needs new bloom filter.
|
// Root node. Needs new bloom filter.
|
||||||
|
@ -82,9 +82,8 @@ fn take_thread_local_bloom_filter<N, Impl: SelectorImplExt>(parent_node: Option<
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn put_thread_local_bloom_filter<Impl: SelectorImplExt>(bf: Box<BloomFilter>,
|
fn put_thread_local_bloom_filter(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");
|
||||||
|
@ -111,10 +110,9 @@ fn insert_ancestors_into_bloom_filter<N>(bf: &mut Box<BloomFilter>,
|
||||||
debug!("[{}] Inserted {} ancestors.", tid(), ancestors);
|
debug!("[{}] Inserted {} ancestors.", tid(), ancestors);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_from_bloom_filter<'a, N, C, Impl>(context: &C, root: OpaqueNode, node: N)
|
pub fn remove_from_bloom_filter<'a, N, C>(context: &C, root: OpaqueNode, node: N)
|
||||||
where N: TNode,
|
where N: TNode,
|
||||||
Impl: SelectorImplExt + 'a,
|
C: StyleContext<'a>
|
||||||
C: StyleContext<'a, Impl>
|
|
||||||
{
|
{
|
||||||
let unsafe_layout_node = node.to_unsafe();
|
let unsafe_layout_node = node.to_unsafe();
|
||||||
|
|
||||||
|
@ -158,7 +156,7 @@ pub fn recalc_style_at<'a, N, C>(context: &'a C,
|
||||||
root: OpaqueNode,
|
root: OpaqueNode,
|
||||||
node: N)
|
node: N)
|
||||||
where N: TNode,
|
where N: TNode,
|
||||||
C: StyleContext<'a, <N::ConcreteElement as Element>::Impl>,
|
C: StyleContext<'a>,
|
||||||
<N::ConcreteElement as Element>::Impl: SelectorImplExt + 'a {
|
<N::ConcreteElement as Element>::Impl: SelectorImplExt + 'a {
|
||||||
// Get the parent node.
|
// Get the parent node.
|
||||||
let parent_opt = match node.parent_node() {
|
let parent_opt = match node.parent_node() {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
/* 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
|
* 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 selector_impl::SharedStyleContext;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use style::context::{LocalStyleContext, StyleContext};
|
use style::context::{LocalStyleContext, StyleContext};
|
||||||
|
@ -40,7 +40,7 @@ impl<'a> StandaloneStyleContext<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> StyleContext<'a, GeckoSelectorImpl> for StandaloneStyleContext<'a> {
|
impl<'a> StyleContext<'a> for StandaloneStyleContext<'a> {
|
||||||
fn shared_context(&self) -> &'a SharedStyleContext {
|
fn shared_context(&self) -> &'a SharedStyleContext {
|
||||||
&self.shared
|
&self.shared
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue