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()
|
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>(
|
pub fn matching_rules<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
type_name: &str,
|
type_name: &str,
|
||||||
@@ -552,6 +608,10 @@ impl StyleSheet {
|
|||||||
preceding_siblings: &[AncestorInfo],
|
preceding_siblings: &[AncestorInfo],
|
||||||
el_attributes: &HashMap<String, String>,
|
el_attributes: &HashMap<String, String>,
|
||||||
) -> Vec<&'a 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
|
let mut matched: Vec<(usize, &StyleRule)> = self
|
||||||
.rules
|
.rules
|
||||||
.iter()
|
.iter()
|
||||||
|
|||||||
Reference in New Issue
Block a user