diff --git a/components/style/selector_matching.rs b/components/style/selector_matching.rs index 037f6522eb9..775f81915d4 100644 --- a/components/style/selector_matching.rs +++ b/components/style/selector_matching.rs @@ -17,7 +17,7 @@ use selectors::Element; use selectors::bloom::BloomFilter; use selectors::matching::{AFFECTED_BY_STYLE_ATTRIBUTE, AFFECTED_BY_PRESENTATIONAL_HINTS}; use selectors::matching::{StyleRelations, matches_compound_selector}; -use selectors::parser::{Selector, SelectorImpl, SimpleSelector, LocalName, CompoundSelector}; +use selectors::parser::{Selector, SimpleSelector, LocalName, CompoundSelector}; use sink::Push; use smallvec::VecLike; use std::borrow::Borrow; @@ -31,8 +31,6 @@ use style_traits::viewport::ViewportConstraints; use stylesheets::{CSSRule, CSSRuleIteratorExt, Origin, Stylesheet}; use viewport::{MaybeNew, ViewportRuleCascade}; -pub type DeclarationBlock = GenericDeclarationBlock>; - /// This structure holds all the selectors and device characteristics /// for a given document. The selectors are converted into `Rule`s /// (defined in rust-selectors), and introduced in a `SelectorMap` @@ -399,7 +397,7 @@ impl Stylist { relations |= AFFECTED_BY_STYLE_ATTRIBUTE; Push::push( applicable_declarations, - GenericDeclarationBlock::from_declarations(sa.normal.clone())); + DeclarationBlock::from_declarations(sa.normal.clone())); } debug!("style attr: {:?}", relations); @@ -416,7 +414,7 @@ impl Stylist { if let Some(ref sa) = style_attribute { Push::push( applicable_declarations, - GenericDeclarationBlock::from_declarations(sa.important.clone())); + DeclarationBlock::from_declarations(sa.important.clone())); } debug!("style attr important: {:?}", relations); @@ -532,10 +530,10 @@ impl Stylist { struct PerOriginSelectorMap { /// Rules that contains at least one property declaration with /// normal importance. - normal: SelectorMap, TheSelectorImpl>, + normal: SelectorMap, /// Rules that contains at least one property declaration with /// !important. - important: SelectorMap, TheSelectorImpl>, + important: SelectorMap, } impl PerOriginSelectorMap { @@ -600,16 +598,16 @@ impl PerPseudoElementSelectorMap { /// element name, etc. will contain the Rules that actually match that /// element. #[cfg_attr(feature = "servo", derive(HeapSizeOf))] -pub struct SelectorMap { +pub struct SelectorMap { // TODO: Tune the initial capacity of the HashMap - id_hash: HashMap>>, - class_hash: HashMap>>, - local_name_hash: HashMap>>, + id_hash: HashMap>, + class_hash: HashMap>, + local_name_hash: HashMap>, /// Same as local_name_hash, but keys are lower-cased. /// For HTML elements in HTML documents. - lower_local_name_hash: HashMap>>, + lower_local_name_hash: HashMap>, /// Rules that don't have ID, class, or element selectors. - other_rules: Vec>, + other_rules: Vec, /// Whether this hash is empty. empty: bool, } @@ -619,14 +617,14 @@ fn sort_by_key K, K: Ord>(v: &mut [T], f: F) { sort_by(v, &|a, b| f(a).cmp(&f(b))) } -impl SelectorMap { - pub fn new() -> SelectorMap { +impl SelectorMap { + pub fn new() -> Self { SelectorMap { id_hash: HashMap::default(), class_hash: HashMap::default(), local_name_hash: HashMap::default(), lower_local_name_hash: HashMap::default(), - other_rules: vec!(), + other_rules: Vec::new(), empty: true, } } @@ -640,8 +638,8 @@ impl SelectorMap { parent_bf: Option<&BloomFilter>, matching_rules_list: &mut V, relations: &mut StyleRelations) - where E: Element, - V: VecLike> + where E: Element, + V: VecLike { if self.empty { return @@ -675,7 +673,7 @@ impl SelectorMap { SelectorMap::get_matching_rules_from_hash(element, parent_bf, local_name_hash, - &element.get_local_name(), + element.get_local_name(), matching_rules_list, relations); @@ -694,7 +692,7 @@ impl SelectorMap { /// `self` sorted by specifity and source order. pub fn get_universal_rules(&self, matching_rules_list: &mut V) - where V: VecLike> + where V: VecLike { if self.empty { return @@ -716,14 +714,14 @@ impl SelectorMap { fn get_matching_rules_from_hash( element: &E, parent_bf: Option<&BloomFilter>, - hash: &HashMap>>, + hash: &HashMap>, key: &BorrowedStr, matching_rules: &mut Vector, relations: &mut StyleRelations) - where E: Element, + where E: Element, Str: Borrow + Eq + Hash, BorrowedStr: Eq + Hash, - Vector: VecLike> + Vector: VecLike { if let Some(rules) = hash.get(key) { SelectorMap::get_matching_rules(element, @@ -737,11 +735,11 @@ impl SelectorMap { /// Adds rules in `rules` that match `element` to the `matching_rules` list. fn get_matching_rules(element: &E, parent_bf: Option<&BloomFilter>, - rules: &[Rule], + rules: &[Rule], matching_rules: &mut V, relations: &mut StyleRelations) - where E: Element, - V: VecLike> + where E: Element, + V: VecLike { for rule in rules.iter() { if matches_compound_selector(&*rule.selector, @@ -753,7 +751,7 @@ impl SelectorMap { /// 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) { + pub fn insert(&mut self, rule: Rule) { self.empty = false; if let Some(id_name) = SelectorMap::get_id_name(&rule) { @@ -776,7 +774,7 @@ impl SelectorMap { } /// Retrieve the first ID name in Rule, or None otherwise. - fn get_id_name(rule: &Rule) -> Option { + fn get_id_name(rule: &Rule) -> Option { for ss in &rule.selector.simple_selectors { // TODO(pradeep): Implement case-sensitivity based on the // document type and quirks mode. @@ -789,7 +787,7 @@ impl SelectorMap { } /// Retrieve the FIRST class name in Rule, or None otherwise. - fn get_class_name(rule: &Rule) -> Option { + fn get_class_name(rule: &Rule) -> Option { for ss in &rule.selector.simple_selectors { // TODO(pradeep): Implement case-sensitivity based on the // document type and quirks mode. @@ -802,7 +800,7 @@ impl SelectorMap { } /// Retrieve the name if it is a type selector, or None otherwise. - fn get_local_name(rule: &Rule) -> Option> { + fn get_local_name(rule: &Rule) -> Option> { for ss in &rule.selector.simple_selectors { if let SimpleSelector::LocalName(ref n) = *ss { return Some(LocalName { @@ -817,50 +815,29 @@ impl SelectorMap { } #[cfg_attr(feature = "servo", derive(HeapSizeOf))] -pub struct Rule { +#[derive(Clone)] +pub struct Rule { // 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>, - pub declarations: GenericDeclarationBlock, + pub selector: Arc>, + pub declarations: DeclarationBlock, } /// 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 { - pub declarations: Arc, +#[derive(Debug, Clone)] +pub struct DeclarationBlock { + pub declarations: Arc>, 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 regardless. -impl Clone for GenericDeclarationBlock { - 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 Clone for Rule { - fn clone(&self) -> Rule { - Rule { - selector: self.selector.clone(), - declarations: self.declarations.clone(), - } - } -} - -impl GenericDeclarationBlock { +impl DeclarationBlock { #[inline] - pub fn from_declarations(declarations: Arc) -> Self { - GenericDeclarationBlock { + pub fn from_declarations(declarations: Arc>) -> Self { + DeclarationBlock { declarations: declarations, source_order: 0, specificity: 0, @@ -868,14 +845,6 @@ impl GenericDeclarationBlock { } } -fn find_push( - map: &mut HashMap>>, - key: Str, - value: Rule -) { - if let Some(vec) = map.get_mut(&key) { - vec.push(value); - return - } - map.insert(key, vec![value]); +fn find_push(map: &mut HashMap>, key: Str, value: Rule) { + map.entry(key).or_insert_with(Vec::new).push(value) }