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(
1831 MatchingMode::Normal,
1832 bloom,
1833 selector_caches,
1834 self.quirks_mode,
1835 needs_selector_flags,
1836 MatchingForInvalidation::No,
1837 );
1838
1839 let mut result = RevalidationResult::default();
1845 let mut relevant_attributes = &mut result.relevant_attributes;
1846 let selectors_matched = &mut result.selectors_matched;
1847
1848 let matches_document_rules =
1849 element.each_applicable_non_document_style_rule_data(|data, host| {
1850 matching_context.with_shadow_host(Some(host), |matching_context| {
1851 data.selectors_for_cache_revalidation.lookup(
1852 element,
1853 self.quirks_mode,
1854 Some(&mut relevant_attributes),
1855 |selector_and_hashes| {
1856 selectors_matched.push(matches_selector(
1857 &selector_and_hashes.selector,
1858 selector_and_hashes.selector_offset,
1859 Some(&selector_and_hashes.hashes),
1860 &element,
1861 matching_context,
1862 ));
1863 true
1864 },
1865 );
1866 })
1867 });
1868
1869 for (data, origin) in self.cascade_data.iter_origins() {
1870 if origin == Origin::Author && !matches_document_rules {
1871 continue;
1872 }
1873
1874 data.selectors_for_cache_revalidation.lookup(
1875 element,
1876 self.quirks_mode,
1877 Some(&mut relevant_attributes),
1878 |selector_and_hashes| {
1879 selectors_matched.push(matches_selector(
1880 &selector_and_hashes.selector,
1881 selector_and_hashes.selector_offset,
1882 Some(&selector_and_hashes.hashes),
1883 &element,
1884 &mut matching_context,
1885 ));
1886 true
1887 },
1888 );
1889 }
1890
1891 result
1892 }
1893
1894 pub fn revalidate_scopes<E: TElement>(
1896 &self,
1897 element: &E,
1898 selector_caches: &mut SelectorCaches,
1899 needs_selector_flags: NeedsSelectorFlags,
1900 ) -> ScopeRevalidationResult {
1901 let mut matching_context = MatchingContext::new(
1902 MatchingMode::Normal,
1903 None,
1904 selector_caches,
1905 self.quirks_mode,
1906 needs_selector_flags,
1907 MatchingForInvalidation::No,
1908 );
1909
1910 let mut result = ScopeRevalidationResult::default();
1911 let matches_document_rules =
1912 element.each_applicable_non_document_style_rule_data(|data, host| {
1913 matching_context.with_shadow_host(Some(host), |matching_context| {
1914 data.revalidate_scopes(element, matching_context, &mut result);
1915 })
1916 });
1917
1918 for (data, origin) in self.cascade_data.iter_origins() {
1919 if origin == Origin::Author && !matches_document_rules {
1920 continue;
1921 }
1922
1923 data.revalidate_scopes(element, &mut matching_context, &mut result);
1924 }
1925
1926 result
1927 }
1928
1929 pub fn compute_for_declarations<E>(
1937 &self,
1938 guards: &StylesheetGuards,
1939 parent_style: &ComputedValues,
1940 declarations: Arc<Locked<PropertyDeclarationBlock>>,
1941 ) -> Arc<ComputedValues>
1942 where
1943 E: TElement,
1944 {
1945 let block = declarations.read_with(guards.author);
1946
1947 properties::apply_declarations::<E, _>(
1954 &self,
1955 None,
1956 self.rule_tree.root(),
1957 guards,
1958 block.declaration_importance_iter().map(|(declaration, _)| {
1959 (
1960 declaration,
1961 CascadePriority::new(
1962 CascadeLevel::same_tree_author_normal(),
1963 LayerOrder::root(),
1964 ),
1965 )
1966 }),
1967 Some(parent_style),
1968 Some(parent_style),
1969 FirstLineReparenting::No,
1970 &PositionTryFallbacksTryTactic::default(),
1971 CascadeMode::Unvisited {
1972 visited_rules: None,
1973 },
1974 Default::default(),
1975 None,
1976 &mut Default::default(),
1977 None,
1978 )
1979 }
1980
1981 #[inline]
1983 pub fn device(&self) -> &Device {
1984 &self.device
1985 }
1986
1987 #[inline]
1989 pub fn device_mut(&mut self) -> &mut Device {
1990 &mut self.device
1991 }
1992
1993 #[inline]
1995 pub fn rule_tree(&self) -> &RuleTree {
1996 &self.rule_tree
1997 }
1998
1999 #[inline]
2001 pub fn custom_property_script_registry(&self) -> &CustomPropertyScriptRegistry {
2002 &self.script_custom_properties
2003 }
2004
2005 #[inline]
2007 pub fn custom_property_script_registry_mut(&mut self) -> &mut CustomPropertyScriptRegistry {
2008 &mut self.script_custom_properties
2009 }
2010
2011 #[cfg(feature = "gecko")]
2013 pub fn add_size_of(&self, ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes) {
2014 self.cascade_data.add_size_of(ops, sizes);
2015 self.author_data_cache.add_size_of(ops, sizes);
2016 sizes.mRuleTree += self.rule_tree.size_of(ops);
2017
2018 }
2020
2021 pub fn shutdown() {
2023 let _entries = UA_CASCADE_DATA_CACHE.lock().unwrap().take_all();
2024 }
2025}
2026
2027#[derive(Clone, Debug, Deref, MallocSizeOf)]
2029pub struct LayerOrderedVec<T>(Vec<(T, LayerId)>);
2030impl<T> Default for LayerOrderedVec<T> {
2031 fn default() -> Self {
2032 Self(Default::default())
2033 }
2034}
2035
2036#[derive(Clone, Debug, Deref, MallocSizeOf)]
2038pub struct LayerOrderedMap<T>(PrecomputedHashMap<Atom, SmallVec<[(T, LayerId); 1]>>);
2039impl<T> Default for LayerOrderedMap<T> {
2040 fn default() -> Self {
2041 Self(Default::default())
2042 }
2043}
2044
2045impl<T: 'static> LayerOrderedVec<T> {
2046 fn clear(&mut self) {
2047 self.0.clear();
2048 }
2049 fn push(&mut self, v: T, id: LayerId) {
2050 self.0.push((v, id));
2051 }
2052 fn sort(&mut self, layers: &[CascadeLayer]) {
2053 self.0
2054 .sort_by_key(|&(_, ref id)| layers[id.0 as usize].order)
2055 }
2056}
2057
2058impl<T: 'static> LayerOrderedMap<T> {
2059 fn shrink_if_needed(&mut self) {
2060 self.0.shrink_if_needed();
2061 }
2062 fn clear(&mut self) {
2063 self.0.clear();
2064 }
2065 fn try_insert(&mut self, name: Atom, v: T, id: LayerId) -> Result<(), AllocErr> {
2066 self.try_insert_with(name, v, id, |_, _| Ordering::Equal)
2067 }
2068 fn try_insert_with(
2069 &mut self,
2070 name: Atom,
2071 v: T,
2072 id: LayerId,
2073 cmp: impl Fn(&T, &T) -> Ordering,
2074 ) -> Result<(), AllocErr> {
2075 self.0.try_reserve(1)?;
2076 let vec = self.0.entry(name).or_default();
2077 if let Some(&mut (ref mut val, ref last_id)) = vec.last_mut() {
2078 if *last_id == id {
2079 if cmp(&val, &v) != Ordering::Greater {
2080 *val = v;
2081 }
2082 return Ok(());
2083 }
2084 }
2085 vec.push((v, id));
2086 Ok(())
2087 }
2088 fn sort(&mut self, layers: &[CascadeLayer]) {
2089 self.sort_with(layers, |_, _| Ordering::Equal)
2090 }
2091 fn sort_with(&mut self, layers: &[CascadeLayer], cmp: impl Fn(&T, &T) -> Ordering) {
2092 for (_, v) in self.0.iter_mut() {
2093 v.sort_by(|&(ref v1, ref id1), &(ref v2, ref id2)| {
2094 let order1 = layers[id1.0 as usize].order;
2095 let order2 = layers[id2.0 as usize].order;
2096 order1.cmp(&order2).then_with(|| cmp(v1, v2))
2097 })
2098 }
2099 }
2100 pub fn get(&self, name: &Atom) -> Option<&T> {
2102 let vec = self.0.get(name)?;
2103 Some(&vec.last()?.0)
2104 }
2105}
2106
2107#[derive(Clone, Debug, MallocSizeOf)]
2111pub struct PageRuleData {
2112 pub layer: LayerId,
2114 #[ignore_malloc_size_of = "Arc, stylesheet measures as primary ref"]
2116 pub rule: Arc<Locked<PageRule>>,
2117}
2118
2119#[derive(Clone, Debug, Default, MallocSizeOf)]
2121pub struct PageRuleMap {
2122 pub rules: PrecomputedHashMap<Atom, SmallVec<[PageRuleData; 1]>>,
2124}
2125
2126impl PageRuleMap {
2127 #[inline]
2128 fn clear(&mut self) {
2129 self.rules.clear();
2130 }
2131
2132 pub fn match_and_append_rules(
2136 &self,
2137 matched_rules: &mut Vec<ApplicableDeclarationBlock>,
2138 origin: Origin,
2139 guards: &StylesheetGuards,
2140 cascade_data: &DocumentCascadeData,
2141 name: &Option<Atom>,
2142 pseudos: PagePseudoClassFlags,
2143 ) {
2144 let level = match origin {
2145 Origin::UserAgent => CascadeLevel::UANormal,
2146 Origin::User => CascadeLevel::UserNormal,
2147 Origin::Author => CascadeLevel::same_tree_author_normal(),
2148 };
2149 let cascade_data = cascade_data.borrow_for_origin(origin);
2150 let start = matched_rules.len();
2151
2152 self.match_and_add_rules(
2153 matched_rules,
2154 level,
2155 guards,
2156 cascade_data,
2157 &atom!(""),
2158 pseudos,
2159 );
2160 if let Some(name) = name {
2161 self.match_and_add_rules(matched_rules, level, guards, cascade_data, name, pseudos);
2162 }
2163
2164 matched_rules[start..].sort_by_key(|block| block.sort_key());
2167 }
2168
2169 fn match_and_add_rules(
2170 &self,
2171 extra_declarations: &mut Vec<ApplicableDeclarationBlock>,
2172 level: CascadeLevel,
2173 guards: &StylesheetGuards,
2174 cascade_data: &CascadeData,
2175 name: &Atom,
2176 pseudos: PagePseudoClassFlags,
2177 ) {
2178 let rules = match self.rules.get(name) {
2179 Some(rules) => rules,
2180 None => return,
2181 };
2182 for data in rules.iter() {
2183 let rule = data.rule.read_with(level.guard(&guards));
2184 let specificity = match rule.match_specificity(pseudos) {
2185 Some(specificity) => specificity,
2186 None => continue,
2187 };
2188 let block = rule.block.clone();
2189 extra_declarations.push(ApplicableDeclarationBlock::new(
2190 StyleSource::from_declarations(block),
2191 0,
2192 level,
2193 specificity,
2194 cascade_data.layer_order_for(data.layer),
2195 ScopeProximity::infinity(), ));
2197 }
2198 }
2199}
2200
2201impl MallocShallowSizeOf for PageRuleMap {
2202 fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
2203 self.rules.shallow_size_of(ops)
2204 }
2205}
2206
2207type PositionTryMap = LayerOrderedMap<Arc<Locked<PositionTryRule>>>;
2208
2209#[derive(Clone, Debug, Default)]
2212pub struct ExtraStyleData {
2213 pub font_faces: LayerOrderedVec<Arc<Locked<FontFaceRule>>>,
2215
2216 pub font_feature_values: LayerOrderedVec<Arc<FontFeatureValuesRule>>,
2218
2219 pub font_palette_values: LayerOrderedVec<Arc<FontPaletteValuesRule>>,
2221
2222 pub counter_styles: LayerOrderedMap<Arc<Locked<CounterStyleRule>>>,
2224
2225 pub position_try_rules: PositionTryMap,
2227
2228 pub pages: PageRuleMap,
2230}
2231
2232impl ExtraStyleData {
2233 fn add_font_face(&mut self, rule: &Arc<Locked<FontFaceRule>>, layer: LayerId) {
2235 self.font_faces.push(rule.clone(), layer);
2236 }
2237
2238 fn add_font_feature_values(&mut self, rule: &Arc<FontFeatureValuesRule>, layer: LayerId) {
2240 self.font_feature_values.push(rule.clone(), layer);
2241 }
2242
2243 fn add_font_palette_values(&mut self, rule: &Arc<FontPaletteValuesRule>, layer: LayerId) {
2245 self.font_palette_values.push(rule.clone(), layer);
2246 }
2247
2248 fn add_counter_style(
2250 &mut self,
2251 guard: &SharedRwLockReadGuard,
2252 rule: &Arc<Locked<CounterStyleRule>>,
2253 layer: LayerId,
2254 ) -> Result<(), AllocErr> {
2255 let name = rule.read_with(guard).name().0.clone();
2256 self.counter_styles.try_insert(name, rule.clone(), layer)
2257 }
2258
2259 fn add_position_try(
2261 &mut self,
2262 name: Atom,
2263 rule: Arc<Locked<PositionTryRule>>,
2264 layer: LayerId,
2265 ) -> Result<(), AllocErr> {
2266 self.position_try_rules.try_insert(name, rule, layer)
2267 }
2268
2269 fn add_page(
2271 &mut self,
2272 guard: &SharedRwLockReadGuard,
2273 rule: &Arc<Locked<PageRule>>,
2274 layer: LayerId,
2275 ) -> Result<(), AllocErr> {
2276 let page_rule = rule.read_with(guard);
2277 let mut add_rule = |name| {
2278 let vec = self.pages.rules.entry(name).or_default();
2279 vec.push(PageRuleData {
2280 layer,
2281 rule: rule.clone(),
2282 });
2283 };
2284 if page_rule.selectors.0.is_empty() {
2285 add_rule(atom!(""));
2286 } else {
2287 for selector in page_rule.selectors.as_slice() {
2288 add_rule(selector.name.0.clone());
2289 }
2290 }
2291 Ok(())
2292 }
2293
2294 fn sort_by_layer(&mut self, layers: &[CascadeLayer]) {
2295 self.font_faces.sort(layers);
2296 self.font_feature_values.sort(layers);
2297 self.font_palette_values.sort(layers);
2298 self.counter_styles.sort(layers);
2299 self.position_try_rules.sort(layers);
2300 }
2301
2302 fn clear(&mut self) {
2303 self.font_faces.clear();
2304 self.font_feature_values.clear();
2305 self.font_palette_values.clear();
2306 self.counter_styles.clear();
2307 self.position_try_rules.clear();
2308 self.pages.clear();
2309 }
2310}
2311
2312fn compare_keyframes_in_same_layer(v1: &KeyframesAnimation, v2: &KeyframesAnimation) -> Ordering {
2315 if v1.vendor_prefix.is_some() == v2.vendor_prefix.is_some() {
2316 Ordering::Equal
2317 } else if v2.vendor_prefix.is_some() {
2318 Ordering::Greater
2319 } else {
2320 Ordering::Less
2321 }
2322}
2323
2324pub struct ExtraStyleDataIterator<'a>(DocumentCascadeDataIter<'a>);
2326
2327impl<'a> Iterator for ExtraStyleDataIterator<'a> {
2328 type Item = (&'a ExtraStyleData, Origin);
2329
2330 fn next(&mut self) -> Option<Self::Item> {
2331 self.0.next().map(|d| (&d.0.extra_data, d.1))
2332 }
2333}
2334
2335impl MallocSizeOf for ExtraStyleData {
2336 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
2338 let mut n = 0;
2339 n += self.font_faces.shallow_size_of(ops);
2340 n += self.font_feature_values.shallow_size_of(ops);
2341 n += self.font_palette_values.shallow_size_of(ops);
2342 n += self.counter_styles.shallow_size_of(ops);
2343 n += self.position_try_rules.shallow_size_of(ops);
2344 n += self.pages.shallow_size_of(ops);
2345 n
2346 }
2347}
2348
2349#[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
2351#[derive(Clone, Debug)]
2352struct RevalidationSelectorAndHashes {
2353 #[cfg_attr(
2354 feature = "gecko",
2355 ignore_malloc_size_of = "CssRules have primary refs, we measure there"
2356 )]
2357 selector: Selector<SelectorImpl>,
2358 selector_offset: usize,
2359 hashes: AncestorHashes,
2360}
2361
2362impl RevalidationSelectorAndHashes {
2363 fn new(selector: Selector<SelectorImpl>, hashes: AncestorHashes) -> Self {
2364 let selector_offset = {
2365 let mut index = 0;
2369 let mut iter = selector.iter();
2370
2371 for _ in &mut iter {
2376 index += 1; }
2378
2379 match iter.next_sequence() {
2380 Some(Combinator::PseudoElement) => index + 1, _ => 0,
2382 }
2383 };
2384
2385 RevalidationSelectorAndHashes {
2386 selector,
2387 selector_offset,
2388 hashes,
2389 }
2390 }
2391}
2392
2393impl SelectorMapEntry for RevalidationSelectorAndHashes {
2394 fn selector(&self) -> SelectorIter<'_, SelectorImpl> {
2395 self.selector.iter_from(self.selector_offset)
2396 }
2397}
2398
2399struct StylistSelectorVisitor<'a> {
2402 passed_rightmost_selector: bool,
2405
2406 needs_revalidation: &'a mut bool,
2408
2409 in_selector_list_of: SelectorListKind,
2412
2413 mapped_ids: &'a mut PrecomputedHashSet<Atom>,
2416
2417 nth_of_mapped_ids: &'a mut PrecomputedHashSet<Atom>,
2420
2421 attribute_dependencies: &'a mut PrecomputedHashSet<LocalName>,
2423
2424 nth_of_class_dependencies: &'a mut PrecomputedHashSet<Atom>,
2427
2428 nth_of_attribute_dependencies: &'a mut PrecomputedHashSet<LocalName>,
2432
2433 nth_of_custom_state_dependencies: &'a mut PrecomputedHashSet<AtomIdent>,
2437
2438 state_dependencies: &'a mut ElementState,
2440
2441 nth_of_state_dependencies: &'a mut ElementState,
2444
2445 document_state_dependencies: &'a mut DocumentState,
2447}
2448
2449fn component_needs_revalidation(
2450 c: &Component<SelectorImpl>,
2451 passed_rightmost_selector: bool,
2452) -> bool {
2453 match *c {
2454 Component::ID(_) => {
2455 passed_rightmost_selector
2461 },
2462 Component::AttributeInNoNamespaceExists { .. }
2463 | Component::AttributeInNoNamespace { .. }
2464 | Component::AttributeOther(_)
2465 | Component::Empty
2466 | Component::Nth(_)
2467 | Component::NthOf(_)
2468 | Component::Has(_) => true,
2469 Component::NonTSPseudoClass(ref p) => p.needs_cache_revalidation(),
2470 _ => false,
2471 }
2472}
2473
2474impl<'a> StylistSelectorVisitor<'a> {
2475 fn visit_nested_selector(
2476 &mut self,
2477 in_selector_list_of: SelectorListKind,
2478 selector: &Selector<SelectorImpl>,
2479 ) {
2480 let old_passed_rightmost_selector = self.passed_rightmost_selector;
2481 let old_in_selector_list_of = self.in_selector_list_of;
2482
2483 self.passed_rightmost_selector = false;
2484 self.in_selector_list_of = in_selector_list_of;
2485 let _ret = selector.visit(self);
2486 debug_assert!(_ret, "We never return false");
2487
2488 self.passed_rightmost_selector = old_passed_rightmost_selector;
2489 self.in_selector_list_of = old_in_selector_list_of;
2490 }
2491}
2492
2493impl<'a> SelectorVisitor for StylistSelectorVisitor<'a> {
2494 type Impl = SelectorImpl;
2495
2496 fn visit_complex_selector(&mut self, combinator: Option<Combinator>) -> bool {
2497 *self.needs_revalidation =
2498 *self.needs_revalidation || combinator.map_or(false, |c| c.is_sibling());
2499
2500 self.passed_rightmost_selector = self.passed_rightmost_selector
2504 || !matches!(combinator, None | Some(Combinator::PseudoElement));
2505
2506 true
2507 }
2508
2509 fn visit_selector_list(
2510 &mut self,
2511 list_kind: SelectorListKind,
2512 list: &[Selector<Self::Impl>],
2513 ) -> bool {
2514 let in_selector_list_of = self.in_selector_list_of | list_kind;
2515 for selector in list {
2516 self.visit_nested_selector(in_selector_list_of, selector);
2517 }
2518 true
2519 }
2520
2521 fn visit_relative_selector_list(
2522 &mut self,
2523 list: &[selectors::parser::RelativeSelector<Self::Impl>],
2524 ) -> bool {
2525 let in_selector_list_of = self.in_selector_list_of | SelectorListKind::HAS;
2526 for selector in list {
2527 self.visit_nested_selector(in_selector_list_of, &selector.selector);
2528 }
2529 true
2530 }
2531
2532 fn visit_attribute_selector(
2533 &mut self,
2534 _ns: &NamespaceConstraint<&Namespace>,
2535 name: &LocalName,
2536 lower_name: &LocalName,
2537 ) -> bool {
2538 if self.in_selector_list_of.relevant_to_nth_of_dependencies() {
2539 self.nth_of_attribute_dependencies.insert(name.clone());
2540 if name != lower_name {
2541 self.nth_of_attribute_dependencies
2542 .insert(lower_name.clone());
2543 }
2544 }
2545
2546 self.attribute_dependencies.insert(name.clone());
2547 if name != lower_name {
2548 self.attribute_dependencies.insert(lower_name.clone());
2549 }
2550
2551 true
2552 }
2553
2554 fn visit_simple_selector(&mut self, s: &Component<SelectorImpl>) -> bool {
2555 *self.needs_revalidation = *self.needs_revalidation
2556 || component_needs_revalidation(s, self.passed_rightmost_selector);
2557
2558 match *s {
2559 Component::NonTSPseudoClass(NonTSPseudoClass::CustomState(ref name)) => {
2560 if self.in_selector_list_of.relevant_to_nth_of_dependencies() {
2566 self.nth_of_custom_state_dependencies.insert(name.0.clone());
2567 }
2568 },
2569 Component::NonTSPseudoClass(ref p) => {
2570 self.state_dependencies.insert(p.state_flag());
2571 self.document_state_dependencies
2572 .insert(p.document_state_flag());
2573
2574 if self.in_selector_list_of.relevant_to_nth_of_dependencies() {
2575 self.nth_of_state_dependencies.insert(p.state_flag());
2576 }
2577 },
2578 Component::ID(ref id) => {
2579 if !self.passed_rightmost_selector {
2591 self.mapped_ids.insert(id.0.clone());
2592 }
2593
2594 if self.in_selector_list_of.relevant_to_nth_of_dependencies() {
2595 self.nth_of_mapped_ids.insert(id.0.clone());
2596 }
2597 },
2598 Component::Class(ref class)
2599 if self.in_selector_list_of.relevant_to_nth_of_dependencies() =>
2600 {
2601 self.nth_of_class_dependencies.insert(class.0.clone());
2602 },
2603 _ => {},
2604 }
2605
2606 true
2607 }
2608}
2609
2610#[derive(Clone, Debug, Default, MallocSizeOf)]
2612struct GenericElementAndPseudoRules<Map> {
2613 element_map: Map,
2615
2616 pseudos_map: PerPseudoElementMap<Self>,
2623}
2624
2625impl<Map: Default + MallocSizeOf> GenericElementAndPseudoRules<Map> {
2626 #[inline(always)]
2627 fn for_insertion<'a>(&mut self, pseudo_elements: &[&'a PseudoElement]) -> &mut Map {
2628 let mut current = self;
2629 for &pseudo_element in pseudo_elements {
2630 debug_assert!(
2631 !pseudo_element.is_precomputed()
2632 && !pseudo_element.is_unknown_webkit_pseudo_element(),
2633 "Precomputed pseudos should end up in precomputed_pseudo_element_decls, \
2634 and unknown webkit pseudos should be discarded before getting here"
2635 );
2636
2637 current = current
2638 .pseudos_map
2639 .get_or_insert_with(pseudo_element, Default::default);
2640 }
2641
2642 &mut current.element_map
2643 }
2644
2645 #[inline]
2646 fn rules(&self, pseudo_elements: &[PseudoElement]) -> Option<&Map> {
2647 let mut current = self;
2648 for pseudo in pseudo_elements {
2649 current = current.pseudos_map.get(&pseudo)?;
2650 }
2651 Some(¤t.element_map)
2652 }
2653
2654 #[cfg(feature = "gecko")]
2656 fn add_size_of(&self, ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes) {
2657 sizes.mElementAndPseudosMaps += self.element_map.size_of(ops);
2658
2659 for elem in self.pseudos_map.iter() {
2660 sizes.mElementAndPseudosMaps += MallocSizeOf::size_of(elem, ops);
2661 }
2662 }
2663}
2664
2665type ElementAndPseudoRules = GenericElementAndPseudoRules<SelectorMap<Rule>>;
2666type PartMap = PrecomputedHashMap<Atom, SmallVec<[Rule; 1]>>;
2667type PartElementAndPseudoRules = GenericElementAndPseudoRules<PartMap>;
2668
2669impl ElementAndPseudoRules {
2670 fn clear(&mut self) {
2672 self.element_map.clear();
2673 self.pseudos_map.clear();
2674 }
2675
2676 fn shrink_if_needed(&mut self) {
2677 self.element_map.shrink_if_needed();
2678 for pseudo in self.pseudos_map.iter_mut() {
2679 pseudo.shrink_if_needed();
2680 }
2681 }
2682}
2683
2684impl PartElementAndPseudoRules {
2685 fn clear(&mut self) {
2687 self.element_map.clear();
2688 self.pseudos_map.clear();
2689 }
2690}
2691
2692#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, PartialOrd, Ord)]
2694pub struct LayerId(u16);
2695
2696impl LayerId {
2697 pub const fn root() -> Self {
2699 Self(0)
2700 }
2701}
2702
2703#[derive(Clone, Debug, MallocSizeOf)]
2704struct CascadeLayer {
2705 id: LayerId,
2706 order: LayerOrder,
2707 children: Vec<LayerId>,
2708}
2709
2710impl CascadeLayer {
2711 const fn root() -> Self {
2712 Self {
2713 id: LayerId::root(),
2714 order: LayerOrder::root(),
2715 children: vec![],
2716 }
2717 }
2718}
2719
2720#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, PartialOrd, Ord)]
2723pub struct ContainerConditionId(u16);
2724
2725impl ContainerConditionId {
2726 pub const fn none() -> Self {
2728 Self(0)
2729 }
2730}
2731
2732#[derive(Clone, Debug, MallocSizeOf)]
2733struct ContainerConditionReference {
2734 parent: ContainerConditionId,
2735 #[ignore_malloc_size_of = "Arc"]
2736 condition: Option<Arc<ContainerCondition>>,
2737}
2738
2739impl ContainerConditionReference {
2740 const fn none() -> Self {
2741 Self {
2742 parent: ContainerConditionId::none(),
2743 condition: None,
2744 }
2745 }
2746}
2747
2748#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, PartialOrd, Ord)]
2751pub struct ScopeConditionId(u16);
2752
2753impl ScopeConditionId {
2754 pub fn new(id: u16) -> Self {
2756 Self(id)
2757 }
2758
2759 pub const fn none() -> Self {
2761 Self(0)
2762 }
2763}
2764
2765#[derive(Clone, Debug, MallocSizeOf)]
2767pub struct ScopeConditionReference {
2768 parent: ScopeConditionId,
2770 condition: Option<ScopeBoundsWithHashes>,
2772 #[ignore_malloc_size_of = "Raw ptr behind the scenes"]
2775 implicit_scope_root: StylistImplicitScopeRoot,
2776 is_trivial: bool,
2778}
2779
2780impl ScopeConditionReference {
2781 pub fn new(
2783 parent: ScopeConditionId,
2784 condition: Option<ScopeBoundsWithHashes>,
2785 implicit_scope_root: ImplicitScopeRoot,
2786 is_trivial: bool,
2787 ) -> Self {
2788 Self {
2789 parent,
2790 condition,
2791 implicit_scope_root: StylistImplicitScopeRoot::Normal(implicit_scope_root),
2792 is_trivial,
2793 }
2794 }
2795
2796 pub const fn none() -> Self {
2798 Self {
2799 parent: ScopeConditionId::none(),
2800 condition: None,
2801 implicit_scope_root: StylistImplicitScopeRoot::default_const(),
2802 is_trivial: true,
2803 }
2804 }
2805}
2806
2807pub struct ScopeRootCandidates {
2809 pub candidates: Vec<ScopeRootCandidate>,
2811 pub is_trivial: bool,
2813}
2814
2815impl Default for ScopeRootCandidates {
2816 fn default() -> Self {
2817 Self {
2818 candidates: vec![],
2819 is_trivial: true,
2820 }
2821 }
2822}
2823
2824impl ScopeRootCandidates {
2825 fn empty(is_trivial: bool) -> Self {
2826 Self {
2827 candidates: vec![],
2828 is_trivial,
2829 }
2830 }
2831}
2832
2833#[derive(Clone, Debug, MallocSizeOf)]
2835pub struct ScopeBoundWithHashes {
2836 #[ignore_malloc_size_of = "Arc"]
2838 selectors: SelectorList<SelectorImpl>,
2839 hashes: SmallVec<[AncestorHashes; 1]>,
2840}
2841
2842impl ScopeBoundWithHashes {
2843 fn new(quirks_mode: QuirksMode, selectors: SelectorList<SelectorImpl>) -> Self {
2844 let mut hashes = SmallVec::with_capacity(selectors.len());
2845 for selector in selectors.slice() {
2846 hashes.push(AncestorHashes::new(selector, quirks_mode));
2847 }
2848 Self { selectors, hashes }
2849 }
2850
2851 fn new_no_hash(selectors: SelectorList<SelectorImpl>) -> Self {
2852 let hashes = selectors
2853 .slice()
2854 .iter()
2855 .map(|_| AncestorHashes {
2856 packed_hashes: [0, 0, 0],
2857 })
2858 .collect();
2859 Self { selectors, hashes }
2860 }
2861}
2862
2863#[derive(Clone, Debug, MallocSizeOf)]
2865pub struct ScopeBoundsWithHashes {
2866 start: Option<ScopeBoundWithHashes>,
2868 end: Option<ScopeBoundWithHashes>,
2870}
2871
2872impl ScopeBoundsWithHashes {
2873 fn new(
2875 quirks_mode: QuirksMode,
2876 start: Option<SelectorList<SelectorImpl>>,
2877 end: Option<SelectorList<SelectorImpl>>,
2878 ) -> Self {
2879 Self {
2880 start: start.map(|selectors| ScopeBoundWithHashes::new(quirks_mode, selectors)),
2881 end: end.map(|selectors| ScopeBoundWithHashes::new(quirks_mode, selectors)),
2882 }
2883 }
2884
2885 pub fn new_no_hash(
2887 start: Option<SelectorList<SelectorImpl>>,
2888 end: Option<SelectorList<SelectorImpl>>,
2889 ) -> Self {
2890 Self {
2891 start: start.map(|selectors| ScopeBoundWithHashes::new_no_hash(selectors)),
2892 end: end.map(|selectors| ScopeBoundWithHashes::new_no_hash(selectors)),
2893 }
2894 }
2895
2896 fn selectors_for<'a>(
2897 bound_with_hashes: Option<&'a ScopeBoundWithHashes>,
2898 ) -> impl Iterator<Item = &'a Selector<SelectorImpl>> {
2899 bound_with_hashes
2900 .map(|b| b.selectors.slice().iter())
2901 .into_iter()
2902 .flatten()
2903 }
2904
2905 fn start_selectors<'a>(&'a self) -> impl Iterator<Item = &'a Selector<SelectorImpl>> {
2906 Self::selectors_for(self.start.as_ref())
2907 }
2908
2909 fn end_selectors<'a>(&'a self) -> impl Iterator<Item = &'a Selector<SelectorImpl>> {
2910 Self::selectors_for(self.end.as_ref())
2911 }
2912
2913 fn is_trivial(&self) -> bool {
2914 fn scope_bound_is_trivial(bound: &Option<ScopeBoundWithHashes>, default: bool) -> bool {
2915 bound.as_ref().map_or(default, |bound| {
2916 scope_selector_list_is_trivial(&bound.selectors)
2917 })
2918 }
2919
2920 scope_bound_is_trivial(&self.start, false) && scope_bound_is_trivial(&self.end, true)
2922 }
2923}
2924
2925pub fn scope_root_candidates<E>(
2927 scope_conditions: &[ScopeConditionReference],
2928 id: ScopeConditionId,
2929 element: &E,
2930 override_matches_shadow_host_for_part: bool,
2931 scope_subject_map: &ScopeSubjectMap,
2932 context: &mut MatchingContext<SelectorImpl>,
2933) -> ScopeRootCandidates
2934where
2935 E: TElement,
2936{
2937 let condition_ref = &scope_conditions[id.0 as usize];
2938 let bounds = match condition_ref.condition {
2939 None => return ScopeRootCandidates::default(),
2940 Some(ref c) => c,
2941 };
2942 let outer_result = scope_root_candidates(
2946 scope_conditions,
2947 condition_ref.parent,
2948 element,
2949 override_matches_shadow_host_for_part,
2950 scope_subject_map,
2951 context,
2952 );
2953
2954 let is_trivial = condition_ref.is_trivial && outer_result.is_trivial;
2955 let is_outermost_scope = condition_ref.parent == ScopeConditionId::none();
2956 if !is_outermost_scope && outer_result.candidates.is_empty() {
2957 return ScopeRootCandidates::empty(is_trivial);
2958 }
2959
2960 let (root_target, matches_shadow_host) = if let Some(start) = bounds.start.as_ref() {
2961 if let Some(filter) = context.bloom_filter {
2962 if !start
2967 .hashes
2968 .iter()
2969 .any(|entry| selector_may_match(entry, filter))
2970 {
2971 return ScopeRootCandidates::empty(is_trivial);
2972 }
2973 }
2974 (
2975 ScopeTarget::Selector(&start.selectors),
2976 scope_start_matches_shadow_host(&start.selectors),
2977 )
2978 } else {
2979 let implicit_root = condition_ref.implicit_scope_root;
2980 match implicit_root {
2981 StylistImplicitScopeRoot::Normal(r) => (
2982 ScopeTarget::Implicit(r.element(context.current_host.clone())),
2983 r.matches_shadow_host(),
2984 ),
2985 StylistImplicitScopeRoot::Cached(index) => {
2986 let host = context
2987 .current_host
2988 .expect("Cached implicit scope for light DOM implicit scope");
2989 match E::implicit_scope_for_sheet_in_shadow_root(host, index) {
2990 None => return ScopeRootCandidates::empty(is_trivial),
2991 Some(root) => (
2992 ScopeTarget::Implicit(root.element(context.current_host.clone())),
2993 root.matches_shadow_host(),
2994 ),
2995 }
2996 },
2997 }
2998 };
2999 let matches_shadow_host = override_matches_shadow_host_for_part || matches_shadow_host;
3002
3003 let potential_scope_roots = if is_outermost_scope {
3004 collect_scope_roots(
3005 *element,
3006 None,
3007 context,
3008 &root_target,
3009 matches_shadow_host,
3010 scope_subject_map,
3011 )
3012 } else {
3013 let mut result = vec![];
3014 for activation in outer_result.candidates {
3015 let mut this_result = collect_scope_roots(
3016 *element,
3017 Some(activation.root),
3018 context,
3019 &root_target,
3020 matches_shadow_host,
3021 scope_subject_map,
3022 );
3023 result.append(&mut this_result);
3024 }
3025 result
3026 };
3027
3028 if potential_scope_roots.is_empty() {
3029 return ScopeRootCandidates::empty(is_trivial);
3030 }
3031
3032 let candidates = if let Some(end) = bounds.end.as_ref() {
3033 let mut result = vec![];
3034 for scope_root in potential_scope_roots {
3036 if end
3037 .selectors
3038 .slice()
3039 .iter()
3040 .zip(end.hashes.iter())
3041 .all(|(selector, hashes)| {
3042 if let Some(filter) = context.bloom_filter {
3044 if !selector_may_match(hashes, filter) {
3045 return true;
3047 }
3048 }
3049
3050 !element_is_outside_of_scope(
3051 selector,
3052 *element,
3053 scope_root.root,
3054 context,
3055 matches_shadow_host,
3056 )
3057 })
3058 {
3059 result.push(scope_root);
3060 }
3061 }
3062 result
3063 } else {
3064 potential_scope_roots
3065 };
3066
3067 ScopeRootCandidates {
3068 candidates,
3069 is_trivial,
3070 }
3071}
3072
3073#[derive(Copy, Clone, Debug, MallocSizeOf)]
3076enum StylistImplicitScopeRoot {
3077 Normal(ImplicitScopeRoot),
3078 Cached(usize),
3079}
3080unsafe impl Sync for StylistImplicitScopeRoot {}
3082
3083impl StylistImplicitScopeRoot {
3084 const fn default_const() -> Self {
3085 Self::Normal(ImplicitScopeRoot::DocumentElement)
3087 }
3088}
3089
3090impl Default for StylistImplicitScopeRoot {
3091 fn default() -> Self {
3092 Self::default_const()
3093 }
3094}
3095
3096#[derive(Debug, Clone, MallocSizeOf)]
3102pub struct CascadeData {
3103 normal_rules: ElementAndPseudoRules,
3106
3107 featureless_host_rules: Option<Box<ElementAndPseudoRules>>,
3111
3112 slotted_rules: Option<Box<ElementAndPseudoRules>>,
3120
3121 part_rules: Option<Box<PartElementAndPseudoRules>>,
3126
3127 invalidation_map: InvalidationMap,
3129
3130 relative_selector_invalidation_map: InvalidationMap,
3132
3133 additional_relative_selector_invalidation_map: AdditionalRelativeSelectorInvalidationMap,
3134
3135 attribute_dependencies: PrecomputedHashSet<LocalName>,
3140
3141 nth_of_class_dependencies: PrecomputedHashSet<Atom>,
3145
3146 nth_of_attribute_dependencies: PrecomputedHashSet<LocalName>,
3150
3151 nth_of_custom_state_dependencies: PrecomputedHashSet<AtomIdent>,
3155
3156 state_dependencies: ElementState,
3160
3161 nth_of_state_dependencies: ElementState,
3164
3165 document_state_dependencies: DocumentState,
3169
3170 mapped_ids: PrecomputedHashSet<Atom>,
3175
3176 nth_of_mapped_ids: PrecomputedHashSet<Atom>,
3180
3181 #[ignore_malloc_size_of = "Arc"]
3185 selectors_for_cache_revalidation: SelectorMap<RevalidationSelectorAndHashes>,
3186
3187 animations: LayerOrderedMap<KeyframesAnimation>,
3190
3191 #[ignore_malloc_size_of = "Arc"]
3194 custom_property_registrations: LayerOrderedMap<Arc<PropertyRegistration>>,
3195
3196 custom_media: CustomMediaMap,
3198
3199 layer_id: FxHashMap<LayerName, LayerId>,
3201
3202 layers: SmallVec<[CascadeLayer; 1]>,
3204
3205 container_conditions: SmallVec<[ContainerConditionReference; 1]>,
3207
3208 scope_conditions: SmallVec<[ScopeConditionReference; 1]>,
3210
3211 scope_subject_map: ScopeSubjectMap,
3213
3214 effective_media_query_results: EffectiveMediaQueryResults,
3216
3217 extra_data: ExtraStyleData,
3219
3220 rules_source_order: u32,
3223
3224 num_selectors: usize,
3226
3227 num_declarations: usize,
3229}
3230
3231static IMPLICIT_SCOPE: LazyLock<SelectorList<SelectorImpl>> = LazyLock::new(|| {
3232 let list = SelectorList::implicit_scope();
3236 list.mark_as_intentionally_leaked();
3237 list
3238});
3239
3240fn scope_start_matches_shadow_host(start: &SelectorList<SelectorImpl>) -> bool {
3241 start
3244 .slice()
3245 .iter()
3246 .any(|s| s.matches_featureless_host(true).may_match())
3247}
3248
3249pub fn replace_parent_selector_with_implicit_scope(
3251 selectors: &SelectorList<SelectorImpl>,
3252) -> SelectorList<SelectorImpl> {
3253 selectors.replace_parent_selector(&IMPLICIT_SCOPE)
3254}
3255
3256impl CascadeData {
3257 pub fn new() -> Self {
3259 Self {
3260 normal_rules: ElementAndPseudoRules::default(),
3261 featureless_host_rules: None,
3262 slotted_rules: None,
3263 part_rules: None,
3264 invalidation_map: InvalidationMap::new(),
3265 relative_selector_invalidation_map: InvalidationMap::new(),
3266 additional_relative_selector_invalidation_map:
3267 AdditionalRelativeSelectorInvalidationMap::new(),
3268 nth_of_mapped_ids: PrecomputedHashSet::default(),
3269 nth_of_class_dependencies: PrecomputedHashSet::default(),
3270 nth_of_attribute_dependencies: PrecomputedHashSet::default(),
3271 nth_of_custom_state_dependencies: PrecomputedHashSet::default(),
3272 nth_of_state_dependencies: ElementState::empty(),
3273 attribute_dependencies: PrecomputedHashSet::default(),
3274 state_dependencies: ElementState::empty(),
3275 document_state_dependencies: DocumentState::empty(),
3276 mapped_ids: PrecomputedHashSet::default(),
3277 selectors_for_cache_revalidation: SelectorMap::new(),
3278 animations: Default::default(),
3279 custom_property_registrations: Default::default(),
3280 custom_media: Default::default(),
3281 layer_id: Default::default(),
3282 layers: smallvec::smallvec![CascadeLayer::root()],
3283 container_conditions: smallvec::smallvec![ContainerConditionReference::none()],
3284 scope_conditions: smallvec::smallvec![ScopeConditionReference::none()],
3285 scope_subject_map: Default::default(),
3286 extra_data: ExtraStyleData::default(),
3287 effective_media_query_results: EffectiveMediaQueryResults::new(),
3288 rules_source_order: 0,
3289 num_selectors: 0,
3290 num_declarations: 0,
3291 }
3292 }
3293
3294 pub fn rebuild<'a, S>(
3296 &mut self,
3297 device: &Device,
3298 quirks_mode: QuirksMode,
3299 collection: SheetCollectionFlusher<S>,
3300 guard: &SharedRwLockReadGuard,
3301 difference: &mut CascadeDataDifference,
3302 ) -> Result<(), AllocErr>
3303 where
3304 S: StylesheetInDocument + PartialEq + 'static,
3305 {
3306 if !collection.dirty() {
3307 return Ok(());
3308 }
3309
3310 let validity = collection.data_validity();
3311
3312 let mut old_position_try_data = LayerOrderedMap::default();
3313 if validity != DataValidity::Valid {
3314 old_position_try_data = std::mem::take(&mut self.extra_data.position_try_rules);
3315 self.clear_cascade_data();
3316 if validity == DataValidity::FullyInvalid {
3317 self.clear_invalidation_data();
3318 }
3319 }
3320
3321 let mut result = Ok(());
3322
3323 collection.each(|index, stylesheet, rebuild_kind| {
3324 result = self.add_stylesheet(
3325 device,
3326 quirks_mode,
3327 stylesheet,
3328 index,
3329 guard,
3330 rebuild_kind,
3331 None,
3332 if validity == DataValidity::Valid {
3333 Some(difference)
3334 } else {
3335 None
3336 },
3337 );
3338 result.is_ok()
3339 });
3340
3341 self.did_finish_rebuild();
3342
3343 if validity != DataValidity::Valid {
3346 difference.update(&old_position_try_data, &self.extra_data.position_try_rules);
3347 }
3348
3349 result
3350 }
3351
3352 pub fn custom_media_map(&self) -> &CustomMediaMap {
3354 &self.custom_media
3355 }
3356
3357 pub fn invalidation_map(&self) -> &InvalidationMap {
3359 &self.invalidation_map
3360 }
3361
3362 pub fn relative_selector_invalidation_map(&self) -> &InvalidationMap {
3364 &self.relative_selector_invalidation_map
3365 }
3366
3367 pub fn relative_invalidation_map_attributes(
3369 &self,
3370 ) -> &AdditionalRelativeSelectorInvalidationMap {
3371 &self.additional_relative_selector_invalidation_map
3372 }
3373
3374 #[inline]
3377 pub fn has_state_dependency(&self, state: ElementState) -> bool {
3378 self.state_dependencies.intersects(state)
3379 }
3380
3381 #[inline]
3384 pub fn has_nth_of_custom_state_dependency(&self, state: &AtomIdent) -> bool {
3385 self.nth_of_custom_state_dependencies.contains(state)
3386 }
3387
3388 #[inline]
3391 pub fn has_nth_of_state_dependency(&self, state: ElementState) -> bool {
3392 self.nth_of_state_dependencies.intersects(state)
3393 }
3394
3395 #[inline]
3398 pub fn might_have_attribute_dependency(&self, local_name: &LocalName) -> bool {
3399 self.attribute_dependencies.contains(local_name)
3400 }
3401
3402 #[inline]
3405 pub fn might_have_nth_of_id_dependency(&self, id: &Atom) -> bool {
3406 self.nth_of_mapped_ids.contains(id)
3407 }
3408
3409 #[inline]
3412 pub fn might_have_nth_of_class_dependency(&self, class: &Atom) -> bool {
3413 self.nth_of_class_dependencies.contains(class)
3414 }
3415
3416 #[inline]
3419 pub fn might_have_nth_of_attribute_dependency(&self, local_name: &LocalName) -> bool {
3420 self.nth_of_attribute_dependencies.contains(local_name)
3421 }
3422
3423 #[inline]
3425 pub fn normal_rules(&self, pseudo_elements: &[PseudoElement]) -> Option<&SelectorMap<Rule>> {
3426 self.normal_rules.rules(pseudo_elements)
3427 }
3428
3429 #[inline]
3431 pub fn featureless_host_rules(
3432 &self,
3433 pseudo_elements: &[PseudoElement],
3434 ) -> Option<&SelectorMap<Rule>> {
3435 self.featureless_host_rules
3436 .as_ref()
3437 .and_then(|d| d.rules(pseudo_elements))
3438 }
3439
3440 pub fn any_featureless_host_rules(&self) -> bool {
3442 self.featureless_host_rules.is_some()
3443 }
3444
3445 #[inline]
3447 pub fn slotted_rules(&self, pseudo_elements: &[PseudoElement]) -> Option<&SelectorMap<Rule>> {
3448 self.slotted_rules
3449 .as_ref()
3450 .and_then(|d| d.rules(pseudo_elements))
3451 }
3452
3453 pub fn any_slotted_rule(&self) -> bool {
3455 self.slotted_rules.is_some()
3456 }
3457
3458 #[inline]
3460 pub fn part_rules(&self, pseudo_elements: &[PseudoElement]) -> Option<&PartMap> {
3461 self.part_rules
3462 .as_ref()
3463 .and_then(|d| d.rules(pseudo_elements))
3464 }
3465
3466 pub fn any_part_rule(&self) -> bool {
3468 self.part_rules.is_some()
3469 }
3470
3471 #[inline]
3472 fn layer_order_for(&self, id: LayerId) -> LayerOrder {
3473 self.layers[id.0 as usize].order
3474 }
3475
3476 pub(crate) fn container_condition_matches<E>(
3477 &self,
3478 mut id: ContainerConditionId,
3479 stylist: &Stylist,
3480 element: E,
3481 context: &mut MatchingContext<E::Impl>,
3482 ) -> bool
3483 where
3484 E: TElement,
3485 {
3486 loop {
3487 let condition_ref = &self.container_conditions[id.0 as usize];
3488 let condition = match condition_ref.condition {
3489 None => return true,
3490 Some(ref c) => c,
3491 };
3492 let matches = condition
3493 .matches(
3494 stylist,
3495 element,
3496 context.extra_data.originating_element_style,
3497 &mut context.extra_data.cascade_input_flags,
3498 )
3499 .to_bool(false);
3500 if !matches {
3501 return false;
3502 }
3503 id = condition_ref.parent;
3504 }
3505 }
3506
3507 pub(crate) fn find_scope_proximity_if_matching<E: TElement>(
3508 &self,
3509 rule: &Rule,
3510 element: E,
3511 context: &mut MatchingContext<E::Impl>,
3512 ) -> ScopeProximity {
3513 context
3514 .extra_data
3515 .cascade_input_flags
3516 .insert(ComputedValueFlags::CONSIDERED_NONTRIVIAL_SCOPED_STYLE);
3517
3518 let result = scope_root_candidates(
3522 &self.scope_conditions,
3523 rule.scope_condition_id,
3524 &element,
3525 rule.selector.is_part(),
3526 &self.scope_subject_map,
3527 context,
3528 );
3529 for candidate in result.candidates {
3530 if context.nest_for_scope(Some(candidate.root), |context| {
3531 matches_selector(&rule.selector, 0, Some(&rule.hashes), &element, context)
3532 }) {
3533 return candidate.proximity;
3534 }
3535 }
3536 ScopeProximity::infinity()
3537 }
3538
3539 fn did_finish_rebuild(&mut self) {
3540 self.shrink_maps_if_needed();
3541 self.compute_layer_order();
3542 }
3543
3544 fn shrink_maps_if_needed(&mut self) {
3545 self.normal_rules.shrink_if_needed();
3546 if let Some(ref mut host_rules) = self.featureless_host_rules {
3547 host_rules.shrink_if_needed();
3548 }
3549 if let Some(ref mut slotted_rules) = self.slotted_rules {
3550 slotted_rules.shrink_if_needed();
3551 }
3552 self.animations.shrink_if_needed();
3553 self.custom_property_registrations.shrink_if_needed();
3554 self.invalidation_map.shrink_if_needed();
3555 self.relative_selector_invalidation_map.shrink_if_needed();
3556 self.additional_relative_selector_invalidation_map
3557 .shrink_if_needed();
3558 self.attribute_dependencies.shrink_if_needed();
3559 self.nth_of_attribute_dependencies.shrink_if_needed();
3560 self.nth_of_custom_state_dependencies.shrink_if_needed();
3561 self.nth_of_class_dependencies.shrink_if_needed();
3562 self.nth_of_mapped_ids.shrink_if_needed();
3563 self.mapped_ids.shrink_if_needed();
3564 self.layer_id.shrink_if_needed();
3565 self.selectors_for_cache_revalidation.shrink_if_needed();
3566 self.scope_subject_map.shrink_if_needed();
3567 }
3568
3569 fn compute_layer_order(&mut self) {
3570 debug_assert_ne!(
3571 self.layers.len(),
3572 0,
3573 "There should be at least the root layer!"
3574 );
3575 if self.layers.len() == 1 {
3576 return; }
3578 let (first, remaining) = self.layers.split_at_mut(1);
3579 let root = &mut first[0];
3580 let mut order = LayerOrder::first();
3581 compute_layer_order_for_subtree(root, remaining, &mut order);
3582
3583 fn compute_layer_order_for_subtree(
3586 parent: &mut CascadeLayer,
3587 remaining_layers: &mut [CascadeLayer],
3588 order: &mut LayerOrder,
3589 ) {
3590 for child in parent.children.iter() {
3591 debug_assert!(
3592 parent.id < *child,
3593 "Children are always registered after parents"
3594 );
3595 let child_index = (child.0 - parent.id.0 - 1) as usize;
3596 let (first, remaining) = remaining_layers.split_at_mut(child_index + 1);
3597 let child = &mut first[child_index];
3598 compute_layer_order_for_subtree(child, remaining, order);
3599 }
3600
3601 if parent.id != LayerId::root() {
3602 parent.order = *order;
3603 order.inc();
3604 }
3605 }
3606 self.extra_data.sort_by_layer(&self.layers);
3607 self.animations
3608 .sort_with(&self.layers, compare_keyframes_in_same_layer);
3609 self.custom_property_registrations.sort(&self.layers)
3610 }
3611
3612 fn collect_applicable_media_query_results_into<S>(
3621 device: &Device,
3622 stylesheet: &S,
3623 guard: &SharedRwLockReadGuard,
3624 results: &mut Vec<MediaListKey>,
3625 contents_list: &mut StyleSheetContentList,
3626 custom_media_map: &mut CustomMediaMap,
3627 ) where
3628 S: StylesheetInDocument + 'static,
3629 {
3630 if !stylesheet.enabled() {
3631 return;
3632 }
3633 if !stylesheet.is_effective_for_device(device, &custom_media_map, guard) {
3634 return;
3635 }
3636
3637 debug!(" + {:?}", stylesheet);
3638 let contents = stylesheet.contents(guard);
3639 results.push(contents.to_media_list_key());
3640
3641 contents_list.push(StylesheetContentsPtr(unsafe {
3643 Arc::from_raw_addrefed(&*contents)
3644 }));
3645
3646 let mut iter = stylesheet
3647 .contents(guard)
3648 .effective_rules(device, custom_media_map, guard);
3649 while let Some(rule) = iter.next() {
3650 match *rule {
3651 CssRule::CustomMedia(ref custom_media) => {
3652 iter.custom_media()
3653 .insert(custom_media.name.0.clone(), custom_media.condition.clone());
3654 },
3655 CssRule::Import(ref lock) => {
3656 let import_rule = lock.read_with(guard);
3657 debug!(" + {:?}", import_rule.stylesheet.media(guard));
3658 results.push(import_rule.to_media_list_key());
3659 },
3660 CssRule::Media(ref media_rule) => {
3661 debug!(" + {:?}", media_rule.media_queries.read_with(guard));
3662 results.push(media_rule.to_media_list_key());
3663 },
3664 _ => {},
3665 }
3666 }
3667 }
3668
3669 fn add_styles(
3670 &mut self,
3671 selectors: &SelectorList<SelectorImpl>,
3672 declarations: &Arc<Locked<PropertyDeclarationBlock>>,
3673 ancestor_selectors: Option<&SelectorList<SelectorImpl>>,
3674 containing_rule_state: &ContainingRuleState,
3675 mut replaced_selectors: Option<&mut ReplacedSelectors>,
3676 guard: &SharedRwLockReadGuard,
3677 rebuild_kind: SheetRebuildKind,
3678 mut precomputed_pseudo_element_decls: Option<&mut PrecomputedPseudoElementDeclarations>,
3679 quirks_mode: QuirksMode,
3680 mut collected_scope_dependencies: Option<&mut Vec<Dependency>>,
3681 ) -> Result<(), AllocErr> {
3682 self.num_declarations += declarations.read_with(guard).len();
3683 for selector in selectors.slice() {
3684 self.num_selectors += 1;
3685
3686 let pseudo_elements = selector.pseudo_elements();
3687 let inner_pseudo_element = pseudo_elements.get(0);
3688 if let Some(pseudo) = inner_pseudo_element {
3689 if pseudo.is_precomputed() {
3690 debug_assert!(selector.is_universal());
3691 debug_assert!(ancestor_selectors.is_none());
3692 debug_assert_eq!(containing_rule_state.layer_id, LayerId::root());
3693 debug_assert!(!containing_rule_state.scope_is_effective());
3695 precomputed_pseudo_element_decls
3696 .as_mut()
3697 .expect("Expected precomputed declarations for the UA level")
3698 .get_or_insert_with(pseudo, Vec::new)
3699 .push(ApplicableDeclarationBlock::new(
3700 StyleSource::from_declarations(declarations.clone()),
3701 self.rules_source_order,
3702 CascadeLevel::UANormal,
3703 selector.specificity(),
3704 LayerOrder::root(),
3705 ScopeProximity::infinity(),
3706 ));
3707 continue;
3708 }
3709 if pseudo_elements
3710 .iter()
3711 .any(|p| p.is_unknown_webkit_pseudo_element())
3712 {
3713 continue;
3714 }
3715 }
3716
3717 debug_assert!(!pseudo_elements
3718 .iter()
3719 .any(|p| p.is_precomputed() || p.is_unknown_webkit_pseudo_element()));
3720
3721 let selector = match ancestor_selectors {
3722 Some(ref s) => selector.replace_parent_selector(&s),
3723 None => selector.clone(),
3724 };
3725
3726 let hashes = AncestorHashes::new(&selector, quirks_mode);
3727
3728 let rule = Rule::new(
3729 selector,
3730 hashes,
3731 StyleSource::from_declarations(declarations.clone()),
3732 self.rules_source_order,
3733 containing_rule_state.layer_id,
3734 containing_rule_state.container_condition_id,
3735 containing_rule_state.in_starting_style,
3736 containing_rule_state.containing_scope_rule_state.id,
3737 );
3738
3739 if let Some(ref mut replaced_selectors) = replaced_selectors {
3740 replaced_selectors.push(rule.selector.clone())
3741 }
3742
3743 if rebuild_kind.should_rebuild_invalidation() {
3744 let mut scope_dependencies = note_selector_for_invalidation(
3745 &rule.selector,
3746 quirks_mode,
3747 &mut self.invalidation_map,
3748 &mut self.relative_selector_invalidation_map,
3749 &mut self.additional_relative_selector_invalidation_map,
3750 None,
3751 None,
3752 )?;
3753 let mut needs_revalidation = false;
3754 let mut visitor = StylistSelectorVisitor {
3755 needs_revalidation: &mut needs_revalidation,
3756 passed_rightmost_selector: false,
3757 in_selector_list_of: SelectorListKind::default(),
3758 mapped_ids: &mut self.mapped_ids,
3759 nth_of_mapped_ids: &mut self.nth_of_mapped_ids,
3760 attribute_dependencies: &mut self.attribute_dependencies,
3761 nth_of_class_dependencies: &mut self.nth_of_class_dependencies,
3762 nth_of_attribute_dependencies: &mut self.nth_of_attribute_dependencies,
3763 nth_of_custom_state_dependencies: &mut self.nth_of_custom_state_dependencies,
3764 state_dependencies: &mut self.state_dependencies,
3765 nth_of_state_dependencies: &mut self.nth_of_state_dependencies,
3766 document_state_dependencies: &mut self.document_state_dependencies,
3767 };
3768 rule.selector.visit(&mut visitor);
3769
3770 if needs_revalidation {
3771 self.selectors_for_cache_revalidation.insert(
3772 RevalidationSelectorAndHashes::new(
3773 rule.selector.clone(),
3774 rule.hashes.clone(),
3775 ),
3776 quirks_mode,
3777 )?;
3778 }
3779
3780 match (
3781 scope_dependencies.as_mut(),
3782 collected_scope_dependencies.as_mut(),
3783 ) {
3784 (Some(inner_scope_deps), Some(scope_deps)) => {
3785 scope_deps.append(inner_scope_deps)
3786 },
3787 _ => {},
3788 }
3789 }
3790
3791 if let Some(parts) = rule.selector.parts() {
3795 let map = self
3802 .part_rules
3803 .get_or_insert_with(|| Box::new(Default::default()))
3804 .for_insertion(&pseudo_elements);
3805 map.try_reserve(1)?;
3806 let vec = map.entry(parts.last().unwrap().clone().0).or_default();
3807 vec.try_reserve(1)?;
3808 vec.push(rule);
3809 } else {
3810 let scope_matches_shadow_host = containing_rule_state
3811 .containing_scope_rule_state
3812 .matches_shadow_host
3813 == ScopeMatchesShadowHost::Yes;
3814 let matches_featureless_host_only = match rule
3815 .selector
3816 .matches_featureless_host(scope_matches_shadow_host)
3817 {
3818 MatchesFeaturelessHost::Only => true,
3819 MatchesFeaturelessHost::Yes => {
3820 self.featureless_host_rules
3822 .get_or_insert_with(|| Box::new(Default::default()))
3823 .for_insertion(&pseudo_elements)
3824 .insert(rule.clone(), quirks_mode)?;
3825 false
3826 },
3827 MatchesFeaturelessHost::Never => false,
3828 };
3829
3830 let rules = if matches_featureless_host_only {
3837 self.featureless_host_rules
3838 .get_or_insert_with(|| Box::new(Default::default()))
3839 } else if rule.selector.is_slotted() {
3840 self.slotted_rules
3841 .get_or_insert_with(|| Box::new(Default::default()))
3842 } else {
3843 &mut self.normal_rules
3844 }
3845 .for_insertion(&pseudo_elements);
3846 rules.insert(rule, quirks_mode)?;
3847 }
3848 }
3849 self.rules_source_order += 1;
3850 Ok(())
3851 }
3852
3853 fn add_rule_list<S>(
3854 &mut self,
3855 rules: std::slice::Iter<CssRule>,
3856 device: &Device,
3857 quirks_mode: QuirksMode,
3858 stylesheet: &S,
3859 sheet_index: usize,
3860 guard: &SharedRwLockReadGuard,
3861 rebuild_kind: SheetRebuildKind,
3862 containing_rule_state: &mut ContainingRuleState,
3863 mut precomputed_pseudo_element_decls: Option<&mut PrecomputedPseudoElementDeclarations>,
3864 mut difference: Option<&mut CascadeDataDifference>,
3865 ) -> Result<(), AllocErr>
3866 where
3867 S: StylesheetInDocument + 'static,
3868 {
3869 for rule in rules {
3870 let mut handled = true;
3873 let mut list_for_nested_rules = None;
3874 match *rule {
3875 CssRule::Style(ref locked) => {
3876 let style_rule = locked.read_with(guard);
3877 let has_nested_rules = style_rule.rules.is_some();
3878 let mut replaced_selectors = ReplacedSelectors::new();
3879 let ancestor_selectors = containing_rule_state.ancestor_selector_lists.last();
3880 let collect_replaced_selectors =
3881 has_nested_rules && ancestor_selectors.is_some();
3882 let mut inner_dependencies: Option<Vec<Dependency>> = containing_rule_state
3883 .scope_is_effective()
3884 .then(|| Vec::new());
3885 self.add_styles(
3886 &style_rule.selectors,
3887 &style_rule.block,
3888 ancestor_selectors,
3889 containing_rule_state,
3890 if collect_replaced_selectors {
3891 Some(&mut replaced_selectors)
3892 } else {
3893 None
3894 },
3895 guard,
3896 rebuild_kind,
3897 precomputed_pseudo_element_decls.as_deref_mut(),
3898 quirks_mode,
3899 inner_dependencies.as_mut(),
3900 )?;
3901 if let Some(mut scope_dependencies) = inner_dependencies {
3902 containing_rule_state
3903 .containing_scope_rule_state
3904 .inner_dependencies
3905 .append(&mut scope_dependencies);
3906 }
3907 if has_nested_rules {
3908 handled = false;
3909 list_for_nested_rules = Some(if collect_replaced_selectors {
3910 SelectorList::from_iter(replaced_selectors.drain(..))
3911 } else {
3912 style_rule.selectors.clone()
3913 });
3914 }
3915 },
3916 CssRule::NestedDeclarations(ref rule) => {
3917 if let Some(ref ancestor_selectors) =
3918 containing_rule_state.ancestor_selector_lists.last()
3919 {
3920 let decls = &rule.read_with(guard).block;
3921 let selectors = match containing_rule_state.nested_declarations_context {
3922 NestedDeclarationsContext::Style => ancestor_selectors,
3923 NestedDeclarationsContext::Scope => &*IMPLICIT_SCOPE,
3924 };
3925 let mut inner_dependencies: Option<Vec<Dependency>> = containing_rule_state
3926 .scope_is_effective()
3927 .then(|| Vec::new());
3928 self.add_styles(
3929 selectors,
3930 decls,
3931 None,
3932 containing_rule_state,
3933 None,
3934 guard,
3935 SheetRebuildKind::CascadeOnly,
3938 precomputed_pseudo_element_decls.as_deref_mut(),
3939 quirks_mode,
3940 inner_dependencies.as_mut(),
3941 )?;
3942 if let Some(mut scope_dependencies) = inner_dependencies {
3943 containing_rule_state
3944 .containing_scope_rule_state
3945 .inner_dependencies
3946 .append(&mut scope_dependencies);
3947 }
3948 }
3949 },
3950 CssRule::Keyframes(ref keyframes_rule) => {
3951 debug!("Found valid keyframes rule: {:?}", *keyframes_rule);
3952 let keyframes_rule = keyframes_rule.read_with(guard);
3953 let name = keyframes_rule.name.as_atom().clone();
3954 let animation = KeyframesAnimation::from_keyframes(
3955 &keyframes_rule.keyframes,
3956 keyframes_rule.vendor_prefix.clone(),
3957 guard,
3958 );
3959 self.animations.try_insert_with(
3960 name,
3961 animation,
3962 containing_rule_state.layer_id,
3963 compare_keyframes_in_same_layer,
3964 )?;
3965 },
3966 CssRule::Property(ref registration) => {
3967 self.custom_property_registrations.try_insert(
3968 registration.name.0.clone(),
3969 Arc::clone(registration),
3970 containing_rule_state.layer_id,
3971 )?;
3972 },
3973 CssRule::FontFace(ref rule) => {
3974 self.extra_data
3985 .add_font_face(rule, containing_rule_state.layer_id);
3986 },
3987 CssRule::FontFeatureValues(ref rule) => {
3988 self.extra_data
3989 .add_font_feature_values(rule, containing_rule_state.layer_id);
3990 },
3991 CssRule::FontPaletteValues(ref rule) => {
3992 self.extra_data
3993 .add_font_palette_values(rule, containing_rule_state.layer_id);
3994 },
3995 CssRule::CounterStyle(ref rule) => {
3996 self.extra_data.add_counter_style(
3997 guard,
3998 rule,
3999 containing_rule_state.layer_id,
4000 )?;
4001 },
4002 CssRule::PositionTry(ref rule) => {
4003 let name = rule.read_with(guard).name.0.clone();
4004 if let Some(ref mut difference) = difference {
4005 difference.changed_position_try_names.insert(name.clone());
4006 }
4007 self.extra_data.add_position_try(
4008 name,
4009 rule.clone(),
4010 containing_rule_state.layer_id,
4011 )?;
4012 },
4013 CssRule::Page(ref rule) => {
4014 self.extra_data
4015 .add_page(guard, rule, containing_rule_state.layer_id)?;
4016 handled = false;
4017 },
4018 _ => {
4019 handled = false;
4020 },
4021 }
4022
4023 if handled {
4024 if cfg!(debug_assertions) {
4027 let mut effective = false;
4028 let children = EffectiveRulesIterator::<&CustomMediaMap>::children(
4029 rule,
4030 device,
4031 quirks_mode,
4032 &self.custom_media,
4033 guard,
4034 &mut effective,
4035 );
4036 debug_assert!(children.is_none());
4037 debug_assert!(effective);
4038 }
4039 continue;
4040 }
4041
4042 let mut effective = false;
4043 let children = EffectiveRulesIterator::<&CustomMediaMap>::children(
4044 rule,
4045 device,
4046 quirks_mode,
4047 &self.custom_media,
4048 guard,
4049 &mut effective,
4050 );
4051 if !effective {
4052 continue;
4053 }
4054
4055 fn maybe_register_layer(data: &mut CascadeData, layer: &LayerName) -> LayerId {
4056 if let Some(id) = data.layer_id.get(layer) {
4060 return *id;
4061 }
4062 let id = LayerId(data.layers.len() as u16);
4063
4064 let parent_layer_id = if layer.layer_names().len() > 1 {
4065 let mut parent = layer.clone();
4066 parent.0.pop();
4067
4068 *data
4069 .layer_id
4070 .get_mut(&parent)
4071 .expect("Parent layers should be registered before child layers")
4072 } else {
4073 LayerId::root()
4074 };
4075
4076 data.layers[parent_layer_id.0 as usize].children.push(id);
4077 data.layers.push(CascadeLayer {
4078 id,
4079 order: LayerOrder::first(),
4082 children: vec![],
4083 });
4084
4085 data.layer_id.insert(layer.clone(), id);
4086
4087 id
4088 }
4089
4090 fn maybe_register_layers(
4091 data: &mut CascadeData,
4092 name: Option<&LayerName>,
4093 containing_rule_state: &mut ContainingRuleState,
4094 ) {
4095 let anon_name;
4096 let name = match name {
4097 Some(name) => name,
4098 None => {
4099 anon_name = LayerName::new_anonymous();
4100 &anon_name
4101 },
4102 };
4103 for name in name.layer_names() {
4104 containing_rule_state.layer_name.0.push(name.clone());
4105 containing_rule_state.layer_id =
4106 maybe_register_layer(data, &containing_rule_state.layer_name);
4107 }
4108 debug_assert_ne!(containing_rule_state.layer_id, LayerId::root());
4109 }
4110
4111 let saved_containing_rule_state = containing_rule_state.save();
4112 match *rule {
4113 CssRule::Import(ref lock) => {
4114 let import_rule = lock.read_with(guard);
4115 if rebuild_kind.should_rebuild_invalidation() {
4116 self.effective_media_query_results
4117 .saw_effective(import_rule);
4118 }
4119 match import_rule.layer {
4120 ImportLayer::Named(ref name) => {
4121 maybe_register_layers(self, Some(name), containing_rule_state)
4122 },
4123 ImportLayer::Anonymous => {
4124 maybe_register_layers(self, None, containing_rule_state)
4125 },
4126 ImportLayer::None => {},
4127 }
4128 },
4129 CssRule::Media(ref media_rule) => {
4130 if rebuild_kind.should_rebuild_invalidation() {
4131 self.effective_media_query_results
4132 .saw_effective(&**media_rule);
4133 }
4134 },
4135 CssRule::LayerBlock(ref rule) => {
4136 maybe_register_layers(self, rule.name.as_ref(), containing_rule_state);
4137 },
4138 CssRule::CustomMedia(ref custom_media) => {
4139 self.custom_media
4140 .insert(custom_media.name.0.clone(), custom_media.condition.clone());
4141 },
4142 CssRule::LayerStatement(ref rule) => {
4143 for name in &*rule.names {
4144 maybe_register_layers(self, Some(name), containing_rule_state);
4145 containing_rule_state.restore(&saved_containing_rule_state);
4147 }
4148 },
4149 CssRule::Style(..) => {
4150 containing_rule_state.nested_declarations_context =
4151 NestedDeclarationsContext::Style;
4152 if let Some(s) = list_for_nested_rules {
4153 containing_rule_state.ancestor_selector_lists.push(s);
4154 }
4155 },
4156 CssRule::Container(ref rule) => {
4157 let id = ContainerConditionId(self.container_conditions.len() as u16);
4158 self.container_conditions.push(ContainerConditionReference {
4159 parent: containing_rule_state.container_condition_id,
4160 condition: Some(rule.condition.clone()),
4161 });
4162 containing_rule_state.container_condition_id = id;
4163 },
4164 CssRule::StartingStyle(..) => {
4165 containing_rule_state.in_starting_style = true;
4166 },
4167 CssRule::Scope(ref rule) => {
4168 containing_rule_state.nested_declarations_context =
4169 NestedDeclarationsContext::Scope;
4170 let id = ScopeConditionId(self.scope_conditions.len() as u16);
4171 let mut matches_shadow_host = false;
4172 let implicit_scope_root = if let Some(start) = rule.bounds.start.as_ref() {
4173 matches_shadow_host = scope_start_matches_shadow_host(start);
4174 StylistImplicitScopeRoot::default()
4176 } else {
4177 if let Some(root) = stylesheet.implicit_scope_root() {
4180 matches_shadow_host = root.matches_shadow_host();
4181 match root {
4182 ImplicitScopeRoot::InLightTree(_)
4183 | ImplicitScopeRoot::Constructed
4184 | ImplicitScopeRoot::DocumentElement => {
4185 StylistImplicitScopeRoot::Normal(root)
4186 },
4187 ImplicitScopeRoot::ShadowHost(_)
4188 | ImplicitScopeRoot::InShadowTree(_) => {
4189 StylistImplicitScopeRoot::Cached(sheet_index)
4196 },
4197 }
4198 } else {
4199 StylistImplicitScopeRoot::default()
4201 }
4202 };
4203
4204 let replaced =
4205 {
4206 let start = rule.bounds.start.as_ref().map(|selector| {
4207 match containing_rule_state.ancestor_selector_lists.last() {
4208 Some(s) => selector.replace_parent_selector(s),
4209 None => selector.clone(),
4210 }
4211 });
4212 let implicit_scope_selector = &*IMPLICIT_SCOPE;
4213 let end = rule.bounds.end.as_ref().map(|selector| {
4214 selector.replace_parent_selector(implicit_scope_selector)
4215 });
4216 containing_rule_state
4217 .ancestor_selector_lists
4218 .push(implicit_scope_selector.clone());
4219 ScopeBoundsWithHashes::new(quirks_mode, start, end)
4220 };
4221
4222 if let Some(selectors) = replaced.start.as_ref() {
4223 self.scope_subject_map
4224 .add_bound_start(&selectors.selectors, quirks_mode);
4225 }
4226
4227 let is_trivial = replaced.is_trivial();
4228 self.scope_conditions.push(ScopeConditionReference {
4229 parent: containing_rule_state.containing_scope_rule_state.id,
4230 condition: Some(replaced),
4231 implicit_scope_root,
4232 is_trivial,
4233 });
4234
4235 containing_rule_state
4236 .containing_scope_rule_state
4237 .matches_shadow_host
4238 .nest_for_scope(matches_shadow_host);
4239 containing_rule_state.containing_scope_rule_state.id = id;
4240 containing_rule_state
4241 .containing_scope_rule_state
4242 .inner_dependencies
4243 .reserve(children.iter().len());
4244 },
4245 _ => {},
4247 }
4248
4249 if let Some(children) = children {
4250 self.add_rule_list(
4251 children,
4252 device,
4253 quirks_mode,
4254 stylesheet,
4255 sheet_index,
4256 guard,
4257 rebuild_kind,
4258 containing_rule_state,
4259 precomputed_pseudo_element_decls.as_deref_mut(),
4260 difference.as_deref_mut(),
4261 )?;
4262 }
4263
4264 if let Some(scope_restore_data) =
4265 containing_rule_state.restore(&saved_containing_rule_state)
4266 {
4267 let (cur_scope_inner_dependencies, scope_idx) = scope_restore_data;
4268 let cur_scope = &self.scope_conditions[scope_idx.0 as usize];
4269 if let Some(cond) = cur_scope.condition.as_ref() {
4270 let mut _unused = false;
4271 let visitor = StylistSelectorVisitor {
4272 needs_revalidation: &mut _unused,
4273 passed_rightmost_selector: true,
4274 in_selector_list_of: SelectorListKind::default(),
4275 mapped_ids: &mut self.mapped_ids,
4276 nth_of_mapped_ids: &mut self.nth_of_mapped_ids,
4277 attribute_dependencies: &mut self.attribute_dependencies,
4278 nth_of_class_dependencies: &mut self.nth_of_class_dependencies,
4279 nth_of_attribute_dependencies: &mut self.nth_of_attribute_dependencies,
4280 nth_of_custom_state_dependencies: &mut self
4281 .nth_of_custom_state_dependencies,
4282 state_dependencies: &mut self.state_dependencies,
4283 nth_of_state_dependencies: &mut self.nth_of_state_dependencies,
4284 document_state_dependencies: &mut self.document_state_dependencies,
4285 };
4286
4287 let dependency_vector = build_scope_dependencies(
4288 quirks_mode,
4289 cur_scope_inner_dependencies,
4290 visitor,
4291 cond,
4292 &mut self.invalidation_map,
4293 &mut self.relative_selector_invalidation_map,
4294 &mut self.additional_relative_selector_invalidation_map,
4295 )?;
4296
4297 containing_rule_state
4298 .containing_scope_rule_state
4299 .inner_dependencies
4300 .extend(dependency_vector);
4301 }
4302 }
4303 }
4304
4305 Ok(())
4306 }
4307
4308 fn add_stylesheet<S>(
4310 &mut self,
4311 device: &Device,
4312 quirks_mode: QuirksMode,
4313 stylesheet: &S,
4314 sheet_index: usize,
4315 guard: &SharedRwLockReadGuard,
4316 rebuild_kind: SheetRebuildKind,
4317 mut precomputed_pseudo_element_decls: Option<&mut PrecomputedPseudoElementDeclarations>,
4318 mut difference: Option<&mut CascadeDataDifference>,
4319 ) -> Result<(), AllocErr>
4320 where
4321 S: StylesheetInDocument + 'static,
4322 {
4323 if !stylesheet.enabled() {
4324 return Ok(());
4325 }
4326
4327 if !stylesheet.is_effective_for_device(device, &self.custom_media, guard) {
4328 return Ok(());
4329 }
4330
4331 let contents = stylesheet.contents(guard);
4332 if rebuild_kind.should_rebuild_invalidation() {
4333 self.effective_media_query_results.saw_effective(&*contents);
4334 }
4335
4336 let mut state = ContainingRuleState::default();
4337 self.add_rule_list(
4338 contents.rules(guard).iter(),
4339 device,
4340 quirks_mode,
4341 stylesheet,
4342 sheet_index,
4343 guard,
4344 rebuild_kind,
4345 &mut state,
4346 precomputed_pseudo_element_decls.as_deref_mut(),
4347 difference.as_deref_mut(),
4348 )?;
4349
4350 Ok(())
4351 }
4352
4353 pub fn media_feature_affected_matches<S>(
4356 &self,
4357 stylesheet: &S,
4358 guard: &SharedRwLockReadGuard,
4359 device: &Device,
4360 quirks_mode: QuirksMode,
4361 ) -> bool
4362 where
4363 S: StylesheetInDocument + 'static,
4364 {
4365 use crate::invalidation::media_queries::PotentiallyEffectiveMediaRules;
4366
4367 let effective_now = stylesheet.is_effective_for_device(device, &self.custom_media, guard);
4368
4369 let contents = stylesheet.contents(guard);
4370 let effective_then = self.effective_media_query_results.was_effective(contents);
4371
4372 if effective_now != effective_then {
4373 debug!(
4374 " > Stylesheet {:?} changed -> {}, {}",
4375 stylesheet.media(guard),
4376 effective_then,
4377 effective_now
4378 );
4379 return false;
4380 }
4381
4382 if !effective_now {
4383 return true;
4384 }
4385
4386 let custom_media = CustomMediaMap::default();
4388 let mut iter =
4389 contents.iter_rules::<PotentiallyEffectiveMediaRules, _>(device, &custom_media, guard);
4390 while let Some(rule) = iter.next() {
4391 match *rule {
4392 CssRule::Style(..)
4393 | CssRule::NestedDeclarations(..)
4394 | CssRule::Namespace(..)
4395 | CssRule::FontFace(..)
4396 | CssRule::Container(..)
4397 | CssRule::CounterStyle(..)
4398 | CssRule::Supports(..)
4399 | CssRule::Keyframes(..)
4400 | CssRule::Margin(..)
4401 | CssRule::Page(..)
4402 | CssRule::Property(..)
4403 | CssRule::Document(..)
4404 | CssRule::LayerBlock(..)
4405 | CssRule::LayerStatement(..)
4406 | CssRule::FontPaletteValues(..)
4407 | CssRule::FontFeatureValues(..)
4408 | CssRule::Scope(..)
4409 | CssRule::StartingStyle(..)
4410 | CssRule::CustomMedia(..)
4411 | CssRule::PositionTry(..) => {
4412 continue;
4415 },
4416 CssRule::Import(ref lock) => {
4417 let import_rule = lock.read_with(guard);
4418 let effective_now = match import_rule.stylesheet.media(guard) {
4419 Some(m) => m.evaluate(
4420 device,
4421 quirks_mode,
4422 &mut CustomMediaEvaluator::new(&self.custom_media, guard),
4423 ),
4424 None => true,
4425 };
4426 let effective_then = self
4427 .effective_media_query_results
4428 .was_effective(import_rule);
4429 if effective_now != effective_then {
4430 debug!(
4431 " > @import rule {:?} changed {} -> {}",
4432 import_rule.stylesheet.media(guard),
4433 effective_then,
4434 effective_now
4435 );
4436 return false;
4437 }
4438
4439 if !effective_now {
4440 iter.skip_children();
4441 }
4442 },
4443 CssRule::Media(ref media_rule) => {
4444 let mq = media_rule.media_queries.read_with(guard);
4445 let effective_now = mq.evaluate(
4446 device,
4447 quirks_mode,
4448 &mut CustomMediaEvaluator::new(&self.custom_media, guard),
4449 );
4450 let effective_then = self
4451 .effective_media_query_results
4452 .was_effective(&**media_rule);
4453
4454 if effective_now != effective_then {
4455 debug!(
4456 " > @media rule {:?} changed {} -> {}",
4457 mq, effective_then, effective_now
4458 );
4459 return false;
4460 }
4461
4462 if !effective_now {
4463 iter.skip_children();
4464 }
4465 },
4466 }
4467 }
4468
4469 true
4470 }
4471
4472 pub fn custom_property_registrations(&self) -> &LayerOrderedMap<Arc<PropertyRegistration>> {
4474 &self.custom_property_registrations
4475 }
4476
4477 fn revalidate_scopes<E: TElement>(
4478 &self,
4479 element: &E,
4480 matching_context: &mut MatchingContext<E::Impl>,
4481 result: &mut ScopeRevalidationResult,
4482 ) {
4483 for condition_id in 1..self.scope_conditions.len() {
4490 let condition = &self.scope_conditions[condition_id];
4491 let matches = if condition.is_trivial {
4492 continue;
4495 } else {
4496 let result = scope_root_candidates(
4497 &self.scope_conditions,
4498 ScopeConditionId(condition_id as u16),
4499 element,
4500 false,
4502 &self.scope_subject_map,
4503 matching_context,
4504 );
4505 !result.candidates.is_empty()
4506 };
4507 result.scopes_matched.push(matches);
4508 }
4509 }
4510
4511 fn clear_cascade_data(&mut self) {
4513 self.normal_rules.clear();
4514 if let Some(ref mut slotted_rules) = self.slotted_rules {
4515 slotted_rules.clear();
4516 }
4517 if let Some(ref mut part_rules) = self.part_rules {
4518 part_rules.clear();
4519 }
4520 if let Some(ref mut host_rules) = self.featureless_host_rules {
4521 host_rules.clear();
4522 }
4523 self.animations.clear();
4524 self.custom_property_registrations.clear();
4525 self.layer_id.clear();
4526 self.layers.clear();
4527 self.layers.push(CascadeLayer::root());
4528 self.custom_media.clear();
4529 self.container_conditions.clear();
4530 self.container_conditions
4531 .push(ContainerConditionReference::none());
4532 self.scope_conditions.clear();
4533 self.scope_conditions.push(ScopeConditionReference::none());
4534 self.extra_data.clear();
4535 self.rules_source_order = 0;
4536 self.num_selectors = 0;
4537 self.num_declarations = 0;
4538 }
4539
4540 fn clear_invalidation_data(&mut self) {
4541 self.invalidation_map.clear();
4542 self.relative_selector_invalidation_map.clear();
4543 self.additional_relative_selector_invalidation_map.clear();
4544 self.attribute_dependencies.clear();
4545 self.nth_of_attribute_dependencies.clear();
4546 self.nth_of_custom_state_dependencies.clear();
4547 self.nth_of_class_dependencies.clear();
4548 self.state_dependencies = ElementState::empty();
4549 self.nth_of_state_dependencies = ElementState::empty();
4550 self.document_state_dependencies = DocumentState::empty();
4551 self.mapped_ids.clear();
4552 self.nth_of_mapped_ids.clear();
4553 self.selectors_for_cache_revalidation.clear();
4554 self.effective_media_query_results.clear();
4555 self.scope_subject_map.clear();
4556 }
4557}
4558
4559fn note_scope_selector_for_invalidation(
4560 quirks_mode: QuirksMode,
4561 scope_dependencies: &Arc<servo_arc::HeaderSlice<(), Dependency>>,
4562 dependency_vector: &mut Vec<Dependency>,
4563 invalidation_map: &mut InvalidationMap,
4564 relative_selector_invalidation_map: &mut InvalidationMap,
4565 additional_relative_selector_invalidation_map: &mut AdditionalRelativeSelectorInvalidationMap,
4566 visitor: &mut StylistSelectorVisitor<'_>,
4567 scope_kind: ScopeDependencyInvalidationKind,
4568 s: &Selector<SelectorImpl>,
4569) -> Result<(), AllocErr> {
4570 let mut new_inner_dependencies = note_selector_for_invalidation(
4571 &s.clone(),
4572 quirks_mode,
4573 invalidation_map,
4574 relative_selector_invalidation_map,
4575 additional_relative_selector_invalidation_map,
4576 Some(&scope_dependencies),
4577 Some(scope_kind),
4578 )?;
4579 s.visit(visitor);
4580 new_inner_dependencies.as_mut().map(|dep| {
4581 dependency_vector.append(dep);
4582 });
4583 Ok(())
4584}
4585
4586fn build_scope_dependencies(
4587 quirks_mode: QuirksMode,
4588 mut cur_scope_inner_dependencies: Vec<Dependency>,
4589 mut visitor: StylistSelectorVisitor<'_>,
4590 cond: &ScopeBoundsWithHashes,
4591 mut invalidation_map: &mut InvalidationMap,
4592 mut relative_selector_invalidation_map: &mut InvalidationMap,
4593 mut additional_relative_selector_invalidation_map: &mut AdditionalRelativeSelectorInvalidationMap,
4594) -> Result<Vec<Dependency>, AllocErr> {
4595 if cond.end.is_some() {
4596 let deps =
4597 ThinArc::from_header_and_iter((), cur_scope_inner_dependencies.clone().into_iter());
4598 let mut end_dependency_vector = Vec::new();
4599 for s in cond.end_selectors() {
4600 note_scope_selector_for_invalidation(
4601 quirks_mode,
4602 &deps,
4603 &mut end_dependency_vector,
4604 &mut invalidation_map,
4605 &mut relative_selector_invalidation_map,
4606 &mut additional_relative_selector_invalidation_map,
4607 &mut visitor,
4608 ScopeDependencyInvalidationKind::ScopeEnd,
4609 s,
4610 )?;
4611 }
4612 cur_scope_inner_dependencies.append(&mut end_dependency_vector);
4613 }
4614 let inner_scope_dependencies =
4615 ThinArc::from_header_and_iter((), cur_scope_inner_dependencies.into_iter());
4616
4617 Ok(if cond.start.is_some() {
4618 let mut dependency_vector = Vec::new();
4619 for s in cond.start_selectors() {
4620 note_scope_selector_for_invalidation(
4621 quirks_mode,
4622 &inner_scope_dependencies,
4623 &mut dependency_vector,
4624 &mut invalidation_map,
4625 &mut relative_selector_invalidation_map,
4626 &mut additional_relative_selector_invalidation_map,
4627 &mut visitor,
4628 ScopeDependencyInvalidationKind::ExplicitScope,
4629 s,
4630 )?;
4631 }
4632 dependency_vector
4633 } else {
4634 vec![Dependency::new(
4635 IMPLICIT_SCOPE.slice()[0].clone(),
4636 0,
4637 Some(inner_scope_dependencies),
4638 DependencyInvalidationKind::Scope(ScopeDependencyInvalidationKind::ImplicitScope),
4639 )]
4640 })
4641}
4642
4643impl CascadeDataCacheEntry for CascadeData {
4644 fn rebuild<S>(
4645 device: &Device,
4646 quirks_mode: QuirksMode,
4647 collection: SheetCollectionFlusher<S>,
4648 guard: &SharedRwLockReadGuard,
4649 old: &Self,
4650 difference: &mut CascadeDataDifference,
4651 ) -> Result<Arc<Self>, AllocErr>
4652 where
4653 S: StylesheetInDocument + PartialEq + 'static,
4654 {
4655 debug_assert!(collection.dirty(), "We surely need to do something?");
4656 let mut updatable_entry = match collection.data_validity() {
4658 DataValidity::Valid | DataValidity::CascadeInvalid => old.clone(),
4659 DataValidity::FullyInvalid => Self::new(),
4660 };
4661 updatable_entry.rebuild(device, quirks_mode, collection, guard, difference)?;
4662 Ok(Arc::new(updatable_entry))
4663 }
4664
4665 #[cfg(feature = "gecko")]
4666 fn add_size_of(&self, ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes) {
4667 self.normal_rules.add_size_of(ops, sizes);
4668 if let Some(ref slotted_rules) = self.slotted_rules {
4669 slotted_rules.add_size_of(ops, sizes);
4670 }
4671 if let Some(ref part_rules) = self.part_rules {
4672 part_rules.add_size_of(ops, sizes);
4673 }
4674 if let Some(ref host_rules) = self.featureless_host_rules {
4675 host_rules.add_size_of(ops, sizes);
4676 }
4677 sizes.mInvalidationMap += self.invalidation_map.size_of(ops);
4678 sizes.mRevalidationSelectors += self.selectors_for_cache_revalidation.size_of(ops);
4679 sizes.mOther += self.animations.size_of(ops);
4680 sizes.mOther += self.effective_media_query_results.size_of(ops);
4681 sizes.mOther += self.extra_data.size_of(ops);
4682 }
4683}
4684
4685impl Default for CascadeData {
4686 fn default() -> Self {
4687 CascadeData::new()
4688 }
4689}
4690
4691#[derive(Clone, Debug, MallocSizeOf)]
4694pub struct Rule {
4695 #[ignore_malloc_size_of = "CssRules have primary refs, we measure there"]
4700 pub selector: Selector<SelectorImpl>,
4701
4702 pub hashes: AncestorHashes,
4704
4705 pub source_order: u32,
4709
4710 pub layer_id: LayerId,
4712
4713 pub container_condition_id: ContainerConditionId,
4715
4716 pub is_starting_style: bool,
4718
4719 pub scope_condition_id: ScopeConditionId,
4721
4722 #[ignore_malloc_size_of = "Secondary ref. Primary ref is in StyleRule under Stylesheet."]
4724 pub style_source: StyleSource,
4725}
4726
4727impl SelectorMapEntry for Rule {
4728 fn selector(&self) -> SelectorIter<'_, SelectorImpl> {
4729 self.selector.iter()
4730 }
4731}
4732
4733impl Rule {
4734 pub fn specificity(&self) -> u32 {
4736 self.selector.specificity()
4737 }
4738
4739 pub fn to_applicable_declaration_block(
4742 &self,
4743 level: CascadeLevel,
4744 cascade_data: &CascadeData,
4745 scope_proximity: ScopeProximity,
4746 ) -> ApplicableDeclarationBlock {
4747 ApplicableDeclarationBlock::new(
4748 self.style_source.clone(),
4749 self.source_order,
4750 level,
4751 self.specificity(),
4752 cascade_data.layer_order_for(self.layer_id),
4753 scope_proximity,
4754 )
4755 }
4756
4757 pub fn new(
4759 selector: Selector<SelectorImpl>,
4760 hashes: AncestorHashes,
4761 style_source: StyleSource,
4762 source_order: u32,
4763 layer_id: LayerId,
4764 container_condition_id: ContainerConditionId,
4765 is_starting_style: bool,
4766 scope_condition_id: ScopeConditionId,
4767 ) -> Self {
4768 Self {
4769 selector,
4770 hashes,
4771 style_source,
4772 source_order,
4773 layer_id,
4774 container_condition_id,
4775 is_starting_style,
4776 scope_condition_id,
4777 }
4778 }
4779}
4780
4781size_of_test!(Rule, 40);
4786
4787pub fn needs_revalidation_for_testing(s: &Selector<SelectorImpl>) -> bool {
4789 let mut needs_revalidation = false;
4790 let mut mapped_ids = Default::default();
4791 let mut nth_of_mapped_ids = Default::default();
4792 let mut attribute_dependencies = Default::default();
4793 let mut nth_of_class_dependencies = Default::default();
4794 let mut nth_of_attribute_dependencies = Default::default();
4795 let mut nth_of_custom_state_dependencies = Default::default();
4796 let mut state_dependencies = ElementState::empty();
4797 let mut nth_of_state_dependencies = ElementState::empty();
4798 let mut document_state_dependencies = DocumentState::empty();
4799 let mut visitor = StylistSelectorVisitor {
4800 passed_rightmost_selector: false,
4801 needs_revalidation: &mut needs_revalidation,
4802 in_selector_list_of: SelectorListKind::default(),
4803 mapped_ids: &mut mapped_ids,
4804 nth_of_mapped_ids: &mut nth_of_mapped_ids,
4805 attribute_dependencies: &mut attribute_dependencies,
4806 nth_of_class_dependencies: &mut nth_of_class_dependencies,
4807 nth_of_attribute_dependencies: &mut nth_of_attribute_dependencies,
4808 nth_of_custom_state_dependencies: &mut nth_of_custom_state_dependencies,
4809 state_dependencies: &mut state_dependencies,
4810 nth_of_state_dependencies: &mut nth_of_state_dependencies,
4811 document_state_dependencies: &mut document_state_dependencies,
4812 };
4813 s.visit(&mut visitor);
4814 needs_revalidation
4815}