Bug 1364412: Store full selectors in the Rule object. r=bholley

MozReview-Commit-ID: EKLKxNCghLD
Signed-off-by: Emilio Cobos Álvarez <emilio@crisal.io>
This commit is contained in:
Emilio Cobos Álvarez 2017-05-12 17:02:07 +02:00
parent 10560ae043
commit dd38740ece
No known key found for this signature in database
GPG key ID: 056B727BB9C1027C
2 changed files with 19 additions and 27 deletions

View file

@ -458,10 +458,9 @@ impl Stylist {
self.element_map.borrow_for_origin(&stylesheet.origin) self.element_map.borrow_for_origin(&stylesheet.origin)
}; };
map.insert(Rule::new(selector.inner.clone(), map.insert(Rule::new(selector.clone(),
rule.clone(), rule.clone(),
self.rules_source_order, self.rules_source_order));
selector.specificity));
} }
#[inline] #[inline]
@ -1321,7 +1320,7 @@ impl SelectorMap<Rule> {
let mut rules_list = vec![]; let mut rules_list = vec![];
for rule in self.other.iter() { for rule in self.other.iter() {
if rule.selector.complex.iter_raw().next().is_none() { if rule.selector.inner.complex.iter_raw().next().is_none() {
rules_list.push(rule.to_applicable_declaration_block(cascade_level)); rules_list.push(rule.to_applicable_declaration_block(cascade_level));
} }
} }
@ -1371,8 +1370,11 @@ impl SelectorMap<Rule> {
F: FnMut(&E, ElementSelectorFlags), F: FnMut(&E, ElementSelectorFlags),
{ {
for rule in rules.iter() { for rule in rules.iter() {
if matches_selector(&rule.selector, element, parent_bf, if matches_selector(&rule.selector.inner,
relations, flags_setter) { element,
parent_bf,
relations,
flags_setter) {
matching_rules.push( matching_rules.push(
rule.to_applicable_declaration_block(cascade_level)); rule.to_applicable_declaration_block(cascade_level));
} }
@ -1579,29 +1581,24 @@ pub struct Rule {
/// pointer-chasing when gathering applicable declarations, which /// pointer-chasing when gathering applicable declarations, which
/// can ruin performance when there are a lot of rules. /// can ruin performance when there are a lot of rules.
#[cfg_attr(feature = "servo", ignore_heap_size_of = "Arc")] #[cfg_attr(feature = "servo", ignore_heap_size_of = "Arc")]
pub selector: SelectorInner<SelectorImpl>, pub selector: Selector<SelectorImpl>,
/// The actual style rule. /// The actual style rule.
#[cfg_attr(feature = "servo", ignore_heap_size_of = "Arc")] #[cfg_attr(feature = "servo", ignore_heap_size_of = "Arc")]
pub style_rule: Arc<Locked<StyleRule>>, pub style_rule: Arc<Locked<StyleRule>>,
/// The source order this style rule appears in. /// The source order this style rule appears in.
pub source_order: usize, pub source_order: usize,
/// The specificity of the rule this selector represents.
///
/// Note: The top two bits of this are unused, and could be used to store
/// flags.
specificity: u32,
} }
impl Borrow<SelectorInner<SelectorImpl>> for Rule { impl Borrow<SelectorInner<SelectorImpl>> for Rule {
fn borrow(&self) -> &SelectorInner<SelectorImpl> { fn borrow(&self) -> &SelectorInner<SelectorImpl> {
&self.selector &self.selector.inner
} }
} }
impl Rule { impl Rule {
/// Returns the specificity of the rule. /// Returns the specificity of the rule.
pub fn specificity(&self) -> u32 { pub fn specificity(&self) -> u32 {
self.specificity self.selector.specificity
} }
fn to_applicable_declaration_block(&self, level: CascadeLevel) -> ApplicableDeclarationBlock { fn to_applicable_declaration_block(&self, level: CascadeLevel) -> ApplicableDeclarationBlock {
@ -1614,17 +1611,15 @@ impl Rule {
} }
/// Creates a new Rule. /// Creates a new Rule.
pub fn new(selector: SelectorInner<SelectorImpl>, pub fn new(selector: Selector<SelectorImpl>,
style_rule: Arc<Locked<StyleRule>>, style_rule: Arc<Locked<StyleRule>>,
source_order: usize, source_order: usize)
specificity: u32)
-> Self -> Self
{ {
Rule { Rule {
selector: selector, selector: selector,
style_rule: style_rule, style_rule: style_rule,
source_order: source_order, source_order: source_order,
specificity: specificity,
} }
} }
} }

View file

@ -42,10 +42,7 @@ fn get_mock_rules(css_selectors: &[&str]) -> (Vec<Vec<Rule>>, SharedRwLock) {
let guard = shared_lock.read(); let guard = shared_lock.read();
let rule = locked.read_with(&guard); let rule = locked.read_with(&guard);
rule.selectors.0.iter().map(|s| { rule.selectors.0.iter().map(|s| {
Rule::new(s.inner.clone(), Rule::new(s.clone(), locked.clone(), i)
locked.clone(),
i,
s.specificity)
}).collect() }).collect()
}).collect(), shared_lock) }).collect(), shared_lock)
} }
@ -175,22 +172,22 @@ fn test_rule_ordering_same_specificity() {
#[test] #[test]
fn test_get_id_name() { fn test_get_id_name() {
let (rules_list, _) = get_mock_rules(&[".intro", "#top"]); let (rules_list, _) = get_mock_rules(&[".intro", "#top"]);
assert_eq!(stylist::get_id_name(&rules_list[0][0].selector), None); assert_eq!(stylist::get_id_name(&rules_list[0][0].selector.inner), None);
assert_eq!(stylist::get_id_name(&rules_list[1][0].selector), Some(Atom::from("top"))); assert_eq!(stylist::get_id_name(&rules_list[1][0].selector.inner), Some(Atom::from("top")));
} }
#[test] #[test]
fn test_get_class_name() { fn test_get_class_name() {
let (rules_list, _) = get_mock_rules(&[".intro.foo", "#top"]); let (rules_list, _) = get_mock_rules(&[".intro.foo", "#top"]);
assert_eq!(stylist::get_class_name(&rules_list[0][0].selector), Some(Atom::from("foo"))); assert_eq!(stylist::get_class_name(&rules_list[0][0].selector.inner), Some(Atom::from("foo")));
assert_eq!(stylist::get_class_name(&rules_list[1][0].selector), None); assert_eq!(stylist::get_class_name(&rules_list[1][0].selector.inner), None);
} }
#[test] #[test]
fn test_get_local_name() { fn test_get_local_name() {
let (rules_list, _) = get_mock_rules(&["img.foo", "#top", "IMG", "ImG"]); let (rules_list, _) = get_mock_rules(&["img.foo", "#top", "IMG", "ImG"]);
let check = |i: usize, names: Option<(&str, &str)>| { let check = |i: usize, names: Option<(&str, &str)>| {
assert!(stylist::get_local_name(&rules_list[i][0].selector) assert!(stylist::get_local_name(&rules_list[i][0].selector.inner)
== names.map(|(name, lower_name)| LocalNameSelector { == names.map(|(name, lower_name)| LocalNameSelector {
name: LocalName::from(name), name: LocalName::from(name),
lower_name: LocalName::from(lower_name) })) lower_name: LocalName::from(lower_name) }))