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;
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::{
40 NonTSPseudoClass, PerPseudoElementMap, PseudoElement, SelectorImpl, SnapshotMap,
41};
42use crate::shared_lock::{Locked, SharedRwLockReadGuard, StylesheetGuards};
43use crate::sharing::{RevalidationResult, ScopeRevalidationResult};
44use crate::stylesheet_set::{DataValidity, DocumentStylesheetSet, SheetRebuildKind};
45use crate::stylesheet_set::{DocumentStylesheetFlusher, SheetCollectionFlusher};
46use crate::stylesheets::container_rule::ContainerCondition;
47use crate::stylesheets::import_rule::ImportLayer;
48use crate::stylesheets::keyframes_rule::KeyframesAnimation;
49use crate::stylesheets::layer_rule::{LayerName, LayerOrder};
50use crate::stylesheets::scope_rule::{
51 collect_scope_roots, element_is_outside_of_scope, scope_selector_list_is_trivial,
52 ImplicitScopeRoot, ScopeRootCandidate, ScopeSubjectMap, ScopeTarget,
53};
54#[cfg(feature = "gecko")]
55use crate::stylesheets::{
56 CounterStyleRule, FontFaceRule, FontFeatureValuesRule, FontPaletteValuesRule,
57 PagePseudoClassFlags, PositionTryRule,
58};
59use crate::stylesheets::{
60 CssRule, CssRuleRef, EffectiveRulesIterator, Origin, OriginSet, PageRule, PerOrigin,
61 PerOriginIter, StylesheetContents, StylesheetInDocument,
62};
63use crate::stylesheets::{CustomMediaEvaluator, CustomMediaMap};
64#[cfg(feature = "gecko")]
65use crate::values::specified::position::PositionTryFallbacksItem;
66use crate::values::specified::position::PositionTryFallbacksTryTactic;
67use crate::values::{computed, AtomIdent};
68use crate::AllocErr;
69use crate::{Atom, LocalName, Namespace, ShrinkIfNeeded, WeakAtom};
70use dom::{DocumentState, ElementState};
71#[cfg(feature = "gecko")]
72use malloc_size_of::MallocUnconditionalShallowSizeOf;
73use malloc_size_of::{MallocShallowSizeOf, MallocSizeOf, MallocSizeOfOps};
74use rustc_hash::FxHashMap;
75use selectors::attr::{CaseSensitivity, NamespaceConstraint};
76use selectors::bloom::BloomFilter;
77use selectors::matching::{
78 matches_selector, selector_may_match, MatchingContext, MatchingMode, NeedsSelectorFlags,
79 SelectorCaches,
80};
81use selectors::matching::{MatchingForInvalidation, VisitedHandlingMode};
82use selectors::parser::{
83 AncestorHashes, Combinator, Component, MatchesFeaturelessHost, Selector, SelectorIter,
84 SelectorList,
85};
86use selectors::visitor::{SelectorListKind, SelectorVisitor};
87use servo_arc::{Arc, ArcBorrow, ThinArc};
88use smallvec::SmallVec;
89use std::cmp::Ordering;
90use std::hash::{Hash, Hasher};
91use std::sync::{LazyLock, Mutex};
92use std::{mem, ops};
93
94#[cfg(feature = "servo")]
96pub type StylistSheet = crate::stylesheets::DocumentStyleSheet;
97
98#[cfg(feature = "gecko")]
100pub type StylistSheet = crate::gecko::data::GeckoStyleSheet;
101
102#[derive(Debug, Clone)]
103struct StylesheetContentsPtr(Arc<StylesheetContents>);
104
105impl PartialEq for StylesheetContentsPtr {
106 #[inline]
107 fn eq(&self, other: &Self) -> bool {
108 Arc::ptr_eq(&self.0, &other.0)
109 }
110}
111
112impl Eq for StylesheetContentsPtr {}
113
114impl Hash for StylesheetContentsPtr {
115 fn hash<H: Hasher>(&self, state: &mut H) {
116 let contents: &StylesheetContents = &*self.0;
117 (contents as *const StylesheetContents).hash(state)
118 }
119}
120
121type StyleSheetContentList = Vec<StylesheetContentsPtr>;
122
123#[derive(Debug, Hash, Default, PartialEq, Eq)]
125struct CascadeDataCacheKey {
126 media_query_results: Vec<MediaListKey>,
127 contents: StyleSheetContentList,
128}
129
130unsafe impl Send for CascadeDataCacheKey {}
131unsafe impl Sync for CascadeDataCacheKey {}
132
133trait CascadeDataCacheEntry: Sized {
134 fn rebuild<S>(
137 device: &Device,
138 quirks_mode: QuirksMode,
139 collection: SheetCollectionFlusher<S>,
140 guard: &SharedRwLockReadGuard,
141 old_entry: &Self,
142 ) -> Result<Arc<Self>, AllocErr>
143 where
144 S: StylesheetInDocument + PartialEq + 'static;
145 #[cfg(feature = "gecko")]
147 fn add_size_of(&self, ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes);
148}
149
150struct CascadeDataCache<Entry> {
151 entries: FxHashMap<CascadeDataCacheKey, Arc<Entry>>,
152}
153
154impl<Entry> CascadeDataCache<Entry>
155where
156 Entry: CascadeDataCacheEntry,
157{
158 fn new() -> Self {
159 Self {
160 entries: Default::default(),
161 }
162 }
163
164 fn len(&self) -> usize {
165 self.entries.len()
166 }
167
168 fn lookup<'a, S>(
173 &'a mut self,
174 device: &Device,
175 quirks_mode: QuirksMode,
176 collection: SheetCollectionFlusher<S>,
177 guard: &SharedRwLockReadGuard,
178 old_entry: &Entry,
179 ) -> Result<Option<Arc<Entry>>, AllocErr>
180 where
181 S: StylesheetInDocument + PartialEq + 'static,
182 {
183 use std::collections::hash_map::Entry as HashMapEntry;
184 debug!("StyleSheetCache::lookup({})", self.len());
185
186 if !collection.dirty() {
187 return Ok(None);
188 }
189
190 let mut key = CascadeDataCacheKey::default();
191 let mut custom_media_map = CustomMediaMap::default();
192 for sheet in collection.sheets() {
193 CascadeData::collect_applicable_media_query_results_into(
194 device,
195 sheet,
196 guard,
197 &mut key.media_query_results,
198 &mut key.contents,
199 &mut custom_media_map,
200 )
201 }
202
203 let new_entry;
204 match self.entries.entry(key) {
205 HashMapEntry::Vacant(e) => {
206 debug!("> Picking the slow path (not in the cache)");
207 new_entry = Entry::rebuild(device, quirks_mode, collection, guard, old_entry)?;
208 e.insert(new_entry.clone());
209 },
210 HashMapEntry::Occupied(mut e) => {
211 if !std::ptr::eq(&**e.get(), old_entry) {
215 if log_enabled!(log::Level::Debug) {
216 debug!("cache hit for:");
217 for sheet in collection.sheets() {
218 debug!(" > {:?}", sheet);
219 }
220 }
221 collection.each(|_, _, _| true);
224 return Ok(Some(e.get().clone()));
225 }
226
227 debug!("> Picking the slow path due to same entry as old");
228 new_entry = Entry::rebuild(device, quirks_mode, collection, guard, old_entry)?;
229 e.insert(new_entry.clone());
230 },
231 }
232
233 Ok(Some(new_entry))
234 }
235
236 fn take_unused(&mut self) -> SmallVec<[Arc<Entry>; 3]> {
244 let mut unused = SmallVec::new();
245 self.entries.retain(|_key, value| {
246 if !value.is_unique() {
250 return true;
251 }
252 unused.push(value.clone());
253 false
254 });
255 unused
256 }
257
258 fn take_all(&mut self) -> FxHashMap<CascadeDataCacheKey, Arc<Entry>> {
259 mem::take(&mut self.entries)
260 }
261
262 #[cfg(feature = "gecko")]
263 fn add_size_of(&self, ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes) {
264 sizes.mOther += self.entries.shallow_size_of(ops);
265 for (_key, arc) in self.entries.iter() {
266 sizes.mOther += arc.unconditional_shallow_size_of(ops);
269 arc.add_size_of(ops, sizes);
270 }
271 }
272}
273
274#[cfg(feature = "gecko")]
276pub fn add_size_of_ua_cache(ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes) {
277 UA_CASCADE_DATA_CACHE
278 .lock()
279 .unwrap()
280 .add_size_of(ops, sizes);
281}
282
283static UA_CASCADE_DATA_CACHE: LazyLock<Mutex<UserAgentCascadeDataCache>> =
285 LazyLock::new(|| Mutex::new(UserAgentCascadeDataCache::new()));
286
287impl CascadeDataCacheEntry for UserAgentCascadeData {
288 fn rebuild<S>(
289 device: &Device,
290 quirks_mode: QuirksMode,
291 collection: SheetCollectionFlusher<S>,
292 guard: &SharedRwLockReadGuard,
293 _old: &Self,
294 ) -> Result<Arc<Self>, AllocErr>
295 where
296 S: StylesheetInDocument + PartialEq + 'static,
297 {
298 let mut new_data = Self {
302 cascade_data: CascadeData::new(),
303 precomputed_pseudo_element_decls: PrecomputedPseudoElementDeclarations::default(),
304 };
305
306 for (index, sheet) in collection.sheets().enumerate() {
307 new_data.cascade_data.add_stylesheet(
308 device,
309 quirks_mode,
310 sheet,
311 index,
312 guard,
313 SheetRebuildKind::Full,
314 Some(&mut new_data.precomputed_pseudo_element_decls),
315 )?;
316 }
317
318 new_data.cascade_data.did_finish_rebuild();
319
320 Ok(Arc::new(new_data))
321 }
322
323 #[cfg(feature = "gecko")]
324 fn add_size_of(&self, ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes) {
325 self.cascade_data.add_size_of(ops, sizes);
326 sizes.mPrecomputedPseudos += self.precomputed_pseudo_element_decls.size_of(ops);
327 }
328}
329
330type UserAgentCascadeDataCache = CascadeDataCache<UserAgentCascadeData>;
331
332type PrecomputedPseudoElementDeclarations = PerPseudoElementMap<Vec<ApplicableDeclarationBlock>>;
333
334#[derive(Default)]
335struct UserAgentCascadeData {
336 cascade_data: CascadeData,
337
338 precomputed_pseudo_element_decls: PrecomputedPseudoElementDeclarations,
345}
346
347static EMPTY_UA_CASCADE_DATA: LazyLock<Arc<UserAgentCascadeData>> = LazyLock::new(|| {
349 let arc = Arc::new(UserAgentCascadeData::default());
350 arc.mark_as_intentionally_leaked();
351 arc
352});
353
354#[derive(MallocSizeOf)]
357pub struct DocumentCascadeData {
358 #[ignore_malloc_size_of = "Arc, owned by UserAgentCascadeDataCache or empty"]
359 user_agent: Arc<UserAgentCascadeData>,
360 user: CascadeData,
361 author: CascadeData,
362 per_origin: PerOrigin<()>,
363}
364
365impl Default for DocumentCascadeData {
366 fn default() -> Self {
367 Self {
368 user_agent: EMPTY_UA_CASCADE_DATA.clone(),
369 user: Default::default(),
370 author: Default::default(),
371 per_origin: Default::default(),
372 }
373 }
374}
375
376pub struct DocumentCascadeDataIter<'a> {
378 iter: PerOriginIter<'a, ()>,
379 cascade_data: &'a DocumentCascadeData,
380}
381
382impl<'a> Iterator for DocumentCascadeDataIter<'a> {
383 type Item = (&'a CascadeData, Origin);
384
385 fn next(&mut self) -> Option<Self::Item> {
386 let (_, origin) = self.iter.next()?;
387 Some((self.cascade_data.borrow_for_origin(origin), origin))
388 }
389}
390
391impl DocumentCascadeData {
392 #[inline]
394 pub fn borrow_for_origin(&self, origin: Origin) -> &CascadeData {
395 match origin {
396 Origin::UserAgent => &self.user_agent.cascade_data,
397 Origin::Author => &self.author,
398 Origin::User => &self.user,
399 }
400 }
401
402 fn iter_origins(&self) -> DocumentCascadeDataIter<'_> {
403 DocumentCascadeDataIter {
404 iter: self.per_origin.iter_origins(),
405 cascade_data: self,
406 }
407 }
408
409 fn iter_origins_rev(&self) -> DocumentCascadeDataIter<'_> {
410 DocumentCascadeDataIter {
411 iter: self.per_origin.iter_origins_rev(),
412 cascade_data: self,
413 }
414 }
415
416 fn custom_media_for_sheet(
417 &self,
418 s: &StylistSheet,
419 guard: &SharedRwLockReadGuard,
420 ) -> &CustomMediaMap {
421 let origin = s.contents(guard).origin;
422 &self.borrow_for_origin(origin).custom_media
423 }
424
425 fn rebuild<'a, S>(
429 &mut self,
430 device: &Device,
431 quirks_mode: QuirksMode,
432 mut flusher: DocumentStylesheetFlusher<'a, S>,
433 guards: &StylesheetGuards,
434 ) -> Result<(), AllocErr>
435 where
436 S: StylesheetInDocument + PartialEq + 'static,
437 {
438 {
440 let origin_flusher = flusher.flush_origin(Origin::UserAgent);
441 if origin_flusher.dirty() {
444 let mut ua_cache = UA_CASCADE_DATA_CACHE.lock().unwrap();
445 let new_data = ua_cache.lookup(
446 device,
447 quirks_mode,
448 origin_flusher,
449 guards.ua_or_user,
450 &self.user_agent,
451 )?;
452 if let Some(new_data) = new_data {
453 self.user_agent = new_data;
454 }
455 let _unused_entries = ua_cache.take_unused();
456 std::mem::drop(ua_cache);
459 }
460 }
461
462 self.user.rebuild(
464 device,
465 quirks_mode,
466 flusher.flush_origin(Origin::User),
467 guards.ua_or_user,
468 )?;
469
470 self.author.rebuild(
472 device,
473 quirks_mode,
474 flusher.flush_origin(Origin::Author),
475 guards.author,
476 )?;
477
478 Ok(())
479 }
480
481 #[cfg(feature = "gecko")]
483 pub fn add_size_of(&self, ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes) {
484 self.user.add_size_of(ops, sizes);
485 self.author.add_size_of(ops, sizes);
486 }
487}
488
489#[allow(missing_docs)]
493#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq)]
494pub enum AuthorStylesEnabled {
495 Yes,
496 No,
497}
498
499#[cfg_attr(feature = "servo", derive(MallocSizeOf))]
502struct StylistStylesheetSet(DocumentStylesheetSet<StylistSheet>);
503unsafe impl Sync for StylistStylesheetSet {}
505
506impl StylistStylesheetSet {
507 fn new() -> Self {
508 StylistStylesheetSet(DocumentStylesheetSet::new())
509 }
510}
511
512impl ops::Deref for StylistStylesheetSet {
513 type Target = DocumentStylesheetSet<StylistSheet>;
514
515 fn deref(&self) -> &Self::Target {
516 &self.0
517 }
518}
519
520impl ops::DerefMut for StylistStylesheetSet {
521 fn deref_mut(&mut self) -> &mut Self::Target {
522 &mut self.0
523 }
524}
525
526#[cfg_attr(feature = "servo", derive(MallocSizeOf))]
534pub struct Stylist {
535 device: Device,
548
549 stylesheets: StylistStylesheetSet,
551
552 #[cfg_attr(feature = "servo", ignore_malloc_size_of = "XXX: how to handle this?")]
554 author_data_cache: CascadeDataCache<CascadeData>,
555
556 #[cfg_attr(feature = "servo", ignore_malloc_size_of = "defined in selectors")]
558 quirks_mode: QuirksMode,
559
560 cascade_data: DocumentCascadeData,
564
565 author_styles_enabled: AuthorStylesEnabled,
567
568 rule_tree: RuleTree,
570
571 script_custom_properties: CustomPropertyScriptRegistry,
574
575 #[cfg_attr(feature = "servo", ignore_malloc_size_of = "Arc")]
577 initial_values_for_custom_properties: ComputedCustomProperties,
578
579 initial_values_for_custom_properties_flags: ComputedValueFlags,
581
582 num_rebuilds: usize,
584}
585
586#[derive(Clone, Copy, PartialEq)]
588pub enum RuleInclusion {
589 All,
592 DefaultOnly,
595}
596
597#[cfg(feature = "gecko")]
598impl From<StyleRuleInclusion> for RuleInclusion {
599 fn from(value: StyleRuleInclusion) -> Self {
600 match value {
601 StyleRuleInclusion::All => RuleInclusion::All,
602 StyleRuleInclusion::DefaultOnly => RuleInclusion::DefaultOnly,
603 }
604 }
605}
606
607#[derive(Clone, Copy, Eq, PartialEq)]
612enum ScopeMatchesShadowHost {
613 NotApplicable,
614 No,
615 Yes,
616}
617
618impl Default for ScopeMatchesShadowHost {
619 fn default() -> Self {
620 Self::NotApplicable
621 }
622}
623
624impl ScopeMatchesShadowHost {
625 fn nest_for_scope(&mut self, matches_shadow_host: bool) {
626 match *self {
627 Self::NotApplicable => {
628 *self = if matches_shadow_host {
630 Self::Yes
631 } else {
632 Self::No
633 };
634 },
635 Self::Yes if !matches_shadow_host => {
636 *self = Self::No;
638 },
639 _ => (),
640 }
641 }
642}
643
644#[derive(Copy, Clone)]
651enum NestedDeclarationsContext {
652 Style,
653 Scope,
654}
655
656struct ContainingScopeRuleState {
658 id: ScopeConditionId,
659 inner_dependencies: Vec<Dependency>,
660 matches_shadow_host: ScopeMatchesShadowHost,
661}
662
663impl Default for ContainingScopeRuleState {
664 fn default() -> Self {
665 Self {
666 id: ScopeConditionId::none(),
667 inner_dependencies: Vec::new(),
668 matches_shadow_host: Default::default(),
669 }
670 }
671}
672
673impl ContainingScopeRuleState {
674 fn save(&self) -> SavedContainingScopeRuleState {
675 SavedContainingScopeRuleState {
676 id: self.id,
677 matches_shadow_host: self.matches_shadow_host,
678 inner_dependencies_len: self.inner_dependencies.len(),
679 }
680 }
681
682 fn restore(
683 &mut self,
684 saved: &SavedContainingScopeRuleState,
685 ) -> Option<(Vec<Dependency>, ScopeConditionId)> {
686 debug_assert!(self.inner_dependencies.len() >= saved.inner_dependencies_len);
687
688 if self.id == saved.id {
689 return None;
690 }
691
692 let scope_id = self.id;
693 let inner_deps = self
694 .inner_dependencies
695 .drain(saved.inner_dependencies_len..)
696 .collect();
697
698 self.id = saved.id;
699 self.matches_shadow_host = saved.matches_shadow_host;
700
701 Some((inner_deps, scope_id))
702 }
703}
704
705struct SavedContainingScopeRuleState {
706 id: ScopeConditionId,
707 matches_shadow_host: ScopeMatchesShadowHost,
708 inner_dependencies_len: usize,
709}
710
711struct ContainingRuleState {
714 layer_name: LayerName,
715 layer_id: LayerId,
716 container_condition_id: ContainerConditionId,
717 in_starting_style: bool,
718 containing_scope_rule_state: ContainingScopeRuleState,
719 ancestor_selector_lists: SmallVec<[SelectorList<SelectorImpl>; 2]>,
720 nested_declarations_context: NestedDeclarationsContext,
721}
722
723impl Default for ContainingRuleState {
724 fn default() -> Self {
725 Self {
726 layer_name: LayerName::new_empty(),
727 layer_id: LayerId::root(),
728 container_condition_id: ContainerConditionId::none(),
729 in_starting_style: false,
730 ancestor_selector_lists: Default::default(),
731 containing_scope_rule_state: Default::default(),
732 nested_declarations_context: NestedDeclarationsContext::Style,
733 }
734 }
735}
736
737struct SavedContainingRuleState {
738 ancestor_selector_lists_len: usize,
739 layer_name_len: usize,
740 layer_id: LayerId,
741 container_condition_id: ContainerConditionId,
742 in_starting_style: bool,
743 saved_containing_scope_rule_state: SavedContainingScopeRuleState,
744 nested_declarations_context: NestedDeclarationsContext,
745}
746
747impl ContainingRuleState {
748 fn save(&self) -> SavedContainingRuleState {
749 SavedContainingRuleState {
750 ancestor_selector_lists_len: self.ancestor_selector_lists.len(),
751 layer_name_len: self.layer_name.0.len(),
752 layer_id: self.layer_id,
753 container_condition_id: self.container_condition_id,
754 in_starting_style: self.in_starting_style,
755 saved_containing_scope_rule_state: self.containing_scope_rule_state.save(),
756 nested_declarations_context: self.nested_declarations_context,
757 }
758 }
759
760 fn restore(
761 &mut self,
762 saved: &SavedContainingRuleState,
763 ) -> Option<(Vec<Dependency>, ScopeConditionId)> {
764 debug_assert!(self.layer_name.0.len() >= saved.layer_name_len);
765 debug_assert!(self.ancestor_selector_lists.len() >= saved.ancestor_selector_lists_len);
766
767 self.ancestor_selector_lists
768 .truncate(saved.ancestor_selector_lists_len);
769 self.layer_name.0.truncate(saved.layer_name_len);
770 self.layer_id = saved.layer_id;
771 self.container_condition_id = saved.container_condition_id;
772 self.in_starting_style = saved.in_starting_style;
773 self.nested_declarations_context = saved.nested_declarations_context;
774
775 self.containing_scope_rule_state
776 .restore(&saved.saved_containing_scope_rule_state)
777 }
778
779 fn scope_is_effective(&self) -> bool {
780 self.containing_scope_rule_state.id != ScopeConditionId::none()
781 }
782}
783
784type ReplacedSelectors = SmallVec<[Selector<SelectorImpl>; 4]>;
785
786impl Stylist {
787 #[inline]
791 pub fn new(device: Device, quirks_mode: QuirksMode) -> Self {
792 Self {
793 device,
794 quirks_mode,
795 stylesheets: StylistStylesheetSet::new(),
796 author_data_cache: CascadeDataCache::new(),
797 cascade_data: Default::default(),
798 author_styles_enabled: AuthorStylesEnabled::Yes,
799 rule_tree: RuleTree::new(),
800 script_custom_properties: Default::default(),
801 initial_values_for_custom_properties: Default::default(),
802 initial_values_for_custom_properties_flags: Default::default(),
803 num_rebuilds: 0,
804 }
805 }
806
807 #[inline]
809 pub fn cascade_data(&self) -> &DocumentCascadeData {
810 &self.cascade_data
811 }
812
813 #[inline]
815 pub fn author_styles_enabled(&self) -> AuthorStylesEnabled {
816 self.author_styles_enabled
817 }
818
819 #[inline]
821 pub fn iter_origins(&self) -> DocumentCascadeDataIter<'_> {
822 self.cascade_data.iter_origins()
823 }
824
825 pub fn remove_unique_author_data_cache_entries(&mut self) {
828 self.author_data_cache.take_unused();
829 }
830
831 pub fn get_custom_property_registration(&self, name: &Atom) -> &PropertyRegistrationData {
834 if let Some(registration) = self.custom_property_script_registry().get(name) {
835 return ®istration.data;
836 }
837 for (data, _) in self.iter_origins() {
838 if let Some(registration) = data.custom_property_registrations.get(name) {
839 return ®istration.data;
840 }
841 }
842 PropertyRegistrationData::unregistered()
843 }
844
845 pub fn get_custom_property_initial_values(&self) -> &ComputedCustomProperties {
847 &self.initial_values_for_custom_properties
848 }
849
850 pub fn get_custom_property_initial_values_flags(&self) -> ComputedValueFlags {
852 self.initial_values_for_custom_properties_flags
853 }
854
855 pub fn rebuild_initial_values_for_custom_properties(&mut self) {
858 let mut initial_values = ComputedCustomProperties::default();
859 let initial_values_flags;
860 {
861 let mut seen_names = PrecomputedHashSet::default();
862 let mut rule_cache_conditions = RuleCacheConditions::default();
863 let context = computed::Context::new_for_initial_at_property_value(
864 self,
865 &mut rule_cache_conditions,
866 );
867
868 for (k, v) in self.custom_property_script_registry().properties().iter() {
869 seen_names.insert(k.clone());
870 let Ok(value) = v.compute_initial_value(&context) else {
871 continue;
872 };
873 let map = if v.inherits() {
874 &mut initial_values.inherited
875 } else {
876 &mut initial_values.non_inherited
877 };
878 map.insert(k, value);
879 }
880 for (data, _) in self.iter_origins() {
881 for (k, v) in data.custom_property_registrations.iter() {
882 if seen_names.insert(k.clone()) {
883 let last_value = &v.last().unwrap().0;
884 let Ok(value) = last_value.compute_initial_value(&context) else {
885 continue;
886 };
887 let map = if last_value.inherits() {
888 &mut initial_values.inherited
889 } else {
890 &mut initial_values.non_inherited
891 };
892 map.insert(k, value);
893 }
894 }
895 }
896 initial_values_flags = context.builder.flags();
897 }
898 self.initial_values_for_custom_properties_flags = initial_values_flags;
899 self.initial_values_for_custom_properties = initial_values;
900 }
901
902 pub fn rebuild_author_data<S>(
904 &mut self,
905 old_data: &CascadeData,
906 collection: SheetCollectionFlusher<S>,
907 guard: &SharedRwLockReadGuard,
908 ) -> Result<Option<Arc<CascadeData>>, AllocErr>
909 where
910 S: StylesheetInDocument + PartialEq + 'static,
911 {
912 self.author_data_cache
913 .lookup(&self.device, self.quirks_mode, collection, guard, old_data)
914 }
915
916 #[inline]
918 pub fn iter_extra_data_origins(&self) -> ExtraStyleDataIterator<'_> {
919 ExtraStyleDataIterator(self.cascade_data.iter_origins())
920 }
921
922 #[inline]
924 pub fn iter_extra_data_origins_rev(&self) -> ExtraStyleDataIterator<'_> {
925 ExtraStyleDataIterator(self.cascade_data.iter_origins_rev())
926 }
927
928 pub fn num_selectors(&self) -> usize {
930 self.cascade_data
931 .iter_origins()
932 .map(|(d, _)| d.num_selectors)
933 .sum()
934 }
935
936 pub fn num_declarations(&self) -> usize {
938 self.cascade_data
939 .iter_origins()
940 .map(|(d, _)| d.num_declarations)
941 .sum()
942 }
943
944 pub fn num_rebuilds(&self) -> usize {
946 self.num_rebuilds
947 }
948
949 pub fn num_revalidation_selectors(&self) -> usize {
951 self.cascade_data
952 .iter_origins()
953 .map(|(data, _)| data.selectors_for_cache_revalidation.len())
954 .sum()
955 }
956
957 pub fn num_invalidations(&self) -> usize {
959 self.cascade_data
960 .iter_origins()
961 .map(|(data, _)| {
962 data.invalidation_map.len() + data.relative_selector_invalidation_map.len()
963 })
964 .sum()
965 }
966
967 pub fn has_document_state_dependency(&self, state: DocumentState) -> bool {
970 self.cascade_data
971 .iter_origins()
972 .any(|(d, _)| d.document_state_dependencies.intersects(state))
973 }
974
975 pub fn flush<E>(
978 &mut self,
979 guards: &StylesheetGuards,
980 document_element: Option<E>,
981 snapshots: Option<&SnapshotMap>,
982 ) -> bool
983 where
984 E: TElement,
985 {
986 if !self.stylesheets.has_changed() {
987 return false;
988 }
989
990 self.num_rebuilds += 1;
991
992 let flusher = self.stylesheets.flush(document_element, snapshots);
993
994 let had_invalidations = flusher.had_invalidations();
995
996 self.cascade_data
997 .rebuild(&self.device, self.quirks_mode, flusher, guards)
998 .unwrap_or_else(|_| warn!("OOM in Stylist::flush"));
999
1000 self.rebuild_initial_values_for_custom_properties();
1001
1002 had_invalidations
1003 }
1004
1005 pub fn force_stylesheet_origins_dirty(&mut self, origins: OriginSet) {
1011 self.stylesheets.force_dirty(origins)
1012 }
1013
1014 pub fn set_author_styles_enabled(&mut self, enabled: AuthorStylesEnabled) {
1016 self.author_styles_enabled = enabled;
1017 }
1018
1019 pub fn stylesheets_have_changed(&self) -> bool {
1021 self.stylesheets.has_changed()
1022 }
1023
1024 pub fn insert_stylesheet_before(
1026 &mut self,
1027 sheet: StylistSheet,
1028 before_sheet: StylistSheet,
1029 guard: &SharedRwLockReadGuard,
1030 ) {
1031 let custom_media = self.cascade_data.custom_media_for_sheet(&sheet, guard);
1032 self.stylesheets.insert_stylesheet_before(
1033 Some(&self.device),
1034 custom_media,
1035 sheet,
1036 before_sheet,
1037 guard,
1038 )
1039 }
1040
1041 pub fn append_stylesheet(&mut self, sheet: StylistSheet, guard: &SharedRwLockReadGuard) {
1043 let custom_media = self.cascade_data.custom_media_for_sheet(&sheet, guard);
1044 self.stylesheets
1045 .append_stylesheet(Some(&self.device), custom_media, sheet, guard)
1046 }
1047
1048 pub fn remove_stylesheet(&mut self, sheet: StylistSheet, guard: &SharedRwLockReadGuard) {
1050 let custom_media = self.cascade_data.custom_media_for_sheet(&sheet, guard);
1051 self.stylesheets
1052 .remove_stylesheet(Some(&self.device), custom_media, sheet, guard)
1053 }
1054
1055 pub fn rule_changed(
1057 &mut self,
1058 sheet: &StylistSheet,
1059 rule: &CssRule,
1060 guard: &SharedRwLockReadGuard,
1061 change_kind: RuleChangeKind,
1062 ancestors: &[CssRuleRef],
1063 ) {
1064 let custom_media = self.cascade_data.custom_media_for_sheet(&sheet, guard);
1065 self.stylesheets.rule_changed(
1066 Some(&self.device),
1067 custom_media,
1068 sheet,
1069 rule,
1070 guard,
1071 change_kind,
1072 ancestors,
1073 )
1074 }
1075
1076 #[inline]
1078 pub fn sheet_count(&self, origin: Origin) -> usize {
1079 self.stylesheets.sheet_count(origin)
1080 }
1081
1082 #[inline]
1084 pub fn sheet_at(&self, origin: Origin, index: usize) -> Option<&StylistSheet> {
1085 self.stylesheets.get(origin, index)
1086 }
1087
1088 pub fn any_applicable_rule_data<E, F>(&self, element: E, mut f: F) -> bool
1091 where
1092 E: TElement,
1093 F: FnMut(&CascadeData) -> bool,
1094 {
1095 if f(&self.cascade_data.user_agent.cascade_data) {
1096 return true;
1097 }
1098
1099 let mut maybe = false;
1100
1101 let doc_author_rules_apply =
1102 element.each_applicable_non_document_style_rule_data(|data, _| {
1103 maybe = maybe || f(&*data);
1104 });
1105
1106 if maybe || f(&self.cascade_data.user) {
1107 return true;
1108 }
1109
1110 doc_author_rules_apply && f(&self.cascade_data.author)
1111 }
1112
1113 pub fn for_each_cascade_data_with_scope<'a, E, F>(&'a self, element: E, mut f: F)
1115 where
1116 E: TElement + 'a,
1117 F: FnMut(&'a CascadeData, Option<E>),
1118 {
1119 f(&self.cascade_data.user_agent.cascade_data, None);
1120 element.each_applicable_non_document_style_rule_data(|data, scope| {
1121 f(data, Some(scope));
1122 });
1123 f(&self.cascade_data.user, None);
1124 f(&self.cascade_data.author, None);
1125 }
1126
1127 pub fn precomputed_values_for_pseudo<E>(
1130 &self,
1131 guards: &StylesheetGuards,
1132 pseudo: &PseudoElement,
1133 parent: Option<&ComputedValues>,
1134 ) -> Arc<ComputedValues>
1135 where
1136 E: TElement,
1137 {
1138 debug_assert!(pseudo.is_precomputed());
1139
1140 let rule_node = self.rule_node_for_precomputed_pseudo(guards, pseudo, vec![]);
1141
1142 self.precomputed_values_for_pseudo_with_rule_node::<E>(guards, pseudo, parent, rule_node)
1143 }
1144
1145 pub fn precomputed_values_for_pseudo_with_rule_node<E>(
1151 &self,
1152 guards: &StylesheetGuards,
1153 pseudo: &PseudoElement,
1154 parent: Option<&ComputedValues>,
1155 rules: StrongRuleNode,
1156 ) -> Arc<ComputedValues>
1157 where
1158 E: TElement,
1159 {
1160 self.compute_pseudo_element_style_with_inputs::<E>(
1161 CascadeInputs {
1162 rules: Some(rules),
1163 visited_rules: None,
1164 flags: Default::default(),
1165 },
1166 pseudo,
1167 guards,
1168 parent,
1169 None,
1170 )
1171 }
1172
1173 pub fn rule_node_for_precomputed_pseudo(
1179 &self,
1180 guards: &StylesheetGuards,
1181 pseudo: &PseudoElement,
1182 mut extra_declarations: Vec<ApplicableDeclarationBlock>,
1183 ) -> StrongRuleNode {
1184 let mut declarations_with_extra;
1185 let declarations = match self
1186 .cascade_data
1187 .user_agent
1188 .precomputed_pseudo_element_decls
1189 .get(pseudo)
1190 {
1191 Some(declarations) => {
1192 if !extra_declarations.is_empty() {
1193 declarations_with_extra = declarations.clone();
1194 declarations_with_extra.append(&mut extra_declarations);
1195 &*declarations_with_extra
1196 } else {
1197 &**declarations
1198 }
1199 },
1200 None => &[],
1201 };
1202
1203 self.rule_tree.insert_ordered_rules_with_important(
1204 declarations.into_iter().map(|a| a.clone().for_rule_tree()),
1205 guards,
1206 )
1207 }
1208
1209 #[cfg(feature = "servo")]
1214 pub fn style_for_anonymous<E>(
1215 &self,
1216 guards: &StylesheetGuards,
1217 pseudo: &PseudoElement,
1218 parent_style: &ComputedValues,
1219 ) -> Arc<ComputedValues>
1220 where
1221 E: TElement,
1222 {
1223 self.precomputed_values_for_pseudo::<E>(guards, &pseudo, Some(parent_style))
1224 }
1225
1226 pub fn lazily_compute_pseudo_element_style<E>(
1234 &self,
1235 guards: &StylesheetGuards,
1236 element: E,
1237 pseudo: &PseudoElement,
1238 rule_inclusion: RuleInclusion,
1239 originating_element_style: &ComputedValues,
1240 is_probe: bool,
1241 matching_fn: Option<&dyn Fn(&PseudoElement) -> bool>,
1242 ) -> Option<Arc<ComputedValues>>
1243 where
1244 E: TElement,
1245 {
1246 let cascade_inputs = self.lazy_pseudo_rules(
1247 guards,
1248 element,
1249 originating_element_style,
1250 pseudo,
1251 is_probe,
1252 rule_inclusion,
1253 matching_fn,
1254 )?;
1255
1256 Some(self.compute_pseudo_element_style_with_inputs(
1257 cascade_inputs,
1258 pseudo,
1259 guards,
1260 Some(originating_element_style),
1261 Some(element),
1262 ))
1263 }
1264
1265 pub fn compute_pseudo_element_style_with_inputs<E>(
1270 &self,
1271 inputs: CascadeInputs,
1272 pseudo: &PseudoElement,
1273 guards: &StylesheetGuards,
1274 parent_style: Option<&ComputedValues>,
1275 element: Option<E>,
1276 ) -> Arc<ComputedValues>
1277 where
1278 E: TElement,
1279 {
1280 self.cascade_style_and_visited(
1293 element,
1294 Some(pseudo),
1295 inputs,
1296 guards,
1297 parent_style,
1298 parent_style,
1299 FirstLineReparenting::No,
1300 &PositionTryFallbacksTryTactic::default(),
1301 None,
1302 &mut RuleCacheConditions::default(),
1303 )
1304 }
1305
1306 #[cfg(feature = "gecko")]
1308 pub fn resolve_position_try<E>(
1309 &self,
1310 style: &ComputedValues,
1311 guards: &StylesheetGuards,
1312 element: E,
1313 fallback_item: &PositionTryFallbacksItem,
1314 ) -> Option<Arc<ComputedValues>>
1315 where
1316 E: TElement,
1317 {
1318 let name_and_try_tactic = match *fallback_item {
1319 PositionTryFallbacksItem::PositionArea(area) => {
1320 let mut builder =
1324 StyleBuilder::for_derived_style(&self.device, Some(self), style, None);
1325 builder.mutate_position().set_position_area(area);
1326 return Some(builder.build());
1327 },
1328 PositionTryFallbacksItem::IdentAndOrTactic(ref name_and_try_tactic) => {
1329 name_and_try_tactic
1330 },
1331 };
1332
1333 let fallback_rule = if !name_and_try_tactic.ident.is_empty() {
1334 Some(self.lookup_position_try(&name_and_try_tactic.ident.0, element)?)
1335 } else {
1336 None
1337 };
1338 let fallback_block = fallback_rule
1339 .as_ref()
1340 .map(|r| &r.read_with(guards.author).block);
1341 let pseudo = style
1342 .pseudo()
1343 .or_else(|| element.implemented_pseudo_element());
1344 let inputs = {
1345 let mut inputs = CascadeInputs::new_from_style(style);
1346 inputs.visited_rules = None;
1348 let rules = inputs.rules.as_ref().unwrap_or(self.rule_tree.root());
1349 let mut important_rules_changed = false;
1350 if let Some(fallback_block) = fallback_block {
1351 let new_rules = self.rule_tree.update_rule_at_level(
1352 CascadeLevel::PositionFallback,
1353 LayerOrder::root(),
1354 Some(fallback_block.borrow_arc()),
1355 rules,
1356 guards,
1357 &mut important_rules_changed,
1358 );
1359 if new_rules.is_some() {
1360 inputs.rules = new_rules;
1361 } else {
1362 }
1366 }
1367 inputs
1368 };
1369 crate::style_resolver::with_default_parent_styles(
1370 element,
1371 |parent_style, layout_parent_style| {
1372 Some(self.cascade_style_and_visited(
1373 Some(element),
1374 pseudo.as_ref(),
1375 inputs,
1376 guards,
1377 parent_style,
1378 layout_parent_style,
1379 FirstLineReparenting::No,
1380 &name_and_try_tactic.try_tactic,
1381 None,
1382 &mut RuleCacheConditions::default(),
1383 ))
1384 },
1385 )
1386 }
1387
1388 pub fn cascade_style_and_visited<E>(
1401 &self,
1402 element: Option<E>,
1403 pseudo: Option<&PseudoElement>,
1404 inputs: CascadeInputs,
1405 guards: &StylesheetGuards,
1406 parent_style: Option<&ComputedValues>,
1407 layout_parent_style: Option<&ComputedValues>,
1408 first_line_reparenting: FirstLineReparenting,
1409 try_tactic: &PositionTryFallbacksTryTactic,
1410 rule_cache: Option<&RuleCache>,
1411 rule_cache_conditions: &mut RuleCacheConditions,
1412 ) -> Arc<ComputedValues>
1413 where
1414 E: TElement,
1415 {
1416 debug_assert!(pseudo.is_some() || element.is_some(), "Huh?");
1417
1418 let visited_rules = match inputs.visited_rules.as_ref() {
1421 Some(rules) => Some(rules),
1422 None => {
1423 if parent_style.and_then(|s| s.visited_style()).is_some() {
1424 Some(inputs.rules.as_ref().unwrap_or(self.rule_tree.root()))
1425 } else {
1426 None
1427 }
1428 },
1429 };
1430
1431 let mut implemented_pseudo = None;
1432 properties::cascade::<E>(
1439 &self,
1440 pseudo.or_else(|| {
1441 implemented_pseudo = element.unwrap().implemented_pseudo_element();
1442 implemented_pseudo.as_ref()
1443 }),
1444 inputs.rules.as_ref().unwrap_or(self.rule_tree.root()),
1445 guards,
1446 parent_style,
1447 layout_parent_style,
1448 first_line_reparenting,
1449 try_tactic,
1450 visited_rules,
1451 inputs.flags,
1452 rule_cache,
1453 rule_cache_conditions,
1454 element,
1455 )
1456 }
1457
1458 fn lazy_pseudo_rules<E>(
1463 &self,
1464 guards: &StylesheetGuards,
1465 element: E,
1466 originating_element_style: &ComputedValues,
1467 pseudo: &PseudoElement,
1468 is_probe: bool,
1469 rule_inclusion: RuleInclusion,
1470 matching_fn: Option<&dyn Fn(&PseudoElement) -> bool>,
1471 ) -> Option<CascadeInputs>
1472 where
1473 E: TElement,
1474 {
1475 debug_assert!(pseudo.is_lazy());
1476
1477 let mut selector_caches = SelectorCaches::default();
1478 let needs_selector_flags = if rule_inclusion == RuleInclusion::DefaultOnly {
1481 NeedsSelectorFlags::No
1482 } else {
1483 NeedsSelectorFlags::Yes
1484 };
1485
1486 let mut declarations = ApplicableDeclarationList::new();
1487 let mut matching_context = MatchingContext::<'_, E::Impl>::new(
1488 MatchingMode::ForStatelessPseudoElement,
1489 None,
1490 &mut selector_caches,
1491 self.quirks_mode,
1492 needs_selector_flags,
1493 MatchingForInvalidation::No,
1494 );
1495
1496 matching_context.pseudo_element_matching_fn = matching_fn;
1497 matching_context.extra_data.originating_element_style = Some(originating_element_style);
1498
1499 self.push_applicable_declarations(
1500 element,
1501 Some(&pseudo),
1502 None,
1503 None,
1504 Default::default(),
1505 rule_inclusion,
1506 &mut declarations,
1507 &mut matching_context,
1508 );
1509
1510 if declarations.is_empty() && is_probe {
1511 return None;
1512 }
1513
1514 let rules = self.rule_tree.compute_rule_node(&mut declarations, guards);
1515
1516 let mut visited_rules = None;
1517 if originating_element_style.visited_style().is_some() {
1518 let mut declarations = ApplicableDeclarationList::new();
1519 let mut selector_caches = SelectorCaches::default();
1520
1521 let mut matching_context = MatchingContext::<'_, E::Impl>::new_for_visited(
1522 MatchingMode::ForStatelessPseudoElement,
1523 None,
1524 &mut selector_caches,
1525 VisitedHandlingMode::RelevantLinkVisited,
1526 selectors::matching::IncludeStartingStyle::No,
1527 self.quirks_mode,
1528 needs_selector_flags,
1529 MatchingForInvalidation::No,
1530 );
1531 matching_context.pseudo_element_matching_fn = matching_fn;
1532 matching_context.extra_data.originating_element_style = Some(originating_element_style);
1533
1534 self.push_applicable_declarations(
1535 element,
1536 Some(&pseudo),
1537 None,
1538 None,
1539 Default::default(),
1540 rule_inclusion,
1541 &mut declarations,
1542 &mut matching_context,
1543 );
1544 if !declarations.is_empty() {
1545 let rule_node = self.rule_tree.insert_ordered_rules_with_important(
1546 declarations.drain(..).map(|a| a.for_rule_tree()),
1547 guards,
1548 );
1549 if rule_node != *self.rule_tree.root() {
1550 visited_rules = Some(rule_node);
1551 }
1552 }
1553 }
1554
1555 Some(CascadeInputs {
1556 rules: Some(rules),
1557 visited_rules,
1558 flags: matching_context.extra_data.cascade_input_flags,
1559 })
1560 }
1561
1562 pub fn set_device(&mut self, device: Device, guards: &StylesheetGuards) -> OriginSet {
1573 self.device = device;
1574 self.media_features_change_changed_style(guards, &self.device)
1575 }
1576
1577 pub fn media_features_change_changed_style(
1581 &self,
1582 guards: &StylesheetGuards,
1583 device: &Device,
1584 ) -> OriginSet {
1585 debug!("Stylist::media_features_change_changed_style {:?}", device);
1586
1587 let mut origins = OriginSet::empty();
1588 let stylesheets = self.stylesheets.iter();
1589
1590 for (stylesheet, origin) in stylesheets {
1591 if origins.contains(origin.into()) {
1592 continue;
1593 }
1594
1595 let guard = guards.for_origin(origin);
1596 let origin_cascade_data = self.cascade_data.borrow_for_origin(origin);
1597
1598 let affected_changed = !origin_cascade_data.media_feature_affected_matches(
1599 stylesheet,
1600 guard,
1601 device,
1602 self.quirks_mode,
1603 );
1604
1605 if affected_changed {
1606 origins |= origin;
1607 }
1608 }
1609
1610 origins
1611 }
1612
1613 pub fn quirks_mode(&self) -> QuirksMode {
1615 self.quirks_mode
1616 }
1617
1618 pub fn set_quirks_mode(&mut self, quirks_mode: QuirksMode) {
1620 if self.quirks_mode == quirks_mode {
1621 return;
1622 }
1623 self.quirks_mode = quirks_mode;
1624 self.force_stylesheet_origins_dirty(OriginSet::all());
1625 }
1626
1627 pub fn push_applicable_declarations<E>(
1629 &self,
1630 element: E,
1631 pseudo_element: Option<&PseudoElement>,
1632 style_attribute: Option<ArcBorrow<Locked<PropertyDeclarationBlock>>>,
1633 smil_override: Option<ArcBorrow<Locked<PropertyDeclarationBlock>>>,
1634 animation_declarations: AnimationDeclarations,
1635 rule_inclusion: RuleInclusion,
1636 applicable_declarations: &mut ApplicableDeclarationList,
1637 context: &mut MatchingContext<E::Impl>,
1638 ) where
1639 E: TElement,
1640 {
1641 let mut cur = element;
1642 let mut pseudos = SmallVec::new();
1643 if let Some(pseudo) = pseudo_element {
1644 pseudos.push(pseudo.clone());
1645 }
1646 while let Some(p) = cur.implemented_pseudo_element() {
1647 pseudos.push(p);
1648 let Some(parent_pseudo) = cur.pseudo_element_originating_element() else {
1649 break;
1650 };
1651 cur = parent_pseudo;
1652 }
1653 RuleCollector::new(
1654 self,
1655 element,
1656 pseudos,
1657 style_attribute,
1658 smil_override,
1659 animation_declarations,
1660 rule_inclusion,
1661 applicable_declarations,
1662 context,
1663 )
1664 .collect_all();
1665 }
1666
1667 #[inline]
1670 pub fn may_have_rules_for_id<E>(&self, id: &WeakAtom, element: E) -> bool
1671 where
1672 E: TElement,
1673 {
1674 match self.quirks_mode().classes_and_ids_case_sensitivity() {
1677 CaseSensitivity::AsciiCaseInsensitive => return true,
1678 CaseSensitivity::CaseSensitive => {},
1679 }
1680
1681 self.any_applicable_rule_data(element, |data| data.mapped_ids.contains(id))
1682 }
1683
1684 #[inline]
1692 fn lookup_element_dependent_at_rule<'a, T, F, E>(
1693 &'a self,
1694 element: E,
1695 find_in: F,
1696 ) -> Option<&'a T>
1697 where
1698 E: TElement + 'a,
1699 F: Fn(&'a CascadeData) -> Option<&'a T>,
1700 {
1701 macro_rules! try_find_in {
1702 ($data:expr) => {
1703 if let Some(thing) = find_in(&$data) {
1704 return Some(thing);
1705 }
1706 };
1707 }
1708
1709 let mut result = None;
1710 let doc_rules_apply =
1711 element.each_applicable_non_document_style_rule_data(|data, _host| {
1712 if result.is_none() {
1713 result = find_in(data);
1714 }
1715 });
1716
1717 if result.is_some() {
1718 return result;
1719 }
1720
1721 if doc_rules_apply {
1722 try_find_in!(self.cascade_data.author);
1723 }
1724 try_find_in!(self.cascade_data.user);
1725 try_find_in!(self.cascade_data.user_agent.cascade_data);
1726
1727 None
1728 }
1729
1730 #[inline]
1732 pub fn lookup_keyframes<'a, E>(
1733 &'a self,
1734 name: &Atom,
1735 element: E,
1736 ) -> Option<&'a KeyframesAnimation>
1737 where
1738 E: TElement + 'a,
1739 {
1740 self.lookup_element_dependent_at_rule(element, |data| data.animations.get(name))
1741 }
1742
1743 #[inline]
1745 #[cfg(feature = "gecko")]
1746 fn lookup_position_try<'a, E>(
1747 &'a self,
1748 name: &Atom,
1749 element: E,
1750 ) -> Option<&'a Arc<Locked<PositionTryRule>>>
1751 where
1752 E: TElement + 'a,
1753 {
1754 self.lookup_element_dependent_at_rule(element, |data| {
1755 data.extra_data.position_try_rules.get(name)
1756 })
1757 }
1758
1759 pub fn match_revalidation_selectors<E>(
1762 &self,
1763 element: E,
1764 bloom: Option<&BloomFilter>,
1765 selector_caches: &mut SelectorCaches,
1766 needs_selector_flags: NeedsSelectorFlags,
1767 ) -> RevalidationResult
1768 where
1769 E: TElement,
1770 {
1771 let mut matching_context = MatchingContext::new(
1774 MatchingMode::Normal,
1775 bloom,
1776 selector_caches,
1777 self.quirks_mode,
1778 needs_selector_flags,
1779 MatchingForInvalidation::No,
1780 );
1781
1782 let mut result = RevalidationResult::default();
1788 let mut relevant_attributes = &mut result.relevant_attributes;
1789 let selectors_matched = &mut result.selectors_matched;
1790
1791 let matches_document_rules =
1792 element.each_applicable_non_document_style_rule_data(|data, host| {
1793 matching_context.with_shadow_host(Some(host), |matching_context| {
1794 data.selectors_for_cache_revalidation.lookup(
1795 element,
1796 self.quirks_mode,
1797 Some(&mut relevant_attributes),
1798 |selector_and_hashes| {
1799 selectors_matched.push(matches_selector(
1800 &selector_and_hashes.selector,
1801 selector_and_hashes.selector_offset,
1802 Some(&selector_and_hashes.hashes),
1803 &element,
1804 matching_context,
1805 ));
1806 true
1807 },
1808 );
1809 })
1810 });
1811
1812 for (data, origin) in self.cascade_data.iter_origins() {
1813 if origin == Origin::Author && !matches_document_rules {
1814 continue;
1815 }
1816
1817 data.selectors_for_cache_revalidation.lookup(
1818 element,
1819 self.quirks_mode,
1820 Some(&mut relevant_attributes),
1821 |selector_and_hashes| {
1822 selectors_matched.push(matches_selector(
1823 &selector_and_hashes.selector,
1824 selector_and_hashes.selector_offset,
1825 Some(&selector_and_hashes.hashes),
1826 &element,
1827 &mut matching_context,
1828 ));
1829 true
1830 },
1831 );
1832 }
1833
1834 result
1835 }
1836
1837 pub fn revalidate_scopes<E: TElement>(
1839 &self,
1840 element: &E,
1841 selector_caches: &mut SelectorCaches,
1842 needs_selector_flags: NeedsSelectorFlags,
1843 ) -> ScopeRevalidationResult {
1844 let mut matching_context = MatchingContext::new(
1845 MatchingMode::Normal,
1846 None,
1847 selector_caches,
1848 self.quirks_mode,
1849 needs_selector_flags,
1850 MatchingForInvalidation::No,
1851 );
1852
1853 let mut result = ScopeRevalidationResult::default();
1854 let matches_document_rules =
1855 element.each_applicable_non_document_style_rule_data(|data, host| {
1856 matching_context.with_shadow_host(Some(host), |matching_context| {
1857 data.revalidate_scopes(element, matching_context, &mut result);
1858 })
1859 });
1860
1861 for (data, origin) in self.cascade_data.iter_origins() {
1862 if origin == Origin::Author && !matches_document_rules {
1863 continue;
1864 }
1865
1866 data.revalidate_scopes(element, &mut matching_context, &mut result);
1867 }
1868
1869 result
1870 }
1871
1872 pub fn compute_for_declarations<E>(
1880 &self,
1881 guards: &StylesheetGuards,
1882 parent_style: &ComputedValues,
1883 declarations: Arc<Locked<PropertyDeclarationBlock>>,
1884 ) -> Arc<ComputedValues>
1885 where
1886 E: TElement,
1887 {
1888 let block = declarations.read_with(guards.author);
1889
1890 properties::apply_declarations::<E, _>(
1897 &self,
1898 None,
1899 self.rule_tree.root(),
1900 guards,
1901 block.declaration_importance_iter().map(|(declaration, _)| {
1902 (
1903 declaration,
1904 CascadePriority::new(
1905 CascadeLevel::same_tree_author_normal(),
1906 LayerOrder::root(),
1907 ),
1908 )
1909 }),
1910 Some(parent_style),
1911 Some(parent_style),
1912 FirstLineReparenting::No,
1913 &PositionTryFallbacksTryTactic::default(),
1914 CascadeMode::Unvisited {
1915 visited_rules: None,
1916 },
1917 Default::default(),
1918 None,
1919 &mut Default::default(),
1920 None,
1921 )
1922 }
1923
1924 #[inline]
1926 pub fn device(&self) -> &Device {
1927 &self.device
1928 }
1929
1930 #[inline]
1932 pub fn device_mut(&mut self) -> &mut Device {
1933 &mut self.device
1934 }
1935
1936 #[inline]
1938 pub fn rule_tree(&self) -> &RuleTree {
1939 &self.rule_tree
1940 }
1941
1942 #[inline]
1944 pub fn custom_property_script_registry(&self) -> &CustomPropertyScriptRegistry {
1945 &self.script_custom_properties
1946 }
1947
1948 #[inline]
1950 pub fn custom_property_script_registry_mut(&mut self) -> &mut CustomPropertyScriptRegistry {
1951 &mut self.script_custom_properties
1952 }
1953
1954 #[cfg(feature = "gecko")]
1956 pub fn add_size_of(&self, ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes) {
1957 self.cascade_data.add_size_of(ops, sizes);
1958 self.author_data_cache.add_size_of(ops, sizes);
1959 sizes.mRuleTree += self.rule_tree.size_of(ops);
1960
1961 }
1963
1964 pub fn shutdown() {
1966 let _entries = UA_CASCADE_DATA_CACHE.lock().unwrap().take_all();
1967 }
1968}
1969
1970#[derive(Clone, Debug, Deref, MallocSizeOf)]
1972pub struct LayerOrderedVec<T>(Vec<(T, LayerId)>);
1973impl<T> Default for LayerOrderedVec<T> {
1974 fn default() -> Self {
1975 Self(Default::default())
1976 }
1977}
1978
1979#[derive(Clone, Debug, Deref, MallocSizeOf)]
1981pub struct LayerOrderedMap<T>(PrecomputedHashMap<Atom, SmallVec<[(T, LayerId); 1]>>);
1982impl<T> Default for LayerOrderedMap<T> {
1983 fn default() -> Self {
1984 Self(Default::default())
1985 }
1986}
1987
1988#[cfg(feature = "gecko")]
1989impl<T: 'static> LayerOrderedVec<T> {
1990 fn clear(&mut self) {
1991 self.0.clear();
1992 }
1993 fn push(&mut self, v: T, id: LayerId) {
1994 self.0.push((v, id));
1995 }
1996 fn sort(&mut self, layers: &[CascadeLayer]) {
1997 self.0
1998 .sort_by_key(|&(_, ref id)| layers[id.0 as usize].order)
1999 }
2000}
2001
2002impl<T: 'static> LayerOrderedMap<T> {
2003 fn shrink_if_needed(&mut self) {
2004 self.0.shrink_if_needed();
2005 }
2006 fn clear(&mut self) {
2007 self.0.clear();
2008 }
2009 fn try_insert(&mut self, name: Atom, v: T, id: LayerId) -> Result<(), AllocErr> {
2010 self.try_insert_with(name, v, id, |_, _| Ordering::Equal)
2011 }
2012 fn try_insert_with(
2013 &mut self,
2014 name: Atom,
2015 v: T,
2016 id: LayerId,
2017 cmp: impl Fn(&T, &T) -> Ordering,
2018 ) -> Result<(), AllocErr> {
2019 self.0.try_reserve(1)?;
2020 let vec = self.0.entry(name).or_default();
2021 if let Some(&mut (ref mut val, ref last_id)) = vec.last_mut() {
2022 if *last_id == id {
2023 if cmp(&val, &v) != Ordering::Greater {
2024 *val = v;
2025 }
2026 return Ok(());
2027 }
2028 }
2029 vec.push((v, id));
2030 Ok(())
2031 }
2032 fn sort(&mut self, layers: &[CascadeLayer]) {
2033 self.sort_with(layers, |_, _| Ordering::Equal)
2034 }
2035 fn sort_with(&mut self, layers: &[CascadeLayer], cmp: impl Fn(&T, &T) -> Ordering) {
2036 for (_, v) in self.0.iter_mut() {
2037 v.sort_by(|&(ref v1, ref id1), &(ref v2, ref id2)| {
2038 let order1 = layers[id1.0 as usize].order;
2039 let order2 = layers[id2.0 as usize].order;
2040 order1.cmp(&order2).then_with(|| cmp(v1, v2))
2041 })
2042 }
2043 }
2044 pub fn get(&self, name: &Atom) -> Option<&T> {
2046 let vec = self.0.get(name)?;
2047 Some(&vec.last()?.0)
2048 }
2049}
2050
2051#[derive(Clone, Debug, MallocSizeOf)]
2055pub struct PageRuleData {
2056 pub layer: LayerId,
2058 #[ignore_malloc_size_of = "Arc, stylesheet measures as primary ref"]
2060 pub rule: Arc<Locked<PageRule>>,
2061}
2062
2063#[derive(Clone, Debug, Default, MallocSizeOf)]
2065pub struct PageRuleMap {
2066 pub rules: PrecomputedHashMap<Atom, SmallVec<[PageRuleData; 1]>>,
2068}
2069
2070#[cfg(feature = "gecko")]
2071impl PageRuleMap {
2072 #[inline]
2073 fn clear(&mut self) {
2074 self.rules.clear();
2075 }
2076
2077 pub fn match_and_append_rules(
2081 &self,
2082 matched_rules: &mut Vec<ApplicableDeclarationBlock>,
2083 origin: Origin,
2084 guards: &StylesheetGuards,
2085 cascade_data: &DocumentCascadeData,
2086 name: &Option<Atom>,
2087 pseudos: PagePseudoClassFlags,
2088 ) {
2089 let level = match origin {
2090 Origin::UserAgent => CascadeLevel::UANormal,
2091 Origin::User => CascadeLevel::UserNormal,
2092 Origin::Author => CascadeLevel::same_tree_author_normal(),
2093 };
2094 let cascade_data = cascade_data.borrow_for_origin(origin);
2095 let start = matched_rules.len();
2096
2097 self.match_and_add_rules(
2098 matched_rules,
2099 level,
2100 guards,
2101 cascade_data,
2102 &atom!(""),
2103 pseudos,
2104 );
2105 if let Some(name) = name {
2106 self.match_and_add_rules(matched_rules, level, guards, cascade_data, name, pseudos);
2107 }
2108
2109 matched_rules[start..].sort_by_key(|block| block.sort_key());
2112 }
2113
2114 fn match_and_add_rules(
2115 &self,
2116 extra_declarations: &mut Vec<ApplicableDeclarationBlock>,
2117 level: CascadeLevel,
2118 guards: &StylesheetGuards,
2119 cascade_data: &CascadeData,
2120 name: &Atom,
2121 pseudos: PagePseudoClassFlags,
2122 ) {
2123 let rules = match self.rules.get(name) {
2124 Some(rules) => rules,
2125 None => return,
2126 };
2127 for data in rules.iter() {
2128 let rule = data.rule.read_with(level.guard(&guards));
2129 let specificity = match rule.match_specificity(pseudos) {
2130 Some(specificity) => specificity,
2131 None => continue,
2132 };
2133 let block = rule.block.clone();
2134 extra_declarations.push(ApplicableDeclarationBlock::new(
2135 StyleSource::from_declarations(block),
2136 0,
2137 level,
2138 specificity,
2139 cascade_data.layer_order_for(data.layer),
2140 ScopeProximity::infinity(), ));
2142 }
2143 }
2144}
2145
2146impl MallocShallowSizeOf for PageRuleMap {
2147 fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
2148 self.rules.shallow_size_of(ops)
2149 }
2150}
2151
2152#[derive(Clone, Debug, Default)]
2155#[cfg_attr(feature = "servo", derive(MallocSizeOf))]
2156pub struct ExtraStyleData {
2157 #[cfg(feature = "gecko")]
2159 pub font_faces: LayerOrderedVec<Arc<Locked<FontFaceRule>>>,
2160
2161 #[cfg(feature = "gecko")]
2163 pub font_feature_values: LayerOrderedVec<Arc<FontFeatureValuesRule>>,
2164
2165 #[cfg(feature = "gecko")]
2167 pub font_palette_values: LayerOrderedVec<Arc<FontPaletteValuesRule>>,
2168
2169 #[cfg(feature = "gecko")]
2171 pub counter_styles: LayerOrderedMap<Arc<Locked<CounterStyleRule>>>,
2172
2173 #[cfg(feature = "gecko")]
2175 pub position_try_rules: LayerOrderedMap<Arc<Locked<PositionTryRule>>>,
2176
2177 #[cfg(feature = "gecko")]
2179 pub pages: PageRuleMap,
2180}
2181
2182#[cfg(feature = "gecko")]
2183impl ExtraStyleData {
2184 fn add_font_face(&mut self, rule: &Arc<Locked<FontFaceRule>>, layer: LayerId) {
2186 self.font_faces.push(rule.clone(), layer);
2187 }
2188
2189 fn add_font_feature_values(&mut self, rule: &Arc<FontFeatureValuesRule>, layer: LayerId) {
2191 self.font_feature_values.push(rule.clone(), layer);
2192 }
2193
2194 fn add_font_palette_values(&mut self, rule: &Arc<FontPaletteValuesRule>, layer: LayerId) {
2196 self.font_palette_values.push(rule.clone(), layer);
2197 }
2198
2199 fn add_counter_style(
2201 &mut self,
2202 guard: &SharedRwLockReadGuard,
2203 rule: &Arc<Locked<CounterStyleRule>>,
2204 layer: LayerId,
2205 ) -> Result<(), AllocErr> {
2206 let name = rule.read_with(guard).name().0.clone();
2207 self.counter_styles.try_insert(name, rule.clone(), layer)
2208 }
2209
2210 fn add_position_try(
2212 &mut self,
2213 guard: &SharedRwLockReadGuard,
2214 rule: &Arc<Locked<PositionTryRule>>,
2215 layer: LayerId,
2216 ) -> Result<(), AllocErr> {
2217 let name = rule.read_with(guard).name.0.clone();
2218 self.position_try_rules
2219 .try_insert(name, rule.clone(), layer)
2220 }
2221
2222 fn add_page(
2224 &mut self,
2225 guard: &SharedRwLockReadGuard,
2226 rule: &Arc<Locked<PageRule>>,
2227 layer: LayerId,
2228 ) -> Result<(), AllocErr> {
2229 let page_rule = rule.read_with(guard);
2230 let mut add_rule = |name| {
2231 let vec = self.pages.rules.entry(name).or_default();
2232 vec.push(PageRuleData {
2233 layer,
2234 rule: rule.clone(),
2235 });
2236 };
2237 if page_rule.selectors.0.is_empty() {
2238 add_rule(atom!(""));
2239 } else {
2240 for selector in page_rule.selectors.as_slice() {
2241 add_rule(selector.name.0.clone());
2242 }
2243 }
2244 Ok(())
2245 }
2246
2247 fn sort_by_layer(&mut self, layers: &[CascadeLayer]) {
2248 self.font_faces.sort(layers);
2249 self.font_feature_values.sort(layers);
2250 self.font_palette_values.sort(layers);
2251 self.counter_styles.sort(layers);
2252 self.position_try_rules.sort(layers);
2253 }
2254
2255 fn clear(&mut self) {
2256 self.font_faces.clear();
2257 self.font_feature_values.clear();
2258 self.font_palette_values.clear();
2259 self.counter_styles.clear();
2260 self.position_try_rules.clear();
2261 self.pages.clear();
2262 }
2263}
2264
2265fn compare_keyframes_in_same_layer(v1: &KeyframesAnimation, v2: &KeyframesAnimation) -> Ordering {
2268 if v1.vendor_prefix.is_some() == v2.vendor_prefix.is_some() {
2269 Ordering::Equal
2270 } else if v2.vendor_prefix.is_some() {
2271 Ordering::Greater
2272 } else {
2273 Ordering::Less
2274 }
2275}
2276
2277pub struct ExtraStyleDataIterator<'a>(DocumentCascadeDataIter<'a>);
2279
2280impl<'a> Iterator for ExtraStyleDataIterator<'a> {
2281 type Item = (&'a ExtraStyleData, Origin);
2282
2283 fn next(&mut self) -> Option<Self::Item> {
2284 self.0.next().map(|d| (&d.0.extra_data, d.1))
2285 }
2286}
2287
2288#[cfg(feature = "gecko")]
2289impl MallocSizeOf for ExtraStyleData {
2290 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
2292 let mut n = 0;
2293 n += self.font_faces.shallow_size_of(ops);
2294 n += self.font_feature_values.shallow_size_of(ops);
2295 n += self.font_palette_values.shallow_size_of(ops);
2296 n += self.counter_styles.shallow_size_of(ops);
2297 n += self.position_try_rules.shallow_size_of(ops);
2298 n += self.pages.shallow_size_of(ops);
2299 n
2300 }
2301}
2302
2303#[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
2305#[derive(Clone, Debug)]
2306struct RevalidationSelectorAndHashes {
2307 #[cfg_attr(
2308 feature = "gecko",
2309 ignore_malloc_size_of = "CssRules have primary refs, we measure there"
2310 )]
2311 selector: Selector<SelectorImpl>,
2312 selector_offset: usize,
2313 hashes: AncestorHashes,
2314}
2315
2316impl RevalidationSelectorAndHashes {
2317 fn new(selector: Selector<SelectorImpl>, hashes: AncestorHashes) -> Self {
2318 let selector_offset = {
2319 let mut index = 0;
2323 let mut iter = selector.iter();
2324
2325 for _ in &mut iter {
2330 index += 1; }
2332
2333 match iter.next_sequence() {
2334 Some(Combinator::PseudoElement) => index + 1, _ => 0,
2336 }
2337 };
2338
2339 RevalidationSelectorAndHashes {
2340 selector,
2341 selector_offset,
2342 hashes,
2343 }
2344 }
2345}
2346
2347impl SelectorMapEntry for RevalidationSelectorAndHashes {
2348 fn selector(&self) -> SelectorIter<'_, SelectorImpl> {
2349 self.selector.iter_from(self.selector_offset)
2350 }
2351}
2352
2353struct StylistSelectorVisitor<'a> {
2356 passed_rightmost_selector: bool,
2359
2360 needs_revalidation: &'a mut bool,
2362
2363 in_selector_list_of: SelectorListKind,
2366
2367 mapped_ids: &'a mut PrecomputedHashSet<Atom>,
2370
2371 nth_of_mapped_ids: &'a mut PrecomputedHashSet<Atom>,
2374
2375 attribute_dependencies: &'a mut PrecomputedHashSet<LocalName>,
2377
2378 nth_of_class_dependencies: &'a mut PrecomputedHashSet<Atom>,
2381
2382 nth_of_attribute_dependencies: &'a mut PrecomputedHashSet<LocalName>,
2386
2387 nth_of_custom_state_dependencies: &'a mut PrecomputedHashSet<AtomIdent>,
2391
2392 state_dependencies: &'a mut ElementState,
2394
2395 nth_of_state_dependencies: &'a mut ElementState,
2398
2399 document_state_dependencies: &'a mut DocumentState,
2401}
2402
2403fn component_needs_revalidation(
2404 c: &Component<SelectorImpl>,
2405 passed_rightmost_selector: bool,
2406) -> bool {
2407 match *c {
2408 Component::ID(_) => {
2409 passed_rightmost_selector
2415 },
2416 Component::AttributeInNoNamespaceExists { .. }
2417 | Component::AttributeInNoNamespace { .. }
2418 | Component::AttributeOther(_)
2419 | Component::Empty
2420 | Component::Nth(_)
2421 | Component::NthOf(_)
2422 | Component::Has(_) => true,
2423 Component::NonTSPseudoClass(ref p) => p.needs_cache_revalidation(),
2424 _ => false,
2425 }
2426}
2427
2428impl<'a> StylistSelectorVisitor<'a> {
2429 fn visit_nested_selector(
2430 &mut self,
2431 in_selector_list_of: SelectorListKind,
2432 selector: &Selector<SelectorImpl>,
2433 ) {
2434 let old_passed_rightmost_selector = self.passed_rightmost_selector;
2435 let old_in_selector_list_of = self.in_selector_list_of;
2436
2437 self.passed_rightmost_selector = false;
2438 self.in_selector_list_of = in_selector_list_of;
2439 let _ret = selector.visit(self);
2440 debug_assert!(_ret, "We never return false");
2441
2442 self.passed_rightmost_selector = old_passed_rightmost_selector;
2443 self.in_selector_list_of = old_in_selector_list_of;
2444 }
2445}
2446
2447impl<'a> SelectorVisitor for StylistSelectorVisitor<'a> {
2448 type Impl = SelectorImpl;
2449
2450 fn visit_complex_selector(&mut self, combinator: Option<Combinator>) -> bool {
2451 *self.needs_revalidation =
2452 *self.needs_revalidation || combinator.map_or(false, |c| c.is_sibling());
2453
2454 self.passed_rightmost_selector = self.passed_rightmost_selector
2458 || !matches!(combinator, None | Some(Combinator::PseudoElement));
2459
2460 true
2461 }
2462
2463 fn visit_selector_list(
2464 &mut self,
2465 list_kind: SelectorListKind,
2466 list: &[Selector<Self::Impl>],
2467 ) -> bool {
2468 let in_selector_list_of = self.in_selector_list_of | list_kind;
2469 for selector in list {
2470 self.visit_nested_selector(in_selector_list_of, selector);
2471 }
2472 true
2473 }
2474
2475 fn visit_relative_selector_list(
2476 &mut self,
2477 list: &[selectors::parser::RelativeSelector<Self::Impl>],
2478 ) -> bool {
2479 let in_selector_list_of = self.in_selector_list_of | SelectorListKind::HAS;
2480 for selector in list {
2481 self.visit_nested_selector(in_selector_list_of, &selector.selector);
2482 }
2483 true
2484 }
2485
2486 fn visit_attribute_selector(
2487 &mut self,
2488 _ns: &NamespaceConstraint<&Namespace>,
2489 name: &LocalName,
2490 lower_name: &LocalName,
2491 ) -> bool {
2492 if self.in_selector_list_of.relevant_to_nth_of_dependencies() {
2493 self.nth_of_attribute_dependencies.insert(name.clone());
2494 if name != lower_name {
2495 self.nth_of_attribute_dependencies
2496 .insert(lower_name.clone());
2497 }
2498 }
2499
2500 self.attribute_dependencies.insert(name.clone());
2501 if name != lower_name {
2502 self.attribute_dependencies.insert(lower_name.clone());
2503 }
2504
2505 true
2506 }
2507
2508 fn visit_simple_selector(&mut self, s: &Component<SelectorImpl>) -> bool {
2509 *self.needs_revalidation = *self.needs_revalidation
2510 || component_needs_revalidation(s, self.passed_rightmost_selector);
2511
2512 match *s {
2513 Component::NonTSPseudoClass(NonTSPseudoClass::CustomState(ref name)) => {
2514 if self.in_selector_list_of.relevant_to_nth_of_dependencies() {
2520 self.nth_of_custom_state_dependencies.insert(name.0.clone());
2521 }
2522 },
2523 Component::NonTSPseudoClass(ref p) => {
2524 self.state_dependencies.insert(p.state_flag());
2525 self.document_state_dependencies
2526 .insert(p.document_state_flag());
2527
2528 if self.in_selector_list_of.relevant_to_nth_of_dependencies() {
2529 self.nth_of_state_dependencies.insert(p.state_flag());
2530 }
2531 },
2532 Component::ID(ref id) => {
2533 if !self.passed_rightmost_selector {
2545 self.mapped_ids.insert(id.0.clone());
2546 }
2547
2548 if self.in_selector_list_of.relevant_to_nth_of_dependencies() {
2549 self.nth_of_mapped_ids.insert(id.0.clone());
2550 }
2551 },
2552 Component::Class(ref class)
2553 if self.in_selector_list_of.relevant_to_nth_of_dependencies() =>
2554 {
2555 self.nth_of_class_dependencies.insert(class.0.clone());
2556 },
2557 _ => {},
2558 }
2559
2560 true
2561 }
2562}
2563
2564#[derive(Clone, Debug, Default, MallocSizeOf)]
2566struct GenericElementAndPseudoRules<Map> {
2567 element_map: Map,
2569
2570 pseudos_map: PerPseudoElementMap<Self>,
2577}
2578
2579impl<Map: Default + MallocSizeOf> GenericElementAndPseudoRules<Map> {
2580 #[inline(always)]
2581 fn for_insertion<'a>(&mut self, pseudo_elements: &[&'a PseudoElement]) -> &mut Map {
2582 let mut current = self;
2583 for &pseudo_element in pseudo_elements {
2584 debug_assert!(
2585 !pseudo_element.is_precomputed()
2586 && !pseudo_element.is_unknown_webkit_pseudo_element(),
2587 "Precomputed pseudos should end up in precomputed_pseudo_element_decls, \
2588 and unknown webkit pseudos should be discarded before getting here"
2589 );
2590
2591 current = current
2592 .pseudos_map
2593 .get_or_insert_with(pseudo_element, Default::default);
2594 }
2595
2596 &mut current.element_map
2597 }
2598
2599 #[inline]
2600 fn rules(&self, pseudo_elements: &[PseudoElement]) -> Option<&Map> {
2601 let mut current = self;
2602 for pseudo in pseudo_elements {
2603 current = current.pseudos_map.get(&pseudo)?;
2604 }
2605 Some(¤t.element_map)
2606 }
2607
2608 #[cfg(feature = "gecko")]
2610 fn add_size_of(&self, ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes) {
2611 sizes.mElementAndPseudosMaps += self.element_map.size_of(ops);
2612
2613 for elem in self.pseudos_map.iter() {
2614 sizes.mElementAndPseudosMaps += MallocSizeOf::size_of(elem, ops);
2615 }
2616 }
2617}
2618
2619type ElementAndPseudoRules = GenericElementAndPseudoRules<SelectorMap<Rule>>;
2620type PartMap = PrecomputedHashMap<Atom, SmallVec<[Rule; 1]>>;
2621type PartElementAndPseudoRules = GenericElementAndPseudoRules<PartMap>;
2622
2623impl ElementAndPseudoRules {
2624 fn clear(&mut self) {
2626 self.element_map.clear();
2627 self.pseudos_map.clear();
2628 }
2629
2630 fn shrink_if_needed(&mut self) {
2631 self.element_map.shrink_if_needed();
2632 for pseudo in self.pseudos_map.iter_mut() {
2633 pseudo.shrink_if_needed();
2634 }
2635 }
2636}
2637
2638impl PartElementAndPseudoRules {
2639 fn clear(&mut self) {
2641 self.element_map.clear();
2642 self.pseudos_map.clear();
2643 }
2644}
2645
2646#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, PartialOrd, Ord)]
2648pub struct LayerId(u16);
2649
2650impl LayerId {
2651 pub const fn root() -> Self {
2653 Self(0)
2654 }
2655}
2656
2657#[derive(Clone, Debug, MallocSizeOf)]
2658struct CascadeLayer {
2659 id: LayerId,
2660 order: LayerOrder,
2661 children: Vec<LayerId>,
2662}
2663
2664impl CascadeLayer {
2665 const fn root() -> Self {
2666 Self {
2667 id: LayerId::root(),
2668 order: LayerOrder::root(),
2669 children: vec![],
2670 }
2671 }
2672}
2673
2674#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, PartialOrd, Ord)]
2677pub struct ContainerConditionId(u16);
2678
2679impl ContainerConditionId {
2680 pub const fn none() -> Self {
2682 Self(0)
2683 }
2684}
2685
2686#[derive(Clone, Debug, MallocSizeOf)]
2687struct ContainerConditionReference {
2688 parent: ContainerConditionId,
2689 #[ignore_malloc_size_of = "Arc"]
2690 condition: Option<Arc<ContainerCondition>>,
2691}
2692
2693impl ContainerConditionReference {
2694 const fn none() -> Self {
2695 Self {
2696 parent: ContainerConditionId::none(),
2697 condition: None,
2698 }
2699 }
2700}
2701
2702#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, PartialOrd, Ord)]
2705pub struct ScopeConditionId(u16);
2706
2707impl ScopeConditionId {
2708 pub fn new(id: u16) -> Self {
2710 Self(id)
2711 }
2712
2713 pub const fn none() -> Self {
2715 Self(0)
2716 }
2717}
2718
2719#[derive(Clone, Debug, MallocSizeOf)]
2721pub struct ScopeConditionReference {
2722 parent: ScopeConditionId,
2724 condition: Option<ScopeBoundsWithHashes>,
2726 #[ignore_malloc_size_of = "Raw ptr behind the scenes"]
2729 implicit_scope_root: StylistImplicitScopeRoot,
2730 is_trivial: bool,
2732}
2733
2734impl ScopeConditionReference {
2735 pub fn new(
2737 parent: ScopeConditionId,
2738 condition: Option<ScopeBoundsWithHashes>,
2739 implicit_scope_root: ImplicitScopeRoot,
2740 is_trivial: bool,
2741 ) -> Self {
2742 Self {
2743 parent,
2744 condition,
2745 implicit_scope_root: StylistImplicitScopeRoot::Normal(implicit_scope_root),
2746 is_trivial,
2747 }
2748 }
2749
2750 pub const fn none() -> Self {
2752 Self {
2753 parent: ScopeConditionId::none(),
2754 condition: None,
2755 implicit_scope_root: StylistImplicitScopeRoot::default_const(),
2756 is_trivial: true,
2757 }
2758 }
2759}
2760
2761pub struct ScopeRootCandidates {
2763 pub candidates: Vec<ScopeRootCandidate>,
2765 pub is_trivial: bool,
2767}
2768
2769impl Default for ScopeRootCandidates {
2770 fn default() -> Self {
2771 Self {
2772 candidates: vec![],
2773 is_trivial: true,
2774 }
2775 }
2776}
2777
2778impl ScopeRootCandidates {
2779 fn empty(is_trivial: bool) -> Self {
2780 Self {
2781 candidates: vec![],
2782 is_trivial,
2783 }
2784 }
2785}
2786
2787#[derive(Clone, Debug, MallocSizeOf)]
2789pub struct ScopeBoundWithHashes {
2790 #[ignore_malloc_size_of = "Arc"]
2792 selectors: SelectorList<SelectorImpl>,
2793 hashes: SmallVec<[AncestorHashes; 1]>,
2794}
2795
2796impl ScopeBoundWithHashes {
2797 fn new(quirks_mode: QuirksMode, selectors: SelectorList<SelectorImpl>) -> Self {
2798 let mut hashes = SmallVec::with_capacity(selectors.len());
2799 for selector in selectors.slice() {
2800 hashes.push(AncestorHashes::new(selector, quirks_mode));
2801 }
2802 Self { selectors, hashes }
2803 }
2804
2805 fn new_no_hash(selectors: SelectorList<SelectorImpl>) -> Self {
2806 let hashes = selectors
2807 .slice()
2808 .iter()
2809 .map(|_| AncestorHashes {
2810 packed_hashes: [0, 0, 0],
2811 })
2812 .collect();
2813 Self { selectors, hashes }
2814 }
2815}
2816
2817#[derive(Clone, Debug, MallocSizeOf)]
2819pub struct ScopeBoundsWithHashes {
2820 start: Option<ScopeBoundWithHashes>,
2822 end: Option<ScopeBoundWithHashes>,
2824}
2825
2826impl ScopeBoundsWithHashes {
2827 fn new(
2829 quirks_mode: QuirksMode,
2830 start: Option<SelectorList<SelectorImpl>>,
2831 end: Option<SelectorList<SelectorImpl>>,
2832 ) -> Self {
2833 Self {
2834 start: start.map(|selectors| ScopeBoundWithHashes::new(quirks_mode, selectors)),
2835 end: end.map(|selectors| ScopeBoundWithHashes::new(quirks_mode, selectors)),
2836 }
2837 }
2838
2839 pub fn new_no_hash(
2841 start: Option<SelectorList<SelectorImpl>>,
2842 end: Option<SelectorList<SelectorImpl>>,
2843 ) -> Self {
2844 Self {
2845 start: start.map(|selectors| ScopeBoundWithHashes::new_no_hash(selectors)),
2846 end: end.map(|selectors| ScopeBoundWithHashes::new_no_hash(selectors)),
2847 }
2848 }
2849
2850 fn selectors_for<'a>(
2851 bound_with_hashes: Option<&'a ScopeBoundWithHashes>,
2852 ) -> impl Iterator<Item = &'a Selector<SelectorImpl>> {
2853 bound_with_hashes
2854 .map(|b| b.selectors.slice().iter())
2855 .into_iter()
2856 .flatten()
2857 }
2858
2859 fn start_selectors<'a>(&'a self) -> impl Iterator<Item = &'a Selector<SelectorImpl>> {
2860 Self::selectors_for(self.start.as_ref())
2861 }
2862
2863 fn end_selectors<'a>(&'a self) -> impl Iterator<Item = &'a Selector<SelectorImpl>> {
2864 Self::selectors_for(self.end.as_ref())
2865 }
2866
2867 fn is_trivial(&self) -> bool {
2868 fn scope_bound_is_trivial(bound: &Option<ScopeBoundWithHashes>, default: bool) -> bool {
2869 bound.as_ref().map_or(default, |bound| {
2870 scope_selector_list_is_trivial(&bound.selectors)
2871 })
2872 }
2873
2874 scope_bound_is_trivial(&self.start, false) && scope_bound_is_trivial(&self.end, true)
2876 }
2877}
2878
2879pub fn scope_root_candidates<E>(
2881 scope_conditions: &[ScopeConditionReference],
2882 id: ScopeConditionId,
2883 element: &E,
2884 override_matches_shadow_host_for_part: bool,
2885 scope_subject_map: &ScopeSubjectMap,
2886 context: &mut MatchingContext<SelectorImpl>,
2887) -> ScopeRootCandidates
2888where
2889 E: TElement,
2890{
2891 let condition_ref = &scope_conditions[id.0 as usize];
2892 let bounds = match condition_ref.condition {
2893 None => return ScopeRootCandidates::default(),
2894 Some(ref c) => c,
2895 };
2896 let outer_result = scope_root_candidates(
2900 scope_conditions,
2901 condition_ref.parent,
2902 element,
2903 override_matches_shadow_host_for_part,
2904 scope_subject_map,
2905 context,
2906 );
2907
2908 let is_trivial = condition_ref.is_trivial && outer_result.is_trivial;
2909 let is_outermost_scope = condition_ref.parent == ScopeConditionId::none();
2910 if !is_outermost_scope && outer_result.candidates.is_empty() {
2911 return ScopeRootCandidates::empty(is_trivial);
2912 }
2913
2914 let (root_target, matches_shadow_host) = if let Some(start) = bounds.start.as_ref() {
2915 if let Some(filter) = context.bloom_filter {
2916 if !start
2921 .hashes
2922 .iter()
2923 .any(|entry| selector_may_match(entry, filter))
2924 {
2925 return ScopeRootCandidates::empty(is_trivial);
2926 }
2927 }
2928 (
2929 ScopeTarget::Selector(&start.selectors),
2930 scope_start_matches_shadow_host(&start.selectors),
2931 )
2932 } else {
2933 let implicit_root = condition_ref.implicit_scope_root;
2934 match implicit_root {
2935 StylistImplicitScopeRoot::Normal(r) => (
2936 ScopeTarget::Implicit(r.element(context.current_host.clone())),
2937 r.matches_shadow_host(),
2938 ),
2939 StylistImplicitScopeRoot::Cached(index) => {
2940 let host = context
2941 .current_host
2942 .expect("Cached implicit scope for light DOM implicit scope");
2943 match E::implicit_scope_for_sheet_in_shadow_root(host, index) {
2944 None => return ScopeRootCandidates::empty(is_trivial),
2945 Some(root) => (
2946 ScopeTarget::Implicit(root.element(context.current_host.clone())),
2947 root.matches_shadow_host(),
2948 ),
2949 }
2950 },
2951 }
2952 };
2953 let matches_shadow_host = override_matches_shadow_host_for_part || matches_shadow_host;
2956
2957 let potential_scope_roots = if is_outermost_scope {
2958 collect_scope_roots(
2959 *element,
2960 None,
2961 context,
2962 &root_target,
2963 matches_shadow_host,
2964 scope_subject_map,
2965 )
2966 } else {
2967 let mut result = vec![];
2968 for activation in outer_result.candidates {
2969 let mut this_result = collect_scope_roots(
2970 *element,
2971 Some(activation.root),
2972 context,
2973 &root_target,
2974 matches_shadow_host,
2975 scope_subject_map,
2976 );
2977 result.append(&mut this_result);
2978 }
2979 result
2980 };
2981
2982 if potential_scope_roots.is_empty() {
2983 return ScopeRootCandidates::empty(is_trivial);
2984 }
2985
2986 let candidates = if let Some(end) = bounds.end.as_ref() {
2987 let mut result = vec![];
2988 for scope_root in potential_scope_roots {
2990 if end
2991 .selectors
2992 .slice()
2993 .iter()
2994 .zip(end.hashes.iter())
2995 .all(|(selector, hashes)| {
2996 if let Some(filter) = context.bloom_filter {
2998 if !selector_may_match(hashes, filter) {
2999 return true;
3001 }
3002 }
3003
3004 !element_is_outside_of_scope(
3005 selector,
3006 *element,
3007 scope_root.root,
3008 context,
3009 matches_shadow_host,
3010 )
3011 })
3012 {
3013 result.push(scope_root);
3014 }
3015 }
3016 result
3017 } else {
3018 potential_scope_roots
3019 };
3020
3021 ScopeRootCandidates {
3022 candidates,
3023 is_trivial,
3024 }
3025}
3026
3027#[derive(Copy, Clone, Debug, MallocSizeOf)]
3030enum StylistImplicitScopeRoot {
3031 Normal(ImplicitScopeRoot),
3032 Cached(usize),
3033}
3034unsafe impl Sync for StylistImplicitScopeRoot {}
3036
3037impl StylistImplicitScopeRoot {
3038 const fn default_const() -> Self {
3039 Self::Normal(ImplicitScopeRoot::DocumentElement)
3041 }
3042}
3043
3044impl Default for StylistImplicitScopeRoot {
3045 fn default() -> Self {
3046 Self::default_const()
3047 }
3048}
3049
3050#[derive(Debug, Clone, MallocSizeOf)]
3056pub struct CascadeData {
3057 normal_rules: ElementAndPseudoRules,
3060
3061 featureless_host_rules: Option<Box<ElementAndPseudoRules>>,
3065
3066 slotted_rules: Option<Box<ElementAndPseudoRules>>,
3074
3075 part_rules: Option<Box<PartElementAndPseudoRules>>,
3080
3081 invalidation_map: InvalidationMap,
3083
3084 relative_selector_invalidation_map: InvalidationMap,
3086
3087 additional_relative_selector_invalidation_map: AdditionalRelativeSelectorInvalidationMap,
3088
3089 attribute_dependencies: PrecomputedHashSet<LocalName>,
3094
3095 nth_of_class_dependencies: PrecomputedHashSet<Atom>,
3099
3100 nth_of_attribute_dependencies: PrecomputedHashSet<LocalName>,
3104
3105 nth_of_custom_state_dependencies: PrecomputedHashSet<AtomIdent>,
3109
3110 state_dependencies: ElementState,
3114
3115 nth_of_state_dependencies: ElementState,
3118
3119 document_state_dependencies: DocumentState,
3123
3124 mapped_ids: PrecomputedHashSet<Atom>,
3129
3130 nth_of_mapped_ids: PrecomputedHashSet<Atom>,
3134
3135 #[ignore_malloc_size_of = "Arc"]
3139 selectors_for_cache_revalidation: SelectorMap<RevalidationSelectorAndHashes>,
3140
3141 animations: LayerOrderedMap<KeyframesAnimation>,
3144
3145 #[ignore_malloc_size_of = "Arc"]
3148 custom_property_registrations: LayerOrderedMap<Arc<PropertyRegistration>>,
3149
3150 custom_media: CustomMediaMap,
3152
3153 layer_id: FxHashMap<LayerName, LayerId>,
3155
3156 layers: SmallVec<[CascadeLayer; 1]>,
3158
3159 container_conditions: SmallVec<[ContainerConditionReference; 1]>,
3161
3162 scope_conditions: SmallVec<[ScopeConditionReference; 1]>,
3164
3165 scope_subject_map: ScopeSubjectMap,
3167
3168 effective_media_query_results: EffectiveMediaQueryResults,
3170
3171 extra_data: ExtraStyleData,
3173
3174 rules_source_order: u32,
3177
3178 num_selectors: usize,
3180
3181 num_declarations: usize,
3183}
3184
3185static IMPLICIT_SCOPE: LazyLock<SelectorList<SelectorImpl>> = LazyLock::new(|| {
3186 let list = SelectorList::implicit_scope();
3190 list.mark_as_intentionally_leaked();
3191 list
3192});
3193
3194fn scope_start_matches_shadow_host(start: &SelectorList<SelectorImpl>) -> bool {
3195 start
3198 .slice()
3199 .iter()
3200 .any(|s| s.matches_featureless_host(true).may_match())
3201}
3202
3203pub fn replace_parent_selector_with_implicit_scope(
3205 selectors: &SelectorList<SelectorImpl>,
3206) -> SelectorList<SelectorImpl> {
3207 selectors.replace_parent_selector(&IMPLICIT_SCOPE)
3208}
3209
3210impl CascadeData {
3211 pub fn new() -> Self {
3213 Self {
3214 normal_rules: ElementAndPseudoRules::default(),
3215 featureless_host_rules: None,
3216 slotted_rules: None,
3217 part_rules: None,
3218 invalidation_map: InvalidationMap::new(),
3219 relative_selector_invalidation_map: InvalidationMap::new(),
3220 additional_relative_selector_invalidation_map:
3221 AdditionalRelativeSelectorInvalidationMap::new(),
3222 nth_of_mapped_ids: PrecomputedHashSet::default(),
3223 nth_of_class_dependencies: PrecomputedHashSet::default(),
3224 nth_of_attribute_dependencies: PrecomputedHashSet::default(),
3225 nth_of_custom_state_dependencies: PrecomputedHashSet::default(),
3226 nth_of_state_dependencies: ElementState::empty(),
3227 attribute_dependencies: PrecomputedHashSet::default(),
3228 state_dependencies: ElementState::empty(),
3229 document_state_dependencies: DocumentState::empty(),
3230 mapped_ids: PrecomputedHashSet::default(),
3231 selectors_for_cache_revalidation: SelectorMap::new(),
3232 animations: Default::default(),
3233 custom_property_registrations: Default::default(),
3234 custom_media: Default::default(),
3235 layer_id: Default::default(),
3236 layers: smallvec::smallvec![CascadeLayer::root()],
3237 container_conditions: smallvec::smallvec![ContainerConditionReference::none()],
3238 scope_conditions: smallvec::smallvec![ScopeConditionReference::none()],
3239 scope_subject_map: Default::default(),
3240 extra_data: ExtraStyleData::default(),
3241 effective_media_query_results: EffectiveMediaQueryResults::new(),
3242 rules_source_order: 0,
3243 num_selectors: 0,
3244 num_declarations: 0,
3245 }
3246 }
3247
3248 pub fn rebuild<'a, S>(
3251 &mut self,
3252 device: &Device,
3253 quirks_mode: QuirksMode,
3254 collection: SheetCollectionFlusher<S>,
3255 guard: &SharedRwLockReadGuard,
3256 ) -> Result<(), AllocErr>
3257 where
3258 S: StylesheetInDocument + PartialEq + 'static,
3259 {
3260 if !collection.dirty() {
3261 return Ok(());
3262 }
3263
3264 let validity = collection.data_validity();
3265
3266 match validity {
3267 DataValidity::Valid => {},
3268 DataValidity::CascadeInvalid => self.clear_cascade_data(),
3269 DataValidity::FullyInvalid => self.clear(),
3270 }
3271
3272 let mut result = Ok(());
3273
3274 collection.each(|index, stylesheet, rebuild_kind| {
3275 result = self.add_stylesheet(
3276 device,
3277 quirks_mode,
3278 stylesheet,
3279 index,
3280 guard,
3281 rebuild_kind,
3282 None,
3283 );
3284 result.is_ok()
3285 });
3286
3287 self.did_finish_rebuild();
3288
3289 result
3290 }
3291
3292 pub fn custom_media_map(&self) -> &CustomMediaMap {
3294 &self.custom_media
3295 }
3296
3297 pub fn invalidation_map(&self) -> &InvalidationMap {
3299 &self.invalidation_map
3300 }
3301
3302 pub fn relative_selector_invalidation_map(&self) -> &InvalidationMap {
3304 &self.relative_selector_invalidation_map
3305 }
3306
3307 pub fn relative_invalidation_map_attributes(
3309 &self,
3310 ) -> &AdditionalRelativeSelectorInvalidationMap {
3311 &self.additional_relative_selector_invalidation_map
3312 }
3313
3314 #[inline]
3317 pub fn has_state_dependency(&self, state: ElementState) -> bool {
3318 self.state_dependencies.intersects(state)
3319 }
3320
3321 #[inline]
3324 pub fn has_nth_of_custom_state_dependency(&self, state: &AtomIdent) -> bool {
3325 self.nth_of_custom_state_dependencies.contains(state)
3326 }
3327
3328 #[inline]
3331 pub fn has_nth_of_state_dependency(&self, state: ElementState) -> bool {
3332 self.nth_of_state_dependencies.intersects(state)
3333 }
3334
3335 #[inline]
3338 pub fn might_have_attribute_dependency(&self, local_name: &LocalName) -> bool {
3339 self.attribute_dependencies.contains(local_name)
3340 }
3341
3342 #[inline]
3345 pub fn might_have_nth_of_id_dependency(&self, id: &Atom) -> bool {
3346 self.nth_of_mapped_ids.contains(id)
3347 }
3348
3349 #[inline]
3352 pub fn might_have_nth_of_class_dependency(&self, class: &Atom) -> bool {
3353 self.nth_of_class_dependencies.contains(class)
3354 }
3355
3356 #[inline]
3359 pub fn might_have_nth_of_attribute_dependency(&self, local_name: &LocalName) -> bool {
3360 self.nth_of_attribute_dependencies.contains(local_name)
3361 }
3362
3363 #[inline]
3365 pub fn normal_rules(&self, pseudo_elements: &[PseudoElement]) -> Option<&SelectorMap<Rule>> {
3366 self.normal_rules.rules(pseudo_elements)
3367 }
3368
3369 #[inline]
3371 pub fn featureless_host_rules(
3372 &self,
3373 pseudo_elements: &[PseudoElement],
3374 ) -> Option<&SelectorMap<Rule>> {
3375 self.featureless_host_rules
3376 .as_ref()
3377 .and_then(|d| d.rules(pseudo_elements))
3378 }
3379
3380 pub fn any_featureless_host_rules(&self) -> bool {
3382 self.featureless_host_rules.is_some()
3383 }
3384
3385 #[inline]
3387 pub fn slotted_rules(&self, pseudo_elements: &[PseudoElement]) -> Option<&SelectorMap<Rule>> {
3388 self.slotted_rules
3389 .as_ref()
3390 .and_then(|d| d.rules(pseudo_elements))
3391 }
3392
3393 pub fn any_slotted_rule(&self) -> bool {
3395 self.slotted_rules.is_some()
3396 }
3397
3398 #[inline]
3400 pub fn part_rules(&self, pseudo_elements: &[PseudoElement]) -> Option<&PartMap> {
3401 self.part_rules
3402 .as_ref()
3403 .and_then(|d| d.rules(pseudo_elements))
3404 }
3405
3406 pub fn any_part_rule(&self) -> bool {
3408 self.part_rules.is_some()
3409 }
3410
3411 #[inline]
3412 fn layer_order_for(&self, id: LayerId) -> LayerOrder {
3413 self.layers[id.0 as usize].order
3414 }
3415
3416 pub(crate) fn container_condition_matches<E>(
3417 &self,
3418 mut id: ContainerConditionId,
3419 stylist: &Stylist,
3420 element: E,
3421 context: &mut MatchingContext<E::Impl>,
3422 ) -> bool
3423 where
3424 E: TElement,
3425 {
3426 loop {
3427 let condition_ref = &self.container_conditions[id.0 as usize];
3428 let condition = match condition_ref.condition {
3429 None => return true,
3430 Some(ref c) => c,
3431 };
3432 let matches = condition
3433 .matches(
3434 stylist,
3435 element,
3436 context.extra_data.originating_element_style,
3437 &mut context.extra_data.cascade_input_flags,
3438 )
3439 .to_bool(false);
3440 if !matches {
3441 return false;
3442 }
3443 id = condition_ref.parent;
3444 }
3445 }
3446
3447 pub(crate) fn find_scope_proximity_if_matching<E: TElement>(
3448 &self,
3449 rule: &Rule,
3450 element: E,
3451 context: &mut MatchingContext<E::Impl>,
3452 ) -> ScopeProximity {
3453 context
3454 .extra_data
3455 .cascade_input_flags
3456 .insert(ComputedValueFlags::CONSIDERED_NONTRIVIAL_SCOPED_STYLE);
3457
3458 let result = scope_root_candidates(
3462 &self.scope_conditions,
3463 rule.scope_condition_id,
3464 &element,
3465 rule.selector.is_part(),
3466 &self.scope_subject_map,
3467 context,
3468 );
3469 for candidate in result.candidates {
3470 if context.nest_for_scope(Some(candidate.root), |context| {
3471 matches_selector(&rule.selector, 0, Some(&rule.hashes), &element, context)
3472 }) {
3473 return candidate.proximity;
3474 }
3475 }
3476 ScopeProximity::infinity()
3477 }
3478
3479 fn did_finish_rebuild(&mut self) {
3480 self.shrink_maps_if_needed();
3481 self.compute_layer_order();
3482 }
3483
3484 fn shrink_maps_if_needed(&mut self) {
3485 self.normal_rules.shrink_if_needed();
3486 if let Some(ref mut host_rules) = self.featureless_host_rules {
3487 host_rules.shrink_if_needed();
3488 }
3489 if let Some(ref mut slotted_rules) = self.slotted_rules {
3490 slotted_rules.shrink_if_needed();
3491 }
3492 self.animations.shrink_if_needed();
3493 self.custom_property_registrations.shrink_if_needed();
3494 self.invalidation_map.shrink_if_needed();
3495 self.relative_selector_invalidation_map.shrink_if_needed();
3496 self.additional_relative_selector_invalidation_map
3497 .shrink_if_needed();
3498 self.attribute_dependencies.shrink_if_needed();
3499 self.nth_of_attribute_dependencies.shrink_if_needed();
3500 self.nth_of_custom_state_dependencies.shrink_if_needed();
3501 self.nth_of_class_dependencies.shrink_if_needed();
3502 self.nth_of_mapped_ids.shrink_if_needed();
3503 self.mapped_ids.shrink_if_needed();
3504 self.layer_id.shrink_if_needed();
3505 self.selectors_for_cache_revalidation.shrink_if_needed();
3506 self.scope_subject_map.shrink_if_needed();
3507 }
3508
3509 fn compute_layer_order(&mut self) {
3510 debug_assert_ne!(
3511 self.layers.len(),
3512 0,
3513 "There should be at least the root layer!"
3514 );
3515 if self.layers.len() == 1 {
3516 return; }
3518 let (first, remaining) = self.layers.split_at_mut(1);
3519 let root = &mut first[0];
3520 let mut order = LayerOrder::first();
3521 compute_layer_order_for_subtree(root, remaining, &mut order);
3522
3523 fn compute_layer_order_for_subtree(
3526 parent: &mut CascadeLayer,
3527 remaining_layers: &mut [CascadeLayer],
3528 order: &mut LayerOrder,
3529 ) {
3530 for child in parent.children.iter() {
3531 debug_assert!(
3532 parent.id < *child,
3533 "Children are always registered after parents"
3534 );
3535 let child_index = (child.0 - parent.id.0 - 1) as usize;
3536 let (first, remaining) = remaining_layers.split_at_mut(child_index + 1);
3537 let child = &mut first[child_index];
3538 compute_layer_order_for_subtree(child, remaining, order);
3539 }
3540
3541 if parent.id != LayerId::root() {
3542 parent.order = *order;
3543 order.inc();
3544 }
3545 }
3546 #[cfg(feature = "gecko")]
3547 self.extra_data.sort_by_layer(&self.layers);
3548 self.animations
3549 .sort_with(&self.layers, compare_keyframes_in_same_layer);
3550 self.custom_property_registrations.sort(&self.layers)
3551 }
3552
3553 fn collect_applicable_media_query_results_into<S>(
3562 device: &Device,
3563 stylesheet: &S,
3564 guard: &SharedRwLockReadGuard,
3565 results: &mut Vec<MediaListKey>,
3566 contents_list: &mut StyleSheetContentList,
3567 custom_media_map: &mut CustomMediaMap,
3568 ) where
3569 S: StylesheetInDocument + 'static,
3570 {
3571 if !stylesheet.enabled() {
3572 return;
3573 }
3574 if !stylesheet.is_effective_for_device(device, &custom_media_map, guard) {
3575 return;
3576 }
3577
3578 debug!(" + {:?}", stylesheet);
3579 let contents = stylesheet.contents(guard);
3580 results.push(contents.to_media_list_key());
3581
3582 contents_list.push(StylesheetContentsPtr(unsafe {
3584 Arc::from_raw_addrefed(&*contents)
3585 }));
3586
3587 let mut iter = stylesheet
3588 .contents(guard)
3589 .effective_rules(device, custom_media_map, guard);
3590 while let Some(rule) = iter.next() {
3591 match *rule {
3592 CssRule::CustomMedia(ref custom_media) => {
3593 iter.custom_media()
3594 .insert(custom_media.name.0.clone(), custom_media.condition.clone());
3595 },
3596 CssRule::Import(ref lock) => {
3597 let import_rule = lock.read_with(guard);
3598 debug!(" + {:?}", import_rule.stylesheet.media(guard));
3599 results.push(import_rule.to_media_list_key());
3600 },
3601 CssRule::Media(ref media_rule) => {
3602 debug!(" + {:?}", media_rule.media_queries.read_with(guard));
3603 results.push(media_rule.to_media_list_key());
3604 },
3605 _ => {},
3606 }
3607 }
3608 }
3609
3610 fn add_styles(
3611 &mut self,
3612 selectors: &SelectorList<SelectorImpl>,
3613 declarations: &Arc<Locked<PropertyDeclarationBlock>>,
3614 ancestor_selectors: Option<&SelectorList<SelectorImpl>>,
3615 containing_rule_state: &ContainingRuleState,
3616 mut replaced_selectors: Option<&mut ReplacedSelectors>,
3617 guard: &SharedRwLockReadGuard,
3618 rebuild_kind: SheetRebuildKind,
3619 mut precomputed_pseudo_element_decls: Option<&mut PrecomputedPseudoElementDeclarations>,
3620 quirks_mode: QuirksMode,
3621 mut collected_scope_dependencies: Option<&mut Vec<Dependency>>,
3622 ) -> Result<(), AllocErr> {
3623 self.num_declarations += declarations.read_with(guard).len();
3624 for selector in selectors.slice() {
3625 self.num_selectors += 1;
3626
3627 let pseudo_elements = selector.pseudo_elements();
3628 let inner_pseudo_element = pseudo_elements.get(0);
3629 if let Some(pseudo) = inner_pseudo_element {
3630 if pseudo.is_precomputed() {
3631 debug_assert!(selector.is_universal());
3632 debug_assert!(ancestor_selectors.is_none());
3633 debug_assert_eq!(containing_rule_state.layer_id, LayerId::root());
3634 debug_assert!(!containing_rule_state.scope_is_effective());
3636 precomputed_pseudo_element_decls
3637 .as_mut()
3638 .expect("Expected precomputed declarations for the UA level")
3639 .get_or_insert_with(pseudo, Vec::new)
3640 .push(ApplicableDeclarationBlock::new(
3641 StyleSource::from_declarations(declarations.clone()),
3642 self.rules_source_order,
3643 CascadeLevel::UANormal,
3644 selector.specificity(),
3645 LayerOrder::root(),
3646 ScopeProximity::infinity(),
3647 ));
3648 continue;
3649 }
3650 if pseudo_elements
3651 .iter()
3652 .any(|p| p.is_unknown_webkit_pseudo_element())
3653 {
3654 continue;
3655 }
3656 }
3657
3658 debug_assert!(!pseudo_elements
3659 .iter()
3660 .any(|p| p.is_precomputed() || p.is_unknown_webkit_pseudo_element()));
3661
3662 let selector = match ancestor_selectors {
3663 Some(ref s) => selector.replace_parent_selector(&s),
3664 None => selector.clone(),
3665 };
3666
3667 let hashes = AncestorHashes::new(&selector, quirks_mode);
3668
3669 let rule = Rule::new(
3670 selector,
3671 hashes,
3672 StyleSource::from_declarations(declarations.clone()),
3673 self.rules_source_order,
3674 containing_rule_state.layer_id,
3675 containing_rule_state.container_condition_id,
3676 containing_rule_state.in_starting_style,
3677 containing_rule_state.containing_scope_rule_state.id,
3678 );
3679
3680 if let Some(ref mut replaced_selectors) = replaced_selectors {
3681 replaced_selectors.push(rule.selector.clone())
3682 }
3683
3684 if rebuild_kind.should_rebuild_invalidation() {
3685 let mut scope_dependencies = note_selector_for_invalidation(
3686 &rule.selector,
3687 quirks_mode,
3688 &mut self.invalidation_map,
3689 &mut self.relative_selector_invalidation_map,
3690 &mut self.additional_relative_selector_invalidation_map,
3691 None,
3692 None,
3693 )?;
3694 let mut needs_revalidation = false;
3695 let mut visitor = StylistSelectorVisitor {
3696 needs_revalidation: &mut needs_revalidation,
3697 passed_rightmost_selector: false,
3698 in_selector_list_of: SelectorListKind::default(),
3699 mapped_ids: &mut self.mapped_ids,
3700 nth_of_mapped_ids: &mut self.nth_of_mapped_ids,
3701 attribute_dependencies: &mut self.attribute_dependencies,
3702 nth_of_class_dependencies: &mut self.nth_of_class_dependencies,
3703 nth_of_attribute_dependencies: &mut self.nth_of_attribute_dependencies,
3704 nth_of_custom_state_dependencies: &mut self.nth_of_custom_state_dependencies,
3705 state_dependencies: &mut self.state_dependencies,
3706 nth_of_state_dependencies: &mut self.nth_of_state_dependencies,
3707 document_state_dependencies: &mut self.document_state_dependencies,
3708 };
3709 rule.selector.visit(&mut visitor);
3710
3711 if needs_revalidation {
3712 self.selectors_for_cache_revalidation.insert(
3713 RevalidationSelectorAndHashes::new(
3714 rule.selector.clone(),
3715 rule.hashes.clone(),
3716 ),
3717 quirks_mode,
3718 )?;
3719 }
3720
3721 match (
3722 scope_dependencies.as_mut(),
3723 collected_scope_dependencies.as_mut(),
3724 ) {
3725 (Some(inner_scope_deps), Some(scope_deps)) => {
3726 scope_deps.append(inner_scope_deps)
3727 },
3728 _ => {},
3729 }
3730 }
3731
3732 if let Some(parts) = rule.selector.parts() {
3736 let map = self
3743 .part_rules
3744 .get_or_insert_with(|| Box::new(Default::default()))
3745 .for_insertion(&pseudo_elements);
3746 map.try_reserve(1)?;
3747 let vec = map.entry(parts.last().unwrap().clone().0).or_default();
3748 vec.try_reserve(1)?;
3749 vec.push(rule);
3750 } else {
3751 let scope_matches_shadow_host = containing_rule_state
3752 .containing_scope_rule_state
3753 .matches_shadow_host
3754 == ScopeMatchesShadowHost::Yes;
3755 let matches_featureless_host_only = match rule
3756 .selector
3757 .matches_featureless_host(scope_matches_shadow_host)
3758 {
3759 MatchesFeaturelessHost::Only => true,
3760 MatchesFeaturelessHost::Yes => {
3761 self.featureless_host_rules
3763 .get_or_insert_with(|| Box::new(Default::default()))
3764 .for_insertion(&pseudo_elements)
3765 .insert(rule.clone(), quirks_mode)?;
3766 false
3767 },
3768 MatchesFeaturelessHost::Never => false,
3769 };
3770
3771 let rules = if matches_featureless_host_only {
3778 self.featureless_host_rules
3779 .get_or_insert_with(|| Box::new(Default::default()))
3780 } else if rule.selector.is_slotted() {
3781 self.slotted_rules
3782 .get_or_insert_with(|| Box::new(Default::default()))
3783 } else {
3784 &mut self.normal_rules
3785 }
3786 .for_insertion(&pseudo_elements);
3787 rules.insert(rule, quirks_mode)?;
3788 }
3789 }
3790 self.rules_source_order += 1;
3791 Ok(())
3792 }
3793
3794 fn add_rule_list<S>(
3795 &mut self,
3796 rules: std::slice::Iter<CssRule>,
3797 device: &Device,
3798 quirks_mode: QuirksMode,
3799 stylesheet: &S,
3800 sheet_index: usize,
3801 guard: &SharedRwLockReadGuard,
3802 rebuild_kind: SheetRebuildKind,
3803 containing_rule_state: &mut ContainingRuleState,
3804 mut precomputed_pseudo_element_decls: Option<&mut PrecomputedPseudoElementDeclarations>,
3805 ) -> Result<(), AllocErr>
3806 where
3807 S: StylesheetInDocument + 'static,
3808 {
3809 for rule in rules {
3810 let mut handled = true;
3813 let mut list_for_nested_rules = None;
3814 match *rule {
3815 CssRule::Style(ref locked) => {
3816 let style_rule = locked.read_with(guard);
3817 let has_nested_rules = style_rule.rules.is_some();
3818 let mut replaced_selectors = ReplacedSelectors::new();
3819 let ancestor_selectors = containing_rule_state.ancestor_selector_lists.last();
3820 let collect_replaced_selectors =
3821 has_nested_rules && ancestor_selectors.is_some();
3822 let mut inner_dependencies: Option<Vec<Dependency>> = containing_rule_state
3823 .scope_is_effective()
3824 .then(|| Vec::new());
3825 self.add_styles(
3826 &style_rule.selectors,
3827 &style_rule.block,
3828 ancestor_selectors,
3829 containing_rule_state,
3830 if collect_replaced_selectors {
3831 Some(&mut replaced_selectors)
3832 } else {
3833 None
3834 },
3835 guard,
3836 rebuild_kind,
3837 precomputed_pseudo_element_decls.as_deref_mut(),
3838 quirks_mode,
3839 inner_dependencies.as_mut(),
3840 )?;
3841 if let Some(mut scope_dependencies) = inner_dependencies {
3842 containing_rule_state
3843 .containing_scope_rule_state
3844 .inner_dependencies
3845 .append(&mut scope_dependencies);
3846 }
3847 if has_nested_rules {
3848 handled = false;
3849 list_for_nested_rules = Some(if collect_replaced_selectors {
3850 SelectorList::from_iter(replaced_selectors.drain(..))
3851 } else {
3852 style_rule.selectors.clone()
3853 });
3854 }
3855 },
3856 CssRule::NestedDeclarations(ref rule) => {
3857 if let Some(ref ancestor_selectors) =
3858 containing_rule_state.ancestor_selector_lists.last()
3859 {
3860 let decls = &rule.read_with(guard).block;
3861 let selectors = match containing_rule_state.nested_declarations_context {
3862 NestedDeclarationsContext::Style => ancestor_selectors,
3863 NestedDeclarationsContext::Scope => &*IMPLICIT_SCOPE,
3864 };
3865 let mut inner_dependencies: Option<Vec<Dependency>> = containing_rule_state
3866 .scope_is_effective()
3867 .then(|| Vec::new());
3868 self.add_styles(
3869 selectors,
3870 decls,
3871 None,
3872 containing_rule_state,
3873 None,
3874 guard,
3875 SheetRebuildKind::CascadeOnly,
3878 precomputed_pseudo_element_decls.as_deref_mut(),
3879 quirks_mode,
3880 inner_dependencies.as_mut(),
3881 )?;
3882 if let Some(mut scope_dependencies) = inner_dependencies {
3883 containing_rule_state
3884 .containing_scope_rule_state
3885 .inner_dependencies
3886 .append(&mut scope_dependencies);
3887 }
3888 }
3889 },
3890 CssRule::Keyframes(ref keyframes_rule) => {
3891 debug!("Found valid keyframes rule: {:?}", *keyframes_rule);
3892 let keyframes_rule = keyframes_rule.read_with(guard);
3893 let name = keyframes_rule.name.as_atom().clone();
3894 let animation = KeyframesAnimation::from_keyframes(
3895 &keyframes_rule.keyframes,
3896 keyframes_rule.vendor_prefix.clone(),
3897 guard,
3898 );
3899 self.animations.try_insert_with(
3900 name,
3901 animation,
3902 containing_rule_state.layer_id,
3903 compare_keyframes_in_same_layer,
3904 )?;
3905 },
3906 CssRule::Property(ref registration) => {
3907 self.custom_property_registrations.try_insert(
3908 registration.name.0.clone(),
3909 Arc::clone(registration),
3910 containing_rule_state.layer_id,
3911 )?;
3912 },
3913 #[cfg(feature = "gecko")]
3914 CssRule::FontFace(ref rule) => {
3915 self.extra_data
3926 .add_font_face(rule, containing_rule_state.layer_id);
3927 },
3928 #[cfg(feature = "gecko")]
3929 CssRule::FontFeatureValues(ref rule) => {
3930 self.extra_data
3931 .add_font_feature_values(rule, containing_rule_state.layer_id);
3932 },
3933 #[cfg(feature = "gecko")]
3934 CssRule::FontPaletteValues(ref rule) => {
3935 self.extra_data
3936 .add_font_palette_values(rule, containing_rule_state.layer_id);
3937 },
3938 #[cfg(feature = "gecko")]
3939 CssRule::CounterStyle(ref rule) => {
3940 self.extra_data.add_counter_style(
3941 guard,
3942 rule,
3943 containing_rule_state.layer_id,
3944 )?;
3945 },
3946 #[cfg(feature = "gecko")]
3947 CssRule::PositionTry(ref rule) => {
3948 self.extra_data.add_position_try(
3949 guard,
3950 rule,
3951 containing_rule_state.layer_id,
3952 )?;
3953 },
3954 #[cfg(feature = "gecko")]
3955 CssRule::Page(ref rule) => {
3956 self.extra_data
3957 .add_page(guard, rule, containing_rule_state.layer_id)?;
3958 handled = false;
3959 },
3960 _ => {
3961 handled = false;
3962 },
3963 }
3964
3965 if handled {
3966 if cfg!(debug_assertions) {
3969 let mut effective = false;
3970 let children = EffectiveRulesIterator::<&CustomMediaMap>::children(
3971 rule,
3972 device,
3973 quirks_mode,
3974 &self.custom_media,
3975 guard,
3976 &mut effective,
3977 );
3978 debug_assert!(children.is_none());
3979 debug_assert!(effective);
3980 }
3981 continue;
3982 }
3983
3984 let mut effective = false;
3985 let children = EffectiveRulesIterator::<&CustomMediaMap>::children(
3986 rule,
3987 device,
3988 quirks_mode,
3989 &self.custom_media,
3990 guard,
3991 &mut effective,
3992 );
3993 if !effective {
3994 continue;
3995 }
3996
3997 fn maybe_register_layer(data: &mut CascadeData, layer: &LayerName) -> LayerId {
3998 if let Some(id) = data.layer_id.get(layer) {
4002 return *id;
4003 }
4004 let id = LayerId(data.layers.len() as u16);
4005
4006 let parent_layer_id = if layer.layer_names().len() > 1 {
4007 let mut parent = layer.clone();
4008 parent.0.pop();
4009
4010 *data
4011 .layer_id
4012 .get_mut(&parent)
4013 .expect("Parent layers should be registered before child layers")
4014 } else {
4015 LayerId::root()
4016 };
4017
4018 data.layers[parent_layer_id.0 as usize].children.push(id);
4019 data.layers.push(CascadeLayer {
4020 id,
4021 order: LayerOrder::first(),
4024 children: vec![],
4025 });
4026
4027 data.layer_id.insert(layer.clone(), id);
4028
4029 id
4030 }
4031
4032 fn maybe_register_layers(
4033 data: &mut CascadeData,
4034 name: Option<&LayerName>,
4035 containing_rule_state: &mut ContainingRuleState,
4036 ) {
4037 let anon_name;
4038 let name = match name {
4039 Some(name) => name,
4040 None => {
4041 anon_name = LayerName::new_anonymous();
4042 &anon_name
4043 },
4044 };
4045 for name in name.layer_names() {
4046 containing_rule_state.layer_name.0.push(name.clone());
4047 containing_rule_state.layer_id =
4048 maybe_register_layer(data, &containing_rule_state.layer_name);
4049 }
4050 debug_assert_ne!(containing_rule_state.layer_id, LayerId::root());
4051 }
4052
4053 let saved_containing_rule_state = containing_rule_state.save();
4054 match *rule {
4055 CssRule::Import(ref lock) => {
4056 let import_rule = lock.read_with(guard);
4057 if rebuild_kind.should_rebuild_invalidation() {
4058 self.effective_media_query_results
4059 .saw_effective(import_rule);
4060 }
4061 match import_rule.layer {
4062 ImportLayer::Named(ref name) => {
4063 maybe_register_layers(self, Some(name), containing_rule_state)
4064 },
4065 ImportLayer::Anonymous => {
4066 maybe_register_layers(self, None, containing_rule_state)
4067 },
4068 ImportLayer::None => {},
4069 }
4070 },
4071 CssRule::Media(ref media_rule) => {
4072 if rebuild_kind.should_rebuild_invalidation() {
4073 self.effective_media_query_results
4074 .saw_effective(&**media_rule);
4075 }
4076 },
4077 CssRule::LayerBlock(ref rule) => {
4078 maybe_register_layers(self, rule.name.as_ref(), containing_rule_state);
4079 },
4080 CssRule::CustomMedia(ref custom_media) => {
4081 self.custom_media
4082 .insert(custom_media.name.0.clone(), custom_media.condition.clone());
4083 },
4084 CssRule::LayerStatement(ref rule) => {
4085 for name in &*rule.names {
4086 maybe_register_layers(self, Some(name), containing_rule_state);
4087 containing_rule_state.restore(&saved_containing_rule_state);
4089 }
4090 },
4091 CssRule::Style(..) => {
4092 containing_rule_state.nested_declarations_context =
4093 NestedDeclarationsContext::Style;
4094 if let Some(s) = list_for_nested_rules {
4095 containing_rule_state.ancestor_selector_lists.push(s);
4096 }
4097 },
4098 CssRule::Container(ref rule) => {
4099 let id = ContainerConditionId(self.container_conditions.len() as u16);
4100 self.container_conditions.push(ContainerConditionReference {
4101 parent: containing_rule_state.container_condition_id,
4102 condition: Some(rule.condition.clone()),
4103 });
4104 containing_rule_state.container_condition_id = id;
4105 },
4106 CssRule::StartingStyle(..) => {
4107 containing_rule_state.in_starting_style = true;
4108 },
4109 CssRule::Scope(ref rule) => {
4110 containing_rule_state.nested_declarations_context =
4111 NestedDeclarationsContext::Scope;
4112 let id = ScopeConditionId(self.scope_conditions.len() as u16);
4113 let mut matches_shadow_host = false;
4114 let implicit_scope_root = if let Some(start) = rule.bounds.start.as_ref() {
4115 matches_shadow_host = scope_start_matches_shadow_host(start);
4116 StylistImplicitScopeRoot::default()
4118 } else {
4119 if let Some(root) = stylesheet.implicit_scope_root() {
4122 matches_shadow_host = root.matches_shadow_host();
4123 match root {
4124 ImplicitScopeRoot::InLightTree(_)
4125 | ImplicitScopeRoot::Constructed
4126 | ImplicitScopeRoot::DocumentElement => {
4127 StylistImplicitScopeRoot::Normal(root)
4128 },
4129 ImplicitScopeRoot::ShadowHost(_)
4130 | ImplicitScopeRoot::InShadowTree(_) => {
4131 StylistImplicitScopeRoot::Cached(sheet_index)
4138 },
4139 }
4140 } else {
4141 StylistImplicitScopeRoot::default()
4143 }
4144 };
4145
4146 let replaced =
4147 {
4148 let start = rule.bounds.start.as_ref().map(|selector| {
4149 match containing_rule_state.ancestor_selector_lists.last() {
4150 Some(s) => selector.replace_parent_selector(s),
4151 None => selector.clone(),
4152 }
4153 });
4154 let implicit_scope_selector = &*IMPLICIT_SCOPE;
4155 let end = rule.bounds.end.as_ref().map(|selector| {
4156 selector.replace_parent_selector(implicit_scope_selector)
4157 });
4158 containing_rule_state
4159 .ancestor_selector_lists
4160 .push(implicit_scope_selector.clone());
4161 ScopeBoundsWithHashes::new(quirks_mode, start, end)
4162 };
4163
4164 if let Some(selectors) = replaced.start.as_ref() {
4165 self.scope_subject_map
4166 .add_bound_start(&selectors.selectors, quirks_mode);
4167 }
4168
4169 let is_trivial = replaced.is_trivial();
4170 self.scope_conditions.push(ScopeConditionReference {
4171 parent: containing_rule_state.containing_scope_rule_state.id,
4172 condition: Some(replaced),
4173 implicit_scope_root,
4174 is_trivial,
4175 });
4176
4177 containing_rule_state
4178 .containing_scope_rule_state
4179 .matches_shadow_host
4180 .nest_for_scope(matches_shadow_host);
4181 containing_rule_state.containing_scope_rule_state.id = id;
4182 containing_rule_state
4183 .containing_scope_rule_state
4184 .inner_dependencies
4185 .reserve(children.iter().len());
4186 },
4187 _ => {},
4189 }
4190
4191 if let Some(children) = children {
4192 self.add_rule_list(
4193 children,
4194 device,
4195 quirks_mode,
4196 stylesheet,
4197 sheet_index,
4198 guard,
4199 rebuild_kind,
4200 containing_rule_state,
4201 precomputed_pseudo_element_decls.as_deref_mut(),
4202 )?;
4203 }
4204
4205 if let Some(scope_restore_data) =
4206 containing_rule_state.restore(&saved_containing_rule_state)
4207 {
4208 let (cur_scope_inner_dependencies, scope_idx) = scope_restore_data;
4209 let cur_scope = &self.scope_conditions[scope_idx.0 as usize];
4210 if let Some(cond) = cur_scope.condition.as_ref() {
4211 let mut _unused = false;
4212 let visitor = StylistSelectorVisitor {
4213 needs_revalidation: &mut _unused,
4214 passed_rightmost_selector: true,
4215 in_selector_list_of: SelectorListKind::default(),
4216 mapped_ids: &mut self.mapped_ids,
4217 nth_of_mapped_ids: &mut self.nth_of_mapped_ids,
4218 attribute_dependencies: &mut self.attribute_dependencies,
4219 nth_of_class_dependencies: &mut self.nth_of_class_dependencies,
4220 nth_of_attribute_dependencies: &mut self.nth_of_attribute_dependencies,
4221 nth_of_custom_state_dependencies: &mut self
4222 .nth_of_custom_state_dependencies,
4223 state_dependencies: &mut self.state_dependencies,
4224 nth_of_state_dependencies: &mut self.nth_of_state_dependencies,
4225 document_state_dependencies: &mut self.document_state_dependencies,
4226 };
4227
4228 let dependency_vector = build_scope_dependencies(
4229 quirks_mode,
4230 cur_scope_inner_dependencies,
4231 visitor,
4232 cond,
4233 &mut self.invalidation_map,
4234 &mut self.relative_selector_invalidation_map,
4235 &mut self.additional_relative_selector_invalidation_map,
4236 )?;
4237
4238 containing_rule_state
4239 .containing_scope_rule_state
4240 .inner_dependencies
4241 .extend(dependency_vector);
4242 }
4243 }
4244 }
4245
4246 Ok(())
4247 }
4248
4249 fn add_stylesheet<S>(
4251 &mut self,
4252 device: &Device,
4253 quirks_mode: QuirksMode,
4254 stylesheet: &S,
4255 sheet_index: usize,
4256 guard: &SharedRwLockReadGuard,
4257 rebuild_kind: SheetRebuildKind,
4258 mut precomputed_pseudo_element_decls: Option<&mut PrecomputedPseudoElementDeclarations>,
4259 ) -> Result<(), AllocErr>
4260 where
4261 S: StylesheetInDocument + 'static,
4262 {
4263 if !stylesheet.enabled() {
4264 return Ok(());
4265 }
4266
4267 if !stylesheet.is_effective_for_device(device, &self.custom_media, guard) {
4268 return Ok(());
4269 }
4270
4271 let contents = stylesheet.contents(guard);
4272 if rebuild_kind.should_rebuild_invalidation() {
4273 self.effective_media_query_results.saw_effective(&*contents);
4274 }
4275
4276 let mut state = ContainingRuleState::default();
4277 self.add_rule_list(
4278 contents.rules(guard).iter(),
4279 device,
4280 quirks_mode,
4281 stylesheet,
4282 sheet_index,
4283 guard,
4284 rebuild_kind,
4285 &mut state,
4286 precomputed_pseudo_element_decls.as_deref_mut(),
4287 )?;
4288
4289 Ok(())
4290 }
4291
4292 pub fn media_feature_affected_matches<S>(
4295 &self,
4296 stylesheet: &S,
4297 guard: &SharedRwLockReadGuard,
4298 device: &Device,
4299 quirks_mode: QuirksMode,
4300 ) -> bool
4301 where
4302 S: StylesheetInDocument + 'static,
4303 {
4304 use crate::invalidation::media_queries::PotentiallyEffectiveMediaRules;
4305
4306 let effective_now = stylesheet.is_effective_for_device(device, &self.custom_media, guard);
4307
4308 let contents = stylesheet.contents(guard);
4309 let effective_then = self.effective_media_query_results.was_effective(contents);
4310
4311 if effective_now != effective_then {
4312 debug!(
4313 " > Stylesheet {:?} changed -> {}, {}",
4314 stylesheet.media(guard),
4315 effective_then,
4316 effective_now
4317 );
4318 return false;
4319 }
4320
4321 if !effective_now {
4322 return true;
4323 }
4324
4325 let custom_media = CustomMediaMap::default();
4327 let mut iter =
4328 contents.iter_rules::<PotentiallyEffectiveMediaRules, _>(device, &custom_media, guard);
4329 while let Some(rule) = iter.next() {
4330 match *rule {
4331 CssRule::Style(..)
4332 | CssRule::NestedDeclarations(..)
4333 | CssRule::Namespace(..)
4334 | CssRule::FontFace(..)
4335 | CssRule::Container(..)
4336 | CssRule::CounterStyle(..)
4337 | CssRule::Supports(..)
4338 | CssRule::Keyframes(..)
4339 | CssRule::Margin(..)
4340 | CssRule::Page(..)
4341 | CssRule::Property(..)
4342 | CssRule::Document(..)
4343 | CssRule::LayerBlock(..)
4344 | CssRule::LayerStatement(..)
4345 | CssRule::FontPaletteValues(..)
4346 | CssRule::FontFeatureValues(..)
4347 | CssRule::Scope(..)
4348 | CssRule::StartingStyle(..)
4349 | CssRule::CustomMedia(..)
4350 | CssRule::PositionTry(..) => {
4351 continue;
4354 },
4355 CssRule::Import(ref lock) => {
4356 let import_rule = lock.read_with(guard);
4357 let effective_now = match import_rule.stylesheet.media(guard) {
4358 Some(m) => m.evaluate(
4359 device,
4360 quirks_mode,
4361 &mut CustomMediaEvaluator::new(&self.custom_media, guard),
4362 ),
4363 None => true,
4364 };
4365 let effective_then = self
4366 .effective_media_query_results
4367 .was_effective(import_rule);
4368 if effective_now != effective_then {
4369 debug!(
4370 " > @import rule {:?} changed {} -> {}",
4371 import_rule.stylesheet.media(guard),
4372 effective_then,
4373 effective_now
4374 );
4375 return false;
4376 }
4377
4378 if !effective_now {
4379 iter.skip_children();
4380 }
4381 },
4382 CssRule::Media(ref media_rule) => {
4383 let mq = media_rule.media_queries.read_with(guard);
4384 let effective_now = mq.evaluate(
4385 device,
4386 quirks_mode,
4387 &mut CustomMediaEvaluator::new(&self.custom_media, guard),
4388 );
4389 let effective_then = self
4390 .effective_media_query_results
4391 .was_effective(&**media_rule);
4392
4393 if effective_now != effective_then {
4394 debug!(
4395 " > @media rule {:?} changed {} -> {}",
4396 mq, effective_then, effective_now
4397 );
4398 return false;
4399 }
4400
4401 if !effective_now {
4402 iter.skip_children();
4403 }
4404 },
4405 }
4406 }
4407
4408 true
4409 }
4410
4411 pub fn custom_property_registrations(&self) -> &LayerOrderedMap<Arc<PropertyRegistration>> {
4413 &self.custom_property_registrations
4414 }
4415
4416 fn revalidate_scopes<E: TElement>(
4417 &self,
4418 element: &E,
4419 matching_context: &mut MatchingContext<E::Impl>,
4420 result: &mut ScopeRevalidationResult,
4421 ) {
4422 for condition_id in 1..self.scope_conditions.len() {
4429 let condition = &self.scope_conditions[condition_id];
4430 let matches = if condition.is_trivial {
4431 continue;
4434 } else {
4435 let result = scope_root_candidates(
4436 &self.scope_conditions,
4437 ScopeConditionId(condition_id as u16),
4438 element,
4439 false,
4441 &self.scope_subject_map,
4442 matching_context,
4443 );
4444 !result.candidates.is_empty()
4445 };
4446 result.scopes_matched.push(matches);
4447 }
4448 }
4449
4450 fn clear_cascade_data(&mut self) {
4452 self.normal_rules.clear();
4453 if let Some(ref mut slotted_rules) = self.slotted_rules {
4454 slotted_rules.clear();
4455 }
4456 if let Some(ref mut part_rules) = self.part_rules {
4457 part_rules.clear();
4458 }
4459 if let Some(ref mut host_rules) = self.featureless_host_rules {
4460 host_rules.clear();
4461 }
4462 self.animations.clear();
4463 self.custom_property_registrations.clear();
4464 self.layer_id.clear();
4465 self.layers.clear();
4466 self.layers.push(CascadeLayer::root());
4467 self.custom_media.clear();
4468 self.container_conditions.clear();
4469 self.container_conditions
4470 .push(ContainerConditionReference::none());
4471 self.scope_conditions.clear();
4472 self.scope_conditions.push(ScopeConditionReference::none());
4473 #[cfg(feature = "gecko")]
4474 self.extra_data.clear();
4475 self.rules_source_order = 0;
4476 self.num_selectors = 0;
4477 self.num_declarations = 0;
4478 }
4479
4480 fn clear(&mut self) {
4481 self.clear_cascade_data();
4482 self.invalidation_map.clear();
4483 self.relative_selector_invalidation_map.clear();
4484 self.additional_relative_selector_invalidation_map.clear();
4485 self.attribute_dependencies.clear();
4486 self.nth_of_attribute_dependencies.clear();
4487 self.nth_of_custom_state_dependencies.clear();
4488 self.nth_of_class_dependencies.clear();
4489 self.state_dependencies = ElementState::empty();
4490 self.nth_of_state_dependencies = ElementState::empty();
4491 self.document_state_dependencies = DocumentState::empty();
4492 self.mapped_ids.clear();
4493 self.nth_of_mapped_ids.clear();
4494 self.selectors_for_cache_revalidation.clear();
4495 self.effective_media_query_results.clear();
4496 self.scope_subject_map.clear();
4497 }
4498}
4499
4500fn note_scope_selector_for_invalidation(
4501 quirks_mode: QuirksMode,
4502 scope_dependencies: &Arc<servo_arc::HeaderSlice<(), Dependency>>,
4503 dependency_vector: &mut Vec<Dependency>,
4504 invalidation_map: &mut InvalidationMap,
4505 relative_selector_invalidation_map: &mut InvalidationMap,
4506 additional_relative_selector_invalidation_map: &mut AdditionalRelativeSelectorInvalidationMap,
4507 visitor: &mut StylistSelectorVisitor<'_>,
4508 scope_kind: ScopeDependencyInvalidationKind,
4509 s: &Selector<SelectorImpl>,
4510) -> Result<(), AllocErr> {
4511 let mut new_inner_dependencies = note_selector_for_invalidation(
4512 &s.clone(),
4513 quirks_mode,
4514 invalidation_map,
4515 relative_selector_invalidation_map,
4516 additional_relative_selector_invalidation_map,
4517 Some(&scope_dependencies),
4518 Some(scope_kind),
4519 )?;
4520 s.visit(visitor);
4521 new_inner_dependencies.as_mut().map(|dep| {
4522 dependency_vector.append(dep);
4523 });
4524 Ok(())
4525}
4526
4527fn build_scope_dependencies(
4528 quirks_mode: QuirksMode,
4529 mut cur_scope_inner_dependencies: Vec<Dependency>,
4530 mut visitor: StylistSelectorVisitor<'_>,
4531 cond: &ScopeBoundsWithHashes,
4532 mut invalidation_map: &mut InvalidationMap,
4533 mut relative_selector_invalidation_map: &mut InvalidationMap,
4534 mut additional_relative_selector_invalidation_map: &mut AdditionalRelativeSelectorInvalidationMap,
4535) -> Result<Vec<Dependency>, AllocErr> {
4536 if cond.end.is_some() {
4537 let deps =
4538 ThinArc::from_header_and_iter((), cur_scope_inner_dependencies.clone().into_iter());
4539 let mut end_dependency_vector = Vec::new();
4540 for s in cond.end_selectors() {
4541 note_scope_selector_for_invalidation(
4542 quirks_mode,
4543 &deps,
4544 &mut end_dependency_vector,
4545 &mut invalidation_map,
4546 &mut relative_selector_invalidation_map,
4547 &mut additional_relative_selector_invalidation_map,
4548 &mut visitor,
4549 ScopeDependencyInvalidationKind::ScopeEnd,
4550 s,
4551 )?;
4552 }
4553 cur_scope_inner_dependencies.append(&mut end_dependency_vector);
4554 }
4555 let inner_scope_dependencies =
4556 ThinArc::from_header_and_iter((), cur_scope_inner_dependencies.into_iter());
4557
4558 Ok(if cond.start.is_some() {
4559 let mut dependency_vector = Vec::new();
4560 for s in cond.start_selectors() {
4561 note_scope_selector_for_invalidation(
4562 quirks_mode,
4563 &inner_scope_dependencies,
4564 &mut dependency_vector,
4565 &mut invalidation_map,
4566 &mut relative_selector_invalidation_map,
4567 &mut additional_relative_selector_invalidation_map,
4568 &mut visitor,
4569 ScopeDependencyInvalidationKind::ExplicitScope,
4570 s,
4571 )?;
4572 }
4573 dependency_vector
4574 } else {
4575 vec![Dependency::new(
4576 IMPLICIT_SCOPE.slice()[0].clone(),
4577 0,
4578 Some(inner_scope_dependencies),
4579 DependencyInvalidationKind::Scope(ScopeDependencyInvalidationKind::ImplicitScope),
4580 )]
4581 })
4582}
4583
4584impl CascadeDataCacheEntry for CascadeData {
4585 fn rebuild<S>(
4586 device: &Device,
4587 quirks_mode: QuirksMode,
4588 collection: SheetCollectionFlusher<S>,
4589 guard: &SharedRwLockReadGuard,
4590 old: &Self,
4591 ) -> Result<Arc<Self>, AllocErr>
4592 where
4593 S: StylesheetInDocument + PartialEq + 'static,
4594 {
4595 debug_assert!(collection.dirty(), "We surely need to do something?");
4596 let mut updatable_entry = match collection.data_validity() {
4598 DataValidity::Valid | DataValidity::CascadeInvalid => old.clone(),
4599 DataValidity::FullyInvalid => Self::new(),
4600 };
4601 updatable_entry.rebuild(device, quirks_mode, collection, guard)?;
4602 Ok(Arc::new(updatable_entry))
4603 }
4604
4605 #[cfg(feature = "gecko")]
4606 fn add_size_of(&self, ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes) {
4607 self.normal_rules.add_size_of(ops, sizes);
4608 if let Some(ref slotted_rules) = self.slotted_rules {
4609 slotted_rules.add_size_of(ops, sizes);
4610 }
4611 if let Some(ref part_rules) = self.part_rules {
4612 part_rules.add_size_of(ops, sizes);
4613 }
4614 if let Some(ref host_rules) = self.featureless_host_rules {
4615 host_rules.add_size_of(ops, sizes);
4616 }
4617 sizes.mInvalidationMap += self.invalidation_map.size_of(ops);
4618 sizes.mRevalidationSelectors += self.selectors_for_cache_revalidation.size_of(ops);
4619 sizes.mOther += self.animations.size_of(ops);
4620 sizes.mOther += self.effective_media_query_results.size_of(ops);
4621 sizes.mOther += self.extra_data.size_of(ops);
4622 }
4623}
4624
4625impl Default for CascadeData {
4626 fn default() -> Self {
4627 CascadeData::new()
4628 }
4629}
4630
4631#[derive(Clone, Debug, MallocSizeOf)]
4634pub struct Rule {
4635 #[ignore_malloc_size_of = "CssRules have primary refs, we measure there"]
4640 pub selector: Selector<SelectorImpl>,
4641
4642 pub hashes: AncestorHashes,
4644
4645 pub source_order: u32,
4649
4650 pub layer_id: LayerId,
4652
4653 pub container_condition_id: ContainerConditionId,
4655
4656 pub is_starting_style: bool,
4658
4659 pub scope_condition_id: ScopeConditionId,
4661
4662 #[ignore_malloc_size_of = "Secondary ref. Primary ref is in StyleRule under Stylesheet."]
4664 pub style_source: StyleSource,
4665}
4666
4667impl SelectorMapEntry for Rule {
4668 fn selector(&self) -> SelectorIter<'_, SelectorImpl> {
4669 self.selector.iter()
4670 }
4671}
4672
4673impl Rule {
4674 pub fn specificity(&self) -> u32 {
4676 self.selector.specificity()
4677 }
4678
4679 pub fn to_applicable_declaration_block(
4682 &self,
4683 level: CascadeLevel,
4684 cascade_data: &CascadeData,
4685 scope_proximity: ScopeProximity,
4686 ) -> ApplicableDeclarationBlock {
4687 ApplicableDeclarationBlock::new(
4688 self.style_source.clone(),
4689 self.source_order,
4690 level,
4691 self.specificity(),
4692 cascade_data.layer_order_for(self.layer_id),
4693 scope_proximity,
4694 )
4695 }
4696
4697 pub fn new(
4699 selector: Selector<SelectorImpl>,
4700 hashes: AncestorHashes,
4701 style_source: StyleSource,
4702 source_order: u32,
4703 layer_id: LayerId,
4704 container_condition_id: ContainerConditionId,
4705 is_starting_style: bool,
4706 scope_condition_id: ScopeConditionId,
4707 ) -> Self {
4708 Self {
4709 selector,
4710 hashes,
4711 style_source,
4712 source_order,
4713 layer_id,
4714 container_condition_id,
4715 is_starting_style,
4716 scope_condition_id,
4717 }
4718 }
4719}
4720
4721size_of_test!(Rule, 40);
4726
4727pub fn needs_revalidation_for_testing(s: &Selector<SelectorImpl>) -> bool {
4729 let mut needs_revalidation = false;
4730 let mut mapped_ids = Default::default();
4731 let mut nth_of_mapped_ids = Default::default();
4732 let mut attribute_dependencies = Default::default();
4733 let mut nth_of_class_dependencies = Default::default();
4734 let mut nth_of_attribute_dependencies = Default::default();
4735 let mut nth_of_custom_state_dependencies = Default::default();
4736 let mut state_dependencies = ElementState::empty();
4737 let mut nth_of_state_dependencies = ElementState::empty();
4738 let mut document_state_dependencies = DocumentState::empty();
4739 let mut visitor = StylistSelectorVisitor {
4740 passed_rightmost_selector: false,
4741 needs_revalidation: &mut needs_revalidation,
4742 in_selector_list_of: SelectorListKind::default(),
4743 mapped_ids: &mut mapped_ids,
4744 nth_of_mapped_ids: &mut nth_of_mapped_ids,
4745 attribute_dependencies: &mut attribute_dependencies,
4746 nth_of_class_dependencies: &mut nth_of_class_dependencies,
4747 nth_of_attribute_dependencies: &mut nth_of_attribute_dependencies,
4748 nth_of_custom_state_dependencies: &mut nth_of_custom_state_dependencies,
4749 state_dependencies: &mut state_dependencies,
4750 nth_of_state_dependencies: &mut nth_of_state_dependencies,
4751 document_state_dependencies: &mut document_state_dependencies,
4752 };
4753 s.visit(&mut visitor);
4754 needs_revalidation
4755}