Phase 4.2: Add query_index() and use it in matching_rules()
This commit is contained in:
@@ -541,6 +541,62 @@ impl StyleSheet {
|
||||
self.index.is_some()
|
||||
}
|
||||
|
||||
pub fn query_index<'a>(
|
||||
&'a self,
|
||||
type_name: &str,
|
||||
el_id: Option<&str>,
|
||||
el_classes: &[&str],
|
||||
active_pseudo: &[&str],
|
||||
structural: &StructuralContext,
|
||||
ancestors: &[AncestorInfo],
|
||||
preceding_siblings: &[AncestorInfo],
|
||||
el_attributes: &HashMap<String, String>,
|
||||
) -> Option<Vec<&'a HashMap<String, String>>> {
|
||||
let index = self.index.as_ref()?;
|
||||
|
||||
let mut candidates: HashSet<RuleId> = HashSet::with_capacity(32);
|
||||
|
||||
candidates.extend(&index.universal_rules);
|
||||
|
||||
if let Some(rules) = index.by_tag.get(type_name) {
|
||||
candidates.extend(rules);
|
||||
}
|
||||
|
||||
for cls in el_classes {
|
||||
if let Some(rules) = index.by_class.get(*cls) {
|
||||
candidates.extend(rules);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(id) = el_id {
|
||||
if let Some(rules) = index.by_id.get(id) {
|
||||
candidates.extend(rules);
|
||||
}
|
||||
}
|
||||
|
||||
for (_, rule_id) in &index.complex_rules {
|
||||
candidates.insert(*rule_id);
|
||||
}
|
||||
|
||||
let mut matched: Vec<(RuleId, &StyleRule)> = candidates
|
||||
.iter()
|
||||
.filter(|&&rule_id| {
|
||||
let rule = &index.rules[rule_id];
|
||||
rule.selector
|
||||
.matches(type_name, el_id, el_classes, active_pseudo, structural, ancestors, preceding_siblings, el_attributes)
|
||||
})
|
||||
.map(|&rule_id| (rule_id, &index.rules[rule_id]))
|
||||
.collect();
|
||||
|
||||
matched.sort_by(|(i, _a), (j, _b)| {
|
||||
index.rule_specificities[*i]
|
||||
.cmp(&index.rule_specificities[*j])
|
||||
.then_with(|| i.cmp(j))
|
||||
});
|
||||
|
||||
Some(matched.into_iter().map(|(_, rule)| &rule.properties).collect())
|
||||
}
|
||||
|
||||
pub fn matching_rules<'a>(
|
||||
&'a self,
|
||||
type_name: &str,
|
||||
@@ -552,6 +608,10 @@ impl StyleSheet {
|
||||
preceding_siblings: &[AncestorInfo],
|
||||
el_attributes: &HashMap<String, String>,
|
||||
) -> Vec<&'a HashMap<String, String>> {
|
||||
if let Some(matched) = self.query_index(type_name, el_id, el_classes, active_pseudo, structural, ancestors, preceding_siblings, el_attributes) {
|
||||
return matched;
|
||||
}
|
||||
|
||||
let mut matched: Vec<(usize, &StyleRule)> = self
|
||||
.rules
|
||||
.iter()
|
||||
|
||||
Reference in New Issue
Block a user