diff --git a/src/interpreter/style.rs b/src/interpreter/style.rs index f23b23c..cfb70d6 100644 --- a/src/interpreter/style.rs +++ b/src/interpreter/style.rs @@ -632,6 +632,59 @@ impl StyleSheet { matched.into_iter().map(|(_, rule)| &rule.properties).collect() } + pub fn query_index_for_pseudo( + &self, + pseudo: &str, + type_name: &str, + el_id: Option<&str>, + el_classes: &[&str], + structural: &StructuralContext, + ancestors: &[AncestorInfo], + preceding_siblings: &[AncestorInfo], + el_attributes: &HashMap, + ) -> Option> { + let index = self.index.as_ref()?; + + let mut candidates: HashSet = HashSet::with_capacity(16); + + 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 props = HashMap::new(); + for &rule_id in &candidates { + let rule = &index.rules[rule_id]; + if !rule.selector.has_pseudo_class(pseudo) { + continue; + } + if !rule.selector.matches(type_name, el_id, el_classes, &[pseudo], structural, ancestors, preceding_siblings, el_attributes) { + continue; + } + for (k, v) in &rule.properties { + props.insert(k.clone(), v.clone()); + } + } + Some(props) + } + pub fn matching_pseudo_rules( &self, pseudo: &str, @@ -643,6 +696,10 @@ impl StyleSheet { preceding_siblings: &[AncestorInfo], el_attributes: &HashMap, ) -> HashMap { + if let Some(props) = self.query_index_for_pseudo(pseudo, type_name, el_id, el_classes, structural, ancestors, preceding_siblings, el_attributes) { + return props; + } + let mut props = HashMap::new(); for rule in &self.rules { if !rule.selector.has_pseudo_class(pseudo) {