mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
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:
parent
10560ae043
commit
dd38740ece
2 changed files with 19 additions and 27 deletions
|
@ -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,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) }))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue