Phase 4.2: Add query_index() and use it in matching_rules()

This commit is contained in:
Glint Dev
2026-07-22 13:06:43 +03:00
parent 24fbd17f3e
commit cd2cf64e80

View File

@@ -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()