1use crate::context::QuirksMode;
8use crate::selector_map::{
9 MaybeCaseInsensitiveHashMap, PrecomputedHashMap, SelectorMap, SelectorMapEntry,
10};
11use crate::selector_parser::{NonTSPseudoClass, SelectorImpl};
12use crate::values::AtomIdent;
13use crate::AllocErr;
14use crate::{Atom, LocalName, Namespace, ShrinkIfNeeded};
15use dom::{DocumentState, ElementState};
16use selectors::attr::NamespaceConstraint;
17use selectors::parser::{
18 Combinator, Component, RelativeSelector, RelativeSelectorCombinatorCount,
19 RelativeSelectorMatchHint,
20};
21use selectors::parser::{Selector, SelectorIter};
22use selectors::visitor::{SelectorListKind, SelectorVisitor};
23use servo_arc::ThinArc;
24use smallvec::SmallVec;
25
26#[derive(Clone, Debug, MallocSizeOf)]
45pub struct Dependency {
46 #[ignore_malloc_size_of = "CssRules have primary refs, we measure there"]
48 pub selector: Selector<SelectorImpl>,
49
50 pub selector_offset: usize,
52
53 #[ignore_malloc_size_of = "Arc"]
72 pub next: Option<ThinArc<(), Dependency>>,
73
74 kind: DependencyInvalidationKind,
76}
77
78impl SelectorMapEntry for Dependency {
79 fn selector(&self) -> SelectorIter<SelectorImpl> {
80 self.selector.iter_from(self.selector_offset)
81 }
82}
83
84#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, MallocSizeOf)]
86pub enum NormalDependencyInvalidationKind {
87 Element,
89 ElementAndDescendants,
94 Descendants,
96 Siblings,
99 SlottedElements,
101 Parts,
103}
104
105#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, MallocSizeOf)]
109pub enum RelativeDependencyInvalidationKind {
110 Ancestors,
112 Parent,
114 PrevSibling,
116 AncestorPrevSibling,
118 EarlierSibling,
120 AncestorEarlierSibling,
122}
123
124#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, MallocSizeOf)]
126pub enum ScopeDependencyInvalidationKind {
127 ExplicitScope,
129 ImplicitScope,
131}
132
133#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, MallocSizeOf)]
135pub enum DependencyInvalidationKind {
136 FullSelector,
139 Normal(NormalDependencyInvalidationKind),
141 Relative(RelativeDependencyInvalidationKind),
143 Scope(ScopeDependencyInvalidationKind),
145}
146
147#[derive(Clone, Copy, Debug, MallocSizeOf)]
149pub enum GeneratedInvalidation<'a> {
150 Normal,
152 Scope(Option<&'a ThinArc<(), Dependency>>),
154}
155
156#[inline(always)]
158fn get_non_relative_invalidation_kind(
159 selector: &Selector<SelectorImpl>,
160 selector_offset: usize,
161 is_scope: bool,
162) -> DependencyInvalidationKind {
163 if is_scope {
164 return DependencyInvalidationKind::Scope(ScopeDependencyInvalidationKind::ExplicitScope);
165 }
166 if selector_offset == 0 {
167 return DependencyInvalidationKind::Normal(NormalDependencyInvalidationKind::Element);
168 }
169 let combinator = selector.combinator_at_match_order(selector_offset - 1);
170 DependencyInvalidationKind::Normal(match combinator {
171 Combinator::Child | Combinator::Descendant => NormalDependencyInvalidationKind::Descendants,
172 Combinator::LaterSibling | Combinator::NextSibling => {
173 NormalDependencyInvalidationKind::Siblings
174 },
175 Combinator::PseudoElement => NormalDependencyInvalidationKind::ElementAndDescendants,
176 Combinator::SlotAssignment => NormalDependencyInvalidationKind::SlottedElements,
177 Combinator::Part => NormalDependencyInvalidationKind::Parts,
178 })
179}
180
181impl Dependency {
182 pub fn new(
184 selector: Selector<SelectorImpl>,
185 selector_offset: usize,
186 next: Option<ThinArc<(), Dependency>>,
187 kind: DependencyInvalidationKind,
188 ) -> Self {
189 Self {
190 selector,
191 selector_offset,
192 next,
193 kind,
194 }
195 }
196 pub fn for_full_selector_invalidation(selector: Selector<SelectorImpl>) -> Self {
205 Self {
206 selector_offset: selector.len() + 1,
207 selector,
208 next: None,
209 kind: DependencyInvalidationKind::FullSelector,
210 }
211 }
212
213 pub fn normal_invalidation_kind(&self) -> NormalDependencyInvalidationKind {
216 if let DependencyInvalidationKind::Normal(kind) = self.kind {
217 return kind;
218 }
219 unreachable!("Querying normal invalidation kind on non-normal dependency.");
220 }
221
222 #[inline(always)]
225 pub fn relative_invalidation_kind(&self) -> RelativeDependencyInvalidationKind {
226 if let DependencyInvalidationKind::Relative(kind) = self.kind {
227 return kind;
228 }
229 unreachable!("Querying relative invalidation kind on non-relative dependency.");
230 }
231
232 pub fn invalidation_kind(&self) -> DependencyInvalidationKind {
234 self.kind
235 }
236
237 pub fn right_combinator_is_next_sibling(&self) -> bool {
242 if self.selector_offset == 0 {
243 return false;
244 }
245 matches!(
246 self.selector
247 .combinator_at_match_order(self.selector_offset - 1),
248 Combinator::NextSibling
249 )
250 }
251
252 pub fn dependency_is_relative_with_single_next_sibling(&self) -> bool {
257 match self.invalidation_kind() {
258 DependencyInvalidationKind::Relative(kind) => {
259 kind == RelativeDependencyInvalidationKind::PrevSibling
260 },
261 _ => false,
262 }
263 }
264}
265
266#[derive(Clone, Debug, MallocSizeOf)]
269pub struct StateDependency {
270 pub dep: Dependency,
272 pub state: ElementState,
274}
275
276impl SelectorMapEntry for StateDependency {
277 fn selector(&self) -> SelectorIter<SelectorImpl> {
278 self.dep.selector()
279 }
280}
281
282#[derive(Clone, Debug, MallocSizeOf)]
284pub struct DocumentStateDependency {
285 #[cfg_attr(
288 feature = "gecko",
289 ignore_malloc_size_of = "CssRules have primary refs, we measure there"
290 )]
291 #[cfg_attr(feature = "servo", ignore_malloc_size_of = "Arc")]
292 pub dependency: Dependency,
293 pub state: DocumentState,
295}
296
297pub type IdOrClassDependencyMap = MaybeCaseInsensitiveHashMap<Atom, SmallVec<[Dependency; 1]>>;
299pub type StateDependencyMap = SelectorMap<StateDependency>;
301pub type LocalNameDependencyMap = PrecomputedHashMap<LocalName, SmallVec<[Dependency; 1]>>;
303pub type CustomStateDependencyMap = PrecomputedHashMap<AtomIdent, SmallVec<[Dependency; 1]>>;
305
306#[derive(Clone, Debug, MallocSizeOf)]
315pub struct InvalidationMap {
316 pub class_to_selector: IdOrClassDependencyMap,
319 pub id_to_selector: IdOrClassDependencyMap,
322 pub state_affecting_selectors: StateDependencyMap,
324 pub document_state_selectors: Vec<DocumentStateDependency>,
326 pub other_attribute_affecting_selectors: LocalNameDependencyMap,
328 pub custom_state_affecting_selectors: CustomStateDependencyMap,
330}
331
332#[derive(Clone, Copy, Debug, MallocSizeOf)]
338pub struct TSStateForInvalidation(u8);
339
340bitflags! {
341 impl TSStateForInvalidation : u8 {
342 const EMPTY = 1 << 0;
345 const NTH = 1 << 1;
347 const NTH_EDGE_FIRST = 1 << 2;
350 const NTH_EDGE_LAST = 1 << 3;
353 }
354}
355
356impl TSStateForInvalidation {
357 pub fn may_be_optimized(&self) -> bool {
360 (Self::EMPTY | Self::NTH_EDGE_FIRST | Self::NTH_EDGE_LAST).contains(*self)
361 }
362}
363
364#[derive(Clone, Debug, MallocSizeOf)]
366pub struct TSStateDependency {
367 pub dep: Dependency,
369 pub state: TSStateForInvalidation,
371}
372
373impl SelectorMapEntry for TSStateDependency {
374 fn selector(&self) -> SelectorIter<SelectorImpl> {
375 self.dep.selector()
376 }
377}
378
379pub type TSStateDependencyMap = SelectorMap<TSStateDependency>;
381pub type AnyDependencyMap = SmallVec<[Dependency; 1]>;
383
384#[derive(Clone, Debug, MallocSizeOf)]
388pub struct AdditionalRelativeSelectorInvalidationMap {
389 pub ts_state_to_selector: TSStateDependencyMap,
391 pub type_to_selector: LocalNameDependencyMap,
393 pub any_to_selector: AnyDependencyMap,
395 pub used: bool,
397 pub needs_ancestors_traversal: bool,
399}
400
401impl AdditionalRelativeSelectorInvalidationMap {
402 pub fn new() -> Self {
404 Self {
405 ts_state_to_selector: TSStateDependencyMap::default(),
406 type_to_selector: LocalNameDependencyMap::default(),
407 any_to_selector: SmallVec::default(),
408 used: false,
409 needs_ancestors_traversal: false,
410 }
411 }
412
413 pub fn clear(&mut self) {
415 self.ts_state_to_selector.clear();
416 self.type_to_selector.clear();
417 self.any_to_selector.clear();
418 }
419
420 pub fn shrink_if_needed(&mut self) {
422 self.ts_state_to_selector.shrink_if_needed();
423 self.type_to_selector.shrink_if_needed();
424 }
425}
426
427impl InvalidationMap {
428 pub fn new() -> Self {
430 Self {
431 class_to_selector: IdOrClassDependencyMap::new(),
432 id_to_selector: IdOrClassDependencyMap::new(),
433 state_affecting_selectors: StateDependencyMap::new(),
434 document_state_selectors: Vec::new(),
435 other_attribute_affecting_selectors: LocalNameDependencyMap::default(),
436 custom_state_affecting_selectors: CustomStateDependencyMap::default(),
437 }
438 }
439
440 pub fn len(&self) -> usize {
442 self.state_affecting_selectors.len()
443 + self.document_state_selectors.len()
444 + self
445 .other_attribute_affecting_selectors
446 .iter()
447 .fold(0, |accum, (_, ref v)| accum + v.len())
448 + self
449 .id_to_selector
450 .iter()
451 .fold(0, |accum, (_, ref v)| accum + v.len())
452 + self
453 .class_to_selector
454 .iter()
455 .fold(0, |accum, (_, ref v)| accum + v.len())
456 + self
457 .custom_state_affecting_selectors
458 .iter()
459 .fold(0, |accum, (_, ref v)| accum + v.len())
460 }
461
462 pub fn clear(&mut self) {
464 self.class_to_selector.clear();
465 self.id_to_selector.clear();
466 self.state_affecting_selectors.clear();
467 self.document_state_selectors.clear();
468 self.other_attribute_affecting_selectors.clear();
469 self.custom_state_affecting_selectors.clear();
470 }
471
472 pub fn shrink_if_needed(&mut self) {
474 self.class_to_selector.shrink_if_needed();
475 self.id_to_selector.shrink_if_needed();
476 self.state_affecting_selectors.shrink_if_needed();
477 self.other_attribute_affecting_selectors.shrink_if_needed();
478 self.custom_state_affecting_selectors.shrink_if_needed();
479 }
480}
481
482pub fn note_selector_for_invalidation(
484 selector: &Selector<SelectorImpl>,
485 quirks_mode: QuirksMode,
486 map: &mut InvalidationMap,
487 relative_selector_invalidation_map: &mut InvalidationMap,
488 additional_relative_selector_invalidation_map: &mut AdditionalRelativeSelectorInvalidationMap,
489 inner_scope_dependencies: Option<&ThinArc<(), Dependency>>,
490) -> Result<Option<Vec<Dependency>>, AllocErr> {
491 let next_dependency = Dependency::for_full_selector_invalidation(selector.clone());
492 let mut document_state = DocumentState::empty();
493 let mut scope_dependencies = ScopeSelectorCollectorState {
494 inner_dependencies: &inner_scope_dependencies.cloned(),
495 this_dependencies: None,
496 };
497
498 {
499 let mut next_stack = NextSelectors::new();
500 let mut alloc_error = None;
501 let mut collector = SelectorDependencyCollector {
502 map,
503 relative_selector_invalidation_map,
504 additional_relative_selector_invalidation_map,
505 document_state: &mut document_state,
506 selector,
507 next_selectors: &mut next_stack,
508 quirks_mode,
509 compound_state: PerCompoundState::new(0),
510 relative_inner_collector: None,
511 scope_dependencies: &mut scope_dependencies,
512 alloc_error: &mut alloc_error,
513 };
514
515 let visit_result = collector.visit_whole_selector();
516
517 debug_assert_eq!(!visit_result, alloc_error.is_some());
518 if let Some(alloc_error) = alloc_error {
519 return Err(alloc_error);
520 }
521 }
522
523 if !document_state.is_empty() {
524 let dep = DocumentStateDependency {
525 state: document_state,
526 dependency: next_dependency,
527 };
528 map.document_state_selectors.try_reserve(1)?;
529 map.document_state_selectors.push(dep);
530 }
531 Ok(scope_dependencies.this_dependencies)
532}
533
534struct PerCompoundState {
535 offset: usize,
537
538 element_state: ElementState,
540}
541
542impl PerCompoundState {
543 fn new(offset: usize) -> Self {
544 Self {
545 offset,
546 element_state: ElementState::empty(),
547 }
548 }
549}
550
551struct NextDependencyEntry {
552 selector: Selector<SelectorImpl>,
553 offset: usize,
554 cached_dependency: Option<ThinArc<(), Dependency>>,
555}
556
557struct RelativeSelectorInnerCollectorState<'a> {
558 next_dependency: &'a ThinArc<(), Dependency>,
559 relative_compound_state: RelativeSelectorCompoundStateAttributes,
560}
561struct ScopeSelectorCollectorState<'a> {
562 inner_dependencies: &'a Option<ThinArc<(), Dependency>>,
564 this_dependencies: Option<Vec<Dependency>>,
566}
567
568trait Collector {
569 fn dependency(&mut self) -> Dependency;
570 fn id_map(&mut self) -> &mut IdOrClassDependencyMap;
571 fn class_map(&mut self) -> &mut IdOrClassDependencyMap;
572 fn state_map(&mut self) -> &mut StateDependencyMap;
573 fn attribute_map(&mut self) -> &mut LocalNameDependencyMap;
574 fn custom_state_map(&mut self) -> &mut CustomStateDependencyMap;
575 fn inner_scope_dependencies(&self) -> Option<ThinArc<(), Dependency>>;
576 fn this_scope_dependencies(&mut self) -> &mut Option<Vec<Dependency>>;
577 fn update_states(&mut self, element_state: ElementState, document_state: DocumentState);
578
579 fn type_map(&mut self) -> &mut LocalNameDependencyMap {
586 unreachable!();
587 }
588
589 fn ts_state_map(&mut self) -> &mut TSStateDependencyMap {
593 unreachable!();
594 }
595
596 fn any_vec(&mut self) -> &mut AnyDependencyMap {
598 unreachable!();
599 }
600}
601
602fn on_attribute<C: Collector>(
603 local_name: &LocalName,
604 local_name_lower: &LocalName,
605 collector: &mut C,
606) -> Result<(), AllocErr> {
607 add_attr_dependency(local_name.clone(), collector)?;
608 if local_name != local_name_lower {
609 add_attr_dependency(local_name_lower.clone(), collector)?;
610 }
611 Ok(())
612}
613
614fn on_id_or_class<C: Collector>(
615 s: &Component<SelectorImpl>,
616 quirks_mode: QuirksMode,
617 collector: &mut C,
618) -> Result<(), AllocErr> {
619 let dependency = collector.dependency();
620
621 let (atom, map) = match *s {
622 Component::ID(ref atom) => (atom, collector.id_map()),
623 Component::Class(ref atom) => (atom, collector.class_map()),
624 _ => unreachable!(),
625 };
626 let entry = map.try_entry(atom.0.clone(), quirks_mode)?;
627 let vec = entry.or_insert_with(SmallVec::new);
628 vec.try_reserve(1)?;
629 vec.push(dependency);
630 Ok(())
631}
632
633fn on_scope<C: Collector>(collector: &mut C) -> Result<(), AllocErr> {
634 let new_dependency = collector.dependency();
635 let this_scope_dependencies = collector.this_scope_dependencies();
636
637 this_scope_dependencies
638 .get_or_insert(Vec::new())
639 .push(new_dependency);
640
641 Ok(())
642}
643
644fn add_attr_dependency<C: Collector>(name: LocalName, collector: &mut C) -> Result<(), AllocErr> {
645 let dependency = collector.dependency();
646 let map = collector.attribute_map();
647 add_local_name(name, dependency, map)
648}
649
650fn add_custom_state_dependency<C: Collector>(
651 name: AtomIdent,
652 collector: &mut C,
653) -> Result<(), AllocErr> {
654 let dependency = collector.dependency();
655 let map = collector.custom_state_map();
656 map.try_reserve(1)?;
657 let vec = map.entry(name).or_default();
658 vec.try_reserve(1)?;
659 vec.push(dependency);
660 Ok(())
661}
662
663fn add_local_name(
664 name: LocalName,
665 dependency: Dependency,
666 map: &mut LocalNameDependencyMap,
667) -> Result<(), AllocErr> {
668 map.try_reserve(1)?;
669 let vec = map.entry(name).or_default();
670 vec.try_reserve(1)?;
671 vec.push(dependency);
672 Ok(())
673}
674
675fn on_pseudo_class<C: Collector>(pc: &NonTSPseudoClass, collector: &mut C) -> Result<(), AllocErr> {
676 collector.update_states(pc.state_flag(), pc.document_state_flag());
677
678 let attr_name = match *pc {
679 #[cfg(feature = "gecko")]
680 NonTSPseudoClass::MozTableBorderNonzero => local_name!("border"),
681 #[cfg(feature = "gecko")]
682 NonTSPseudoClass::MozSelectListBox => {
683 add_attr_dependency(local_name!("multiple"), collector)?;
685 return add_attr_dependency(local_name!("size"), collector);
686 },
687 NonTSPseudoClass::Lang(..) => local_name!("lang"),
688 NonTSPseudoClass::CustomState(ref name) => {
689 return add_custom_state_dependency(name.0.clone(), collector);
690 },
691 _ => return Ok(()),
692 };
693
694 add_attr_dependency(attr_name, collector)
695}
696
697fn add_pseudo_class_dependency<C: Collector>(
698 element_state: ElementState,
699 quirks_mode: QuirksMode,
700 collector: &mut C,
701) -> Result<(), AllocErr> {
702 if element_state.is_empty() {
703 return Ok(());
704 }
705 let dependency = collector.dependency();
706 collector.state_map().insert(
707 StateDependency {
708 dep: dependency,
709 state: element_state,
710 },
711 quirks_mode,
712 )
713}
714
715fn visit_all_in_iter_compound<T: SelectorVisitor<Impl = SelectorImpl>>(
722 visitor: &mut T,
723 iter: &mut SelectorIter<'_, SelectorImpl>,
724) -> (bool, usize) {
725 let mut index = 0;
726 for ss in iter {
727 if !ss.visit(visitor) {
728 return (false, index);
729 }
730 index += 1;
731 }
732 (true, index)
733}
734
735type NextSelectors = SmallVec<[NextDependencyEntry; 5]>;
736
737struct SelectorDependencyCollector<'a, 'b, 'c> {
739 map: &'a mut InvalidationMap,
740 relative_selector_invalidation_map: &'a mut InvalidationMap,
741 additional_relative_selector_invalidation_map:
742 &'a mut AdditionalRelativeSelectorInvalidationMap,
743
744 document_state: &'a mut DocumentState,
749
750 selector: &'a Selector<SelectorImpl>,
752
753 next_selectors: &'a mut NextSelectors,
759
760 quirks_mode: QuirksMode,
762
763 compound_state: PerCompoundState,
765
766 relative_inner_collector: Option<RelativeSelectorInnerCollectorState<'b>>,
769
770 scope_dependencies: &'a mut ScopeSelectorCollectorState<'c>,
771
772 alloc_error: &'a mut Option<AllocErr>,
774}
775
776fn next_dependency(
777 next_selector: &mut NextSelectors,
778 next_outer_dependency: Option<&ThinArc<(), Dependency>>,
779 next_scope_dependencies: Option<&ThinArc<(), Dependency>>,
780) -> Option<ThinArc<(), Dependency>> {
781 if next_selector.is_empty() {
782 return match next_outer_dependency {
783 Some(..) => next_outer_dependency.cloned(),
784 None => next_scope_dependencies.cloned(),
785 };
786 }
787
788 fn dependencies_from(
789 entries: &mut [NextDependencyEntry],
790 next_outer_dependency: &Option<&ThinArc<(), Dependency>>,
791 next_scope_dependencies: &Option<&ThinArc<(), Dependency>>,
792 ) -> Option<ThinArc<(), Dependency>> {
793 if entries.is_empty() {
794 return next_scope_dependencies.cloned();
795 }
796
797 let last_index = entries.len() - 1;
798 let (previous, last) = entries.split_at_mut(last_index);
799 let last = &mut last[0];
800 let selector = &last.selector;
801 let selector_offset = last.offset;
802
803 let dependency = Dependency {
804 selector: selector.clone(),
805 selector_offset,
806 next: dependencies_from(previous, next_outer_dependency, next_scope_dependencies),
807 kind: get_non_relative_invalidation_kind(
808 selector,
809 selector_offset,
810 next_scope_dependencies.is_some(),
811 ),
812 };
813
814 Some(
815 last.cached_dependency
816 .get_or_insert_with(|| ThinArc::from_header_and_iter((), [dependency].into_iter()))
817 .clone(),
818 )
819 }
820
821 dependencies_from(
822 next_selector,
823 &next_outer_dependency,
824 &next_scope_dependencies,
825 )
826}
827
828impl<'a, 'b, 'c> Collector for SelectorDependencyCollector<'a, 'b, 'c> {
829 fn dependency(&mut self) -> Dependency {
830 let optional_dependency = self
831 .relative_inner_collector
832 .as_ref()
833 .map(|collector| collector.next_dependency);
834
835 let offset = self.compound_state.offset;
836
837 let scope_dependencies = self.inner_scope_dependencies();
838
839 let next = next_dependency(
840 self.next_selectors,
841 optional_dependency,
842 scope_dependencies.as_ref(),
843 );
844
845 Dependency {
846 selector: self.selector.clone(),
847 selector_offset: offset,
848 next: next,
849 kind: get_non_relative_invalidation_kind(
850 self.selector,
851 offset,
852 scope_dependencies.is_some(),
853 ),
854 }
855 }
856
857 fn id_map(&mut self) -> &mut IdOrClassDependencyMap {
858 if self.relative_inner_collector.is_none() {
859 &mut self.map.id_to_selector
860 } else {
861 &mut self.relative_selector_invalidation_map.id_to_selector
862 }
863 }
864
865 fn class_map(&mut self) -> &mut IdOrClassDependencyMap {
866 if self.relative_inner_collector.is_none() {
867 &mut self.map.class_to_selector
868 } else {
869 &mut self.relative_selector_invalidation_map.class_to_selector
870 }
871 }
872
873 fn state_map(&mut self) -> &mut StateDependencyMap {
874 if self.relative_inner_collector.is_none() {
875 &mut self.map.state_affecting_selectors
876 } else {
877 &mut self
878 .relative_selector_invalidation_map
879 .state_affecting_selectors
880 }
881 }
882
883 fn attribute_map(&mut self) -> &mut LocalNameDependencyMap {
884 if self.relative_inner_collector.is_none() {
885 &mut self.map.other_attribute_affecting_selectors
886 } else {
887 &mut self
888 .relative_selector_invalidation_map
889 .other_attribute_affecting_selectors
890 }
891 }
892
893 fn inner_scope_dependencies(&self) -> Option<ThinArc<(), Dependency>> {
894 self.scope_dependencies.inner_dependencies.clone()
895 }
896
897 fn this_scope_dependencies(&mut self) -> &mut Option<Vec<Dependency>> {
898 &mut self.scope_dependencies.this_dependencies
899 }
900
901 fn update_states(&mut self, element_state: ElementState, document_state: DocumentState) {
902 self.compound_state.element_state |= element_state;
903 *self.document_state |= document_state;
904 }
905
906 fn custom_state_map(&mut self) -> &mut CustomStateDependencyMap {
907 if self.relative_inner_collector.is_none() {
908 &mut self.map.custom_state_affecting_selectors
909 } else {
910 &mut self
911 .relative_selector_invalidation_map
912 .custom_state_affecting_selectors
913 }
914 }
915
916 fn type_map(&mut self) -> &mut LocalNameDependencyMap {
917 debug_assert!(
918 self.relative_inner_collector.is_some(),
919 "Asking for relative selector invalidation outside of relative selector"
920 );
921 &mut self
922 .additional_relative_selector_invalidation_map
923 .type_to_selector
924 }
925
926 fn ts_state_map(&mut self) -> &mut TSStateDependencyMap {
927 debug_assert!(
928 self.relative_inner_collector.is_some(),
929 "Asking for relative selector invalidation outside of relative selector"
930 );
931 &mut self
932 .additional_relative_selector_invalidation_map
933 .ts_state_to_selector
934 }
935
936 fn any_vec(&mut self) -> &mut AnyDependencyMap {
937 debug_assert!(
938 self.relative_inner_collector.is_some(),
939 "Asking for relative selector invalidation outside of relative selector"
940 );
941 &mut self
942 .additional_relative_selector_invalidation_map
943 .any_to_selector
944 }
945}
946
947impl<'a, 'b, 'c> SelectorDependencyCollector<'a, 'b, 'c> {
948 fn visit_whole_selector(&mut self) -> bool {
949 let iter = self.selector.iter();
950 self.visit_whole_selector_from(iter, 0)
951 }
952
953 fn visit_whole_selector_from(
954 &mut self,
955 mut iter: SelectorIter<SelectorImpl>,
956 mut index: usize,
957 ) -> bool {
958 loop {
959 self.compound_state = PerCompoundState::new(index);
961 if let Some(state) = self.relative_inner_collector.as_mut() {
962 state.relative_compound_state = RelativeSelectorCompoundStateAttributes::new();
963 }
964
965 let (keep_traversing, index_offset) = visit_all_in_iter_compound(self, &mut iter);
967
968 if !keep_traversing {
969 return false;
970 }
971
972 index += index_offset;
973
974 if let Err(err) = add_pseudo_class_dependency(
975 self.compound_state.element_state,
976 self.quirks_mode,
977 self,
978 ) {
979 *self.alloc_error = Some(err);
980 return false;
981 }
982
983 if let Some(state) = self
984 .relative_inner_collector
985 .as_ref()
986 .map(|state| state.relative_compound_state)
987 {
988 if let Err(err) =
989 add_ts_pseudo_class_dependency(state.ts_state, self.quirks_mode, self)
990 {
991 *self.alloc_error = Some(err);
992 return false;
993 }
994
995 if !state.added_entry {
996 if let Err(err) =
998 add_non_unique_info(&self.selector, self.compound_state.offset, self)
999 {
1000 *self.alloc_error = Some(err);
1001 return false;
1002 }
1003 }
1004 }
1005
1006 let combinator = iter.next_sequence();
1007 if combinator.is_none() {
1008 return true;
1009 }
1010 index += 1; }
1012 }
1013}
1014
1015impl<'a, 'b, 'c> SelectorVisitor for SelectorDependencyCollector<'a, 'b, 'c> {
1016 type Impl = SelectorImpl;
1017
1018 fn visit_selector_list(
1019 &mut self,
1020 _list_kind: SelectorListKind,
1021 list: &[Selector<SelectorImpl>],
1022 ) -> bool {
1023 let next_relative_dependency = self
1024 .relative_inner_collector
1025 .is_some()
1026 .then(|| ThinArc::from_header_and_iter((), std::iter::once(self.dependency())));
1027 for selector in list {
1028 let mut iter = selector.iter();
1034 let saved_added_entry = self
1035 .relative_inner_collector
1036 .as_ref()
1037 .map(|state| state.relative_compound_state.added_entry);
1038
1039 let (keep_traversing, mut index) = visit_all_in_iter_compound(self, &mut iter);
1040
1041 if !keep_traversing {
1042 return false;
1043 }
1044
1045 if let Some(state) = self.relative_inner_collector.as_mut() {
1046 state.relative_compound_state.added_entry = saved_added_entry.unwrap_or_default();
1047 }
1048 let combinator = iter.next_sequence();
1049 if combinator.is_none() {
1050 continue;
1051 }
1052
1053 index += 1; let offset = self.compound_state.offset;
1056
1057 if self.relative_inner_collector.is_none() {
1058 self.next_selectors.push(NextDependencyEntry {
1059 selector: self.selector.clone(),
1060 offset: offset,
1061 cached_dependency: None,
1062 });
1063 }
1064 debug_assert!(
1065 next_relative_dependency.is_some() == self.relative_inner_collector.is_some(),
1066 "Next relative dependency and relative inner collector must be Some/None at the same time!"
1067 );
1068 let mut nested = SelectorDependencyCollector {
1069 map: &mut *self.map,
1070 relative_selector_invalidation_map: &mut *self.relative_selector_invalidation_map,
1071 additional_relative_selector_invalidation_map: &mut *self
1072 .additional_relative_selector_invalidation_map,
1073 document_state: &mut *self.document_state,
1074 selector,
1075 next_selectors: &mut *self.next_selectors,
1076 quirks_mode: self.quirks_mode,
1077 compound_state: PerCompoundState::new(index),
1078 relative_inner_collector: next_relative_dependency.as_ref().map(
1079 |next_dependency| RelativeSelectorInnerCollectorState {
1080 next_dependency,
1081 relative_compound_state: RelativeSelectorCompoundStateAttributes::new(),
1082 },
1083 ),
1084 scope_dependencies: &mut self.scope_dependencies,
1085 alloc_error: &mut *self.alloc_error,
1086 };
1087 if !nested.visit_whole_selector_from(iter, index) {
1088 return false;
1089 }
1090 self.next_selectors.pop();
1091 }
1092 true
1093 }
1094
1095 fn visit_relative_selector_list(
1096 &mut self,
1097 list: &[selectors::parser::RelativeSelector<Self::Impl>],
1098 ) -> bool {
1099 if self.relative_inner_collector.is_some() {
1101 return true;
1102 }
1103
1104 self.additional_relative_selector_invalidation_map.used = true;
1105 for relative_selector in list {
1106 self.next_selectors.push(NextDependencyEntry {
1109 selector: self.selector.clone(),
1110 offset: self.compound_state.offset,
1111 cached_dependency: None,
1112 });
1113 let mut nested = RelativeSelectorDependencyCollector {
1114 map: &mut *self.map,
1115 relative_selector_invalidation_map: &mut *self.relative_selector_invalidation_map,
1116 additional_relative_selector_invalidation_map: &mut *self
1117 .additional_relative_selector_invalidation_map,
1118 document_state: &mut *self.document_state,
1119 selector: &relative_selector,
1120 combinator_count: RelativeSelectorCombinatorCount::new(relative_selector),
1121 next_selectors: &mut *self.next_selectors,
1122 quirks_mode: self.quirks_mode,
1123 compound_state: PerCompoundState::new(0),
1124 compound_state_attributes: RelativeSelectorCompoundStateAttributes::new(),
1125 scope_dependencies: &mut self.scope_dependencies,
1126 alloc_error: &mut *self.alloc_error,
1127 };
1128 if !nested.visit_whole_selector() {
1129 return false;
1130 }
1131 self.next_selectors.pop();
1132 }
1133 true
1134 }
1135
1136 fn visit_simple_selector(&mut self, s: &Component<SelectorImpl>) -> bool {
1137 match on_simple_selector(s, self.quirks_mode, self) {
1138 Ok(result) => {
1139 if let ComponentVisitResult::Handled(state) = result {
1140 if let Some(inner_collector_state) = self.relative_inner_collector.as_mut() {
1141 inner_collector_state.relative_compound_state.added_entry = true;
1142 inner_collector_state
1143 .relative_compound_state
1144 .ts_state
1145 .insert(state);
1146 }
1147 }
1148 true
1149 },
1150 Err(err) => {
1151 *self.alloc_error = Some(err.into());
1152 false
1153 },
1154 }
1155 }
1156
1157 fn visit_attribute_selector(
1158 &mut self,
1159 _: &NamespaceConstraint<&Namespace>,
1160 local_name: &LocalName,
1161 local_name_lower: &LocalName,
1162 ) -> bool {
1163 if let Some(state) = self.relative_inner_collector.as_mut() {
1164 state.relative_compound_state.added_entry = true;
1165 }
1166 if let Err(err) = on_attribute(local_name, local_name_lower, self) {
1167 *self.alloc_error = Some(err);
1168 return false;
1169 }
1170 true
1171 }
1172}
1173
1174#[derive(Clone, Copy)]
1175struct RelativeSelectorCompoundStateAttributes {
1176 ts_state: TSStateForInvalidation,
1177 added_entry: bool,
1178}
1179
1180impl RelativeSelectorCompoundStateAttributes {
1181 fn new() -> Self {
1182 Self {
1183 ts_state: TSStateForInvalidation::empty(),
1184 added_entry: false,
1185 }
1186 }
1187}
1188
1189struct RelativeSelectorDependencyCollector<'a, 'b> {
1191 map: &'a mut InvalidationMap,
1192 relative_selector_invalidation_map: &'a mut InvalidationMap,
1193 additional_relative_selector_invalidation_map:
1194 &'a mut AdditionalRelativeSelectorInvalidationMap,
1195
1196 document_state: &'a mut DocumentState,
1201
1202 selector: &'a RelativeSelector<SelectorImpl>,
1204 combinator_count: RelativeSelectorCombinatorCount,
1206
1207 next_selectors: &'a mut NextSelectors,
1213
1214 quirks_mode: QuirksMode,
1216
1217 compound_state: PerCompoundState,
1219
1220 compound_state_attributes: RelativeSelectorCompoundStateAttributes,
1222
1223 scope_dependencies: &'a mut ScopeSelectorCollectorState<'b>,
1224
1225 alloc_error: &'a mut Option<AllocErr>,
1227}
1228
1229fn add_non_unique_info<C: Collector>(
1230 selector: &Selector<SelectorImpl>,
1231 offset: usize,
1232 collector: &mut C,
1233) -> Result<(), AllocErr> {
1234 for ss in selector.iter_from(offset) {
1236 match ss {
1237 Component::LocalName(ref name) => {
1238 let dependency = collector.dependency();
1239 add_local_name(name.name.clone(), dependency, &mut collector.type_map())?;
1240 if name.name != name.lower_name {
1241 let dependency = collector.dependency();
1242 add_local_name(
1243 name.lower_name.clone(),
1244 dependency,
1245 &mut collector.type_map(),
1246 )?;
1247 }
1248 return Ok(());
1249 },
1250 _ => (),
1251 };
1252 }
1253 collector.any_vec().try_reserve(1)?;
1255 let dependency = collector.dependency();
1256 collector.any_vec().push(dependency);
1257 Ok(())
1258}
1259
1260fn add_ts_pseudo_class_dependency<C: Collector>(
1261 state: TSStateForInvalidation,
1262 quirks_mode: QuirksMode,
1263 collector: &mut C,
1264) -> Result<(), AllocErr> {
1265 if state.is_empty() {
1266 return Ok(());
1267 }
1268 let dependency = collector.dependency();
1269 collector.ts_state_map().insert(
1270 TSStateDependency {
1271 dep: dependency,
1272 state,
1273 },
1274 quirks_mode,
1275 )
1276}
1277
1278impl<'a, 'b> RelativeSelectorDependencyCollector<'a, 'b> {
1279 fn visit_whole_selector(&mut self) -> bool {
1280 let mut iter = self.selector.selector.iter_skip_relative_selector_anchor();
1281 let mut index = 0;
1282
1283 self.additional_relative_selector_invalidation_map
1284 .needs_ancestors_traversal |= match self.selector.match_hint {
1285 RelativeSelectorMatchHint::InNextSiblingSubtree
1286 | RelativeSelectorMatchHint::InSiblingSubtree
1287 | RelativeSelectorMatchHint::InSubtree => true,
1288 _ => false,
1289 };
1290 loop {
1291 self.compound_state = PerCompoundState::new(index);
1293
1294 let (keep_traversing, index_offset) = visit_all_in_iter_compound(self, &mut iter);
1295
1296 if !keep_traversing {
1297 return false;
1298 }
1299
1300 index += index_offset;
1301
1302 if let Err(err) = add_pseudo_class_dependency(
1303 self.compound_state.element_state,
1304 self.quirks_mode,
1305 self,
1306 ) {
1307 *self.alloc_error = Some(err);
1308 return false;
1309 }
1310
1311 if let Err(err) = add_ts_pseudo_class_dependency(
1312 self.compound_state_attributes.ts_state,
1313 self.quirks_mode,
1314 self,
1315 ) {
1316 *self.alloc_error = Some(err);
1317 return false;
1318 }
1319
1320 if !self.compound_state_attributes.added_entry {
1321 if let Err(err) =
1323 add_non_unique_info(&self.selector.selector, self.compound_state.offset, self)
1324 {
1325 *self.alloc_error = Some(err);
1326 return false;
1327 }
1328 }
1329
1330 let combinator = iter.next_sequence();
1331 if let Some(c) = combinator {
1332 match c {
1333 Combinator::Child | Combinator::Descendant => {
1334 self.combinator_count.child_or_descendants -= 1
1335 },
1336 Combinator::NextSibling | Combinator::LaterSibling => {
1337 self.combinator_count.adjacent_or_next_siblings -= 1
1338 },
1339 Combinator::Part | Combinator::PseudoElement | Combinator::SlotAssignment => (),
1340 }
1341 } else {
1342 return true;
1343 }
1344 index += 1; }
1346 }
1347}
1348
1349impl<'a, 'b> Collector for RelativeSelectorDependencyCollector<'a, 'b> {
1350 fn dependency(&mut self) -> Dependency {
1351 let scope_dependencies = self.inner_scope_dependencies();
1352
1353 let next = next_dependency(self.next_selectors, None, scope_dependencies.as_ref());
1354 debug_assert!(
1355 next.as_ref().is_some_and(|d| !matches!(
1356 d.slice()[0].kind,
1357 DependencyInvalidationKind::Relative(_)
1358 )),
1359 "Duplicate relative dependency?"
1360 );
1361 debug_assert!(
1362 next.as_ref().is_some_and(|d| !d.slice().is_empty()),
1363 "Empty dependency?"
1364 );
1365
1366 Dependency {
1367 selector: self.selector.selector.clone(),
1368 selector_offset: self.compound_state.offset,
1369 kind: DependencyInvalidationKind::Relative(
1370 match self.combinator_count.get_match_hint() {
1371 RelativeSelectorMatchHint::InChild => {
1372 RelativeDependencyInvalidationKind::Parent
1373 },
1374 RelativeSelectorMatchHint::InSubtree => {
1375 RelativeDependencyInvalidationKind::Ancestors
1376 },
1377 RelativeSelectorMatchHint::InNextSibling => {
1378 RelativeDependencyInvalidationKind::PrevSibling
1379 },
1380 RelativeSelectorMatchHint::InSibling => {
1381 RelativeDependencyInvalidationKind::EarlierSibling
1382 },
1383 RelativeSelectorMatchHint::InNextSiblingSubtree => {
1384 RelativeDependencyInvalidationKind::AncestorPrevSibling
1385 },
1386 RelativeSelectorMatchHint::InSiblingSubtree => {
1387 RelativeDependencyInvalidationKind::AncestorEarlierSibling
1388 },
1389 },
1390 ),
1391 next: next,
1392 }
1393 }
1394
1395 fn id_map(&mut self) -> &mut IdOrClassDependencyMap {
1396 &mut self.relative_selector_invalidation_map.id_to_selector
1397 }
1398
1399 fn class_map(&mut self) -> &mut IdOrClassDependencyMap {
1400 &mut self.relative_selector_invalidation_map.class_to_selector
1401 }
1402
1403 fn state_map(&mut self) -> &mut StateDependencyMap {
1404 &mut self
1405 .relative_selector_invalidation_map
1406 .state_affecting_selectors
1407 }
1408
1409 fn attribute_map(&mut self) -> &mut LocalNameDependencyMap {
1410 &mut self
1411 .relative_selector_invalidation_map
1412 .other_attribute_affecting_selectors
1413 }
1414
1415 fn custom_state_map(&mut self) -> &mut CustomStateDependencyMap {
1416 &mut self
1417 .relative_selector_invalidation_map
1418 .custom_state_affecting_selectors
1419 }
1420
1421 fn inner_scope_dependencies(&self) -> Option<ThinArc<(), Dependency>> {
1422 self.scope_dependencies.inner_dependencies.clone()
1423 }
1424
1425 fn this_scope_dependencies(&mut self) -> &mut Option<Vec<Dependency>> {
1426 &mut self.scope_dependencies.this_dependencies
1427 }
1428
1429 fn update_states(&mut self, element_state: ElementState, document_state: DocumentState) {
1430 self.compound_state.element_state |= element_state;
1431 *self.document_state |= document_state;
1432 }
1433
1434 fn type_map(&mut self) -> &mut LocalNameDependencyMap {
1435 &mut self
1436 .additional_relative_selector_invalidation_map
1437 .type_to_selector
1438 }
1439
1440 fn ts_state_map(&mut self) -> &mut TSStateDependencyMap {
1441 &mut self
1442 .additional_relative_selector_invalidation_map
1443 .ts_state_to_selector
1444 }
1445
1446 fn any_vec(&mut self) -> &mut AnyDependencyMap {
1447 &mut self
1448 .additional_relative_selector_invalidation_map
1449 .any_to_selector
1450 }
1451}
1452
1453enum ComponentVisitResult {
1454 IsIrrelevant,
1456 Handled(TSStateForInvalidation),
1459}
1460
1461#[inline(always)]
1462fn on_simple_selector<C: Collector>(
1463 s: &Component<SelectorImpl>,
1464 quirks_mode: QuirksMode,
1465 collector: &mut C,
1466) -> Result<ComponentVisitResult, AllocErr> {
1467 match *s {
1468 Component::ID(..) | Component::Class(..) => {
1469 on_id_or_class(s, quirks_mode, collector)?;
1470 Ok(ComponentVisitResult::Handled(
1471 TSStateForInvalidation::empty(),
1472 ))
1473 },
1474 Component::ImplicitScope | Component::Scope => {
1475 on_scope(collector)?;
1476 Ok(ComponentVisitResult::Handled(
1477 TSStateForInvalidation::empty(),
1478 ))
1479 },
1480 Component::NonTSPseudoClass(ref pc) => {
1481 on_pseudo_class(pc, collector)?;
1482 Ok(ComponentVisitResult::Handled(
1483 TSStateForInvalidation::empty(),
1484 ))
1485 },
1486 Component::Empty => Ok(ComponentVisitResult::Handled(TSStateForInvalidation::EMPTY)),
1487 Component::Nth(data) => {
1488 let kind = if data.is_simple_edge() {
1489 if data.ty.is_from_end() {
1490 TSStateForInvalidation::NTH_EDGE_LAST
1491 } else {
1492 TSStateForInvalidation::NTH_EDGE_FIRST
1493 }
1494 } else {
1495 TSStateForInvalidation::NTH
1496 };
1497 Ok(ComponentVisitResult::Handled(kind))
1498 },
1499 Component::RelativeSelectorAnchor => unreachable!("Should not visit this far"),
1500 _ => Ok(ComponentVisitResult::IsIrrelevant),
1501 }
1502}
1503
1504impl<'a, 'b> SelectorVisitor for RelativeSelectorDependencyCollector<'a, 'b> {
1505 type Impl = SelectorImpl;
1506
1507 fn visit_selector_list(
1508 &mut self,
1509 _list_kind: SelectorListKind,
1510 list: &[Selector<SelectorImpl>],
1511 ) -> bool {
1512 let mut next_stack = NextSelectors::new();
1513 let next_dependency = ThinArc::from_header_and_iter((), [self.dependency()].into_iter());
1514 for selector in list {
1515 let mut iter = selector.iter();
1516 let saved_added_entry = self.compound_state_attributes.added_entry;
1517
1518 let (keep_traversing, mut index) = visit_all_in_iter_compound(self, &mut iter);
1519
1520 if !keep_traversing {
1521 return false;
1522 }
1523
1524 let combinator = iter.next_sequence();
1525
1526 self.compound_state_attributes.added_entry = saved_added_entry;
1531 if combinator.is_none() {
1532 continue;
1533 }
1534
1535 index += 1; let mut nested = SelectorDependencyCollector {
1538 map: &mut *self.map,
1539 relative_selector_invalidation_map: &mut *self.relative_selector_invalidation_map,
1540 additional_relative_selector_invalidation_map: self
1541 .additional_relative_selector_invalidation_map,
1542 document_state: &mut *self.document_state,
1543 selector,
1544 next_selectors: &mut next_stack,
1545 quirks_mode: self.quirks_mode,
1546 compound_state: PerCompoundState::new(index),
1547 relative_inner_collector: Some(RelativeSelectorInnerCollectorState {
1548 next_dependency: &next_dependency,
1549 relative_compound_state: RelativeSelectorCompoundStateAttributes::new(),
1550 }),
1551 scope_dependencies: &mut self.scope_dependencies,
1552 alloc_error: &mut *self.alloc_error,
1553 };
1554 if !nested.visit_whole_selector_from(iter, index) {
1555 return false;
1556 }
1557 }
1558 true
1559 }
1560
1561 fn visit_relative_selector_list(
1562 &mut self,
1563 _list: &[selectors::parser::RelativeSelector<Self::Impl>],
1564 ) -> bool {
1565 true
1567 }
1568
1569 fn visit_simple_selector(&mut self, s: &Component<SelectorImpl>) -> bool {
1570 match on_simple_selector(s, self.quirks_mode, self) {
1571 Ok(result) => {
1572 if let ComponentVisitResult::Handled(state) = result {
1573 self.compound_state_attributes.added_entry = true;
1574 self.compound_state_attributes.ts_state.insert(state);
1575 }
1576 true
1577 },
1578 Err(err) => {
1579 *self.alloc_error = Some(err.into());
1580 false
1581 },
1582 }
1583 }
1584
1585 fn visit_attribute_selector(
1586 &mut self,
1587 _: &NamespaceConstraint<&Namespace>,
1588 local_name: &LocalName,
1589 local_name_lower: &LocalName,
1590 ) -> bool {
1591 self.compound_state_attributes.added_entry = true;
1592 if let Err(err) = on_attribute(local_name, local_name_lower, self) {
1593 *self.alloc_error = Some(err);
1594 return false;
1595 }
1596 true
1597 }
1598}