mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Import SelectorMap back from the selectors crate.
Nobody else uses it, and I want to make breaking changes to it.
This commit is contained in:
parent
bc71e8b65b
commit
4062899fd8
13 changed files with 332 additions and 24 deletions
|
@ -71,7 +71,7 @@ use html5ever::serialize::TraversalScope;
|
||||||
use html5ever::serialize::TraversalScope::{ChildrenOnly, IncludeNode};
|
use html5ever::serialize::TraversalScope::{ChildrenOnly, IncludeNode};
|
||||||
use html5ever::tree_builder::{LimitedQuirks, NoQuirks, Quirks};
|
use html5ever::tree_builder::{LimitedQuirks, NoQuirks, Quirks};
|
||||||
use ref_filter_map::ref_filter_map;
|
use ref_filter_map::ref_filter_map;
|
||||||
use selectors::matching::{DeclarationBlock, ElementFlags, matches};
|
use selectors::matching::{ElementFlags, matches};
|
||||||
use selectors::matching::{HAS_SLOW_SELECTOR, HAS_EDGE_CHILD_SELECTOR, HAS_SLOW_SELECTOR_LATER_SIBLINGS};
|
use selectors::matching::{HAS_SLOW_SELECTOR, HAS_EDGE_CHILD_SELECTOR, HAS_SLOW_SELECTOR_LATER_SIBLINGS};
|
||||||
use selectors::parser::{AttrSelector, NamespaceConstraint, parse_author_origin_selector_list_from_str};
|
use selectors::parser::{AttrSelector, NamespaceConstraint, parse_author_origin_selector_list_from_str};
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
|
@ -92,6 +92,7 @@ use style::properties::longhands::{self, background_image, border_spacing, font_
|
||||||
use style::properties::{DeclaredValue, Importance};
|
use style::properties::{DeclaredValue, Importance};
|
||||||
use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, parse_style_attribute};
|
use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, parse_style_attribute};
|
||||||
use style::selector_impl::{NonTSPseudoClass, ServoSelectorImpl};
|
use style::selector_impl::{NonTSPseudoClass, ServoSelectorImpl};
|
||||||
|
use style::selector_matching::DeclarationBlock;
|
||||||
use style::sink::Push;
|
use style::sink::Push;
|
||||||
use style::values::CSSFloat;
|
use style::values::CSSFloat;
|
||||||
use style::values::specified::{self, CSSColor, CSSRGBA, LengthOrPercentage};
|
use style::values::specified::{self, CSSColor, CSSRGBA, LengthOrPercentage};
|
||||||
|
@ -291,7 +292,7 @@ pub trait LayoutElementHelpers {
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
unsafe fn synthesize_presentational_hints_for_legacy_attributes<V>(&self, &mut V)
|
unsafe fn synthesize_presentational_hints_for_legacy_attributes<V>(&self, &mut V)
|
||||||
where V: Push<DeclarationBlock<Vec<PropertyDeclaration>>>;
|
where V: Push<DeclarationBlock>;
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
unsafe fn get_colspan(self) -> u32;
|
unsafe fn get_colspan(self) -> u32;
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
|
@ -324,10 +325,10 @@ impl LayoutElementHelpers for LayoutJS<Element> {
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
unsafe fn synthesize_presentational_hints_for_legacy_attributes<V>(&self, hints: &mut V)
|
unsafe fn synthesize_presentational_hints_for_legacy_attributes<V>(&self, hints: &mut V)
|
||||||
where V: Push<DeclarationBlock<Vec<PropertyDeclaration>>>
|
where V: Push<DeclarationBlock>
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_declaration(rule: PropertyDeclaration) -> DeclarationBlock<Vec<PropertyDeclaration>> {
|
fn from_declaration(rule: PropertyDeclaration) -> DeclarationBlock {
|
||||||
DeclarationBlock::from_declarations(Arc::new(vec![rule]))
|
DeclarationBlock::from_declarations(Arc::new(vec![rule]))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ use script_layout_interface::wrapper_traits::{DangerousThreadSafeLayoutNode, Lay
|
||||||
use script_layout_interface::wrapper_traits::{ThreadSafeLayoutNode, ThreadSafeLayoutElement};
|
use script_layout_interface::wrapper_traits::{ThreadSafeLayoutNode, ThreadSafeLayoutElement};
|
||||||
use script_layout_interface::{HTMLCanvasData, LayoutNodeType, TrustedNodeAddress};
|
use script_layout_interface::{HTMLCanvasData, LayoutNodeType, TrustedNodeAddress};
|
||||||
use script_layout_interface::{OpaqueStyleAndLayoutData, PartialStyleAndLayoutData};
|
use script_layout_interface::{OpaqueStyleAndLayoutData, PartialStyleAndLayoutData};
|
||||||
use selectors::matching::{DeclarationBlock, ElementFlags};
|
use selectors::matching::ElementFlags;
|
||||||
use selectors::parser::{AttrSelector, NamespaceConstraint};
|
use selectors::parser::{AttrSelector, NamespaceConstraint};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
@ -60,9 +60,10 @@ use style::context::SharedStyleContext;
|
||||||
use style::data::PrivateStyleData;
|
use style::data::PrivateStyleData;
|
||||||
use style::dom::{PresentationalHintsSynthetizer, OpaqueNode, TDocument, TElement, TNode, UnsafeNode};
|
use style::dom::{PresentationalHintsSynthetizer, OpaqueNode, TDocument, TElement, TNode, UnsafeNode};
|
||||||
use style::element_state::*;
|
use style::element_state::*;
|
||||||
use style::properties::{ComputedValues, PropertyDeclaration, PropertyDeclarationBlock};
|
use style::properties::{ComputedValues, PropertyDeclarationBlock};
|
||||||
use style::refcell::{Ref, RefCell, RefMut};
|
use style::refcell::{Ref, RefCell, RefMut};
|
||||||
use style::selector_impl::{ElementSnapshot, NonTSPseudoClass, PseudoElement, ServoSelectorImpl};
|
use style::selector_impl::{ElementSnapshot, NonTSPseudoClass, PseudoElement, ServoSelectorImpl};
|
||||||
|
use style::selector_matching::DeclarationBlock;
|
||||||
use style::sink::Push;
|
use style::sink::Push;
|
||||||
use style::str::is_whitespace;
|
use style::str::is_whitespace;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
@ -418,7 +419,7 @@ impl<'le> fmt::Debug for ServoLayoutElement<'le> {
|
||||||
|
|
||||||
impl<'le> PresentationalHintsSynthetizer for ServoLayoutElement<'le> {
|
impl<'le> PresentationalHintsSynthetizer for ServoLayoutElement<'le> {
|
||||||
fn synthesize_presentational_hints_for_legacy_attributes<V>(&self, hints: &mut V)
|
fn synthesize_presentational_hints_for_legacy_attributes<V>(&self, hints: &mut V)
|
||||||
where V: Push<DeclarationBlock<Vec<PropertyDeclaration>>>
|
where V: Push<DeclarationBlock>
|
||||||
{
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
self.element.synthesize_presentational_hints_for_legacy_attributes(hints);
|
self.element.synthesize_presentational_hints_for_legacy_attributes(hints);
|
||||||
|
@ -1070,5 +1071,5 @@ impl<'le> ::selectors::Element for ServoThreadSafeLayoutElement<'le> {
|
||||||
|
|
||||||
impl<'le> PresentationalHintsSynthetizer for ServoThreadSafeLayoutElement<'le> {
|
impl<'le> PresentationalHintsSynthetizer for ServoThreadSafeLayoutElement<'le> {
|
||||||
fn synthesize_presentational_hints_for_legacy_attributes<V>(&self, _hints: &mut V)
|
fn synthesize_presentational_hints_for_legacy_attributes<V>(&self, _hints: &mut V)
|
||||||
where V: Push<DeclarationBlock<Vec<PropertyDeclaration>>> {}
|
where V: Push<DeclarationBlock> {}
|
||||||
}
|
}
|
||||||
|
|
1
components/servo/Cargo.lock
generated
1
components/servo/Cargo.lock
generated
|
@ -2236,6 +2236,7 @@ dependencies = [
|
||||||
"num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ordered-float 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ordered-float 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"plugins 0.0.1",
|
"plugins 0.0.1",
|
||||||
|
"quickersort 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"selectors 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"selectors 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
|
@ -36,6 +36,7 @@ log = "0.3.5"
|
||||||
matches = "0.1"
|
matches = "0.1"
|
||||||
num-traits = "0.1.32"
|
num-traits = "0.1.32"
|
||||||
ordered-float = "0.2.2"
|
ordered-float = "0.2.2"
|
||||||
|
quickersort = "2.0.0"
|
||||||
rand = "0.3"
|
rand = "0.3"
|
||||||
rustc-serialize = "0.3"
|
rustc-serialize = "0.3"
|
||||||
selectors = "0.11"
|
selectors = "0.11"
|
||||||
|
|
|
@ -16,7 +16,7 @@ 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 selectors::matching::DeclarationBlock;
|
use selector_matching::DeclarationBlock;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::mpsc::Sender;
|
use std::sync::mpsc::Sender;
|
||||||
use string_cache::Atom;
|
use string_cache::Atom;
|
||||||
|
|
|
@ -9,11 +9,11 @@
|
||||||
use context::SharedStyleContext;
|
use context::SharedStyleContext;
|
||||||
use data::PrivateStyleData;
|
use data::PrivateStyleData;
|
||||||
use element_state::ElementState;
|
use element_state::ElementState;
|
||||||
use properties::{ComputedValues, PropertyDeclaration, PropertyDeclarationBlock};
|
use properties::{ComputedValues, PropertyDeclarationBlock};
|
||||||
use refcell::{Ref, RefMut};
|
use refcell::{Ref, RefMut};
|
||||||
use restyle_hints::{RESTYLE_DESCENDANTS, RESTYLE_LATER_SIBLINGS, RESTYLE_SELF, RestyleHint};
|
use restyle_hints::{RESTYLE_DESCENDANTS, RESTYLE_LATER_SIBLINGS, RESTYLE_SELF, RestyleHint};
|
||||||
use selector_impl::{ElementExt, PseudoElement};
|
use selector_impl::{ElementExt, PseudoElement};
|
||||||
use selectors::matching::DeclarationBlock;
|
use selector_matching::DeclarationBlock;
|
||||||
use sink::Push;
|
use sink::Push;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::ops::BitOr;
|
use std::ops::BitOr;
|
||||||
|
@ -198,7 +198,7 @@ pub trait TDocument : Sized + Copy + Clone {
|
||||||
|
|
||||||
pub trait PresentationalHintsSynthetizer {
|
pub trait PresentationalHintsSynthetizer {
|
||||||
fn synthesize_presentational_hints_for_legacy_attributes<V>(&self, hints: &mut V)
|
fn synthesize_presentational_hints_for_legacy_attributes<V>(&self, hints: &mut V)
|
||||||
where V: Push<DeclarationBlock<Vec<PropertyDeclaration>>>;
|
where V: Push<DeclarationBlock>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait TElement : PartialEq + Debug + Sized + Copy + Clone + ElementExt + PresentationalHintsSynthetizer {
|
pub trait TElement : PartialEq + Debug + Sized + Copy + Clone + ElementExt + PresentationalHintsSynthetizer {
|
||||||
|
|
|
@ -58,6 +58,7 @@ extern crate log;
|
||||||
extern crate matches;
|
extern crate matches;
|
||||||
extern crate num_traits;
|
extern crate num_traits;
|
||||||
extern crate ordered_float;
|
extern crate ordered_float;
|
||||||
|
extern crate quickersort;
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
extern crate rustc_serialize;
|
extern crate rustc_serialize;
|
||||||
extern crate selectors;
|
extern crate selectors;
|
||||||
|
|
|
@ -31,7 +31,7 @@ use computed_values;
|
||||||
#[cfg(feature = "servo")] use logical_geometry::{LogicalMargin, PhysicalSide};
|
#[cfg(feature = "servo")] use logical_geometry::{LogicalMargin, PhysicalSide};
|
||||||
use logical_geometry::WritingMode;
|
use logical_geometry::WritingMode;
|
||||||
use parser::{ParserContext, ParserContextExtraData, log_css_error};
|
use parser::{ParserContext, ParserContextExtraData, log_css_error};
|
||||||
use selectors::matching::DeclarationBlock;
|
use selector_matching::DeclarationBlock;
|
||||||
use stylesheets::Origin;
|
use stylesheets::Origin;
|
||||||
use values::LocalToCss;
|
use values::LocalToCss;
|
||||||
use values::HasViewportPercentage;
|
use values::HasViewportPercentage;
|
||||||
|
@ -1670,7 +1670,7 @@ mod lazy_static_module {
|
||||||
#[allow(unused_mut, unused_imports)]
|
#[allow(unused_mut, unused_imports)]
|
||||||
fn cascade_with_cached_declarations(
|
fn cascade_with_cached_declarations(
|
||||||
viewport_size: Size2D<Au>,
|
viewport_size: Size2D<Au>,
|
||||||
applicable_declarations: &[DeclarationBlock<Vec<PropertyDeclaration>>],
|
applicable_declarations: &[DeclarationBlock],
|
||||||
shareable: bool,
|
shareable: bool,
|
||||||
parent_style: &ComputedValues,
|
parent_style: &ComputedValues,
|
||||||
cached_style: &ComputedValues,
|
cached_style: &ComputedValues,
|
||||||
|
@ -1815,7 +1815,7 @@ static CASCADE_PROPERTY: [CascadePropertyFn; ${len(data.longhands)}] = [
|
||||||
///
|
///
|
||||||
/// Returns the computed values and a boolean indicating whether the result is cacheable.
|
/// Returns the computed values and a boolean indicating whether the result is cacheable.
|
||||||
pub fn cascade(viewport_size: Size2D<Au>,
|
pub fn cascade(viewport_size: Size2D<Au>,
|
||||||
applicable_declarations: &[DeclarationBlock<Vec<PropertyDeclaration>>],
|
applicable_declarations: &[DeclarationBlock],
|
||||||
shareable: bool,
|
shareable: bool,
|
||||||
parent_style: Option<<&ComputedValues>,
|
parent_style: Option<<&ComputedValues>,
|
||||||
cached_style: Option<<&ComputedValues>,
|
cached_style: Option<<&ComputedValues>,
|
||||||
|
|
|
@ -10,19 +10,22 @@ use error_reporting::StdoutErrorReporter;
|
||||||
use keyframes::KeyframesAnimation;
|
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 quickersort::sort_by;
|
||||||
use restyle_hints::{RestyleHint, DependencySet};
|
use restyle_hints::{RestyleHint, DependencySet};
|
||||||
use selector_impl::{ElementExt, TheSelectorImpl, PseudoElement};
|
use selector_impl::{ElementExt, TheSelectorImpl, PseudoElement};
|
||||||
use selectors::Element;
|
use selectors::Element;
|
||||||
use selectors::bloom::BloomFilter;
|
use selectors::bloom::BloomFilter;
|
||||||
use selectors::matching::DeclarationBlock as GenericDeclarationBlock;
|
|
||||||
use selectors::matching::{AFFECTED_BY_STYLE_ATTRIBUTE, AFFECTED_BY_PRESENTATIONAL_HINTS};
|
use selectors::matching::{AFFECTED_BY_STYLE_ATTRIBUTE, AFFECTED_BY_PRESENTATIONAL_HINTS};
|
||||||
use selectors::matching::{Rule, SelectorMap, StyleRelations};
|
use selectors::matching::{StyleRelations, matches_compound_selector};
|
||||||
use selectors::parser::Selector;
|
use selectors::parser::{Selector, SelectorImpl, SimpleSelector, LocalName, CompoundSelector};
|
||||||
use sink::Push;
|
use sink::Push;
|
||||||
use smallvec::VecLike;
|
use smallvec::VecLike;
|
||||||
|
use std::borrow::Borrow;
|
||||||
|
use std::cmp::Ordering;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::hash::BuildHasherDefault;
|
use std::hash::BuildHasherDefault;
|
||||||
|
use std::hash::Hash;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use string_cache::Atom;
|
use string_cache::Atom;
|
||||||
use style_traits::viewport::ViewportConstraints;
|
use style_traits::viewport::ViewportConstraints;
|
||||||
|
@ -276,7 +279,7 @@ impl Stylist {
|
||||||
parent: &Arc<ComputedValues>)
|
parent: &Arc<ComputedValues>)
|
||||||
-> Option<Arc<ComputedValues>>
|
-> Option<Arc<ComputedValues>>
|
||||||
where E: Element<Impl=TheSelectorImpl> +
|
where E: Element<Impl=TheSelectorImpl> +
|
||||||
Debug +
|
fmt::Debug +
|
||||||
PresentationalHintsSynthetizer
|
PresentationalHintsSynthetizer
|
||||||
{
|
{
|
||||||
debug_assert!(TheSelectorImpl::pseudo_element_cascade_type(pseudo).is_lazy());
|
debug_assert!(TheSelectorImpl::pseudo_element_cascade_type(pseudo).is_lazy());
|
||||||
|
@ -345,7 +348,7 @@ impl Stylist {
|
||||||
pseudo_element: Option<&PseudoElement>,
|
pseudo_element: Option<&PseudoElement>,
|
||||||
applicable_declarations: &mut V) -> StyleRelations
|
applicable_declarations: &mut V) -> StyleRelations
|
||||||
where E: Element<Impl=TheSelectorImpl> +
|
where E: Element<Impl=TheSelectorImpl> +
|
||||||
fmt::Debug +
|
fmt::Debug +
|
||||||
PresentationalHintsSynthetizer,
|
PresentationalHintsSynthetizer,
|
||||||
V: Push<DeclarationBlock> + VecLike<DeclarationBlock>
|
V: Push<DeclarationBlock> + VecLike<DeclarationBlock>
|
||||||
{
|
{
|
||||||
|
@ -577,3 +580,301 @@ impl PerPseudoElementSelectorMap {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Map element data to Rules whose last simple selector starts with them.
|
||||||
|
///
|
||||||
|
/// e.g.,
|
||||||
|
/// "p > img" would go into the set of Rules corresponding to the
|
||||||
|
/// element "img"
|
||||||
|
/// "a .foo .bar.baz" would go into the set of Rules corresponding to
|
||||||
|
/// the class "bar"
|
||||||
|
///
|
||||||
|
/// Because we match Rules right-to-left (i.e., moving up the tree
|
||||||
|
/// from an element), we need to compare the last simple selector in the
|
||||||
|
/// Rule with the element.
|
||||||
|
///
|
||||||
|
/// So, if an element has ID "id1" and classes "foo" and "bar", then all
|
||||||
|
/// the rules it matches will have their last simple selector starting
|
||||||
|
/// either with "#id1" or with ".foo" or with ".bar".
|
||||||
|
///
|
||||||
|
/// Hence, the union of the rules keyed on each of element's classes, ID,
|
||||||
|
/// element name, etc. will contain the Rules that actually match that
|
||||||
|
/// element.
|
||||||
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
|
pub struct SelectorMap<T, Impl: SelectorImpl> {
|
||||||
|
// TODO: Tune the initial capacity of the HashMap
|
||||||
|
id_hash: HashMap<Impl::Identifier, Vec<Rule<T, Impl>>>,
|
||||||
|
class_hash: HashMap<Impl::ClassName, Vec<Rule<T, Impl>>>,
|
||||||
|
local_name_hash: HashMap<Impl::LocalName, Vec<Rule<T, Impl>>>,
|
||||||
|
/// Same as local_name_hash, but keys are lower-cased.
|
||||||
|
/// For HTML elements in HTML documents.
|
||||||
|
lower_local_name_hash: HashMap<Impl::LocalName, Vec<Rule<T, Impl>>>,
|
||||||
|
/// Rules that don't have ID, class, or element selectors.
|
||||||
|
other_rules: Vec<Rule<T, Impl>>,
|
||||||
|
/// Whether this hash is empty.
|
||||||
|
empty: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn compare<T>(a: &GenericDeclarationBlock<T>, b: &GenericDeclarationBlock<T>) -> Ordering {
|
||||||
|
(a.specificity, a.source_order).cmp(&(b.specificity, b.source_order))
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, Impl: SelectorImpl> SelectorMap<T, Impl> {
|
||||||
|
pub fn new() -> SelectorMap<T, Impl> {
|
||||||
|
SelectorMap {
|
||||||
|
id_hash: HashMap::default(),
|
||||||
|
class_hash: HashMap::default(),
|
||||||
|
local_name_hash: HashMap::default(),
|
||||||
|
lower_local_name_hash: HashMap::default(),
|
||||||
|
other_rules: vec!(),
|
||||||
|
empty: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Append to `rule_list` all Rules in `self` that match element.
|
||||||
|
///
|
||||||
|
/// Extract matching rules as per element's ID, classes, tag name, etc..
|
||||||
|
/// Sort the Rules at the end to maintain cascading order.
|
||||||
|
pub fn get_all_matching_rules<E, V>(&self,
|
||||||
|
element: &E,
|
||||||
|
parent_bf: Option<&BloomFilter>,
|
||||||
|
matching_rules_list: &mut V,
|
||||||
|
relations: &mut StyleRelations)
|
||||||
|
where E: Element<Impl=Impl>,
|
||||||
|
V: VecLike<GenericDeclarationBlock<T>>
|
||||||
|
{
|
||||||
|
if self.empty {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// At the end, we're going to sort the rules that we added, so remember where we began.
|
||||||
|
let init_len = matching_rules_list.len();
|
||||||
|
if let Some(id) = element.get_id() {
|
||||||
|
SelectorMap::get_matching_rules_from_hash(element,
|
||||||
|
parent_bf,
|
||||||
|
&self.id_hash,
|
||||||
|
&id,
|
||||||
|
matching_rules_list,
|
||||||
|
relations)
|
||||||
|
}
|
||||||
|
|
||||||
|
element.each_class(|class| {
|
||||||
|
SelectorMap::get_matching_rules_from_hash(element,
|
||||||
|
parent_bf,
|
||||||
|
&self.class_hash,
|
||||||
|
class,
|
||||||
|
matching_rules_list,
|
||||||
|
relations);
|
||||||
|
});
|
||||||
|
|
||||||
|
let local_name_hash = if element.is_html_element_in_html_document() {
|
||||||
|
&self.lower_local_name_hash
|
||||||
|
} else {
|
||||||
|
&self.local_name_hash
|
||||||
|
};
|
||||||
|
SelectorMap::get_matching_rules_from_hash(element,
|
||||||
|
parent_bf,
|
||||||
|
local_name_hash,
|
||||||
|
&element.get_local_name(),
|
||||||
|
matching_rules_list,
|
||||||
|
relations);
|
||||||
|
|
||||||
|
SelectorMap::get_matching_rules(element,
|
||||||
|
parent_bf,
|
||||||
|
&self.other_rules,
|
||||||
|
matching_rules_list,
|
||||||
|
relations);
|
||||||
|
|
||||||
|
// Sort only the rules we just added.
|
||||||
|
sort_by(&mut matching_rules_list[init_len..], &compare);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Append to `rule_list` all universal Rules (rules with selector `*|*`) in
|
||||||
|
/// `self` sorted by specifity and source order.
|
||||||
|
pub fn get_universal_rules<V>(&self,
|
||||||
|
matching_rules_list: &mut V)
|
||||||
|
where V: VecLike<GenericDeclarationBlock<T>>
|
||||||
|
{
|
||||||
|
if self.empty {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let init_len = matching_rules_list.len();
|
||||||
|
|
||||||
|
for rule in self.other_rules.iter() {
|
||||||
|
if rule.selector.simple_selectors.is_empty() &&
|
||||||
|
rule.selector.next.is_none() {
|
||||||
|
matching_rules_list.push(rule.declarations.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sort_by(&mut matching_rules_list[init_len..], &compare);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_matching_rules_from_hash<E, Str, BorrowedStr: ?Sized, Vector>(
|
||||||
|
element: &E,
|
||||||
|
parent_bf: Option<&BloomFilter>,
|
||||||
|
hash: &HashMap<Str, Vec<Rule<T, Impl>>>,
|
||||||
|
key: &BorrowedStr,
|
||||||
|
matching_rules: &mut Vector,
|
||||||
|
relations: &mut StyleRelations)
|
||||||
|
where E: Element<Impl=Impl>,
|
||||||
|
Str: Borrow<BorrowedStr> + Eq + Hash,
|
||||||
|
BorrowedStr: Eq + Hash,
|
||||||
|
Vector: VecLike<GenericDeclarationBlock<T>>
|
||||||
|
{
|
||||||
|
if let Some(rules) = hash.get(key) {
|
||||||
|
SelectorMap::get_matching_rules(element,
|
||||||
|
parent_bf,
|
||||||
|
rules,
|
||||||
|
matching_rules,
|
||||||
|
relations)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Adds rules in `rules` that match `element` to the `matching_rules` list.
|
||||||
|
fn get_matching_rules<E, V>(element: &E,
|
||||||
|
parent_bf: Option<&BloomFilter>,
|
||||||
|
rules: &[Rule<T, Impl>],
|
||||||
|
matching_rules: &mut V,
|
||||||
|
relations: &mut StyleRelations)
|
||||||
|
where E: Element<Impl=Impl>,
|
||||||
|
V: VecLike<GenericDeclarationBlock<T>>
|
||||||
|
{
|
||||||
|
for rule in rules.iter() {
|
||||||
|
if matches_compound_selector(&*rule.selector,
|
||||||
|
element, parent_bf, relations) {
|
||||||
|
matching_rules.push(rule.declarations.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Insert rule into the correct hash.
|
||||||
|
/// Order in which to try: id_hash, class_hash, local_name_hash, other_rules.
|
||||||
|
pub fn insert(&mut self, rule: Rule<T, Impl>) {
|
||||||
|
self.empty = false;
|
||||||
|
|
||||||
|
if let Some(id_name) = SelectorMap::get_id_name(&rule) {
|
||||||
|
find_push(&mut self.id_hash, id_name, rule);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(class_name) = SelectorMap::get_class_name(&rule) {
|
||||||
|
find_push(&mut self.class_hash, class_name, rule);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(LocalName { name, lower_name }) = SelectorMap::get_local_name(&rule) {
|
||||||
|
find_push(&mut self.local_name_hash, name, rule.clone());
|
||||||
|
find_push(&mut self.lower_local_name_hash, lower_name, rule);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.other_rules.push(rule);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Retrieve the first ID name in Rule, or None otherwise.
|
||||||
|
fn get_id_name(rule: &Rule<T, Impl>) -> Option<Impl::Identifier> {
|
||||||
|
for ss in &rule.selector.simple_selectors {
|
||||||
|
// TODO(pradeep): Implement case-sensitivity based on the
|
||||||
|
// document type and quirks mode.
|
||||||
|
if let SimpleSelector::ID(ref id) = *ss {
|
||||||
|
return Some(id.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Retrieve the FIRST class name in Rule, or None otherwise.
|
||||||
|
fn get_class_name(rule: &Rule<T, Impl>) -> Option<Impl::ClassName> {
|
||||||
|
for ss in &rule.selector.simple_selectors {
|
||||||
|
// TODO(pradeep): Implement case-sensitivity based on the
|
||||||
|
// document type and quirks mode.
|
||||||
|
if let SimpleSelector::Class(ref class) = *ss {
|
||||||
|
return Some(class.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Retrieve the name if it is a type selector, or None otherwise.
|
||||||
|
fn get_local_name(rule: &Rule<T, Impl>) -> Option<LocalName<Impl>> {
|
||||||
|
for ss in &rule.selector.simple_selectors {
|
||||||
|
if let SimpleSelector::LocalName(ref n) = *ss {
|
||||||
|
return Some(LocalName {
|
||||||
|
name: n.name.clone(),
|
||||||
|
lower_name: n.lower_name.clone(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
|
pub struct Rule<T, Impl: SelectorImpl> {
|
||||||
|
// This is an Arc because Rule will essentially be cloned for every element
|
||||||
|
// that it matches. Selector contains an owned vector (through
|
||||||
|
// CompoundSelector) and we want to avoid the allocation.
|
||||||
|
pub selector: Arc<CompoundSelector<Impl>>,
|
||||||
|
pub declarations: GenericDeclarationBlock<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A property declaration together with its precedence among rules of equal specificity so that
|
||||||
|
/// we can sort them.
|
||||||
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct GenericDeclarationBlock<T> {
|
||||||
|
pub declarations: Arc<T>,
|
||||||
|
pub source_order: usize,
|
||||||
|
pub specificity: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME(https://github.com/rust-lang/rust/issues/7671)
|
||||||
|
// derive(Clone) requires T: Clone, even though Arc<T>: T regardless.
|
||||||
|
impl<T> Clone for GenericDeclarationBlock<T> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
GenericDeclarationBlock {
|
||||||
|
declarations: self.declarations.clone(),
|
||||||
|
source_order: self.source_order,
|
||||||
|
specificity: self.specificity,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME(https://github.com/rust-lang/rust/issues/7671)
|
||||||
|
impl<T, Impl: SelectorImpl> Clone for Rule<T, Impl> {
|
||||||
|
fn clone(&self) -> Rule<T, Impl> {
|
||||||
|
Rule {
|
||||||
|
selector: self.selector.clone(),
|
||||||
|
declarations: self.declarations.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> GenericDeclarationBlock<T> {
|
||||||
|
#[inline]
|
||||||
|
pub fn from_declarations(declarations: Arc<T>) -> Self {
|
||||||
|
GenericDeclarationBlock {
|
||||||
|
declarations: declarations,
|
||||||
|
source_order: 0,
|
||||||
|
specificity: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn find_push<T, Impl: SelectorImpl, Str: Eq + Hash>(
|
||||||
|
map: &mut HashMap<Str, Vec<Rule<T, Impl>>>,
|
||||||
|
key: Str,
|
||||||
|
value: Rule<T, Impl>
|
||||||
|
) {
|
||||||
|
if let Some(vec) = map.get_mut(&key) {
|
||||||
|
vec.push(value);
|
||||||
|
return
|
||||||
|
}
|
||||||
|
map.insert(key, vec![value]);
|
||||||
|
}
|
||||||
|
|
|
@ -149,8 +149,8 @@ that you didn't find it here so it can be added :)
|
||||||
[mdn-pseudo-after]: https://developer.mozilla.org/en/docs/Web/CSS/::after
|
[mdn-pseudo-after]: https://developer.mozilla.org/en/docs/Web/CSS/::after
|
||||||
[mdn-pseudo-selection]: https://developer.mozilla.org/en/docs/Web/CSS/::selection
|
[mdn-pseudo-selection]: https://developer.mozilla.org/en/docs/Web/CSS/::selection
|
||||||
[stylist]: http://doc.servo.org/style/selector_matching/struct.Stylist.html
|
[stylist]: http://doc.servo.org/style/selector_matching/struct.Stylist.html
|
||||||
[selectors-selectormap]: http://doc.servo.org/selectors/matching/struct.SelectorMap.html
|
[selectors-selectormap]: http://doc.servo.org/style/selector_matching/struct.SelectorMap.html
|
||||||
[selectors-rule]: http://doc.servo.org/selectors/matching/struct.Rule.html
|
[selectors-rule]: http://doc.servo.org/style/selector_matching/struct.Rule.html
|
||||||
[per-pseudo-selectormap]: http://doc.servo.org/style/selector_matching/struct.PerPseudoElementSelectorMap.html
|
[per-pseudo-selectormap]: http://doc.servo.org/style/selector_matching/struct.PerPseudoElementSelectorMap.html
|
||||||
[per-origin-selectormap]: http://doc.servo.org/style/selector_matching/struct.PerOriginSelectorMap.html
|
[per-origin-selectormap]: http://doc.servo.org/style/selector_matching/struct.PerOriginSelectorMap.html
|
||||||
[docs-pipeline]: https://github.com/servo/servo/blob/master/docs/glossary.md#pipeline
|
[docs-pipeline]: https://github.com/servo/servo/blob/master/docs/glossary.md#pipeline
|
||||||
|
|
1
ports/cef/Cargo.lock
generated
1
ports/cef/Cargo.lock
generated
|
@ -2119,6 +2119,7 @@ dependencies = [
|
||||||
"num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ordered-float 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ordered-float 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"plugins 0.0.1",
|
"plugins 0.0.1",
|
||||||
|
"quickersort 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"selectors 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"selectors 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
1
ports/geckolib/Cargo.lock
generated
1
ports/geckolib/Cargo.lock
generated
|
@ -365,6 +365,7 @@ dependencies = [
|
||||||
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ordered-float 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ordered-float 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"quickersort 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"selectors 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"selectors 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
|
@ -30,7 +30,6 @@ use gecko_string_cache::{Atom, Namespace, WeakAtom, WeakNamespace};
|
||||||
use glue::GeckoDeclarationBlock;
|
use glue::GeckoDeclarationBlock;
|
||||||
use libc::uintptr_t;
|
use libc::uintptr_t;
|
||||||
use selectors::Element;
|
use selectors::Element;
|
||||||
use selectors::matching::DeclarationBlock;
|
|
||||||
use selectors::parser::{AttrSelector, NamespaceConstraint};
|
use selectors::parser::{AttrSelector, NamespaceConstraint};
|
||||||
use snapshot::GeckoElementSnapshot;
|
use snapshot::GeckoElementSnapshot;
|
||||||
use snapshot_helpers;
|
use snapshot_helpers;
|
||||||
|
@ -50,6 +49,7 @@ use style::properties::{ComputedValues, parse_style_attribute};
|
||||||
use style::properties::{PropertyDeclaration, PropertyDeclarationBlock};
|
use style::properties::{PropertyDeclaration, PropertyDeclarationBlock};
|
||||||
use style::refcell::{Ref, RefCell, RefMut};
|
use style::refcell::{Ref, RefCell, RefMut};
|
||||||
use style::selector_impl::ElementExt;
|
use style::selector_impl::ElementExt;
|
||||||
|
use style::selector_matching::DeclarationBlock;
|
||||||
use style::sink::Push;
|
use style::sink::Push;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
|
@ -473,7 +473,7 @@ impl<'le> PartialEq for GeckoElement<'le> {
|
||||||
|
|
||||||
impl<'le> PresentationalHintsSynthetizer for GeckoElement<'le> {
|
impl<'le> PresentationalHintsSynthetizer for GeckoElement<'le> {
|
||||||
fn synthesize_presentational_hints_for_legacy_attributes<V>(&self, _hints: &mut V)
|
fn synthesize_presentational_hints_for_legacy_attributes<V>(&self, _hints: &mut V)
|
||||||
where V: Push<DeclarationBlock<Vec<PropertyDeclaration>>>
|
where V: Push<DeclarationBlock>
|
||||||
{
|
{
|
||||||
// FIXME(bholley) - Need to implement this.
|
// FIXME(bholley) - Need to implement this.
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue