1use crate::applicable_declarations::{
8 ApplicableDeclarationBlock, ApplicableDeclarationList, CascadePriority, ScopeProximity,
9};
10use crate::computed_value_flags::ComputedValueFlags;
11use crate::context::{CascadeInputs, QuirksMode};
12use crate::custom_properties::ComputedCustomProperties;
13use crate::derives::*;
14use crate::dom::TElement;
15#[cfg(feature = "gecko")]
16use crate::gecko_bindings::structs::{ServoStyleSetSizes, StyleRuleInclusion};
17use crate::invalidation::element::invalidation_map::{
18 note_selector_for_invalidation, AdditionalRelativeSelectorInvalidationMap, Dependency,
19 DependencyInvalidationKind, InvalidationMap, ScopeDependencyInvalidationKind,
20};
21use crate::invalidation::media_queries::{
22 EffectiveMediaQueryResults, MediaListKey, ToMediaListKey,
23};
24use crate::invalidation::stylesheets::{RuleChangeKind, StylesheetInvalidationSet};
25use crate::media_queries::Device;
26#[cfg(feature = "gecko")]
27use crate::properties::StyleBuilder;
28use crate::properties::{
29 self, AnimationDeclarations, CascadeMode, ComputedValues, FirstLineReparenting,
30 PropertyDeclarationBlock,
31};
32use crate::properties_and_values::registry::{
33 PropertyRegistration, PropertyRegistrationData, ScriptRegistry as CustomPropertyScriptRegistry,
34};
35use crate::rule_cache::{RuleCache, RuleCacheConditions};
36use crate::rule_collector::RuleCollector;
37use crate::rule_tree::{CascadeLevel, RuleTree, StrongRuleNode, StyleSource};
38use crate::selector_map::{PrecomputedHashMap, PrecomputedHashSet, SelectorMap, SelectorMapEntry};
39use crate::selector_parser::{NonTSPseudoClass, PerPseudoElementMap, PseudoElement, SelectorImpl};
40use crate::shared_lock::{Locked, SharedRwLockReadGuard, StylesheetGuards};
41use crate::sharing::{RevalidationResult, ScopeRevalidationResult};
42use crate::stylesheet_set::{DataValidity, DocumentStylesheetSet, SheetRebuildKind};
43use crate::stylesheet_set::{DocumentStylesheetFlusher, SheetCollectionFlusher};
44use crate::stylesheets::container_rule::ContainerCondition;
45use crate::stylesheets::import_rule::ImportLayer;
46use crate::stylesheets::keyframes_rule::KeyframesAnimation;
47use crate::stylesheets::layer_rule::{LayerName, LayerOrder};
48use crate::stylesheets::scope_rule::{
49 collect_scope_roots, element_is_outside_of_scope, scope_selector_list_is_trivial,
50 ImplicitScopeRoot, ScopeRootCandidate, ScopeSubjectMap, ScopeTarget,
51};
52use crate::stylesheets::{
53 CounterStyleRule, CssRule, CssRuleRef, EffectiveRulesIterator, FontFaceRule,
54 FontFeatureValuesRule, FontPaletteValuesRule, Origin, OriginSet, PagePseudoClassFlags,
55 PageRule, PerOrigin, PerOriginIter, PositionTryRule, StylesheetContents, StylesheetInDocument,
56};
57use crate::stylesheets::{CustomMediaEvaluator, CustomMediaMap};
58#[cfg(feature = "gecko")]
59use crate::values::specified::position::PositionTryFallbacksItem;
60use crate::values::specified::position::PositionTryFallbacksTryTactic;
61use crate::values::{computed, AtomIdent};
62use crate::AllocErr;
63use crate::{Atom, LocalName, Namespace, ShrinkIfNeeded, WeakAtom};
64use dom::{DocumentState, ElementState};
65#[cfg(feature = "gecko")]
66use malloc_size_of::MallocUnconditionalShallowSizeOf;
67use malloc_size_of::{MallocShallowSizeOf, MallocSizeOf, MallocSizeOfOps};
68use rustc_hash::FxHashMap;
69use selectors::attr::{CaseSensitivity, NamespaceConstraint};
70use selectors::bloom::BloomFilter;
71use selectors::matching::{
72 matches_selector, selector_may_match, MatchingContext, MatchingMode, NeedsSelectorFlags,
73 SelectorCaches,
74};
75use selectors::matching::{MatchingForInvalidation, VisitedHandlingMode};
76use selectors::parser::{
77 AncestorHashes, Combinator, Component, MatchesFeaturelessHost, Selector, SelectorIter,
78 SelectorList,
79};
80use selectors::visitor::{SelectorListKind, SelectorVisitor};
81use servo_arc::{Arc, ArcBorrow, ThinArc};
82use smallvec::SmallVec;
83use std::cmp::Ordering;
84use std::hash::{Hash, Hasher};
85use std::mem;
86use std::sync::{LazyLock, Mutex};
87
88#[cfg(feature = "servo")]
90pub type StylistSheet = crate::stylesheets::DocumentStyleSheet;
91
92#[cfg(feature = "gecko")]
94pub type StylistSheet = crate::gecko::data::GeckoStyleSheet;
95
96#[derive(Debug, Clone)]
97struct StylesheetContentsPtr(Arc<StylesheetContents>);
98
99impl PartialEq for StylesheetContentsPtr {
100 #[inline]
101 fn eq(&self, other: &Self) -> bool {
102 Arc::ptr_eq(&self.0, &other.0)
103 }
104}
105
106impl Eq for StylesheetContentsPtr {}
107
108impl Hash for StylesheetContentsPtr {
109 fn hash<H: Hasher>(&self, state: &mut H) {
110 let contents: &StylesheetContents = &*self.0;
111 (contents as *const StylesheetContents).hash(state)
112 }
113}
114
115type StyleSheetContentList = Vec<StylesheetContentsPtr>;
116
117#[derive(Default, Debug, MallocSizeOf)]
119pub struct CascadeDataDifference {
120 pub changed_position_try_names: PrecomputedHashSet<Atom>,
122}
123
124impl CascadeDataDifference {
125 pub fn merge_with(&mut self, other: Self) {
127 self.changed_position_try_names
128 .extend(other.changed_position_try_names.into_iter())
129 }
130
131 pub fn is_empty(&self) -> bool {
133 self.changed_position_try_names.is_empty()
134 }
135
136 fn update(&mut self, old_data: &PositionTryMap, new_data: &PositionTryMap) {
137 let mut any_different_key = false;
138 let different_len = old_data.len() != new_data.len();
139 for (name, rules) in old_data.iter() {
140 let changed = match new_data.get(name) {
141 Some(new_rule) => !Arc::ptr_eq(&rules.last().unwrap().0, new_rule),
142 None => {
143 any_different_key = true;
144 true
145 },
146 };
147 if changed {
148 self.changed_position_try_names.insert(name.clone());
149 }
150 }
151
152 if any_different_key || different_len {
153 for name in new_data.keys() {
154 if !old_data.contains_key(name) {
156 self.changed_position_try_names.insert(name.clone());
157 }
158 }
159 }
160 }
161}
162
163#[derive(Debug, Hash, Default, PartialEq, Eq)]
165struct CascadeDataCacheKey {
166 media_query_results: Vec<MediaListKey>,
167 contents: StyleSheetContentList,
168}
169
170unsafe impl Send for CascadeDataCacheKey {}
171unsafe impl Sync for CascadeDataCacheKey {}
172
173trait CascadeDataCacheEntry: Sized {
174 fn rebuild<S>(
177 device: &Device,
178 quirks_mode: QuirksMode,
179 collection: SheetCollectionFlusher<S>,
180 guard: &SharedRwLockReadGuard,
181 old_entry: &Self,
182 difference: &mut CascadeDataDifference,
183 ) -> Result<Arc<Self>, AllocErr>
184 where
185 S: StylesheetInDocument + PartialEq + 'static;
186 #[cfg(feature = "gecko")]
188 fn add_size_of(&self, ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes);
189}
190
191struct CascadeDataCache<Entry> {
192 entries: FxHashMap<CascadeDataCacheKey, Arc<Entry>>,
193}
194
195impl<Entry> CascadeDataCache<Entry>
196where
197 Entry: CascadeDataCacheEntry,
198{
199 fn new() -> Self {
200 Self {
201 entries: Default::default(),
202 }
203 }
204
205 fn len(&self) -> usize {
206 self.entries.len()
207 }
208
209 fn lookup<'a, S>(
214 &'a mut self,
215 device: &Device,
216 quirks_mode: QuirksMode,
217 collection: SheetCollectionFlusher<S>,
218 guard: &SharedRwLockReadGuard,
219 old_entry: &Entry,
220 difference: &mut CascadeDataDifference,
221 ) -> Result<Option<Arc<Entry>>, AllocErr>
222 where
223 S: StylesheetInDocument + PartialEq + 'static,
224 {
225 use std::collections::hash_map::Entry as HashMapEntry;
226 debug!("StyleSheetCache::lookup({})", self.len());
227
228 if !collection.dirty() {
229 return Ok(None);
230 }
231
232 let mut key = CascadeDataCacheKey::default();
233 let mut custom_media_map = CustomMediaMap::default();
234 for sheet in collection.sheets() {
235 CascadeData::collect_applicable_media_query_results_into(
236 device,
237 sheet,
238 guard,
239 &mut key.media_query_results,
240 &mut key.contents,
241 &mut custom_media_map,
242 )
243 }
244
245 let new_entry;
246 match self.entries.entry(key) {
247 HashMapEntry::Vacant(e) => {
248 debug!("> Picking the slow path (not in the cache)");
249 new_entry = Entry::rebuild(
250 device,
251 quirks_mode,
252 collection,
253 guard,
254 old_entry,
255 difference,
256 )?;
257 e.insert(new_entry.clone());
258 },
259 HashMapEntry::Occupied(mut e) => {
260 if !std::ptr::eq(&**e.get(), old_entry) {
264 if log_enabled!(log::Level::Debug) {
265 debug!("cache hit for:");
266 for sheet in collection.sheets() {
267 debug!(" > {:?}", sheet);
268 }
269 }
270 collection.each(|_, _, _| true);
273 return Ok(Some(e.get().clone()));
274 }
275
276 debug!("> Picking the slow path due to same entry as old");
277 new_entry = Entry::rebuild(
278 device,
279 quirks_mode,
280 collection,
281 guard,
282 old_entry,
283 difference,
284 )?;
285 e.insert(new_entry.clone());
286 },
287 }
288
289 Ok(Some(new_entry))
290 }
291
292 fn take_unused(&mut self) -> SmallVec<[Arc<Entry>; 3]> {
300 let mut unused = SmallVec::new();
301 self.entries.retain(|_key, value| {
302 if !value.is_unique() {
306 return true;
307 }
308 unused.push(value.clone());
309 false
310 });
311 unused
312 }
313
314 fn take_all(&mut self) -> FxHashMap<CascadeDataCacheKey, Arc<Entry>> {
315 mem::take(&mut self.entries)
316 }
317
318 #[cfg(feature = "gecko")]
319 fn add_size_of(&self, ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes) {
320 sizes.mOther += self.entries.shallow_size_of(ops);
321 for (_key, arc) in self.entries.iter() {
322 sizes.mOther += arc.unconditional_shallow_size_of(ops);
325 arc.add_size_of(ops, sizes);
326 }
327 }
328}
329
330#[cfg(feature = "gecko")]
332pub fn add_size_of_ua_cache(ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes) {
333 UA_CASCADE_DATA_CACHE
334 .lock()
335 .unwrap()
336 .add_size_of(ops, sizes);
337}
338
339static UA_CASCADE_DATA_CACHE: LazyLock<Mutex<UserAgentCascadeDataCache>> =
341 LazyLock::new(|| Mutex::new(UserAgentCascadeDataCache::new()));
342
343impl CascadeDataCacheEntry for UserAgentCascadeData {
344 fn rebuild<S>(
345 device: &Device,
346 quirks_mode: QuirksMode,
347 collection: SheetCollectionFlusher<S>,
348 guard: &SharedRwLockReadGuard,
349 old: &Self,
350 difference: &mut CascadeDataDifference,
351 ) -> Result<Arc<Self>, AllocErr>
352 where
353 S: StylesheetInDocument + PartialEq + 'static,
354 {
355 let mut new_data = servo_arc::UniqueArc::new(Self {
358 cascade_data: CascadeData::new(),
359 precomputed_pseudo_element_decls: PrecomputedPseudoElementDeclarations::default(),
360 });
361
362 for (index, sheet) in collection.sheets().enumerate() {
363 let new_data = &mut *new_data;
364 new_data.cascade_data.add_stylesheet(
365 device,
366 quirks_mode,
367 sheet,
368 index,
369 guard,
370 SheetRebuildKind::Full,
371 Some(&mut new_data.precomputed_pseudo_element_decls),
372 None,
373 )?;
374 }
375
376 new_data.cascade_data.did_finish_rebuild();
377 difference.update(
378 &old.cascade_data.extra_data.position_try_rules,
379 &new_data.cascade_data.extra_data.position_try_rules,
380 );
381
382 Ok(new_data.shareable())
383 }
384
385 #[cfg(feature = "gecko")]
386 fn add_size_of(&self, ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes) {
387 self.cascade_data.add_size_of(ops, sizes);
388 sizes.mPrecomputedPseudos += self.precomputed_pseudo_element_decls.size_of(ops);
389 }
390}
391
392type UserAgentCascadeDataCache = CascadeDataCache<UserAgentCascadeData>;
393
394type PrecomputedPseudoElementDeclarations = PerPseudoElementMap<Vec<ApplicableDeclarationBlock>>;
395
396#[derive(Default)]
397struct UserAgentCascadeData {
398 cascade_data: CascadeData,
399
400 precomputed_pseudo_element_decls: PrecomputedPseudoElementDeclarations,
407}
408
409static EMPTY_UA_CASCADE_DATA: LazyLock<Arc<UserAgentCascadeData>> = LazyLock::new(|| {
411 let arc = Arc::new(UserAgentCascadeData::default());
412 arc.mark_as_intentionally_leaked();
413 arc
414});
415
416#[derive(MallocSizeOf)]
419pub struct DocumentCascadeData {
420 #[ignore_malloc_size_of = "Arc, owned by UserAgentCascadeDataCache or empty"]
421 user_agent: Arc<UserAgentCascadeData>,
422 user: CascadeData,
423 author: CascadeData,
424 per_origin: PerOrigin<()>,
425}
426
427impl Default for DocumentCascadeData {
428 fn default() -> Self {
429 Self {
430 user_agent: EMPTY_UA_CASCADE_DATA.clone(),
431 user: Default::default(),
432 author: Default::default(),
433 per_origin: Default::default(),
434 }
435 }
436}
437
438pub struct DocumentCascadeDataIter<'a> {
440 iter: PerOriginIter<'a, ()>,
441 cascade_data: &'a DocumentCascadeData,
442}
443
444impl<'a> Iterator for DocumentCascadeDataIter<'a> {
445 type Item = (&'a CascadeData, Origin);
446
447 fn next(&mut self) -> Option<Self::Item> {
448 let (_, origin) = self.iter.next()?;
449 Some((self.cascade_data.borrow_for_origin(origin), origin))
450 }
451}
452
453impl DocumentCascadeData {
454 #[inline]
456 pub fn borrow_for_origin(&self, origin: Origin) -> &CascadeData {
457 match origin {
458 Origin::UserAgent => &self.user_agent.cascade_data,
459 Origin::Author => &self.author,
460 Origin::User => &self.user,
461 }
462 }
463
464 fn iter_origins(&self) -> DocumentCascadeDataIter<'_> {
465 DocumentCascadeDataIter {
466 iter: self.per_origin.iter_origins(),
467 cascade_data: self,
468 }
469 }
470
471 fn iter_origins_rev(&self) -> DocumentCascadeDataIter<'_> {
472 DocumentCascadeDataIter {
473 iter: self.per_origin.iter_origins_rev(),
474 cascade_data: self,
475 }
476 }
477
478 fn custom_media_for_sheet(
479 &self,
480 s: &StylistSheet,
481 guard: &SharedRwLockReadGuard,
482 ) -> &CustomMediaMap {
483 let origin = s.contents(guard).origin;
484 &self.borrow_for_origin(origin).custom_media
485 }
486
487 fn rebuild<'a, S>(
491 &mut self,
492 device: &Device,
493 quirks_mode: QuirksMode,
494 mut flusher: DocumentStylesheetFlusher<'a, S>,
495 guards: &StylesheetGuards,
496 difference: &mut CascadeDataDifference,
497 ) -> Result<(), AllocErr>
498 where
499 S: StylesheetInDocument + PartialEq + 'static,
500 {
501 {
503 let origin_flusher = flusher.flush_origin(Origin::UserAgent);
504 if origin_flusher.dirty() {
507 let mut ua_cache = UA_CASCADE_DATA_CACHE.lock().unwrap();
508 let new_data = ua_cache.lookup(
509 device,
510 quirks_mode,
511 origin_flusher,
512 guards.ua_or_user,
513 &self.user_agent,
514 difference,
515 )?;
516 if let Some(new_data) = new_data {
517 self.user_agent = new_data;
518 }
519 let _unused_entries = ua_cache.take_unused();
520 std::mem::drop(ua_cache);
522 }
523 }
524
525 self.user.rebuild(
527 device,
528 quirks_mode,
529 flusher.flush_origin(Origin::User),
530 guards.ua_or_user,
531 difference,
532 )?;
533
534 self.author.rebuild(
536 device,
537 quirks_mode,
538 flusher.flush_origin(Origin::Author),
539 guards.author,
540 difference,
541 )?;
542
543 Ok(())
544 }
545
546 #[cfg(feature = "gecko")]
548 pub fn add_size_of(&self, ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes) {
549 self.user.add_size_of(ops, sizes);
550 self.author.add_size_of(ops, sizes);
551 }
552}
553
554#[allow(missing_docs)]
558#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq)]
559pub enum AuthorStylesEnabled {
560 Yes,
561 No,
562}
563
564#[cfg_attr(feature = "servo", derive(MallocSizeOf))]
567#[derive(Deref, DerefMut)]
568struct StylistStylesheetSet(DocumentStylesheetSet<StylistSheet>);
569unsafe impl Sync for StylistStylesheetSet {}
571
572impl StylistStylesheetSet {
573 fn new() -> Self {
574 StylistStylesheetSet(DocumentStylesheetSet::new())
575 }
576}
577
578#[cfg_attr(feature = "servo", derive(MallocSizeOf))]
586pub struct Stylist {
587 device: Device,
600
601 stylesheets: StylistStylesheetSet,
603
604 #[cfg_attr(feature = "servo", ignore_malloc_size_of = "XXX: how to handle this?")]
606 author_data_cache: CascadeDataCache<CascadeData>,
607
608 #[cfg_attr(feature = "servo", ignore_malloc_size_of = "defined in selectors")]
610 quirks_mode: QuirksMode,
611
612 cascade_data: DocumentCascadeData,
616
617 author_styles_enabled: AuthorStylesEnabled,
619
620 rule_tree: RuleTree,
622
623 script_custom_properties: CustomPropertyScriptRegistry,
626
627 #[cfg_attr(feature = "servo", ignore_malloc_size_of = "Arc")]
629 initial_values_for_custom_properties: ComputedCustomProperties,
630
631 initial_values_for_custom_properties_flags: ComputedValueFlags,
633
634 num_rebuilds: usize,
636}
637
638#[derive(Clone, Copy, PartialEq)]
640pub enum RuleInclusion {
641 All,
644 DefaultOnly,
647}
648
649#[cfg(feature = "gecko")]
650impl From<StyleRuleInclusion> for RuleInclusion {
651 fn from(value: StyleRuleInclusion) -> Self {
652 match value {
653 StyleRuleInclusion::All => RuleInclusion::All,
654 StyleRuleInclusion::DefaultOnly => RuleInclusion::DefaultOnly,
655 }
656 }
657}
658
659#[derive(Clone, Copy, Eq, PartialEq)]
664enum ScopeMatchesShadowHost {
665 NotApplicable,
666 No,
667 Yes,
668}
669
670impl Default for ScopeMatchesShadowHost {
671 fn default() -> Self {
672 Self::NotApplicable
673 }
674}
675
676impl ScopeMatchesShadowHost {
677 fn nest_for_scope(&mut self, matches_shadow_host: bool) {
678 match *self {
679 Self::NotApplicable => {
680 *self = if matches_shadow_host {
682 Self::Yes
683 } else {
684 Self::No
685 };
686 },
687 Self::Yes if !matches_shadow_host => {
688 *self = Self::No;
690 },
691 _ => (),
692 }
693 }
694}
695
696#[derive(Copy, Clone)]
703enum NestedDeclarationsContext {
704 Style,
705 Scope,
706}
707
708struct ContainingScopeRuleState {
710 id: ScopeConditionId,
711 inner_dependencies: Vec<Dependency>,
712 matches_shadow_host: ScopeMatchesShadowHost,
713}
714
715impl Default for ContainingScopeRuleState {
716 fn default() -> Self {
717 Self {
718 id: ScopeConditionId::none(),
719 inner_dependencies: Vec::new(),
720 matches_shadow_host: Default::default(),
721 }
722 }
723}
724
725impl ContainingScopeRuleState {
726 fn save(&self) -> SavedContainingScopeRuleState {
727 SavedContainingScopeRuleState {
728 id: self.id,
729 matches_shadow_host: self.matches_shadow_host,
730 inner_dependencies_len: self.inner_dependencies.len(),
731 }
732 }
733
734 fn restore(
735 &mut self,
736 saved: &SavedContainingScopeRuleState,
737 ) -> Option<(Vec<Dependency>, ScopeConditionId)> {
738 debug_assert!(self.inner_dependencies.len() >= saved.inner_dependencies_len);
739
740 if self.id == saved.id {
741 return None;
742 }
743
744 let scope_id = self.id;
745 let inner_deps = self
746 .inner_dependencies
747 .drain(saved.inner_dependencies_len..)
748 .collect();
749
750 self.id = saved.id;
751 self.matches_shadow_host = saved.matches_shadow_host;
752
753 Some((inner_deps, scope_id))
754 }
755}
756
757struct SavedContainingScopeRuleState {
758 id: ScopeConditionId,
759 matches_shadow_host: ScopeMatchesShadowHost,
760 inner_dependencies_len: usize,
761}
762
763struct ContainingRuleState {
766 layer_name: LayerName,
767 layer_id: LayerId,
768 container_condition_id: ContainerConditionId,
769 in_starting_style: bool,
770 containing_scope_rule_state: ContainingScopeRuleState,
771 ancestor_selector_lists: SmallVec<[SelectorList<SelectorImpl>; 2]>,
772 nested_declarations_context: NestedDeclarationsContext,
773}
774
775impl Default for ContainingRuleState {
776 fn default() -> Self {
777 Self {
778 layer_name: LayerName::new_empty(),
779 layer_id: LayerId::root(),
780 container_condition_id: ContainerConditionId::none(),
781 in_starting_style: false,
782 ancestor_selector_lists: Default::default(),
783 containing_scope_rule_state: Default::default(),
784 nested_declarations_context: NestedDeclarationsContext::Style,
785 }
786 }
787}
788
789struct SavedContainingRuleState {
790 ancestor_selector_lists_len: usize,
791 layer_name_len: usize,
792 layer_id: LayerId,
793 container_condition_id: ContainerConditionId,
794 in_starting_style: bool,
795 saved_containing_scope_rule_state: SavedContainingScopeRuleState,
796 nested_declarations_context: NestedDeclarationsContext,
797}
798
799impl ContainingRuleState {
800 fn save(&self) -> SavedContainingRuleState {
801 SavedContainingRuleState {
802 ancestor_selector_lists_len: self.ancestor_selector_lists.len(),
803 layer_name_len: self.layer_name.0.len(),
804 layer_id: self.layer_id,
805 container_condition_id: self.container_condition_id,
806 in_starting_style: self.in_starting_style,
807 saved_containing_scope_rule_state: self.containing_scope_rule_state.save(),
808 nested_declarations_context: self.nested_declarations_context,
809 }
810 }
811
812 fn restore(
813 &mut self,
814 saved: &SavedContainingRuleState,
815 ) -> Option<(Vec<Dependency>, ScopeConditionId)> {
816 debug_assert!(self.layer_name.0.len() >= saved.layer_name_len);
817 debug_assert!(self.ancestor_selector_lists.len() >= saved.ancestor_selector_lists_len);
818
819 self.ancestor_selector_lists
820 .truncate(saved.ancestor_selector_lists_len);
821 self.layer_name.0.truncate(saved.layer_name_len);
822 self.layer_id = saved.layer_id;
823 self.container_condition_id = saved.container_condition_id;
824 self.in_starting_style = saved.in_starting_style;
825 self.nested_declarations_context = saved.nested_declarations_context;
826
827 self.containing_scope_rule_state
828 .restore(&saved.saved_containing_scope_rule_state)
829 }
830
831 fn scope_is_effective(&self) -> bool {
832 self.containing_scope_rule_state.id != ScopeConditionId::none()
833 }
834}
835
836type ReplacedSelectors = SmallVec<[Selector<SelectorImpl>; 4]>;
837
838impl Stylist {
839 #[inline]
843 pub fn new(device: Device, quirks_mode: QuirksMode) -> Self {
844 Self {
845 device,
846 quirks_mode,
847 stylesheets: StylistStylesheetSet::new(),
848 author_data_cache: CascadeDataCache::new(),
849 cascade_data: Default::default(),
850 author_styles_enabled: AuthorStylesEnabled::Yes,
851 rule_tree: RuleTree::new(),
852 script_custom_properties: Default::default(),
853 initial_values_for_custom_properties: Default::default(),
854 initial_values_for_custom_properties_flags: Default::default(),
855 num_rebuilds: 0,
856 }
857 }
858
859 #[inline]
861 pub fn cascade_data(&self) -> &DocumentCascadeData {
862 &self.cascade_data
863 }
864
865 #[inline]
867 pub fn author_styles_enabled(&self) -> AuthorStylesEnabled {
868 self.author_styles_enabled
869 }
870
871 #[inline]
873 pub fn iter_origins(&self) -> DocumentCascadeDataIter<'_> {
874 self.cascade_data.iter_origins()
875 }
876
877 pub fn remove_unique_author_data_cache_entries(&mut self) {
880 self.author_data_cache.take_unused();
881 }
882
883 pub fn get_custom_property_registration(&self, name: &Atom) -> &PropertyRegistrationData {
886 if let Some(registration) = self.custom_property_script_registry().get(name) {
887 return ®istration.data;
888 }
889 for (data, _) in self.iter_origins() {
890 if let Some(registration) = data.custom_property_registrations.get(name) {
891 return ®istration.data;
892 }
893 }
894 PropertyRegistrationData::unregistered()
895 }
896
897 pub fn get_custom_property_initial_values(&self) -> &ComputedCustomProperties {
899 &self.initial_values_for_custom_properties
900 }
901
902 pub fn get_custom_property_initial_values_flags(&self) -> ComputedValueFlags {
904 self.initial_values_for_custom_properties_flags
905 }
906
907 pub fn rebuild_initial_values_for_custom_properties(&mut self) {
910 let mut initial_values = ComputedCustomProperties::default();
911 let initial_values_flags;
912 {
913 let mut seen_names = PrecomputedHashSet::default();
914 let mut rule_cache_conditions = RuleCacheConditions::default();
915 let context = computed::Context::new_for_initial_at_property_value(
916 self,
917 &mut rule_cache_conditions,
918 );
919
920 for (k, v) in self.custom_property_script_registry().properties().iter() {
921 seen_names.insert(k.clone());
922 let Ok(value) = v.compute_initial_value(&context) else {
923 continue;
924 };
925 let map = if v.inherits() {
926 &mut initial_values.inherited
927 } else {
928 &mut initial_values.non_inherited
929 };
930 map.insert(k, value);
931 }
932 for (data, _) in self.iter_origins() {
933 for (k, v) in data.custom_property_registrations.iter() {
934 if seen_names.insert(k.clone()) {
935 let last_value = &v.last().unwrap().0;
936 let Ok(value) = last_value.compute_initial_value(&context) else {
937 continue;
938 };
939 let map = if last_value.inherits() {
940 &mut initial_values.inherited
941 } else {
942 &mut initial_values.non_inherited
943 };
944 map.insert(k, value);
945 }
946 }
947 }
948 initial_values_flags = context.builder.flags();
949 }
950 self.initial_values_for_custom_properties_flags = initial_values_flags;
951 self.initial_values_for_custom_properties = initial_values;
952 }
953
954 pub fn rebuild_author_data<S>(
956 &mut self,
957 old_data: &CascadeData,
958 collection: SheetCollectionFlusher<S>,
959 guard: &SharedRwLockReadGuard,
960 difference: &mut CascadeDataDifference,
961 ) -> Result<Option<Arc<CascadeData>>, AllocErr>
962 where
963 S: StylesheetInDocument + PartialEq + 'static,
964 {
965 self.author_data_cache.lookup(
966 &self.device,
967 self.quirks_mode,
968 collection,
969 guard,
970 old_data,
971 difference,
972 )
973 }
974
975 #[inline]
977 pub fn iter_extra_data_origins(&self) -> ExtraStyleDataIterator<'_> {
978 ExtraStyleDataIterator(self.cascade_data.iter_origins())
979 }
980
981 #[inline]
983 pub fn iter_extra_data_origins_rev(&self) -> ExtraStyleDataIterator<'_> {
984 ExtraStyleDataIterator(self.cascade_data.iter_origins_rev())
985 }
986
987 pub fn num_selectors(&self) -> usize {
989 self.cascade_data
990 .iter_origins()
991 .map(|(d, _)| d.num_selectors)
992 .sum()
993 }
994
995 pub fn num_declarations(&self) -> usize {
997 self.cascade_data
998 .iter_origins()
999 .map(|(d, _)| d.num_declarations)
1000 .sum()
1001 }
1002
1003 pub fn num_rebuilds(&self) -> usize {
1005 self.num_rebuilds
1006 }
1007
1008 pub fn num_revalidation_selectors(&self) -> usize {
1010 self.cascade_data
1011 .iter_origins()
1012 .map(|(data, _)| data.selectors_for_cache_revalidation.len())
1013 .sum()
1014 }
1015
1016 pub fn num_invalidations(&self) -> usize {
1018 self.cascade_data
1019 .iter_origins()
1020 .map(|(data, _)| {
1021 data.invalidation_map.len() + data.relative_selector_invalidation_map.len()
1022 })
1023 .sum()
1024 }
1025
1026 pub fn has_document_state_dependency(&self, state: DocumentState) -> bool {
1029 self.cascade_data
1030 .iter_origins()
1031 .any(|(d, _)| d.document_state_dependencies.intersects(state))
1032 }
1033
1034 pub fn flush(&mut self, guards: &StylesheetGuards) -> StylesheetInvalidationSet {
1037 if !self.stylesheets.has_changed() {
1038 return Default::default();
1039 }
1040
1041 self.num_rebuilds += 1;
1042
1043 let (flusher, mut invalidations) = self.stylesheets.flush();
1044
1045 self.cascade_data
1046 .rebuild(
1047 &self.device,
1048 self.quirks_mode,
1049 flusher,
1050 guards,
1051 &mut invalidations.cascade_data_difference,
1052 )
1053 .unwrap_or_else(|_| {
1054 warn!("OOM in Stylist::flush");
1055 });
1056
1057 self.rebuild_initial_values_for_custom_properties();
1058 invalidations
1059 }
1060
1061 pub fn force_stylesheet_origins_dirty(&mut self, origins: OriginSet) {
1067 self.stylesheets.force_dirty(origins)
1068 }
1069
1070 pub fn set_author_styles_enabled(&mut self, enabled: AuthorStylesEnabled) {
1072 self.author_styles_enabled = enabled;
1073 }
1074
1075 pub fn stylesheets_have_changed(&self) -> bool {
1077 self.stylesheets.has_changed()
1078 }
1079
1080 pub fn insert_stylesheet_before(
1082 &mut self,
1083 sheet: StylistSheet,
1084 before_sheet: StylistSheet,
1085 guard: &SharedRwLockReadGuard,
1086 ) {
1087 let custom_media = self.cascade_data.custom_media_for_sheet(&sheet, guard);
1088 self.stylesheets.insert_stylesheet_before(
1089 Some(&self.device),
1090 custom_media,
1091 sheet,
1092 before_sheet,
1093 guard,
1094 )
1095 }
1096
1097 pub fn append_stylesheet(&mut self, sheet: StylistSheet, guard: &SharedRwLockReadGuard) {
1099 let custom_media = self.cascade_data.custom_media_for_sheet(&sheet, guard);
1100 self.stylesheets
1101 .append_stylesheet(Some(&self.device), custom_media, sheet, guard)
1102 }
1103
1104 pub fn remove_stylesheet(&mut self, sheet: StylistSheet, guard: &SharedRwLockReadGuard) {
1106 let custom_media = self.cascade_data.custom_media_for_sheet(&sheet, guard);
1107 self.stylesheets
1108 .remove_stylesheet(Some(&self.device), custom_media, sheet, guard)
1109 }
1110
1111 pub fn rule_changed(
1113 &mut self,
1114 sheet: &StylistSheet,
1115 rule: &CssRule,
1116 guard: &SharedRwLockReadGuard,
1117 change_kind: RuleChangeKind,
1118 ancestors: &[CssRuleRef],
1119 ) {
1120 let custom_media = self.cascade_data.custom_media_for_sheet(&sheet, guard);
1121 self.stylesheets.rule_changed(
1122 Some(&self.device),
1123 custom_media,
1124 sheet,
1125 rule,
1126 guard,
1127 change_kind,
1128 ancestors,
1129 )
1130 }
1131
1132 #[inline]
1134 pub fn sheet_count(&self, origin: Origin) -> usize {
1135 self.stylesheets.sheet_count(origin)
1136 }
1137
1138 #[inline]
1140 pub fn sheet_at(&self, origin: Origin, index: usize) -> Option<&StylistSheet> {
1141 self.stylesheets.get(origin, index)
1142 }
1143
1144 pub fn any_applicable_rule_data<E, F>(&self, element: E, mut f: F) -> bool
1147 where
1148 E: TElement,
1149 F: FnMut(&CascadeData) -> bool,
1150 {
1151 if f(&self.cascade_data.user_agent.cascade_data) {
1152 return true;
1153 }
1154
1155 let mut maybe = false;
1156
1157 let doc_author_rules_apply =
1158 element.each_applicable_non_document_style_rule_data(|data, _| {
1159 maybe = maybe || f(&*data);
1160 });
1161
1162 if maybe || f(&self.cascade_data.user) {
1163 return true;
1164 }
1165
1166 doc_author_rules_apply && f(&self.cascade_data.author)
1167 }
1168
1169 pub fn for_each_cascade_data_with_scope<'a, E, F>(&'a self, element: E, mut f: F)
1171 where
1172 E: TElement + 'a,
1173 F: FnMut(&'a CascadeData, Option<E>),
1174 {
1175 f(&self.cascade_data.user_agent.cascade_data, None);
1176 element.each_applicable_non_document_style_rule_data(|data, scope| {
1177 f(data, Some(scope));
1178 });
1179 f(&self.cascade_data.user, None);
1180 f(&self.cascade_data.author, None);
1181 }
1182
1183 pub fn precomputed_values_for_pseudo<E>(
1186 &self,
1187 guards: &StylesheetGuards,
1188 pseudo: &PseudoElement,
1189 parent: Option<&ComputedValues>,
1190 ) -> Arc<ComputedValues>
1191 where
1192 E: TElement,
1193 {
1194 debug_assert!(pseudo.is_precomputed());
1195
1196 let rule_node = self.rule_node_for_precomputed_pseudo(guards, pseudo, vec![]);
1197
1198 self.precomputed_values_for_pseudo_with_rule_node::<E>(guards, pseudo, parent, rule_node)
1199 }
1200
1201 pub fn precomputed_values_for_pseudo_with_rule_node<E>(
1207 &self,
1208 guards: &StylesheetGuards,
1209 pseudo: &PseudoElement,
1210 parent: Option<&ComputedValues>,
1211 rules: StrongRuleNode,
1212 ) -> Arc<ComputedValues>
1213 where
1214 E: TElement,
1215 {
1216 self.compute_pseudo_element_style_with_inputs::<E>(
1217 CascadeInputs {
1218 rules: Some(rules),
1219 visited_rules: None,
1220 flags: Default::default(),
1221 },
1222 pseudo,
1223 guards,
1224 parent,
1225 None,
1226 )
1227 }
1228
1229 pub fn rule_node_for_precomputed_pseudo(
1235 &self,
1236 guards: &StylesheetGuards,
1237 pseudo: &PseudoElement,
1238 mut extra_declarations: Vec<ApplicableDeclarationBlock>,
1239 ) -> StrongRuleNode {
1240 let mut declarations_with_extra;
1241 let declarations = match self
1242 .cascade_data
1243 .user_agent
1244 .precomputed_pseudo_element_decls
1245 .get(pseudo)
1246 {
1247 Some(declarations) => {
1248 if !extra_declarations.is_empty() {
1249 declarations_with_extra = declarations.clone();
1250 declarations_with_extra.append(&mut extra_declarations);
1251 &*declarations_with_extra
1252 } else {
1253 &**declarations
1254 }
1255 },
1256 None => &[],
1257 };
1258
1259 self.rule_tree.insert_ordered_rules_with_important(
1260 declarations.into_iter().map(|a| a.clone().for_rule_tree()),
1261 guards,
1262 )
1263 }
1264
1265 #[cfg(feature = "servo")]
1270 pub fn style_for_anonymous<E>(
1271 &self,
1272 guards: &StylesheetGuards,
1273 pseudo: &PseudoElement,
1274 parent_style: &ComputedValues,
1275 ) -> Arc<ComputedValues>
1276 where
1277 E: TElement,
1278 {
1279 self.precomputed_values_for_pseudo::<E>(guards, &pseudo, Some(parent_style))
1280 }
1281
1282 pub fn lazily_compute_pseudo_element_style<E>(
1290 &self,
1291 guards: &StylesheetGuards,
1292 element: E,
1293 pseudo: &PseudoElement,
1294 rule_inclusion: RuleInclusion,
1295 originating_element_style: &ComputedValues,
1296 is_probe: bool,
1297 matching_fn: Option<&dyn Fn(&PseudoElement) -> bool>,
1298 ) -> Option<Arc<ComputedValues>>
1299 where
1300 E: TElement,
1301 {
1302 let cascade_inputs = self.lazy_pseudo_rules(
1303 guards,
1304 element,
1305 originating_element_style,
1306 pseudo,
1307 is_probe,
1308 rule_inclusion,
1309 matching_fn,
1310 )?;
1311
1312 Some(self.compute_pseudo_element_style_with_inputs(
1313 cascade_inputs,
1314 pseudo,
1315 guards,
1316 Some(originating_element_style),
1317 Some(element),
1318 ))
1319 }
1320
1321 pub fn compute_pseudo_element_style_with_inputs<E>(
1326 &self,
1327 inputs: CascadeInputs,
1328 pseudo: &PseudoElement,
1329 guards: &StylesheetGuards,
1330 parent_style: Option<&ComputedValues>,
1331 element: Option<E>,
1332 ) -> Arc<ComputedValues>
1333 where
1334 E: TElement,
1335 {
1336 self.cascade_style_and_visited(
1349 element,
1350 Some(pseudo),
1351 inputs,
1352 guards,
1353 parent_style,
1354 parent_style,
1355 FirstLineReparenting::No,
1356 &PositionTryFallbacksTryTactic::default(),
1357 None,
1358 &mut RuleCacheConditions::default(),
1359 )
1360 }
1361
1362 #[cfg(feature = "gecko")]
1364 pub fn resolve_position_try<E>(
1365 &self,
1366 style: &ComputedValues,
1367 guards: &StylesheetGuards,
1368 element: E,
1369 fallback_item: &PositionTryFallbacksItem,
1370 ) -> Option<Arc<ComputedValues>>
1371 where
1372 E: TElement,
1373 {
1374 let name_and_try_tactic = match *fallback_item {
1375 PositionTryFallbacksItem::PositionArea(area) => {
1376 let mut builder =
1380 StyleBuilder::for_derived_style(&self.device, Some(self), style, None);
1381 builder.rules = style.rules.clone();
1382 builder.mutate_position().set_position_area(area);
1383 return Some(builder.build());
1384 },
1385 PositionTryFallbacksItem::IdentAndOrTactic(ref name_and_try_tactic) => {
1386 name_and_try_tactic
1387 },
1388 };
1389
1390 let fallback_rule = if !name_and_try_tactic.ident.is_empty() {
1391 Some(self.lookup_position_try(&name_and_try_tactic.ident.0, element)?)
1392 } else {
1393 None
1394 };
1395 let fallback_block = fallback_rule
1396 .as_ref()
1397 .map(|r| &r.read_with(guards.author).block);
1398 let pseudo = style
1399 .pseudo()
1400 .or_else(|| element.implemented_pseudo_element());
1401 let inputs = {
1402 let mut inputs = CascadeInputs::new_from_style(style);
1403 inputs.visited_rules = None;
1405 let rules = inputs.rules.as_ref().unwrap_or(self.rule_tree.root());
1406 let mut important_rules_changed = false;
1407 if let Some(fallback_block) = fallback_block {
1408 let new_rules = self.rule_tree.update_rule_at_level(
1409 CascadeLevel::PositionFallback,
1410 LayerOrder::root(),
1411 Some(fallback_block.borrow_arc()),
1412 rules,
1413 guards,
1414 &mut important_rules_changed,
1415 );
1416 if new_rules.is_some() {
1417 inputs.rules = new_rules;
1418 } else {
1419 }
1423 }
1424 inputs
1425 };
1426 crate::style_resolver::with_default_parent_styles(
1427 element,
1428 |parent_style, layout_parent_style| {
1429 Some(self.cascade_style_and_visited(
1430 Some(element),
1431 pseudo.as_ref(),
1432 inputs,
1433 guards,
1434 parent_style,
1435 layout_parent_style,
1436 FirstLineReparenting::No,
1437 &name_and_try_tactic.try_tactic,
1438 None,
1439 &mut RuleCacheConditions::default(),
1440 ))
1441 },
1442 )
1443 }
1444
1445 pub fn cascade_style_and_visited<E>(
1458 &self,
1459 element: Option<E>,
1460 pseudo: Option<&PseudoElement>,
1461 inputs: CascadeInputs,
1462 guards: &StylesheetGuards,
1463 parent_style: Option<&ComputedValues>,
1464 layout_parent_style: Option<&ComputedValues>,
1465 first_line_reparenting: FirstLineReparenting,
1466 try_tactic: &PositionTryFallbacksTryTactic,
1467 rule_cache: Option<&RuleCache>,
1468 rule_cache_conditions: &mut RuleCacheConditions,
1469 ) -> Arc<ComputedValues>
1470 where
1471 E: TElement,
1472 {
1473 debug_assert!(pseudo.is_some() || element.is_some(), "Huh?");
1474
1475 let visited_rules = match inputs.visited_rules.as_ref() {
1478 Some(rules) => Some(rules),
1479 None => {
1480 if parent_style.and_then(|s| s.visited_style()).is_some() {
1481 Some(inputs.rules.as_ref().unwrap_or(self.rule_tree.root()))
1482 } else {
1483 None
1484 }
1485 },
1486 };
1487
1488 let mut implemented_pseudo = None;
1489 properties::cascade::<E>(
1496 &self,
1497 pseudo.or_else(|| {
1498 implemented_pseudo = element.unwrap().implemented_pseudo_element();
1499 implemented_pseudo.as_ref()
1500 }),
1501 inputs.rules.as_ref().unwrap_or(self.rule_tree.root()),
1502 guards,
1503 parent_style,
1504 layout_parent_style,
1505 first_line_reparenting,
1506 try_tactic,
1507 visited_rules,
1508 inputs.flags,
1509 rule_cache,
1510 rule_cache_conditions,
1511 element,
1512 )
1513 }
1514
1515 fn lazy_pseudo_rules<E>(
1520 &self,
1521 guards: &StylesheetGuards,
1522 element: E,
1523 originating_element_style: &ComputedValues,
1524 pseudo: &PseudoElement,
1525 is_probe: bool,
1526 rule_inclusion: RuleInclusion,
1527 matching_fn: Option<&dyn Fn(&PseudoElement) -> bool>,
1528 ) -> Option<CascadeInputs>
1529 where
1530 E: TElement,
1531 {
1532 debug_assert!(pseudo.is_lazy());
1533
1534 let mut selector_caches = SelectorCaches::default();
1535 let needs_selector_flags = if rule_inclusion == RuleInclusion::DefaultOnly {
1538 NeedsSelectorFlags::No
1539 } else {
1540 NeedsSelectorFlags::Yes
1541 };
1542
1543 let mut declarations = ApplicableDeclarationList::new();
1544 let mut matching_context = MatchingContext::<'_, E::Impl>::new(
1545 MatchingMode::ForStatelessPseudoElement,
1546 None,
1547 &mut selector_caches,
1548 self.quirks_mode,
1549 needs_selector_flags,
1550 MatchingForInvalidation::No,
1551 );
1552
1553 matching_context.pseudo_element_matching_fn = matching_fn;
1554 matching_context.extra_data.originating_element_style = Some(originating_element_style);
1555
1556 self.push_applicable_declarations(
1557 element,
1558 Some(&pseudo),
1559 None,
1560 None,
1561 Default::default(),
1562 rule_inclusion,
1563 &mut declarations,
1564 &mut matching_context,
1565 );
1566
1567 if declarations.is_empty() && is_probe {
1568 return None;
1569 }
1570
1571 let rules = self.rule_tree.compute_rule_node(&mut declarations, guards);
1572
1573 let mut visited_rules = None;
1574 if originating_element_style.visited_style().is_some() {
1575 let mut declarations = ApplicableDeclarationList::new();
1576 let mut selector_caches = SelectorCaches::default();
1577
1578 let mut matching_context = MatchingContext::<'_, E::Impl>::new_for_visited(
1579 MatchingMode::ForStatelessPseudoElement,
1580 None,
1581 &mut selector_caches,
1582 VisitedHandlingMode::RelevantLinkVisited,
1583 selectors::matching::IncludeStartingStyle::No,
1584 self.quirks_mode,
1585 needs_selector_flags,
1586 MatchingForInvalidation::No,
1587 );
1588 matching_context.pseudo_element_matching_fn = matching_fn;
1589 matching_context.extra_data.originating_element_style = Some(originating_element_style);
1590
1591 self.push_applicable_declarations(
1592 element,
1593 Some(&pseudo),
1594 None,
1595 None,
1596 Default::default(),
1597 rule_inclusion,
1598 &mut declarations,
1599 &mut matching_context,
1600 );
1601 if !declarations.is_empty() {
1602 let rule_node = self.rule_tree.insert_ordered_rules_with_important(
1603 declarations.drain(..).map(|a| a.for_rule_tree()),
1604 guards,
1605 );
1606 if rule_node != *self.rule_tree.root() {
1607 visited_rules = Some(rule_node);
1608 }
1609 }
1610 }
1611
1612 Some(CascadeInputs {
1613 rules: Some(rules),
1614 visited_rules,
1615 flags: matching_context.extra_data.cascade_input_flags,
1616 })
1617 }
1618
1619 pub fn set_device(&mut self, device: Device, guards: &StylesheetGuards) -> OriginSet {
1630 self.device = device;
1631 self.media_features_change_changed_style(guards, &self.device)
1632 }
1633
1634 pub fn media_features_change_changed_style(
1638 &self,
1639 guards: &StylesheetGuards,
1640 device: &Device,
1641 ) -> OriginSet {
1642 debug!("Stylist::media_features_change_changed_style {:?}", device);
1643
1644 let mut origins = OriginSet::empty();
1645 let stylesheets = self.stylesheets.iter();
1646
1647 for (stylesheet, origin) in stylesheets {
1648 if origins.contains(origin.into()) {
1649 continue;
1650 }
1651
1652 let guard = guards.for_origin(origin);
1653 let origin_cascade_data = self.cascade_data.borrow_for_origin(origin);
1654
1655 let affected_changed = !origin_cascade_data.media_feature_affected_matches(
1656 stylesheet,
1657 guard,
1658 device,
1659 self.quirks_mode,
1660 );
1661
1662 if affected_changed {
1663 origins |= origin;
1664 }
1665 }
1666
1667 origins
1668 }
1669
1670 pub fn quirks_mode(&self) -> QuirksMode {
1672 self.quirks_mode
1673 }
1674
1675 pub fn set_quirks_mode(&mut self, quirks_mode: QuirksMode) {
1677 if self.quirks_mode == quirks_mode {
1678 return;
1679 }
1680 self.quirks_mode = quirks_mode;
1681 self.force_stylesheet_origins_dirty(OriginSet::all());
1682 }
1683
1684 pub fn push_applicable_declarations<E>(
1686 &self,
1687 element: E,
1688 pseudo_element: Option<&PseudoElement>,
1689 style_attribute: Option<ArcBorrow<Locked<PropertyDeclarationBlock>>>,
1690 smil_override: Option<ArcBorrow<Locked<PropertyDeclarationBlock>>>,
1691 animation_declarations: AnimationDeclarations,
1692 rule_inclusion: RuleInclusion,
1693 applicable_declarations: &mut ApplicableDeclarationList,
1694 context: &mut MatchingContext<E::Impl>,
1695 ) where
1696 E: TElement,
1697 {
1698 let mut cur = element;
1699 let mut pseudos = SmallVec::new();
1700 if let Some(pseudo) = pseudo_element {
1701 pseudos.push(pseudo.clone());
1702 }
1703 while let Some(p) = cur.implemented_pseudo_element() {
1704 pseudos.push(p);
1705 let Some(parent_pseudo) = cur.pseudo_element_originating_element() else {
1706 break;
1707 };
1708 cur = parent_pseudo;
1709 }
1710 RuleCollector::new(
1711 self,
1712 element,
1713 pseudos,
1714 style_attribute,
1715 smil_override,
1716 animation_declarations,
1717 rule_inclusion,
1718 applicable_declarations,
1719 context,
1720 )
1721 .collect_all();
1722 }
1723
1724 #[inline]
1727 pub fn may_have_rules_for_id<E>(&self, id: &WeakAtom, element: E) -> bool
1728 where
1729 E: TElement,
1730 {
1731 match self.quirks_mode().classes_and_ids_case_sensitivity() {
1734 CaseSensitivity::AsciiCaseInsensitive => return true,
1735 CaseSensitivity::CaseSensitive => {},
1736 }
1737
1738 self.any_applicable_rule_data(element, |data| data.mapped_ids.contains(id))
1739 }
1740
1741 #[inline]
1749 fn lookup_element_dependent_at_rule<'a, T, F, E>(
1750 &'a self,
1751 element: E,
1752 find_in: F,
1753 ) -> Option<&'a T>
1754 where
1755 E: TElement + 'a,
1756 F: Fn(&'a CascadeData) -> Option<&'a T>,
1757 {
1758 macro_rules! try_find_in {
1759 ($data:expr) => {
1760 if let Some(thing) = find_in(&$data) {
1761 return Some(thing);
1762 }
1763 };
1764 }
1765
1766 let mut result = None;
1767 let doc_rules_apply =
1768 element.each_applicable_non_document_style_rule_data(|data, _host| {
1769 if result.is_none() {
1770 result = find_in(data);
1771 }
1772 });
1773
1774 if result.is_some() {
1775 return result;
1776 }
1777
1778 if doc_rules_apply {
1779 try_find_in!(self.cascade_data.author);
1780 }
1781 try_find_in!(self.cascade_data.user);
1782 try_find_in!(self.cascade_data.user_agent.cascade_data);
1783
1784 None
1785 }
1786
1787 #[inline]
1789 pub fn lookup_keyframes<'a, E>(
1790 &'a self,
1791 name: &Atom,
1792 element: E,
1793 ) -> Option<&'a KeyframesAnimation>
1794 where
1795 E: TElement + 'a,
1796 {
1797 self.lookup_element_dependent_at_rule(element, |data| data.animations.get(name))
1798 }
1799
1800 #[inline]
1802 #[cfg(feature = "gecko")]
1803 fn lookup_position_try<'a, E>(
1804 &'a self,
1805 name: &Atom,
1806 element: E,
1807 ) -> Option<&'a Arc<Locked<PositionTryRule>>>
1808 where
1809 E: TElement + 'a,
1810 {
1811 self.lookup_element_dependent_at_rule(element, |data| {
1812 data.extra_data.position_try_rules.get(name)
1813 })
1814 }
1815
1816 pub fn match_revalidation_selectors<E>(
1819 &self,
1820 element: E,
1821 bloom: Option<&BloomFilter>,
1822 selector_caches: &mut SelectorCaches,
1823 needs_selector_flags: NeedsSelectorFlags,
1824 ) -> RevalidationResult
1825 where
1826 E: TElement,
1827 {
1828 let mut matching_context = MatchingContext::new_for_revalidation(
1829 bloom,
1830 selector_caches,
1831 self.quirks_mode,
1832 needs_selector_flags,
1833 );
1834
1835 let mut result = RevalidationResult::default();
1841 let mut relevant_attributes = &mut result.relevant_attributes;
1842 let selectors_matched = &mut result.selectors_matched;
1843
1844 let matches_document_rules =
1845 element.each_applicable_non_document_style_rule_data(|data, host| {
1846 matching_context.with_shadow_host(Some(host), |matching_context| {
1847 data.selectors_for_cache_revalidation.lookup(
1848 element,
1849 self.quirks_mode,
1850 Some(&mut relevant_attributes),
1851 |selector_and_hashes| {
1852 selectors_matched.push(matches_selector(
1853 &selector_and_hashes.selector,
1854 selector_and_hashes.selector_offset,
1855 Some(&selector_and_hashes.hashes),
1856 &element,
1857 matching_context,
1858 ));
1859 true
1860 },
1861 );
1862 })
1863 });
1864
1865 for (data, origin) in self.cascade_data.iter_origins() {
1866 if origin == Origin::Author && !matches_document_rules {
1867 continue;
1868 }
1869
1870 data.selectors_for_cache_revalidation.lookup(
1871 element,
1872 self.quirks_mode,
1873 Some(&mut relevant_attributes),
1874 |selector_and_hashes| {
1875 selectors_matched.push(matches_selector(
1876 &selector_and_hashes.selector,
1877 selector_and_hashes.selector_offset,
1878 Some(&selector_and_hashes.hashes),
1879 &element,
1880 &mut matching_context,
1881 ));
1882 true
1883 },
1884 );
1885 }
1886
1887 result
1888 }
1889
1890 pub fn revalidate_scopes<E: TElement>(
1892 &self,
1893 element: &E,
1894 selector_caches: &mut SelectorCaches,
1895 needs_selector_flags: NeedsSelectorFlags,
1896 ) -> ScopeRevalidationResult {
1897 let mut matching_context = MatchingContext::new(
1898 MatchingMode::Normal,
1899 None,
1900 selector_caches,
1901 self.quirks_mode,
1902 needs_selector_flags,
1903 MatchingForInvalidation::No,
1904 );
1905
1906 let mut result = ScopeRevalidationResult::default();
1907 let matches_document_rules =
1908 element.each_applicable_non_document_style_rule_data(|data, host| {
1909 matching_context.with_shadow_host(Some(host), |matching_context| {
1910 data.revalidate_scopes(element, matching_context, &mut result);
1911 })
1912 });
1913
1914 for (data, origin) in self.cascade_data.iter_origins() {
1915 if origin == Origin::Author && !matches_document_rules {
1916 continue;
1917 }
1918
1919 data.revalidate_scopes(element, &mut matching_context, &mut result);
1920 }
1921
1922 result
1923 }
1924
1925 pub fn compute_for_declarations<E>(
1933 &self,
1934 guards: &StylesheetGuards,
1935 parent_style: &ComputedValues,
1936 declarations: Arc<Locked<PropertyDeclarationBlock>>,
1937 ) -> Arc<ComputedValues>
1938 where
1939 E: TElement,
1940 {
1941 let block = declarations.read_with(guards.author);
1942
1943 properties::apply_declarations::<E, _>(
1950 &self,
1951 None,
1952 self.rule_tree.root(),
1953 guards,
1954 block.declaration_importance_iter().map(|(declaration, _)| {
1955 (
1956 declaration,
1957 CascadePriority::new(
1958 CascadeLevel::same_tree_author_normal(),
1959 LayerOrder::root(),
1960 ),
1961 )
1962 }),
1963 Some(parent_style),
1964 Some(parent_style),
1965 FirstLineReparenting::No,
1966 &PositionTryFallbacksTryTactic::default(),
1967 CascadeMode::Unvisited {
1968 visited_rules: None,
1969 },
1970 Default::default(),
1971 None,
1972 &mut Default::default(),
1973 None,
1974 )
1975 }
1976
1977 #[inline]
1979 pub fn device(&self) -> &Device {
1980 &self.device
1981 }
1982
1983 #[inline]
1985 pub fn device_mut(&mut self) -> &mut Device {
1986 &mut self.device
1987 }
1988
1989 #[inline]
1991 pub fn rule_tree(&self) -> &RuleTree {
1992 &self.rule_tree
1993 }
1994
1995 #[inline]
1997 pub fn custom_property_script_registry(&self) -> &CustomPropertyScriptRegistry {
1998 &self.script_custom_properties
1999 }
2000
2001 #[inline]
2003 pub fn custom_property_script_registry_mut(&mut self) -> &mut CustomPropertyScriptRegistry {
2004 &mut self.script_custom_properties
2005 }
2006
2007 #[cfg(feature = "gecko")]
2009 pub fn add_size_of(&self, ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes) {
2010 self.cascade_data.add_size_of(ops, sizes);
2011 self.author_data_cache.add_size_of(ops, sizes);
2012 sizes.mRuleTree += self.rule_tree.size_of(ops);
2013
2014 }
2016
2017 pub fn shutdown() {
2019 let _entries = UA_CASCADE_DATA_CACHE.lock().unwrap().take_all();
2020 }
2021}
2022
2023#[derive(Clone, Debug, Deref, MallocSizeOf)]
2025pub struct LayerOrderedVec<T>(Vec<(T, LayerId)>);
2026impl<T> Default for LayerOrderedVec<T> {
2027 fn default() -> Self {
2028 Self(Default::default())
2029 }
2030}
2031
2032#[derive(Clone, Debug, Deref, MallocSizeOf)]
2034pub struct LayerOrderedMap<T>(PrecomputedHashMap<Atom, SmallVec<[(T, LayerId); 1]>>);
2035impl<T> Default for LayerOrderedMap<T> {
2036 fn default() -> Self {
2037 Self(Default::default())
2038 }
2039}
2040
2041impl<T: 'static> LayerOrderedVec<T> {
2042 fn clear(&mut self) {
2043 self.0.clear();
2044 }
2045 fn push(&mut self, v: T, id: LayerId) {
2046 self.0.push((v, id));
2047 }
2048 fn sort(&mut self, layers: &[CascadeLayer]) {
2049 self.0
2050 .sort_by_key(|&(_, ref id)| layers[id.0 as usize].order)
2051 }
2052}
2053
2054impl<T: 'static> LayerOrderedMap<T> {
2055 fn shrink_if_needed(&mut self) {
2056 self.0.shrink_if_needed();
2057 }
2058 fn clear(&mut self) {
2059 self.0.clear();
2060 }
2061 fn try_insert(&mut self, name: Atom, v: T, id: LayerId) -> Result<(), AllocErr> {
2062 self.try_insert_with(name, v, id, |_, _| Ordering::Equal)
2063 }
2064 fn try_insert_with(
2065 &mut self,
2066 name: Atom,
2067 v: T,
2068 id: LayerId,
2069 cmp: impl Fn(&T, &T) -> Ordering,
2070 ) -> Result<(), AllocErr> {
2071 self.0.try_reserve(1)?;
2072 let vec = self.0.entry(name).or_default();
2073 if let Some(&mut (ref mut val, ref last_id)) = vec.last_mut() {
2074 if *last_id == id {
2075 if cmp(&val, &v) != Ordering::Greater {
2076 *val = v;
2077 }
2078 return Ok(());
2079 }
2080 }
2081 vec.push((v, id));
2082 Ok(())
2083 }
2084 fn sort(&mut self, layers: &[CascadeLayer]) {
2085 self.sort_with(layers, |_, _| Ordering::Equal)
2086 }
2087 fn sort_with(&mut self, layers: &[CascadeLayer], cmp: impl Fn(&T, &T) -> Ordering) {
2088 for (_, v) in self.0.iter_mut() {
2089 v.sort_by(|&(ref v1, ref id1), &(ref v2, ref id2)| {
2090 let order1 = layers[id1.0 as usize].order;
2091 let order2 = layers[id2.0 as usize].order;
2092 order1.cmp(&order2).then_with(|| cmp(v1, v2))
2093 })
2094 }
2095 }
2096 pub fn get(&self, name: &Atom) -> Option<&T> {
2098 let vec = self.0.get(name)?;
2099 Some(&vec.last()?.0)
2100 }
2101}
2102
2103#[derive(Clone, Debug, MallocSizeOf)]
2107pub struct PageRuleData {
2108 pub layer: LayerId,
2110 #[ignore_malloc_size_of = "Arc, stylesheet measures as primary ref"]
2112 pub rule: Arc<Locked<PageRule>>,
2113}
2114
2115#[derive(Clone, Debug, Default, MallocSizeOf)]
2117pub struct PageRuleMap {
2118 pub rules: PrecomputedHashMap<Atom, SmallVec<[PageRuleData; 1]>>,
2120}
2121
2122impl PageRuleMap {
2123 #[inline]
2124 fn clear(&mut self) {
2125 self.rules.clear();
2126 }
2127
2128 pub fn match_and_append_rules(
2132 &self,
2133 matched_rules: &mut Vec<ApplicableDeclarationBlock>,
2134 origin: Origin,
2135 guards: &StylesheetGuards,
2136 cascade_data: &DocumentCascadeData,
2137 name: &Option<Atom>,
2138 pseudos: PagePseudoClassFlags,
2139 ) {
2140 let level = match origin {
2141 Origin::UserAgent => CascadeLevel::UANormal,
2142 Origin::User => CascadeLevel::UserNormal,
2143 Origin::Author => CascadeLevel::same_tree_author_normal(),
2144 };
2145 let cascade_data = cascade_data.borrow_for_origin(origin);
2146 let start = matched_rules.len();
2147
2148 self.match_and_add_rules(
2149 matched_rules,
2150 level,
2151 guards,
2152 cascade_data,
2153 &atom!(""),
2154 pseudos,
2155 );
2156 if let Some(name) = name {
2157 self.match_and_add_rules(matched_rules, level, guards, cascade_data, name, pseudos);
2158 }
2159
2160 matched_rules[start..].sort_by_key(|block| block.sort_key());
2163 }
2164
2165 fn match_and_add_rules(
2166 &self,
2167 extra_declarations: &mut Vec<ApplicableDeclarationBlock>,
2168 level: CascadeLevel,
2169 guards: &StylesheetGuards,
2170 cascade_data: &CascadeData,
2171 name: &Atom,
2172 pseudos: PagePseudoClassFlags,
2173 ) {
2174 let rules = match self.rules.get(name) {
2175 Some(rules) => rules,
2176 None => return,
2177 };
2178 for data in rules.iter() {
2179 let rule = data.rule.read_with(level.guard(&guards));
2180 let specificity = match rule.match_specificity(pseudos) {
2181 Some(specificity) => specificity,
2182 None => continue,
2183 };
2184 let block = rule.block.clone();
2185 extra_declarations.push(ApplicableDeclarationBlock::new(
2186 StyleSource::from_declarations(block),
2187 0,
2188 level,
2189 specificity,
2190 cascade_data.layer_order_for(data.layer),
2191 ScopeProximity::infinity(), ));
2193 }
2194 }
2195}
2196
2197impl MallocShallowSizeOf for PageRuleMap {
2198 fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
2199 self.rules.shallow_size_of(ops)
2200 }
2201}
2202
2203type PositionTryMap = LayerOrderedMap<Arc<Locked<PositionTryRule>>>;
2204
2205#[derive(Clone, Debug, Default)]
2208pub struct ExtraStyleData {
2209 pub font_faces: LayerOrderedVec<Arc<Locked<FontFaceRule>>>,
2211
2212 pub font_feature_values: LayerOrderedVec<Arc<FontFeatureValuesRule>>,
2214
2215 pub font_palette_values: LayerOrderedVec<Arc<FontPaletteValuesRule>>,
2217
2218 pub counter_styles: LayerOrderedMap<Arc<Locked<CounterStyleRule>>>,
2220
2221 pub position_try_rules: PositionTryMap,
2223
2224 pub pages: PageRuleMap,
2226}
2227
2228impl ExtraStyleData {
2229 fn add_font_face(&mut self, rule: &Arc<Locked<FontFaceRule>>, layer: LayerId) {
2231 self.font_faces.push(rule.clone(), layer);
2232 }
2233
2234 fn add_font_feature_values(&mut self, rule: &Arc<FontFeatureValuesRule>, layer: LayerId) {
2236 self.font_feature_values.push(rule.clone(), layer);
2237 }
2238
2239 fn add_font_palette_values(&mut self, rule: &Arc<FontPaletteValuesRule>, layer: LayerId) {
2241 self.font_palette_values.push(rule.clone(), layer);
2242 }
2243
2244 fn add_counter_style(
2246 &mut self,
2247 guard: &SharedRwLockReadGuard,
2248 rule: &Arc<Locked<CounterStyleRule>>,
2249 layer: LayerId,
2250 ) -> Result<(), AllocErr> {
2251 let name = rule.read_with(guard).name().0.clone();
2252 self.counter_styles.try_insert(name, rule.clone(), layer)
2253 }
2254
2255 fn add_position_try(
2257 &mut self,
2258 name: Atom,
2259 rule: Arc<Locked<PositionTryRule>>,
2260 layer: LayerId,
2261 ) -> Result<(), AllocErr> {
2262 self.position_try_rules.try_insert(name, rule, layer)
2263 }
2264
2265 fn add_page(
2267 &mut self,
2268 guard: &SharedRwLockReadGuard,
2269 rule: &Arc<Locked<PageRule>>,
2270 layer: LayerId,
2271 ) -> Result<(), AllocErr> {
2272 let page_rule = rule.read_with(guard);
2273 let mut add_rule = |name| {
2274 let vec = self.pages.rules.entry(name).or_default();
2275 vec.push(PageRuleData {
2276 layer,
2277 rule: rule.clone(),
2278 });
2279 };
2280 if page_rule.selectors.0.is_empty() {
2281 add_rule(atom!(""));
2282 } else {
2283 for selector in page_rule.selectors.as_slice() {
2284 add_rule(selector.name.0.clone());
2285 }
2286 }
2287 Ok(())
2288 }
2289
2290 fn sort_by_layer(&mut self, layers: &[CascadeLayer]) {
2291 self.font_faces.sort(layers);
2292 self.font_feature_values.sort(layers);
2293 self.font_palette_values.sort(layers);
2294 self.counter_styles.sort(layers);
2295 self.position_try_rules.sort(layers);
2296 }
2297
2298 fn clear(&mut self) {
2299 self.font_faces.clear();
2300 self.font_feature_values.clear();
2301 self.font_palette_values.clear();
2302 self.counter_styles.clear();
2303 self.position_try_rules.clear();
2304 self.pages.clear();
2305 }
2306}
2307
2308fn compare_keyframes_in_same_layer(v1: &KeyframesAnimation, v2: &KeyframesAnimation) -> Ordering {
2311 if v1.vendor_prefix.is_some() == v2.vendor_prefix.is_some() {
2312 Ordering::Equal
2313 } else if v2.vendor_prefix.is_some() {
2314 Ordering::Greater
2315 } else {
2316 Ordering::Less
2317 }
2318}
2319
2320pub struct ExtraStyleDataIterator<'a>(DocumentCascadeDataIter<'a>);
2322
2323impl<'a> Iterator for ExtraStyleDataIterator<'a> {
2324 type Item = (&'a ExtraStyleData, Origin);
2325
2326 fn next(&mut self) -> Option<Self::Item> {
2327 self.0.next().map(|d| (&d.0.extra_data, d.1))
2328 }
2329}
2330
2331impl MallocSizeOf for ExtraStyleData {
2332 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
2334 let mut n = 0;
2335 n += self.font_faces.shallow_size_of(ops);
2336 n += self.font_feature_values.shallow_size_of(ops);
2337 n += self.font_palette_values.shallow_size_of(ops);
2338 n += self.counter_styles.shallow_size_of(ops);
2339 n += self.position_try_rules.shallow_size_of(ops);
2340 n += self.pages.shallow_size_of(ops);
2341 n
2342 }
2343}
2344
2345#[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
2347#[derive(Clone, Debug)]
2348struct RevalidationSelectorAndHashes {
2349 #[cfg_attr(
2350 feature = "gecko",
2351 ignore_malloc_size_of = "CssRules have primary refs, we measure there"
2352 )]
2353 selector: Selector<SelectorImpl>,
2354 selector_offset: usize,
2355 hashes: AncestorHashes,
2356}
2357
2358impl RevalidationSelectorAndHashes {
2359 fn new(selector: Selector<SelectorImpl>, hashes: AncestorHashes) -> Self {
2360 let selector_offset = {
2361 let mut index = 0;
2365 let mut iter = selector.iter();
2366
2367 for _ in &mut iter {
2372 index += 1; }
2374
2375 match iter.next_sequence() {
2376 Some(Combinator::PseudoElement) => index + 1, _ => 0,
2378 }
2379 };
2380
2381 RevalidationSelectorAndHashes {
2382 selector,
2383 selector_offset,
2384 hashes,
2385 }
2386 }
2387}
2388
2389impl SelectorMapEntry for RevalidationSelectorAndHashes {
2390 fn selector(&self) -> SelectorIter<'_, SelectorImpl> {
2391 self.selector.iter_from(self.selector_offset)
2392 }
2393}
2394
2395struct StylistSelectorVisitor<'a> {
2398 passed_rightmost_selector: bool,
2401
2402 needs_revalidation: &'a mut bool,
2404
2405 in_selector_list_of: SelectorListKind,
2408
2409 mapped_ids: &'a mut PrecomputedHashSet<Atom>,
2412
2413 nth_of_mapped_ids: &'a mut PrecomputedHashSet<Atom>,
2416
2417 attribute_dependencies: &'a mut PrecomputedHashSet<LocalName>,
2419
2420 nth_of_class_dependencies: &'a mut PrecomputedHashSet<Atom>,
2423
2424 nth_of_attribute_dependencies: &'a mut PrecomputedHashSet<LocalName>,
2428
2429 nth_of_custom_state_dependencies: &'a mut PrecomputedHashSet<AtomIdent>,
2433
2434 state_dependencies: &'a mut ElementState,
2436
2437 nth_of_state_dependencies: &'a mut ElementState,
2440
2441 document_state_dependencies: &'a mut DocumentState,
2443}
2444
2445fn component_needs_revalidation(
2446 c: &Component<SelectorImpl>,
2447 passed_rightmost_selector: bool,
2448) -> bool {
2449 match *c {
2450 Component::ID(_) => {
2451 passed_rightmost_selector
2457 },
2458 Component::AttributeInNoNamespaceExists { .. }
2459 | Component::AttributeInNoNamespace { .. }
2460 | Component::AttributeOther(_)
2461 | Component::Empty
2462 | Component::Nth(_)
2463 | Component::NthOf(_)
2464 | Component::Has(_) => true,
2465 Component::NonTSPseudoClass(ref p) => p.needs_cache_revalidation(),
2466 _ => false,
2467 }
2468}
2469
2470impl<'a> StylistSelectorVisitor<'a> {
2471 fn visit_nested_selector(
2472 &mut self,
2473 in_selector_list_of: SelectorListKind,
2474 selector: &Selector<SelectorImpl>,
2475 ) {
2476 let old_passed_rightmost_selector = self.passed_rightmost_selector;
2477 let old_in_selector_list_of = self.in_selector_list_of;
2478
2479 self.passed_rightmost_selector = false;
2480 self.in_selector_list_of = in_selector_list_of;
2481 let _ret = selector.visit(self);
2482 debug_assert!(_ret, "We never return false");
2483
2484 self.passed_rightmost_selector = old_passed_rightmost_selector;
2485 self.in_selector_list_of = old_in_selector_list_of;
2486 }
2487}
2488
2489impl<'a> SelectorVisitor for StylistSelectorVisitor<'a> {
2490 type Impl = SelectorImpl;
2491
2492 fn visit_complex_selector(&mut self, combinator: Option<Combinator>) -> bool {
2493 *self.needs_revalidation =
2494 *self.needs_revalidation || combinator.map_or(false, |c| c.is_sibling());
2495
2496 self.passed_rightmost_selector = self.passed_rightmost_selector
2500 || !matches!(combinator, None | Some(Combinator::PseudoElement));
2501
2502 true
2503 }
2504
2505 fn visit_selector_list(
2506 &mut self,
2507 list_kind: SelectorListKind,
2508 list: &[Selector<Self::Impl>],
2509 ) -> bool {
2510 let in_selector_list_of = self.in_selector_list_of | list_kind;
2511 for selector in list {
2512 self.visit_nested_selector(in_selector_list_of, selector);
2513 }
2514 true
2515 }
2516
2517 fn visit_relative_selector_list(
2518 &mut self,
2519 list: &[selectors::parser::RelativeSelector<Self::Impl>],
2520 ) -> bool {
2521 let in_selector_list_of = self.in_selector_list_of | SelectorListKind::HAS;
2522 for selector in list {
2523 self.visit_nested_selector(in_selector_list_of, &selector.selector);
2524 }
2525 true
2526 }
2527
2528 fn visit_attribute_selector(
2529 &mut self,
2530 _ns: &NamespaceConstraint<&Namespace>,
2531 name: &LocalName,
2532 lower_name: &LocalName,
2533 ) -> bool {
2534 if self.in_selector_list_of.relevant_to_nth_of_dependencies() {
2535 self.nth_of_attribute_dependencies.insert(name.clone());
2536 if name != lower_name {
2537 self.nth_of_attribute_dependencies
2538 .insert(lower_name.clone());
2539 }
2540 }
2541
2542 self.attribute_dependencies.insert(name.clone());
2543 if name != lower_name {
2544 self.attribute_dependencies.insert(lower_name.clone());
2545 }
2546
2547 true
2548 }
2549
2550 fn visit_simple_selector(&mut self, s: &Component<SelectorImpl>) -> bool {
2551 *self.needs_revalidation = *self.needs_revalidation
2552 || component_needs_revalidation(s, self.passed_rightmost_selector);
2553
2554 match *s {
2555 Component::NonTSPseudoClass(NonTSPseudoClass::CustomState(ref name)) => {
2556 if self.in_selector_list_of.relevant_to_nth_of_dependencies() {
2562 self.nth_of_custom_state_dependencies.insert(name.0.clone());
2563 }
2564 },
2565 Component::NonTSPseudoClass(ref p) => {
2566 self.state_dependencies.insert(p.state_flag());
2567 self.document_state_dependencies
2568 .insert(p.document_state_flag());
2569
2570 if self.in_selector_list_of.relevant_to_nth_of_dependencies() {
2571 self.nth_of_state_dependencies.insert(p.state_flag());
2572 }
2573 },
2574 Component::ID(ref id) => {
2575 if !self.passed_rightmost_selector {
2587 self.mapped_ids.insert(id.0.clone());
2588 }
2589
2590 if self.in_selector_list_of.relevant_to_nth_of_dependencies() {
2591 self.nth_of_mapped_ids.insert(id.0.clone());
2592 }
2593 },
2594 Component::Class(ref class)
2595 if self.in_selector_list_of.relevant_to_nth_of_dependencies() =>
2596 {
2597 self.nth_of_class_dependencies.insert(class.0.clone());
2598 },
2599 _ => {},
2600 }
2601
2602 true
2603 }
2604}
2605
2606#[derive(Clone, Debug, Default, MallocSizeOf)]
2608struct GenericElementAndPseudoRules<Map> {
2609 element_map: Map,
2611
2612 pseudos_map: PerPseudoElementMap<Self>,
2619}
2620
2621impl<Map: Default + MallocSizeOf> GenericElementAndPseudoRules<Map> {
2622 #[inline(always)]
2623 fn for_insertion<'a>(&mut self, pseudo_elements: &[&'a PseudoElement]) -> &mut Map {
2624 let mut current = self;
2625 for &pseudo_element in pseudo_elements {
2626 debug_assert!(
2627 !pseudo_element.is_precomputed()
2628 && !pseudo_element.is_unknown_webkit_pseudo_element(),
2629 "Precomputed pseudos should end up in precomputed_pseudo_element_decls, \
2630 and unknown webkit pseudos should be discarded before getting here"
2631 );
2632
2633 current = current
2634 .pseudos_map
2635 .get_or_insert_with(pseudo_element, Default::default);
2636 }
2637
2638 &mut current.element_map
2639 }
2640
2641 #[inline]
2642 fn rules(&self, pseudo_elements: &[PseudoElement]) -> Option<&Map> {
2643 let mut current = self;
2644 for pseudo in pseudo_elements {
2645 current = current.pseudos_map.get(&pseudo)?;
2646 }
2647 Some(¤t.element_map)
2648 }
2649
2650 #[cfg(feature = "gecko")]
2652 fn add_size_of(&self, ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes) {
2653 sizes.mElementAndPseudosMaps += self.element_map.size_of(ops);
2654
2655 for elem in self.pseudos_map.iter() {
2656 sizes.mElementAndPseudosMaps += MallocSizeOf::size_of(elem, ops);
2657 }
2658 }
2659}
2660
2661type ElementAndPseudoRules = GenericElementAndPseudoRules<SelectorMap<Rule>>;
2662type PartMap = PrecomputedHashMap<Atom, SmallVec<[Rule; 1]>>;
2663type PartElementAndPseudoRules = GenericElementAndPseudoRules<PartMap>;
2664
2665impl ElementAndPseudoRules {
2666 fn clear(&mut self) {
2668 self.element_map.clear();
2669 self.pseudos_map.clear();
2670 }
2671
2672 fn shrink_if_needed(&mut self) {
2673 self.element_map.shrink_if_needed();
2674 for pseudo in self.pseudos_map.iter_mut() {
2675 pseudo.shrink_if_needed();
2676 }
2677 }
2678}
2679
2680impl PartElementAndPseudoRules {
2681 fn clear(&mut self) {
2683 self.element_map.clear();
2684 self.pseudos_map.clear();
2685 }
2686}
2687
2688#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, PartialOrd, Ord)]
2690pub struct LayerId(u16);
2691
2692impl LayerId {
2693 pub const fn root() -> Self {
2695 Self(0)
2696 }
2697}
2698
2699#[derive(Clone, Debug, MallocSizeOf)]
2700struct CascadeLayer {
2701 id: LayerId,
2702 order: LayerOrder,
2703 children: Vec<LayerId>,
2704}
2705
2706impl CascadeLayer {
2707 const fn root() -> Self {
2708 Self {
2709 id: LayerId::root(),
2710 order: LayerOrder::root(),
2711 children: vec![],
2712 }
2713 }
2714}
2715
2716#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, PartialOrd, Ord)]
2719pub struct ContainerConditionId(u16);
2720
2721impl ContainerConditionId {
2722 pub const fn none() -> Self {
2724 Self(0)
2725 }
2726}
2727
2728#[derive(Clone, Debug, MallocSizeOf)]
2729struct ContainerConditionReference {
2730 parent: ContainerConditionId,
2731 #[ignore_malloc_size_of = "Arc"]
2732 condition: Option<Arc<ContainerCondition>>,
2733}
2734
2735impl ContainerConditionReference {
2736 const fn none() -> Self {
2737 Self {
2738 parent: ContainerConditionId::none(),
2739 condition: None,
2740 }
2741 }
2742}
2743
2744#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, PartialOrd, Ord)]
2747pub struct ScopeConditionId(u16);
2748
2749impl ScopeConditionId {
2750 pub fn new(id: u16) -> Self {
2752 Self(id)
2753 }
2754
2755 pub const fn none() -> Self {
2757 Self(0)
2758 }
2759}
2760
2761#[derive(Clone, Debug, MallocSizeOf)]
2763pub struct ScopeConditionReference {
2764 parent: ScopeConditionId,
2766 condition: Option<ScopeBoundsWithHashes>,
2768 #[ignore_malloc_size_of = "Raw ptr behind the scenes"]
2771 implicit_scope_root: StylistImplicitScopeRoot,
2772 is_trivial: bool,
2774}
2775
2776impl ScopeConditionReference {
2777 pub fn new(
2779 parent: ScopeConditionId,
2780 condition: Option<ScopeBoundsWithHashes>,
2781 implicit_scope_root: ImplicitScopeRoot,
2782 is_trivial: bool,
2783 ) -> Self {
2784 Self {
2785 parent,
2786 condition,
2787 implicit_scope_root: StylistImplicitScopeRoot::Normal(implicit_scope_root),
2788 is_trivial,
2789 }
2790 }
2791
2792 pub const fn none() -> Self {
2794 Self {
2795 parent: ScopeConditionId::none(),
2796 condition: None,
2797 implicit_scope_root: StylistImplicitScopeRoot::default_const(),
2798 is_trivial: true,
2799 }
2800 }
2801}
2802
2803pub struct ScopeRootCandidates {
2805 pub candidates: Vec<ScopeRootCandidate>,
2807 pub is_trivial: bool,
2809}
2810
2811impl Default for ScopeRootCandidates {
2812 fn default() -> Self {
2813 Self {
2814 candidates: vec![],
2815 is_trivial: true,
2816 }
2817 }
2818}
2819
2820impl ScopeRootCandidates {
2821 fn empty(is_trivial: bool) -> Self {
2822 Self {
2823 candidates: vec![],
2824 is_trivial,
2825 }
2826 }
2827}
2828
2829#[derive(Clone, Debug, MallocSizeOf)]
2831pub struct ScopeBoundWithHashes {
2832 #[ignore_malloc_size_of = "Arc"]
2834 selectors: SelectorList<SelectorImpl>,
2835 hashes: SmallVec<[AncestorHashes; 1]>,
2836}
2837
2838impl ScopeBoundWithHashes {
2839 fn new(quirks_mode: QuirksMode, selectors: SelectorList<SelectorImpl>) -> Self {
2840 let mut hashes = SmallVec::with_capacity(selectors.len());
2841 for selector in selectors.slice() {
2842 hashes.push(AncestorHashes::new(selector, quirks_mode));
2843 }
2844 Self { selectors, hashes }
2845 }
2846
2847 fn new_no_hash(selectors: SelectorList<SelectorImpl>) -> Self {
2848 let hashes = selectors
2849 .slice()
2850 .iter()
2851 .map(|_| AncestorHashes {
2852 packed_hashes: [0, 0, 0],
2853 })
2854 .collect();
2855 Self { selectors, hashes }
2856 }
2857}
2858
2859#[derive(Clone, Debug, MallocSizeOf)]
2861pub struct ScopeBoundsWithHashes {
2862 start: Option<ScopeBoundWithHashes>,
2864 end: Option<ScopeBoundWithHashes>,
2866}
2867
2868impl ScopeBoundsWithHashes {
2869 fn new(
2871 quirks_mode: QuirksMode,
2872 start: Option<SelectorList<SelectorImpl>>,
2873 end: Option<SelectorList<SelectorImpl>>,
2874 ) -> Self {
2875 Self {
2876 start: start.map(|selectors| ScopeBoundWithHashes::new(quirks_mode, selectors)),
2877 end: end.map(|selectors| ScopeBoundWithHashes::new(quirks_mode, selectors)),
2878 }
2879 }
2880
2881 pub fn new_no_hash(
2883 start: Option<SelectorList<SelectorImpl>>,
2884 end: Option<SelectorList<SelectorImpl>>,
2885 ) -> Self {
2886 Self {
2887 start: start.map(|selectors| ScopeBoundWithHashes::new_no_hash(selectors)),
2888 end: end.map(|selectors| ScopeBoundWithHashes::new_no_hash(selectors)),
2889 }
2890 }
2891
2892 fn selectors_for<'a>(
2893 bound_with_hashes: Option<&'a ScopeBoundWithHashes>,
2894 ) -> impl Iterator<Item = &'a Selector<SelectorImpl>> {
2895 bound_with_hashes
2896 .map(|b| b.selectors.slice().iter())
2897 .into_iter()
2898 .flatten()
2899 }
2900
2901 fn start_selectors<'a>(&'a self) -> impl Iterator<Item = &'a Selector<SelectorImpl>> {
2902 Self::selectors_for(self.start.as_ref())
2903 }
2904
2905 fn end_selectors<'a>(&'a self) -> impl Iterator<Item = &'a Selector<SelectorImpl>> {
2906 Self::selectors_for(self.end.as_ref())
2907 }
2908
2909 fn is_trivial(&self) -> bool {
2910 fn scope_bound_is_trivial(bound: &Option<ScopeBoundWithHashes>, default: bool) -> bool {
2911 bound.as_ref().map_or(default, |bound| {
2912 scope_selector_list_is_trivial(&bound.selectors)
2913 })
2914 }
2915
2916 scope_bound_is_trivial(&self.start, false) && scope_bound_is_trivial(&self.end, true)
2918 }
2919}
2920
2921pub fn scope_root_candidates<E>(
2923 scope_conditions: &[ScopeConditionReference],
2924 id: ScopeConditionId,
2925 element: &E,
2926 override_matches_shadow_host_for_part: bool,
2927 scope_subject_map: &ScopeSubjectMap,
2928 context: &mut MatchingContext<SelectorImpl>,
2929) -> ScopeRootCandidates
2930where
2931 E: TElement,
2932{
2933 let condition_ref = &scope_conditions[id.0 as usize];
2934 let bounds = match condition_ref.condition {
2935 None => return ScopeRootCandidates::default(),
2936 Some(ref c) => c,
2937 };
2938 let outer_result = scope_root_candidates(
2942 scope_conditions,
2943 condition_ref.parent,
2944 element,
2945 override_matches_shadow_host_for_part,
2946 scope_subject_map,
2947 context,
2948 );
2949
2950 let is_trivial = condition_ref.is_trivial && outer_result.is_trivial;
2951 let is_outermost_scope = condition_ref.parent == ScopeConditionId::none();
2952 if !is_outermost_scope && outer_result.candidates.is_empty() {
2953 return ScopeRootCandidates::empty(is_trivial);
2954 }
2955
2956 let (root_target, matches_shadow_host) = if let Some(start) = bounds.start.as_ref() {
2957 if let Some(filter) = context.bloom_filter {
2958 if !start
2963 .hashes
2964 .iter()
2965 .any(|entry| selector_may_match(entry, filter))
2966 {
2967 return ScopeRootCandidates::empty(is_trivial);
2968 }
2969 }
2970 (
2971 ScopeTarget::Selector(&start.selectors),
2972 scope_start_matches_shadow_host(&start.selectors),
2973 )
2974 } else {
2975 let implicit_root = condition_ref.implicit_scope_root;
2976 match implicit_root {
2977 StylistImplicitScopeRoot::Normal(r) => (
2978 ScopeTarget::Implicit(r.element(context.current_host.clone())),
2979 r.matches_shadow_host(),
2980 ),
2981 StylistImplicitScopeRoot::Cached(index) => {
2982 let host = context
2983 .current_host
2984 .expect("Cached implicit scope for light DOM implicit scope");
2985 match E::implicit_scope_for_sheet_in_shadow_root(host, index) {
2986 None => return ScopeRootCandidates::empty(is_trivial),
2987 Some(root) => (
2988 ScopeTarget::Implicit(root.element(context.current_host.clone())),
2989 root.matches_shadow_host(),
2990 ),
2991 }
2992 },
2993 }
2994 };
2995 let matches_shadow_host = override_matches_shadow_host_for_part || matches_shadow_host;
2998
2999 let potential_scope_roots = if is_outermost_scope {
3000 collect_scope_roots(
3001 *element,
3002 None,
3003 context,
3004 &root_target,
3005 matches_shadow_host,
3006 scope_subject_map,
3007 )
3008 } else {
3009 let mut result = vec![];
3010 for activation in outer_result.candidates {
3011 let mut this_result = collect_scope_roots(
3012 *element,
3013 Some(activation.root),
3014 context,
3015 &root_target,
3016 matches_shadow_host,
3017 scope_subject_map,
3018 );
3019 result.append(&mut this_result);
3020 }
3021 result
3022 };
3023
3024 if potential_scope_roots.is_empty() {
3025 return ScopeRootCandidates::empty(is_trivial);
3026 }
3027
3028 let candidates = if let Some(end) = bounds.end.as_ref() {
3029 let mut result = vec![];
3030 for scope_root in potential_scope_roots {
3032 if end
3033 .selectors
3034 .slice()
3035 .iter()
3036 .zip(end.hashes.iter())
3037 .all(|(selector, hashes)| {
3038 if let Some(filter) = context.bloom_filter {
3040 if !selector_may_match(hashes, filter) {
3041 return true;
3043 }
3044 }
3045
3046 !element_is_outside_of_scope(
3047 selector,
3048 *element,
3049 scope_root.root,
3050 context,
3051 matches_shadow_host,
3052 )
3053 })
3054 {
3055 result.push(scope_root);
3056 }
3057 }
3058 result
3059 } else {
3060 potential_scope_roots
3061 };
3062
3063 ScopeRootCandidates {
3064 candidates,
3065 is_trivial,
3066 }
3067}
3068
3069#[derive(Copy, Clone, Debug, MallocSizeOf)]
3072enum StylistImplicitScopeRoot {
3073 Normal(ImplicitScopeRoot),
3074 Cached(usize),
3075}
3076unsafe impl Sync for StylistImplicitScopeRoot {}
3078
3079impl StylistImplicitScopeRoot {
3080 const fn default_const() -> Self {
3081 Self::Normal(ImplicitScopeRoot::DocumentElement)
3083 }
3084}
3085
3086impl Default for StylistImplicitScopeRoot {
3087 fn default() -> Self {
3088 Self::default_const()
3089 }
3090}
3091
3092#[derive(Debug, Clone, MallocSizeOf)]
3098pub struct CascadeData {
3099 normal_rules: ElementAndPseudoRules,
3102
3103 featureless_host_rules: Option<Box<ElementAndPseudoRules>>,
3107
3108 slotted_rules: Option<Box<ElementAndPseudoRules>>,
3116
3117 part_rules: Option<Box<PartElementAndPseudoRules>>,
3122
3123 invalidation_map: InvalidationMap,
3125
3126 relative_selector_invalidation_map: InvalidationMap,
3128
3129 additional_relative_selector_invalidation_map: AdditionalRelativeSelectorInvalidationMap,
3130
3131 attribute_dependencies: PrecomputedHashSet<LocalName>,
3136
3137 nth_of_class_dependencies: PrecomputedHashSet<Atom>,
3141
3142 nth_of_attribute_dependencies: PrecomputedHashSet<LocalName>,
3146
3147 nth_of_custom_state_dependencies: PrecomputedHashSet<AtomIdent>,
3151
3152 state_dependencies: ElementState,
3156
3157 nth_of_state_dependencies: ElementState,
3160
3161 document_state_dependencies: DocumentState,
3165
3166 mapped_ids: PrecomputedHashSet<Atom>,
3171
3172 nth_of_mapped_ids: PrecomputedHashSet<Atom>,
3176
3177 #[ignore_malloc_size_of = "Arc"]
3181 selectors_for_cache_revalidation: SelectorMap<RevalidationSelectorAndHashes>,
3182
3183 animations: LayerOrderedMap<KeyframesAnimation>,
3186
3187 #[ignore_malloc_size_of = "Arc"]
3190 custom_property_registrations: LayerOrderedMap<Arc<PropertyRegistration>>,
3191
3192 custom_media: CustomMediaMap,
3194
3195 layer_id: FxHashMap<LayerName, LayerId>,
3197
3198 layers: SmallVec<[CascadeLayer; 1]>,
3200
3201 container_conditions: SmallVec<[ContainerConditionReference; 1]>,
3203
3204 scope_conditions: SmallVec<[ScopeConditionReference; 1]>,
3206
3207 scope_subject_map: ScopeSubjectMap,
3209
3210 effective_media_query_results: EffectiveMediaQueryResults,
3212
3213 extra_data: ExtraStyleData,
3215
3216 rules_source_order: u32,
3219
3220 num_selectors: usize,
3222
3223 num_declarations: usize,
3225}
3226
3227static IMPLICIT_SCOPE: LazyLock<SelectorList<SelectorImpl>> = LazyLock::new(|| {
3228 let list = SelectorList::implicit_scope();
3232 list.mark_as_intentionally_leaked();
3233 list
3234});
3235
3236fn scope_start_matches_shadow_host(start: &SelectorList<SelectorImpl>) -> bool {
3237 start
3240 .slice()
3241 .iter()
3242 .any(|s| s.matches_featureless_host(true).may_match())
3243}
3244
3245pub fn replace_parent_selector_with_implicit_scope(
3247 selectors: &SelectorList<SelectorImpl>,
3248) -> SelectorList<SelectorImpl> {
3249 selectors.replace_parent_selector(&IMPLICIT_SCOPE)
3250}
3251
3252impl CascadeData {
3253 pub fn new() -> Self {
3255 Self {
3256 normal_rules: ElementAndPseudoRules::default(),
3257 featureless_host_rules: None,
3258 slotted_rules: None,
3259 part_rules: None,
3260 invalidation_map: InvalidationMap::new(),
3261 relative_selector_invalidation_map: InvalidationMap::new(),
3262 additional_relative_selector_invalidation_map:
3263 AdditionalRelativeSelectorInvalidationMap::new(),
3264 nth_of_mapped_ids: PrecomputedHashSet::default(),
3265 nth_of_class_dependencies: PrecomputedHashSet::default(),
3266 nth_of_attribute_dependencies: PrecomputedHashSet::default(),
3267 nth_of_custom_state_dependencies: PrecomputedHashSet::default(),
3268 nth_of_state_dependencies: ElementState::empty(),
3269 attribute_dependencies: PrecomputedHashSet::default(),
3270 state_dependencies: ElementState::empty(),
3271 document_state_dependencies: DocumentState::empty(),
3272 mapped_ids: PrecomputedHashSet::default(),
3273 selectors_for_cache_revalidation: SelectorMap::new(),
3274 animations: Default::default(),
3275 custom_property_registrations: Default::default(),
3276 custom_media: Default::default(),
3277 layer_id: Default::default(),
3278 layers: smallvec::smallvec![CascadeLayer::root()],
3279 container_conditions: smallvec::smallvec![ContainerConditionReference::none()],
3280 scope_conditions: smallvec::smallvec![ScopeConditionReference::none()],
3281 scope_subject_map: Default::default(),
3282 extra_data: ExtraStyleData::default(),
3283 effective_media_query_results: EffectiveMediaQueryResults::new(),
3284 rules_source_order: 0,
3285 num_selectors: 0,
3286 num_declarations: 0,
3287 }
3288 }
3289
3290 pub fn rebuild<'a, S>(
3292 &mut self,
3293 device: &Device,
3294 quirks_mode: QuirksMode,
3295 collection: SheetCollectionFlusher<S>,
3296 guard: &SharedRwLockReadGuard,
3297 difference: &mut CascadeDataDifference,
3298 ) -> Result<(), AllocErr>
3299 where
3300 S: StylesheetInDocument + PartialEq + 'static,
3301 {
3302 if !collection.dirty() {
3303 return Ok(());
3304 }
3305
3306 let validity = collection.data_validity();
3307
3308 let mut old_position_try_data = LayerOrderedMap::default();
3309 if validity != DataValidity::Valid {
3310 old_position_try_data = std::mem::take(&mut self.extra_data.position_try_rules);
3311 self.clear_cascade_data();
3312 if validity == DataValidity::FullyInvalid {
3313 self.clear_invalidation_data();
3314 }
3315 }
3316
3317 let mut result = Ok(());
3318
3319 collection.each(|index, stylesheet, rebuild_kind| {
3320 result = self.add_stylesheet(
3321 device,
3322 quirks_mode,
3323 stylesheet,
3324 index,
3325 guard,
3326 rebuild_kind,
3327 None,
3328 if validity == DataValidity::Valid {
3329 Some(difference)
3330 } else {
3331 None
3332 },
3333 );
3334 result.is_ok()
3335 });
3336
3337 self.did_finish_rebuild();
3338
3339 if validity != DataValidity::Valid {
3342 difference.update(&old_position_try_data, &self.extra_data.position_try_rules);
3343 }
3344
3345 result
3346 }
3347
3348 pub fn custom_media_map(&self) -> &CustomMediaMap {
3350 &self.custom_media
3351 }
3352
3353 pub fn invalidation_map(&self) -> &InvalidationMap {
3355 &self.invalidation_map
3356 }
3357
3358 pub fn relative_selector_invalidation_map(&self) -> &InvalidationMap {
3360 &self.relative_selector_invalidation_map
3361 }
3362
3363 pub fn relative_invalidation_map_attributes(
3365 &self,
3366 ) -> &AdditionalRelativeSelectorInvalidationMap {
3367 &self.additional_relative_selector_invalidation_map
3368 }
3369
3370 #[inline]
3373 pub fn has_state_dependency(&self, state: ElementState) -> bool {
3374 self.state_dependencies.intersects(state)
3375 }
3376
3377 #[inline]
3380 pub fn has_nth_of_custom_state_dependency(&self, state: &AtomIdent) -> bool {
3381 self.nth_of_custom_state_dependencies.contains(state)
3382 }
3383
3384 #[inline]
3387 pub fn has_nth_of_state_dependency(&self, state: ElementState) -> bool {
3388 self.nth_of_state_dependencies.intersects(state)
3389 }
3390
3391 #[inline]
3394 pub fn might_have_attribute_dependency(&self, local_name: &LocalName) -> bool {
3395 self.attribute_dependencies.contains(local_name)
3396 }
3397
3398 #[inline]
3401 pub fn might_have_nth_of_id_dependency(&self, id: &Atom) -> bool {
3402 self.nth_of_mapped_ids.contains(id)
3403 }
3404
3405 #[inline]
3408 pub fn might_have_nth_of_class_dependency(&self, class: &Atom) -> bool {
3409 self.nth_of_class_dependencies.contains(class)
3410 }
3411
3412 #[inline]
3415 pub fn might_have_nth_of_attribute_dependency(&self, local_name: &LocalName) -> bool {
3416 self.nth_of_attribute_dependencies.contains(local_name)
3417 }
3418
3419 #[inline]
3421 pub fn normal_rules(&self, pseudo_elements: &[PseudoElement]) -> Option<&SelectorMap<Rule>> {
3422 self.normal_rules.rules(pseudo_elements)
3423 }
3424
3425 #[inline]
3427 pub fn featureless_host_rules(
3428 &self,
3429 pseudo_elements: &[PseudoElement],
3430 ) -> Option<&SelectorMap<Rule>> {
3431 self.featureless_host_rules
3432 .as_ref()
3433 .and_then(|d| d.rules(pseudo_elements))
3434 }
3435
3436 pub fn any_featureless_host_rules(&self) -> bool {
3438 self.featureless_host_rules.is_some()
3439 }
3440
3441 #[inline]
3443 pub fn slotted_rules(&self, pseudo_elements: &[PseudoElement]) -> Option<&SelectorMap<Rule>> {
3444 self.slotted_rules
3445 .as_ref()
3446 .and_then(|d| d.rules(pseudo_elements))
3447 }
3448
3449 pub fn any_slotted_rule(&self) -> bool {
3451 self.slotted_rules.is_some()
3452 }
3453
3454 #[inline]
3456 pub fn part_rules(&self, pseudo_elements: &[PseudoElement]) -> Option<&PartMap> {
3457 self.part_rules
3458 .as_ref()
3459 .and_then(|d| d.rules(pseudo_elements))
3460 }
3461
3462 pub fn any_part_rule(&self) -> bool {
3464 self.part_rules.is_some()
3465 }
3466
3467 #[inline]
3468 fn layer_order_for(&self, id: LayerId) -> LayerOrder {
3469 self.layers[id.0 as usize].order
3470 }
3471
3472 pub(crate) fn container_condition_matches<E>(
3473 &self,
3474 mut id: ContainerConditionId,
3475 stylist: &Stylist,
3476 element: E,
3477 context: &mut MatchingContext<E::Impl>,
3478 ) -> bool
3479 where
3480 E: TElement,
3481 {
3482 loop {
3483 let condition_ref = &self.container_conditions[id.0 as usize];
3484 let condition = match condition_ref.condition {
3485 None => return true,
3486 Some(ref c) => c,
3487 };
3488 let matches = condition
3489 .matches(
3490 stylist,
3491 element,
3492 context.extra_data.originating_element_style,
3493 &mut context.extra_data.cascade_input_flags,
3494 )
3495 .to_bool(false);
3496 if !matches {
3497 return false;
3498 }
3499 id = condition_ref.parent;
3500 }
3501 }
3502
3503 pub(crate) fn find_scope_proximity_if_matching<E: TElement>(
3504 &self,
3505 rule: &Rule,
3506 element: E,
3507 context: &mut MatchingContext<E::Impl>,
3508 ) -> ScopeProximity {
3509 context
3510 .extra_data
3511 .cascade_input_flags
3512 .insert(ComputedValueFlags::CONSIDERED_NONTRIVIAL_SCOPED_STYLE);
3513
3514 let result = scope_root_candidates(
3518 &self.scope_conditions,
3519 rule.scope_condition_id,
3520 &element,
3521 rule.selector.is_part(),
3522 &self.scope_subject_map,
3523 context,
3524 );
3525 for candidate in result.candidates {
3526 if context.nest_for_scope(Some(candidate.root), |context| {
3527 matches_selector(&rule.selector, 0, Some(&rule.hashes), &element, context)
3528 }) {
3529 return candidate.proximity;
3530 }
3531 }
3532 ScopeProximity::infinity()
3533 }
3534
3535 fn did_finish_rebuild(&mut self) {
3536 self.shrink_maps_if_needed();
3537 self.compute_layer_order();
3538 }
3539
3540 fn shrink_maps_if_needed(&mut self) {
3541 self.normal_rules.shrink_if_needed();
3542 if let Some(ref mut host_rules) = self.featureless_host_rules {
3543 host_rules.shrink_if_needed();
3544 }
3545 if let Some(ref mut slotted_rules) = self.slotted_rules {
3546 slotted_rules.shrink_if_needed();
3547 }
3548 self.animations.shrink_if_needed();
3549 self.custom_property_registrations.shrink_if_needed();
3550 self.invalidation_map.shrink_if_needed();
3551 self.relative_selector_invalidation_map.shrink_if_needed();
3552 self.additional_relative_selector_invalidation_map
3553 .shrink_if_needed();
3554 self.attribute_dependencies.shrink_if_needed();
3555 self.nth_of_attribute_dependencies.shrink_if_needed();
3556 self.nth_of_custom_state_dependencies.shrink_if_needed();
3557 self.nth_of_class_dependencies.shrink_if_needed();
3558 self.nth_of_mapped_ids.shrink_if_needed();
3559 self.mapped_ids.shrink_if_needed();
3560 self.layer_id.shrink_if_needed();
3561 self.selectors_for_cache_revalidation.shrink_if_needed();
3562 self.scope_subject_map.shrink_if_needed();
3563 }
3564
3565 fn compute_layer_order(&mut self) {
3566 debug_assert_ne!(
3567 self.layers.len(),
3568 0,
3569 "There should be at least the root layer!"
3570 );
3571 if self.layers.len() == 1 {
3572 return; }
3574 let (first, remaining) = self.layers.split_at_mut(1);
3575 let root = &mut first[0];
3576 let mut order = LayerOrder::first();
3577 compute_layer_order_for_subtree(root, remaining, &mut order);
3578
3579 fn compute_layer_order_for_subtree(
3582 parent: &mut CascadeLayer,
3583 remaining_layers: &mut [CascadeLayer],
3584 order: &mut LayerOrder,
3585 ) {
3586 for child in parent.children.iter() {
3587 debug_assert!(
3588 parent.id < *child,
3589 "Children are always registered after parents"
3590 );
3591 let child_index = (child.0 - parent.id.0 - 1) as usize;
3592 let (first, remaining) = remaining_layers.split_at_mut(child_index + 1);
3593 let child = &mut first[child_index];
3594 compute_layer_order_for_subtree(child, remaining, order);
3595 }
3596
3597 if parent.id != LayerId::root() {
3598 parent.order = *order;
3599 order.inc();
3600 }
3601 }
3602 self.extra_data.sort_by_layer(&self.layers);
3603 self.animations
3604 .sort_with(&self.layers, compare_keyframes_in_same_layer);
3605 self.custom_property_registrations.sort(&self.layers)
3606 }
3607
3608 fn collect_applicable_media_query_results_into<S>(
3617 device: &Device,
3618 stylesheet: &S,
3619 guard: &SharedRwLockReadGuard,
3620 results: &mut Vec<MediaListKey>,
3621 contents_list: &mut StyleSheetContentList,
3622 custom_media_map: &mut CustomMediaMap,
3623 ) where
3624 S: StylesheetInDocument + 'static,
3625 {
3626 if !stylesheet.enabled() {
3627 return;
3628 }
3629 if !stylesheet.is_effective_for_device(device, &custom_media_map, guard) {
3630 return;
3631 }
3632
3633 debug!(" + {:?}", stylesheet);
3634 let contents = stylesheet.contents(guard);
3635 results.push(contents.to_media_list_key());
3636
3637 contents_list.push(StylesheetContentsPtr(unsafe {
3639 Arc::from_raw_addrefed(&*contents)
3640 }));
3641
3642 let mut iter = stylesheet
3643 .contents(guard)
3644 .effective_rules(device, custom_media_map, guard);
3645 while let Some(rule) = iter.next() {
3646 match *rule {
3647 CssRule::CustomMedia(ref custom_media) => {
3648 iter.custom_media()
3649 .insert(custom_media.name.0.clone(), custom_media.condition.clone());
3650 },
3651 CssRule::Import(ref lock) => {
3652 let import_rule = lock.read_with(guard);
3653 debug!(" + {:?}", import_rule.stylesheet.media(guard));
3654 results.push(import_rule.to_media_list_key());
3655 },
3656 CssRule::Media(ref media_rule) => {
3657 debug!(" + {:?}", media_rule.media_queries.read_with(guard));
3658 results.push(media_rule.to_media_list_key());
3659 },
3660 _ => {},
3661 }
3662 }
3663 }
3664
3665 fn add_styles(
3666 &mut self,
3667 selectors: &SelectorList<SelectorImpl>,
3668 declarations: &Arc<Locked<PropertyDeclarationBlock>>,
3669 ancestor_selectors: Option<&SelectorList<SelectorImpl>>,
3670 containing_rule_state: &ContainingRuleState,
3671 mut replaced_selectors: Option<&mut ReplacedSelectors>,
3672 guard: &SharedRwLockReadGuard,
3673 rebuild_kind: SheetRebuildKind,
3674 mut precomputed_pseudo_element_decls: Option<&mut PrecomputedPseudoElementDeclarations>,
3675 quirks_mode: QuirksMode,
3676 mut collected_scope_dependencies: Option<&mut Vec<Dependency>>,
3677 ) -> Result<(), AllocErr> {
3678 self.num_declarations += declarations.read_with(guard).len();
3679 for selector in selectors.slice() {
3680 self.num_selectors += 1;
3681
3682 let pseudo_elements = selector.pseudo_elements();
3683 let inner_pseudo_element = pseudo_elements.get(0);
3684 if let Some(pseudo) = inner_pseudo_element {
3685 if pseudo.is_precomputed() {
3686 debug_assert!(selector.is_universal());
3687 debug_assert!(ancestor_selectors.is_none());
3688 debug_assert_eq!(containing_rule_state.layer_id, LayerId::root());
3689 debug_assert!(!containing_rule_state.scope_is_effective());
3691 precomputed_pseudo_element_decls
3692 .as_mut()
3693 .expect("Expected precomputed declarations for the UA level")
3694 .get_or_insert_with(pseudo, Vec::new)
3695 .push(ApplicableDeclarationBlock::new(
3696 StyleSource::from_declarations(declarations.clone()),
3697 self.rules_source_order,
3698 CascadeLevel::UANormal,
3699 selector.specificity(),
3700 LayerOrder::root(),
3701 ScopeProximity::infinity(),
3702 ));
3703 continue;
3704 }
3705 if pseudo_elements
3706 .iter()
3707 .any(|p| p.is_unknown_webkit_pseudo_element())
3708 {
3709 continue;
3710 }
3711 }
3712
3713 debug_assert!(!pseudo_elements
3714 .iter()
3715 .any(|p| p.is_precomputed() || p.is_unknown_webkit_pseudo_element()));
3716
3717 let selector = match ancestor_selectors {
3718 Some(ref s) => selector.replace_parent_selector(&s),
3719 None => selector.clone(),
3720 };
3721
3722 let hashes = AncestorHashes::new(&selector, quirks_mode);
3723
3724 let rule = Rule::new(
3725 selector,
3726 hashes,
3727 StyleSource::from_declarations(declarations.clone()),
3728 self.rules_source_order,
3729 containing_rule_state.layer_id,
3730 containing_rule_state.container_condition_id,
3731 containing_rule_state.in_starting_style,
3732 containing_rule_state.containing_scope_rule_state.id,
3733 );
3734
3735 if let Some(ref mut replaced_selectors) = replaced_selectors {
3736 replaced_selectors.push(rule.selector.clone())
3737 }
3738
3739 if rebuild_kind.should_rebuild_invalidation() {
3740 let mut scope_dependencies = note_selector_for_invalidation(
3741 &rule.selector,
3742 quirks_mode,
3743 &mut self.invalidation_map,
3744 &mut self.relative_selector_invalidation_map,
3745 &mut self.additional_relative_selector_invalidation_map,
3746 None,
3747 None,
3748 )?;
3749 let mut needs_revalidation = false;
3750 let mut visitor = StylistSelectorVisitor {
3751 needs_revalidation: &mut needs_revalidation,
3752 passed_rightmost_selector: false,
3753 in_selector_list_of: SelectorListKind::default(),
3754 mapped_ids: &mut self.mapped_ids,
3755 nth_of_mapped_ids: &mut self.nth_of_mapped_ids,
3756 attribute_dependencies: &mut self.attribute_dependencies,
3757 nth_of_class_dependencies: &mut self.nth_of_class_dependencies,
3758 nth_of_attribute_dependencies: &mut self.nth_of_attribute_dependencies,
3759 nth_of_custom_state_dependencies: &mut self.nth_of_custom_state_dependencies,
3760 state_dependencies: &mut self.state_dependencies,
3761 nth_of_state_dependencies: &mut self.nth_of_state_dependencies,
3762 document_state_dependencies: &mut self.document_state_dependencies,
3763 };
3764 rule.selector.visit(&mut visitor);
3765
3766 if needs_revalidation {
3767 self.selectors_for_cache_revalidation.insert(
3768 RevalidationSelectorAndHashes::new(
3769 rule.selector.clone(),
3770 rule.hashes.clone(),
3771 ),
3772 quirks_mode,
3773 )?;
3774 }
3775
3776 match (
3777 scope_dependencies.as_mut(),
3778 collected_scope_dependencies.as_mut(),
3779 ) {
3780 (Some(inner_scope_deps), Some(scope_deps)) => {
3781 scope_deps.append(inner_scope_deps)
3782 },
3783 _ => {},
3784 }
3785 }
3786
3787 if let Some(parts) = rule.selector.parts() {
3791 let map = self
3798 .part_rules
3799 .get_or_insert_with(|| Box::new(Default::default()))
3800 .for_insertion(&pseudo_elements);
3801 map.try_reserve(1)?;
3802 let vec = map.entry(parts.last().unwrap().clone().0).or_default();
3803 vec.try_reserve(1)?;
3804 vec.push(rule);
3805 } else {
3806 let scope_matches_shadow_host = containing_rule_state
3807 .containing_scope_rule_state
3808 .matches_shadow_host
3809 == ScopeMatchesShadowHost::Yes;
3810 let matches_featureless_host_only = match rule
3811 .selector
3812 .matches_featureless_host(scope_matches_shadow_host)
3813 {
3814 MatchesFeaturelessHost::Only => true,
3815 MatchesFeaturelessHost::Yes => {
3816 self.featureless_host_rules
3818 .get_or_insert_with(|| Box::new(Default::default()))
3819 .for_insertion(&pseudo_elements)
3820 .insert(rule.clone(), quirks_mode)?;
3821 false
3822 },
3823 MatchesFeaturelessHost::Never => false,
3824 };
3825
3826 let rules = if matches_featureless_host_only {
3833 self.featureless_host_rules
3834 .get_or_insert_with(|| Box::new(Default::default()))
3835 } else if rule.selector.is_slotted() {
3836 self.slotted_rules
3837 .get_or_insert_with(|| Box::new(Default::default()))
3838 } else {
3839 &mut self.normal_rules
3840 }
3841 .for_insertion(&pseudo_elements);
3842 rules.insert(rule, quirks_mode)?;
3843 }
3844 }
3845 self.rules_source_order += 1;
3846 Ok(())
3847 }
3848
3849 fn add_rule_list<S>(
3850 &mut self,
3851 rules: std::slice::Iter<CssRule>,
3852 device: &Device,
3853 quirks_mode: QuirksMode,
3854 stylesheet: &S,
3855 sheet_index: usize,
3856 guard: &SharedRwLockReadGuard,
3857 rebuild_kind: SheetRebuildKind,
3858 containing_rule_state: &mut ContainingRuleState,
3859 mut precomputed_pseudo_element_decls: Option<&mut PrecomputedPseudoElementDeclarations>,
3860 mut difference: Option<&mut CascadeDataDifference>,
3861 ) -> Result<(), AllocErr>
3862 where
3863 S: StylesheetInDocument + 'static,
3864 {
3865 for rule in rules {
3866 let mut handled = true;
3869 let mut list_for_nested_rules = None;
3870 match *rule {
3871 CssRule::Style(ref locked) => {
3872 let style_rule = locked.read_with(guard);
3873 let has_nested_rules = style_rule.rules.is_some();
3874 let mut replaced_selectors = ReplacedSelectors::new();
3875 let ancestor_selectors = containing_rule_state.ancestor_selector_lists.last();
3876 let collect_replaced_selectors =
3877 has_nested_rules && ancestor_selectors.is_some();
3878 let mut inner_dependencies: Option<Vec<Dependency>> = containing_rule_state
3879 .scope_is_effective()
3880 .then(|| Vec::new());
3881 self.add_styles(
3882 &style_rule.selectors,
3883 &style_rule.block,
3884 ancestor_selectors,
3885 containing_rule_state,
3886 if collect_replaced_selectors {
3887 Some(&mut replaced_selectors)
3888 } else {
3889 None
3890 },
3891 guard,
3892 rebuild_kind,
3893 precomputed_pseudo_element_decls.as_deref_mut(),
3894 quirks_mode,
3895 inner_dependencies.as_mut(),
3896 )?;
3897 if let Some(mut scope_dependencies) = inner_dependencies {
3898 containing_rule_state
3899 .containing_scope_rule_state
3900 .inner_dependencies
3901 .append(&mut scope_dependencies);
3902 }
3903 if has_nested_rules {
3904 handled = false;
3905 list_for_nested_rules = Some(if collect_replaced_selectors {
3906 SelectorList::from_iter(replaced_selectors.drain(..))
3907 } else {
3908 style_rule.selectors.clone()
3909 });
3910 }
3911 },
3912 CssRule::NestedDeclarations(ref rule) => {
3913 if let Some(ref ancestor_selectors) =
3914 containing_rule_state.ancestor_selector_lists.last()
3915 {
3916 let decls = &rule.read_with(guard).block;
3917 let selectors = match containing_rule_state.nested_declarations_context {
3918 NestedDeclarationsContext::Style => ancestor_selectors,
3919 NestedDeclarationsContext::Scope => &*IMPLICIT_SCOPE,
3920 };
3921 let mut inner_dependencies: Option<Vec<Dependency>> = containing_rule_state
3922 .scope_is_effective()
3923 .then(|| Vec::new());
3924 self.add_styles(
3925 selectors,
3926 decls,
3927 None,
3928 containing_rule_state,
3929 None,
3930 guard,
3931 SheetRebuildKind::CascadeOnly,
3934 precomputed_pseudo_element_decls.as_deref_mut(),
3935 quirks_mode,
3936 inner_dependencies.as_mut(),
3937 )?;
3938 if let Some(mut scope_dependencies) = inner_dependencies {
3939 containing_rule_state
3940 .containing_scope_rule_state
3941 .inner_dependencies
3942 .append(&mut scope_dependencies);
3943 }
3944 }
3945 },
3946 CssRule::Keyframes(ref keyframes_rule) => {
3947 debug!("Found valid keyframes rule: {:?}", *keyframes_rule);
3948 let keyframes_rule = keyframes_rule.read_with(guard);
3949 let name = keyframes_rule.name.as_atom().clone();
3950 let animation = KeyframesAnimation::from_keyframes(
3951 &keyframes_rule.keyframes,
3952 keyframes_rule.vendor_prefix.clone(),
3953 guard,
3954 );
3955 self.animations.try_insert_with(
3956 name,
3957 animation,
3958 containing_rule_state.layer_id,
3959 compare_keyframes_in_same_layer,
3960 )?;
3961 },
3962 CssRule::Property(ref registration) => {
3963 self.custom_property_registrations.try_insert(
3964 registration.name.0.clone(),
3965 Arc::clone(registration),
3966 containing_rule_state.layer_id,
3967 )?;
3968 },
3969 CssRule::FontFace(ref rule) => {
3970 self.extra_data
3981 .add_font_face(rule, containing_rule_state.layer_id);
3982 },
3983 CssRule::FontFeatureValues(ref rule) => {
3984 self.extra_data
3985 .add_font_feature_values(rule, containing_rule_state.layer_id);
3986 },
3987 CssRule::FontPaletteValues(ref rule) => {
3988 self.extra_data
3989 .add_font_palette_values(rule, containing_rule_state.layer_id);
3990 },
3991 CssRule::CounterStyle(ref rule) => {
3992 self.extra_data.add_counter_style(
3993 guard,
3994 rule,
3995 containing_rule_state.layer_id,
3996 )?;
3997 },
3998 CssRule::PositionTry(ref rule) => {
3999 let name = rule.read_with(guard).name.0.clone();
4000 if let Some(ref mut difference) = difference {
4001 difference.changed_position_try_names.insert(name.clone());
4002 }
4003 self.extra_data.add_position_try(
4004 name,
4005 rule.clone(),
4006 containing_rule_state.layer_id,
4007 )?;
4008 },
4009 CssRule::Page(ref rule) => {
4010 self.extra_data
4011 .add_page(guard, rule, containing_rule_state.layer_id)?;
4012 handled = false;
4013 },
4014 _ => {
4015 handled = false;
4016 },
4017 }
4018
4019 if handled {
4020 if cfg!(debug_assertions) {
4023 let mut effective = false;
4024 let children = EffectiveRulesIterator::<&CustomMediaMap>::children(
4025 rule,
4026 device,
4027 quirks_mode,
4028 &self.custom_media,
4029 guard,
4030 &mut effective,
4031 );
4032 debug_assert!(children.is_none());
4033 debug_assert!(effective);
4034 }
4035 continue;
4036 }
4037
4038 let mut effective = false;
4039 let children = EffectiveRulesIterator::<&CustomMediaMap>::children(
4040 rule,
4041 device,
4042 quirks_mode,
4043 &self.custom_media,
4044 guard,
4045 &mut effective,
4046 );
4047 if !effective {
4048 continue;
4049 }
4050
4051 fn maybe_register_layer(data: &mut CascadeData, layer: &LayerName) -> LayerId {
4052 if let Some(id) = data.layer_id.get(layer) {
4056 return *id;
4057 }
4058 let id = LayerId(data.layers.len() as u16);
4059
4060 let parent_layer_id = if layer.layer_names().len() > 1 {
4061 let mut parent = layer.clone();
4062 parent.0.pop();
4063
4064 *data
4065 .layer_id
4066 .get_mut(&parent)
4067 .expect("Parent layers should be registered before child layers")
4068 } else {
4069 LayerId::root()
4070 };
4071
4072 data.layers[parent_layer_id.0 as usize].children.push(id);
4073 data.layers.push(CascadeLayer {
4074 id,
4075 order: LayerOrder::first(),
4078 children: vec![],
4079 });
4080
4081 data.layer_id.insert(layer.clone(), id);
4082
4083 id
4084 }
4085
4086 fn maybe_register_layers(
4087 data: &mut CascadeData,
4088 name: Option<&LayerName>,
4089 containing_rule_state: &mut ContainingRuleState,
4090 ) {
4091 let anon_name;
4092 let name = match name {
4093 Some(name) => name,
4094 None => {
4095 anon_name = LayerName::new_anonymous();
4096 &anon_name
4097 },
4098 };
4099 for name in name.layer_names() {
4100 containing_rule_state.layer_name.0.push(name.clone());
4101 containing_rule_state.layer_id =
4102 maybe_register_layer(data, &containing_rule_state.layer_name);
4103 }
4104 debug_assert_ne!(containing_rule_state.layer_id, LayerId::root());
4105 }
4106
4107 let saved_containing_rule_state = containing_rule_state.save();
4108 match *rule {
4109 CssRule::Import(ref lock) => {
4110 let import_rule = lock.read_with(guard);
4111 if rebuild_kind.should_rebuild_invalidation() {
4112 self.effective_media_query_results
4113 .saw_effective(import_rule);
4114 }
4115 match import_rule.layer {
4116 ImportLayer::Named(ref name) => {
4117 maybe_register_layers(self, Some(name), containing_rule_state)
4118 },
4119 ImportLayer::Anonymous => {
4120 maybe_register_layers(self, None, containing_rule_state)
4121 },
4122 ImportLayer::None => {},
4123 }
4124 },
4125 CssRule::Media(ref media_rule) => {
4126 if rebuild_kind.should_rebuild_invalidation() {
4127 self.effective_media_query_results
4128 .saw_effective(&**media_rule);
4129 }
4130 },
4131 CssRule::LayerBlock(ref rule) => {
4132 maybe_register_layers(self, rule.name.as_ref(), containing_rule_state);
4133 },
4134 CssRule::CustomMedia(ref custom_media) => {
4135 self.custom_media
4136 .insert(custom_media.name.0.clone(), custom_media.condition.clone());
4137 },
4138 CssRule::LayerStatement(ref rule) => {
4139 for name in &*rule.names {
4140 maybe_register_layers(self, Some(name), containing_rule_state);
4141 containing_rule_state.restore(&saved_containing_rule_state);
4143 }
4144 },
4145 CssRule::Style(..) => {
4146 containing_rule_state.nested_declarations_context =
4147 NestedDeclarationsContext::Style;
4148 if let Some(s) = list_for_nested_rules {
4149 containing_rule_state.ancestor_selector_lists.push(s);
4150 }
4151 },
4152 CssRule::Container(ref rule) => {
4153 let id = ContainerConditionId(self.container_conditions.len() as u16);
4154 self.container_conditions.push(ContainerConditionReference {
4155 parent: containing_rule_state.container_condition_id,
4156 condition: Some(rule.condition.clone()),
4157 });
4158 containing_rule_state.container_condition_id = id;
4159 },
4160 CssRule::StartingStyle(..) => {
4161 containing_rule_state.in_starting_style = true;
4162 },
4163 CssRule::Scope(ref rule) => {
4164 containing_rule_state.nested_declarations_context =
4165 NestedDeclarationsContext::Scope;
4166 let id = ScopeConditionId(self.scope_conditions.len() as u16);
4167 let mut matches_shadow_host = false;
4168 let implicit_scope_root = if let Some(start) = rule.bounds.start.as_ref() {
4169 matches_shadow_host = scope_start_matches_shadow_host(start);
4170 StylistImplicitScopeRoot::default()
4172 } else {
4173 if let Some(root) = stylesheet.implicit_scope_root() {
4176 matches_shadow_host = root.matches_shadow_host();
4177 match root {
4178 ImplicitScopeRoot::InLightTree(_)
4179 | ImplicitScopeRoot::Constructed
4180 | ImplicitScopeRoot::DocumentElement => {
4181 StylistImplicitScopeRoot::Normal(root)
4182 },
4183 ImplicitScopeRoot::ShadowHost(_)
4184 | ImplicitScopeRoot::InShadowTree(_) => {
4185 StylistImplicitScopeRoot::Cached(sheet_index)
4192 },
4193 }
4194 } else {
4195 StylistImplicitScopeRoot::default()
4197 }
4198 };
4199
4200 let replaced =
4201 {
4202 let start = rule.bounds.start.as_ref().map(|selector| {
4203 match containing_rule_state.ancestor_selector_lists.last() {
4204 Some(s) => selector.replace_parent_selector(s),
4205 None => selector.clone(),
4206 }
4207 });
4208 let implicit_scope_selector = &*IMPLICIT_SCOPE;
4209 let end = rule.bounds.end.as_ref().map(|selector| {
4210 selector.replace_parent_selector(implicit_scope_selector)
4211 });
4212 containing_rule_state
4213 .ancestor_selector_lists
4214 .push(implicit_scope_selector.clone());
4215 ScopeBoundsWithHashes::new(quirks_mode, start, end)
4216 };
4217
4218 if let Some(selectors) = replaced.start.as_ref() {
4219 self.scope_subject_map
4220 .add_bound_start(&selectors.selectors, quirks_mode);
4221 }
4222
4223 let is_trivial = replaced.is_trivial();
4224 self.scope_conditions.push(ScopeConditionReference {
4225 parent: containing_rule_state.containing_scope_rule_state.id,
4226 condition: Some(replaced),
4227 implicit_scope_root,
4228 is_trivial,
4229 });
4230
4231 containing_rule_state
4232 .containing_scope_rule_state
4233 .matches_shadow_host
4234 .nest_for_scope(matches_shadow_host);
4235 containing_rule_state.containing_scope_rule_state.id = id;
4236 containing_rule_state
4237 .containing_scope_rule_state
4238 .inner_dependencies
4239 .reserve(children.iter().len());
4240 },
4241 _ => {},
4243 }
4244
4245 if let Some(children) = children {
4246 self.add_rule_list(
4247 children,
4248 device,
4249 quirks_mode,
4250 stylesheet,
4251 sheet_index,
4252 guard,
4253 rebuild_kind,
4254 containing_rule_state,
4255 precomputed_pseudo_element_decls.as_deref_mut(),
4256 difference.as_deref_mut(),
4257 )?;
4258 }
4259
4260 if let Some(scope_restore_data) =
4261 containing_rule_state.restore(&saved_containing_rule_state)
4262 {
4263 let (cur_scope_inner_dependencies, scope_idx) = scope_restore_data;
4264 let cur_scope = &self.scope_conditions[scope_idx.0 as usize];
4265 if let Some(cond) = cur_scope.condition.as_ref() {
4266 let mut _unused = false;
4267 let visitor = StylistSelectorVisitor {
4268 needs_revalidation: &mut _unused,
4269 passed_rightmost_selector: true,
4270 in_selector_list_of: SelectorListKind::default(),
4271 mapped_ids: &mut self.mapped_ids,
4272 nth_of_mapped_ids: &mut self.nth_of_mapped_ids,
4273 attribute_dependencies: &mut self.attribute_dependencies,
4274 nth_of_class_dependencies: &mut self.nth_of_class_dependencies,
4275 nth_of_attribute_dependencies: &mut self.nth_of_attribute_dependencies,
4276 nth_of_custom_state_dependencies: &mut self
4277 .nth_of_custom_state_dependencies,
4278 state_dependencies: &mut self.state_dependencies,
4279 nth_of_state_dependencies: &mut self.nth_of_state_dependencies,
4280 document_state_dependencies: &mut self.document_state_dependencies,
4281 };
4282
4283 let dependency_vector = build_scope_dependencies(
4284 quirks_mode,
4285 cur_scope_inner_dependencies,
4286 visitor,
4287 cond,
4288 &mut self.invalidation_map,
4289 &mut self.relative_selector_invalidation_map,
4290 &mut self.additional_relative_selector_invalidation_map,
4291 )?;
4292
4293 containing_rule_state
4294 .containing_scope_rule_state
4295 .inner_dependencies
4296 .extend(dependency_vector);
4297 }
4298 }
4299 }
4300
4301 Ok(())
4302 }
4303
4304 fn add_stylesheet<S>(
4306 &mut self,
4307 device: &Device,
4308 quirks_mode: QuirksMode,
4309 stylesheet: &S,
4310 sheet_index: usize,
4311 guard: &SharedRwLockReadGuard,
4312 rebuild_kind: SheetRebuildKind,
4313 mut precomputed_pseudo_element_decls: Option<&mut PrecomputedPseudoElementDeclarations>,
4314 mut difference: Option<&mut CascadeDataDifference>,
4315 ) -> Result<(), AllocErr>
4316 where
4317 S: StylesheetInDocument + 'static,
4318 {
4319 if !stylesheet.enabled() {
4320 return Ok(());
4321 }
4322
4323 if !stylesheet.is_effective_for_device(device, &self.custom_media, guard) {
4324 return Ok(());
4325 }
4326
4327 let contents = stylesheet.contents(guard);
4328 if rebuild_kind.should_rebuild_invalidation() {
4329 self.effective_media_query_results.saw_effective(&*contents);
4330 }
4331
4332 let mut state = ContainingRuleState::default();
4333 self.add_rule_list(
4334 contents.rules(guard).iter(),
4335 device,
4336 quirks_mode,
4337 stylesheet,
4338 sheet_index,
4339 guard,
4340 rebuild_kind,
4341 &mut state,
4342 precomputed_pseudo_element_decls.as_deref_mut(),
4343 difference.as_deref_mut(),
4344 )?;
4345
4346 Ok(())
4347 }
4348
4349 pub fn media_feature_affected_matches<S>(
4352 &self,
4353 stylesheet: &S,
4354 guard: &SharedRwLockReadGuard,
4355 device: &Device,
4356 quirks_mode: QuirksMode,
4357 ) -> bool
4358 where
4359 S: StylesheetInDocument + 'static,
4360 {
4361 use crate::invalidation::media_queries::PotentiallyEffectiveMediaRules;
4362
4363 let effective_now = stylesheet.is_effective_for_device(device, &self.custom_media, guard);
4364
4365 let contents = stylesheet.contents(guard);
4366 let effective_then = self.effective_media_query_results.was_effective(contents);
4367
4368 if effective_now != effective_then {
4369 debug!(
4370 " > Stylesheet {:?} changed -> {}, {}",
4371 stylesheet.media(guard),
4372 effective_then,
4373 effective_now
4374 );
4375 return false;
4376 }
4377
4378 if !effective_now {
4379 return true;
4380 }
4381
4382 let custom_media = CustomMediaMap::default();
4384 let mut iter =
4385 contents.iter_rules::<PotentiallyEffectiveMediaRules, _>(device, &custom_media, guard);
4386 while let Some(rule) = iter.next() {
4387 match *rule {
4388 CssRule::Style(..)
4389 | CssRule::NestedDeclarations(..)
4390 | CssRule::Namespace(..)
4391 | CssRule::FontFace(..)
4392 | CssRule::Container(..)
4393 | CssRule::CounterStyle(..)
4394 | CssRule::Supports(..)
4395 | CssRule::Keyframes(..)
4396 | CssRule::Margin(..)
4397 | CssRule::Page(..)
4398 | CssRule::Property(..)
4399 | CssRule::Document(..)
4400 | CssRule::LayerBlock(..)
4401 | CssRule::LayerStatement(..)
4402 | CssRule::FontPaletteValues(..)
4403 | CssRule::FontFeatureValues(..)
4404 | CssRule::Scope(..)
4405 | CssRule::StartingStyle(..)
4406 | CssRule::CustomMedia(..)
4407 | CssRule::PositionTry(..) => {
4408 continue;
4411 },
4412 CssRule::Import(ref lock) => {
4413 let import_rule = lock.read_with(guard);
4414 let effective_now = match import_rule.stylesheet.media(guard) {
4415 Some(m) => m.evaluate(
4416 device,
4417 quirks_mode,
4418 &mut CustomMediaEvaluator::new(&self.custom_media, guard),
4419 ),
4420 None => true,
4421 };
4422 let effective_then = self
4423 .effective_media_query_results
4424 .was_effective(import_rule);
4425 if effective_now != effective_then {
4426 debug!(
4427 " > @import rule {:?} changed {} -> {}",
4428 import_rule.stylesheet.media(guard),
4429 effective_then,
4430 effective_now
4431 );
4432 return false;
4433 }
4434
4435 if !effective_now {
4436 iter.skip_children();
4437 }
4438 },
4439 CssRule::Media(ref media_rule) => {
4440 let mq = media_rule.media_queries.read_with(guard);
4441 let effective_now = mq.evaluate(
4442 device,
4443 quirks_mode,
4444 &mut CustomMediaEvaluator::new(&self.custom_media, guard),
4445 );
4446 let effective_then = self
4447 .effective_media_query_results
4448 .was_effective(&**media_rule);
4449
4450 if effective_now != effective_then {
4451 debug!(
4452 " > @media rule {:?} changed {} -> {}",
4453 mq, effective_then, effective_now
4454 );
4455 return false;
4456 }
4457
4458 if !effective_now {
4459 iter.skip_children();
4460 }
4461 },
4462 }
4463 }
4464
4465 true
4466 }
4467
4468 pub fn custom_property_registrations(&self) -> &LayerOrderedMap<Arc<PropertyRegistration>> {
4470 &self.custom_property_registrations
4471 }
4472
4473 fn revalidate_scopes<E: TElement>(
4474 &self,
4475 element: &E,
4476 matching_context: &mut MatchingContext<E::Impl>,
4477 result: &mut ScopeRevalidationResult,
4478 ) {
4479 for condition_id in 1..self.scope_conditions.len() {
4486 let condition = &self.scope_conditions[condition_id];
4487 let matches = if condition.is_trivial {
4488 continue;
4491 } else {
4492 let result = scope_root_candidates(
4493 &self.scope_conditions,
4494 ScopeConditionId(condition_id as u16),
4495 element,
4496 false,
4498 &self.scope_subject_map,
4499 matching_context,
4500 );
4501 !result.candidates.is_empty()
4502 };
4503 result.scopes_matched.push(matches);
4504 }
4505 }
4506
4507 fn clear_cascade_data(&mut self) {
4509 self.normal_rules.clear();
4510 if let Some(ref mut slotted_rules) = self.slotted_rules {
4511 slotted_rules.clear();
4512 }
4513 if let Some(ref mut part_rules) = self.part_rules {
4514 part_rules.clear();
4515 }
4516 if let Some(ref mut host_rules) = self.featureless_host_rules {
4517 host_rules.clear();
4518 }
4519 self.animations.clear();
4520 self.custom_property_registrations.clear();
4521 self.layer_id.clear();
4522 self.layers.clear();
4523 self.layers.push(CascadeLayer::root());
4524 self.custom_media.clear();
4525 self.container_conditions.clear();
4526 self.container_conditions
4527 .push(ContainerConditionReference::none());
4528 self.scope_conditions.clear();
4529 self.scope_conditions.push(ScopeConditionReference::none());
4530 self.extra_data.clear();
4531 self.rules_source_order = 0;
4532 self.num_selectors = 0;
4533 self.num_declarations = 0;
4534 }
4535
4536 fn clear_invalidation_data(&mut self) {
4537 self.invalidation_map.clear();
4538 self.relative_selector_invalidation_map.clear();
4539 self.additional_relative_selector_invalidation_map.clear();
4540 self.attribute_dependencies.clear();
4541 self.nth_of_attribute_dependencies.clear();
4542 self.nth_of_custom_state_dependencies.clear();
4543 self.nth_of_class_dependencies.clear();
4544 self.state_dependencies = ElementState::empty();
4545 self.nth_of_state_dependencies = ElementState::empty();
4546 self.document_state_dependencies = DocumentState::empty();
4547 self.mapped_ids.clear();
4548 self.nth_of_mapped_ids.clear();
4549 self.selectors_for_cache_revalidation.clear();
4550 self.effective_media_query_results.clear();
4551 self.scope_subject_map.clear();
4552 }
4553}
4554
4555fn note_scope_selector_for_invalidation(
4556 quirks_mode: QuirksMode,
4557 scope_dependencies: &Arc<servo_arc::HeaderSlice<(), Dependency>>,
4558 dependency_vector: &mut Vec<Dependency>,
4559 invalidation_map: &mut InvalidationMap,
4560 relative_selector_invalidation_map: &mut InvalidationMap,
4561 additional_relative_selector_invalidation_map: &mut AdditionalRelativeSelectorInvalidationMap,
4562 visitor: &mut StylistSelectorVisitor<'_>,
4563 scope_kind: ScopeDependencyInvalidationKind,
4564 s: &Selector<SelectorImpl>,
4565) -> Result<(), AllocErr> {
4566 let mut new_inner_dependencies = note_selector_for_invalidation(
4567 &s.clone(),
4568 quirks_mode,
4569 invalidation_map,
4570 relative_selector_invalidation_map,
4571 additional_relative_selector_invalidation_map,
4572 Some(&scope_dependencies),
4573 Some(scope_kind),
4574 )?;
4575 s.visit(visitor);
4576 new_inner_dependencies.as_mut().map(|dep| {
4577 dependency_vector.append(dep);
4578 });
4579 Ok(())
4580}
4581
4582fn build_scope_dependencies(
4583 quirks_mode: QuirksMode,
4584 mut cur_scope_inner_dependencies: Vec<Dependency>,
4585 mut visitor: StylistSelectorVisitor<'_>,
4586 cond: &ScopeBoundsWithHashes,
4587 mut invalidation_map: &mut InvalidationMap,
4588 mut relative_selector_invalidation_map: &mut InvalidationMap,
4589 mut additional_relative_selector_invalidation_map: &mut AdditionalRelativeSelectorInvalidationMap,
4590) -> Result<Vec<Dependency>, AllocErr> {
4591 if cond.end.is_some() {
4592 let deps =
4593 ThinArc::from_header_and_iter((), cur_scope_inner_dependencies.clone().into_iter());
4594 let mut end_dependency_vector = Vec::new();
4595 for s in cond.end_selectors() {
4596 note_scope_selector_for_invalidation(
4597 quirks_mode,
4598 &deps,
4599 &mut end_dependency_vector,
4600 &mut invalidation_map,
4601 &mut relative_selector_invalidation_map,
4602 &mut additional_relative_selector_invalidation_map,
4603 &mut visitor,
4604 ScopeDependencyInvalidationKind::ScopeEnd,
4605 s,
4606 )?;
4607 }
4608 cur_scope_inner_dependencies.append(&mut end_dependency_vector);
4609 }
4610 let inner_scope_dependencies =
4611 ThinArc::from_header_and_iter((), cur_scope_inner_dependencies.into_iter());
4612
4613 Ok(if cond.start.is_some() {
4614 let mut dependency_vector = Vec::new();
4615 for s in cond.start_selectors() {
4616 note_scope_selector_for_invalidation(
4617 quirks_mode,
4618 &inner_scope_dependencies,
4619 &mut dependency_vector,
4620 &mut invalidation_map,
4621 &mut relative_selector_invalidation_map,
4622 &mut additional_relative_selector_invalidation_map,
4623 &mut visitor,
4624 ScopeDependencyInvalidationKind::ExplicitScope,
4625 s,
4626 )?;
4627 }
4628 dependency_vector
4629 } else {
4630 vec![Dependency::new(
4631 IMPLICIT_SCOPE.slice()[0].clone(),
4632 0,
4633 Some(inner_scope_dependencies),
4634 DependencyInvalidationKind::Scope(ScopeDependencyInvalidationKind::ImplicitScope),
4635 )]
4636 })
4637}
4638
4639impl CascadeDataCacheEntry for CascadeData {
4640 fn rebuild<S>(
4641 device: &Device,
4642 quirks_mode: QuirksMode,
4643 collection: SheetCollectionFlusher<S>,
4644 guard: &SharedRwLockReadGuard,
4645 old: &Self,
4646 difference: &mut CascadeDataDifference,
4647 ) -> Result<Arc<Self>, AllocErr>
4648 where
4649 S: StylesheetInDocument + PartialEq + 'static,
4650 {
4651 debug_assert!(collection.dirty(), "We surely need to do something?");
4652 let mut updatable_entry = match collection.data_validity() {
4654 DataValidity::Valid | DataValidity::CascadeInvalid => old.clone(),
4655 DataValidity::FullyInvalid => Self::new(),
4656 };
4657 updatable_entry.rebuild(device, quirks_mode, collection, guard, difference)?;
4658 Ok(Arc::new(updatable_entry))
4659 }
4660
4661 #[cfg(feature = "gecko")]
4662 fn add_size_of(&self, ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes) {
4663 self.normal_rules.add_size_of(ops, sizes);
4664 if let Some(ref slotted_rules) = self.slotted_rules {
4665 slotted_rules.add_size_of(ops, sizes);
4666 }
4667 if let Some(ref part_rules) = self.part_rules {
4668 part_rules.add_size_of(ops, sizes);
4669 }
4670 if let Some(ref host_rules) = self.featureless_host_rules {
4671 host_rules.add_size_of(ops, sizes);
4672 }
4673 sizes.mInvalidationMap += self.invalidation_map.size_of(ops);
4674 sizes.mRevalidationSelectors += self.selectors_for_cache_revalidation.size_of(ops);
4675 sizes.mOther += self.animations.size_of(ops);
4676 sizes.mOther += self.effective_media_query_results.size_of(ops);
4677 sizes.mOther += self.extra_data.size_of(ops);
4678 }
4679}
4680
4681impl Default for CascadeData {
4682 fn default() -> Self {
4683 CascadeData::new()
4684 }
4685}
4686
4687#[derive(Clone, Debug, MallocSizeOf)]
4690pub struct Rule {
4691 #[ignore_malloc_size_of = "CssRules have primary refs, we measure there"]
4696 pub selector: Selector<SelectorImpl>,
4697
4698 pub hashes: AncestorHashes,
4700
4701 pub source_order: u32,
4705
4706 pub layer_id: LayerId,
4708
4709 pub container_condition_id: ContainerConditionId,
4711
4712 pub is_starting_style: bool,
4714
4715 pub scope_condition_id: ScopeConditionId,
4717
4718 #[ignore_malloc_size_of = "Secondary ref. Primary ref is in StyleRule under Stylesheet."]
4720 pub style_source: StyleSource,
4721}
4722
4723impl SelectorMapEntry for Rule {
4724 fn selector(&self) -> SelectorIter<'_, SelectorImpl> {
4725 self.selector.iter()
4726 }
4727}
4728
4729impl Rule {
4730 pub fn specificity(&self) -> u32 {
4732 self.selector.specificity()
4733 }
4734
4735 pub fn to_applicable_declaration_block(
4738 &self,
4739 level: CascadeLevel,
4740 cascade_data: &CascadeData,
4741 scope_proximity: ScopeProximity,
4742 ) -> ApplicableDeclarationBlock {
4743 ApplicableDeclarationBlock::new(
4744 self.style_source.clone(),
4745 self.source_order,
4746 level,
4747 self.specificity(),
4748 cascade_data.layer_order_for(self.layer_id),
4749 scope_proximity,
4750 )
4751 }
4752
4753 pub fn new(
4755 selector: Selector<SelectorImpl>,
4756 hashes: AncestorHashes,
4757 style_source: StyleSource,
4758 source_order: u32,
4759 layer_id: LayerId,
4760 container_condition_id: ContainerConditionId,
4761 is_starting_style: bool,
4762 scope_condition_id: ScopeConditionId,
4763 ) -> Self {
4764 Self {
4765 selector,
4766 hashes,
4767 style_source,
4768 source_order,
4769 layer_id,
4770 container_condition_id,
4771 is_starting_style,
4772 scope_condition_id,
4773 }
4774 }
4775}
4776
4777size_of_test!(Rule, 40);
4782
4783pub fn needs_revalidation_for_testing(s: &Selector<SelectorImpl>) -> bool {
4785 let mut needs_revalidation = false;
4786 let mut mapped_ids = Default::default();
4787 let mut nth_of_mapped_ids = Default::default();
4788 let mut attribute_dependencies = Default::default();
4789 let mut nth_of_class_dependencies = Default::default();
4790 let mut nth_of_attribute_dependencies = Default::default();
4791 let mut nth_of_custom_state_dependencies = Default::default();
4792 let mut state_dependencies = ElementState::empty();
4793 let mut nth_of_state_dependencies = ElementState::empty();
4794 let mut document_state_dependencies = DocumentState::empty();
4795 let mut visitor = StylistSelectorVisitor {
4796 passed_rightmost_selector: false,
4797 needs_revalidation: &mut needs_revalidation,
4798 in_selector_list_of: SelectorListKind::default(),
4799 mapped_ids: &mut mapped_ids,
4800 nth_of_mapped_ids: &mut nth_of_mapped_ids,
4801 attribute_dependencies: &mut attribute_dependencies,
4802 nth_of_class_dependencies: &mut nth_of_class_dependencies,
4803 nth_of_attribute_dependencies: &mut nth_of_attribute_dependencies,
4804 nth_of_custom_state_dependencies: &mut nth_of_custom_state_dependencies,
4805 state_dependencies: &mut state_dependencies,
4806 nth_of_state_dependencies: &mut nth_of_state_dependencies,
4807 document_state_dependencies: &mut document_state_dependencies,
4808 };
4809 s.visit(&mut visitor);
4810 needs_revalidation
4811}