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::dom::TElement;
14#[cfg(feature = "gecko")]
15use crate::gecko_bindings::structs::{ServoStyleSetSizes, StyleRuleInclusion};
16use crate::invalidation::element::invalidation_map::{
17 note_selector_for_invalidation, AdditionalRelativeSelectorInvalidationMap, Dependency,
18 DependencyInvalidationKind, InvalidationMap, ScopeDependencyInvalidationKind,
19};
20use crate::invalidation::media_queries::{
21 EffectiveMediaQueryResults, MediaListKey, ToMediaListKey,
22};
23use crate::invalidation::stylesheets::RuleChangeKind;
24use crate::media_queries::Device;
25use crate::properties::{self, CascadeMode, ComputedValues, FirstLineReparenting};
26use crate::properties::{AnimationDeclarations, PropertyDeclarationBlock};
27use crate::properties_and_values::registry::{
28 PropertyRegistration, PropertyRegistrationData, ScriptRegistry as CustomPropertyScriptRegistry,
29};
30use crate::rule_cache::{RuleCache, RuleCacheConditions};
31use crate::rule_collector::RuleCollector;
32use crate::rule_tree::{CascadeLevel, RuleTree, StrongRuleNode, StyleSource};
33use crate::selector_map::{PrecomputedHashMap, PrecomputedHashSet, SelectorMap, SelectorMapEntry};
34use crate::selector_parser::{
35 NonTSPseudoClass, PerPseudoElementMap, PseudoElement, SelectorImpl, SnapshotMap,
36};
37use crate::shared_lock::{Locked, SharedRwLockReadGuard, StylesheetGuards};
38use crate::sharing::{RevalidationResult, ScopeRevalidationResult};
39use crate::stylesheet_set::{DataValidity, DocumentStylesheetSet, SheetRebuildKind};
40use crate::stylesheet_set::{DocumentStylesheetFlusher, SheetCollectionFlusher};
41use crate::stylesheets::container_rule::ContainerCondition;
42use crate::stylesheets::import_rule::ImportLayer;
43use crate::stylesheets::keyframes_rule::KeyframesAnimation;
44use crate::stylesheets::layer_rule::{LayerName, LayerOrder};
45use crate::stylesheets::scope_rule::{
46 collect_scope_roots, element_is_outside_of_scope, scope_selector_list_is_trivial,
47 ImplicitScopeRoot, ScopeRootCandidate, ScopeSubjectMap, ScopeTarget,
48};
49#[cfg(feature = "gecko")]
50use crate::stylesheets::{
51 CounterStyleRule, FontFaceRule, FontFeatureValuesRule, FontPaletteValuesRule,
52 PagePseudoClassFlags, PositionTryRule,
53};
54use crate::stylesheets::{
55 CssRule, EffectiveRulesIterator, Origin, OriginSet, PageRule, PerOrigin, PerOriginIter,
56 StylesheetContents, StylesheetInDocument,
57};
58use crate::values::{computed, AtomIdent};
59use crate::AllocErr;
60use crate::{Atom, LocalName, Namespace, ShrinkIfNeeded, WeakAtom};
61use dom::{DocumentState, ElementState};
62#[cfg(feature = "gecko")]
63use malloc_size_of::MallocUnconditionalShallowSizeOf;
64use malloc_size_of::{MallocShallowSizeOf, MallocSizeOf, MallocSizeOfOps};
65use rustc_hash::FxHashMap;
66use selectors::attr::{CaseSensitivity, NamespaceConstraint};
67use selectors::bloom::BloomFilter;
68use selectors::matching::{
69 matches_selector, selector_may_match, MatchingContext, MatchingMode, NeedsSelectorFlags,
70 SelectorCaches,
71};
72use selectors::matching::{MatchingForInvalidation, VisitedHandlingMode};
73use selectors::parser::{
74 AncestorHashes, Combinator, Component, MatchesFeaturelessHost, Selector, SelectorIter,
75 SelectorList,
76};
77use selectors::visitor::{SelectorListKind, SelectorVisitor};
78use servo_arc::{Arc, ArcBorrow, ThinArc};
79use smallvec::SmallVec;
80use std::cmp::Ordering;
81use std::hash::{Hash, Hasher};
82use std::sync::Mutex;
83use std::{mem, ops};
84
85#[cfg(feature = "servo")]
87pub type StylistSheet = crate::stylesheets::DocumentStyleSheet;
88
89#[cfg(feature = "gecko")]
91pub type StylistSheet = crate::gecko::data::GeckoStyleSheet;
92
93#[derive(Debug, Clone)]
94struct StylesheetContentsPtr(Arc<StylesheetContents>);
95
96impl PartialEq for StylesheetContentsPtr {
97 #[inline]
98 fn eq(&self, other: &Self) -> bool {
99 Arc::ptr_eq(&self.0, &other.0)
100 }
101}
102
103impl Eq for StylesheetContentsPtr {}
104
105impl Hash for StylesheetContentsPtr {
106 fn hash<H: Hasher>(&self, state: &mut H) {
107 let contents: &StylesheetContents = &*self.0;
108 (contents as *const StylesheetContents).hash(state)
109 }
110}
111
112type StyleSheetContentList = Vec<StylesheetContentsPtr>;
113
114#[derive(Debug, Hash, Default, PartialEq, Eq)]
116struct CascadeDataCacheKey {
117 media_query_results: Vec<MediaListKey>,
118 contents: StyleSheetContentList,
119}
120
121unsafe impl Send for CascadeDataCacheKey {}
122unsafe impl Sync for CascadeDataCacheKey {}
123
124trait CascadeDataCacheEntry: Sized {
125 fn rebuild<S>(
128 device: &Device,
129 quirks_mode: QuirksMode,
130 collection: SheetCollectionFlusher<S>,
131 guard: &SharedRwLockReadGuard,
132 old_entry: &Self,
133 ) -> Result<Arc<Self>, AllocErr>
134 where
135 S: StylesheetInDocument + PartialEq + 'static;
136 #[cfg(feature = "gecko")]
138 fn add_size_of(&self, ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes);
139}
140
141struct CascadeDataCache<Entry> {
142 entries: FxHashMap<CascadeDataCacheKey, Arc<Entry>>,
143}
144
145impl<Entry> CascadeDataCache<Entry>
146where
147 Entry: CascadeDataCacheEntry,
148{
149 fn new() -> Self {
150 Self {
151 entries: Default::default(),
152 }
153 }
154
155 fn len(&self) -> usize {
156 self.entries.len()
157 }
158
159 fn lookup<'a, S>(
164 &'a mut self,
165 device: &Device,
166 quirks_mode: QuirksMode,
167 collection: SheetCollectionFlusher<S>,
168 guard: &SharedRwLockReadGuard,
169 old_entry: &Entry,
170 ) -> Result<Option<Arc<Entry>>, AllocErr>
171 where
172 S: StylesheetInDocument + PartialEq + 'static,
173 {
174 use std::collections::hash_map::Entry as HashMapEntry;
175 debug!("StyleSheetCache::lookup({})", self.len());
176
177 if !collection.dirty() {
178 return Ok(None);
179 }
180
181 let mut key = CascadeDataCacheKey::default();
182 for sheet in collection.sheets() {
183 CascadeData::collect_applicable_media_query_results_into(
184 device,
185 sheet,
186 guard,
187 &mut key.media_query_results,
188 &mut key.contents,
189 )
190 }
191
192 let new_entry;
193 match self.entries.entry(key) {
194 HashMapEntry::Vacant(e) => {
195 debug!("> Picking the slow path (not in the cache)");
196 new_entry = Entry::rebuild(device, quirks_mode, collection, guard, old_entry)?;
197 e.insert(new_entry.clone());
198 },
199 HashMapEntry::Occupied(mut e) => {
200 if !std::ptr::eq(&**e.get(), old_entry) {
204 if log_enabled!(log::Level::Debug) {
205 debug!("cache hit for:");
206 for sheet in collection.sheets() {
207 debug!(" > {:?}", sheet);
208 }
209 }
210 collection.each(|_, _, _| true);
213 return Ok(Some(e.get().clone()));
214 }
215
216 debug!("> Picking the slow path due to same entry as old");
217 new_entry = Entry::rebuild(device, quirks_mode, collection, guard, old_entry)?;
218 e.insert(new_entry.clone());
219 },
220 }
221
222 Ok(Some(new_entry))
223 }
224
225 fn take_unused(&mut self) -> SmallVec<[Arc<Entry>; 3]> {
233 let mut unused = SmallVec::new();
234 self.entries.retain(|_key, value| {
235 if !value.is_unique() {
239 return true;
240 }
241 unused.push(value.clone());
242 false
243 });
244 unused
245 }
246
247 fn take_all(&mut self) -> FxHashMap<CascadeDataCacheKey, Arc<Entry>> {
248 mem::take(&mut self.entries)
249 }
250
251 #[cfg(feature = "gecko")]
252 fn add_size_of(&self, ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes) {
253 sizes.mOther += self.entries.shallow_size_of(ops);
254 for (_key, arc) in self.entries.iter() {
255 sizes.mOther += arc.unconditional_shallow_size_of(ops);
258 arc.add_size_of(ops, sizes);
259 }
260 }
261}
262
263#[cfg(feature = "gecko")]
265pub fn add_size_of_ua_cache(ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes) {
266 UA_CASCADE_DATA_CACHE
267 .lock()
268 .unwrap()
269 .add_size_of(ops, sizes);
270}
271
272lazy_static! {
273 static ref UA_CASCADE_DATA_CACHE: Mutex<UserAgentCascadeDataCache> =
275 Mutex::new(UserAgentCascadeDataCache::new());
276}
277
278impl CascadeDataCacheEntry for UserAgentCascadeData {
279 fn rebuild<S>(
280 device: &Device,
281 quirks_mode: QuirksMode,
282 collection: SheetCollectionFlusher<S>,
283 guard: &SharedRwLockReadGuard,
284 _old: &Self,
285 ) -> Result<Arc<Self>, AllocErr>
286 where
287 S: StylesheetInDocument + PartialEq + 'static,
288 {
289 let mut new_data = Self {
293 cascade_data: CascadeData::new(),
294 precomputed_pseudo_element_decls: PrecomputedPseudoElementDeclarations::default(),
295 };
296
297 for (index, sheet) in collection.sheets().enumerate() {
298 new_data.cascade_data.add_stylesheet(
299 device,
300 quirks_mode,
301 sheet,
302 index,
303 guard,
304 SheetRebuildKind::Full,
305 Some(&mut new_data.precomputed_pseudo_element_decls),
306 )?;
307 }
308
309 new_data.cascade_data.did_finish_rebuild();
310
311 Ok(Arc::new(new_data))
312 }
313
314 #[cfg(feature = "gecko")]
315 fn add_size_of(&self, ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes) {
316 self.cascade_data.add_size_of(ops, sizes);
317 sizes.mPrecomputedPseudos += self.precomputed_pseudo_element_decls.size_of(ops);
318 }
319}
320
321type UserAgentCascadeDataCache = CascadeDataCache<UserAgentCascadeData>;
322
323type PrecomputedPseudoElementDeclarations = PerPseudoElementMap<Vec<ApplicableDeclarationBlock>>;
324
325#[derive(Default)]
326struct UserAgentCascadeData {
327 cascade_data: CascadeData,
328
329 precomputed_pseudo_element_decls: PrecomputedPseudoElementDeclarations,
336}
337
338lazy_static! {
339 static ref EMPTY_UA_CASCADE_DATA: Arc<UserAgentCascadeData> = {
341 let arc = Arc::new(UserAgentCascadeData::default());
342 arc.mark_as_intentionally_leaked();
343 arc
344 };
345}
346
347#[derive(MallocSizeOf)]
350pub struct DocumentCascadeData {
351 #[ignore_malloc_size_of = "Arc, owned by UserAgentCascadeDataCache or empty"]
352 user_agent: Arc<UserAgentCascadeData>,
353 user: CascadeData,
354 author: CascadeData,
355 per_origin: PerOrigin<()>,
356}
357
358impl Default for DocumentCascadeData {
359 fn default() -> Self {
360 Self {
361 user_agent: EMPTY_UA_CASCADE_DATA.clone(),
362 user: Default::default(),
363 author: Default::default(),
364 per_origin: Default::default(),
365 }
366 }
367}
368
369pub struct DocumentCascadeDataIter<'a> {
371 iter: PerOriginIter<'a, ()>,
372 cascade_data: &'a DocumentCascadeData,
373}
374
375impl<'a> Iterator for DocumentCascadeDataIter<'a> {
376 type Item = (&'a CascadeData, Origin);
377
378 fn next(&mut self) -> Option<Self::Item> {
379 let (_, origin) = self.iter.next()?;
380 Some((self.cascade_data.borrow_for_origin(origin), origin))
381 }
382}
383
384impl DocumentCascadeData {
385 #[inline]
387 pub fn borrow_for_origin(&self, origin: Origin) -> &CascadeData {
388 match origin {
389 Origin::UserAgent => &self.user_agent.cascade_data,
390 Origin::Author => &self.author,
391 Origin::User => &self.user,
392 }
393 }
394
395 fn iter_origins(&self) -> DocumentCascadeDataIter<'_> {
396 DocumentCascadeDataIter {
397 iter: self.per_origin.iter_origins(),
398 cascade_data: self,
399 }
400 }
401
402 fn iter_origins_rev(&self) -> DocumentCascadeDataIter<'_> {
403 DocumentCascadeDataIter {
404 iter: self.per_origin.iter_origins_rev(),
405 cascade_data: self,
406 }
407 }
408
409 fn rebuild<'a, S>(
413 &mut self,
414 device: &Device,
415 quirks_mode: QuirksMode,
416 mut flusher: DocumentStylesheetFlusher<'a, S>,
417 guards: &StylesheetGuards,
418 ) -> Result<(), AllocErr>
419 where
420 S: StylesheetInDocument + PartialEq + 'static,
421 {
422 {
424 let origin_flusher = flusher.flush_origin(Origin::UserAgent);
425 if origin_flusher.dirty() {
428 let mut ua_cache = UA_CASCADE_DATA_CACHE.lock().unwrap();
429 let new_data = ua_cache.lookup(
430 device,
431 quirks_mode,
432 origin_flusher,
433 guards.ua_or_user,
434 &self.user_agent,
435 )?;
436 if let Some(new_data) = new_data {
437 self.user_agent = new_data;
438 }
439 let _unused_entries = ua_cache.take_unused();
440 std::mem::drop(ua_cache);
443 }
444 }
445
446 self.user.rebuild(
448 device,
449 quirks_mode,
450 flusher.flush_origin(Origin::User),
451 guards.ua_or_user,
452 )?;
453
454 self.author.rebuild(
456 device,
457 quirks_mode,
458 flusher.flush_origin(Origin::Author),
459 guards.author,
460 )?;
461
462 Ok(())
463 }
464
465 #[cfg(feature = "gecko")]
467 pub fn add_size_of(&self, ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes) {
468 self.user.add_size_of(ops, sizes);
469 self.author.add_size_of(ops, sizes);
470 }
471}
472
473#[allow(missing_docs)]
477#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq)]
478pub enum AuthorStylesEnabled {
479 Yes,
480 No,
481}
482
483#[cfg_attr(feature = "servo", derive(MallocSizeOf))]
486struct StylistStylesheetSet(DocumentStylesheetSet<StylistSheet>);
487unsafe impl Sync for StylistStylesheetSet {}
489
490impl StylistStylesheetSet {
491 fn new() -> Self {
492 StylistStylesheetSet(DocumentStylesheetSet::new())
493 }
494}
495
496impl ops::Deref for StylistStylesheetSet {
497 type Target = DocumentStylesheetSet<StylistSheet>;
498
499 fn deref(&self) -> &Self::Target {
500 &self.0
501 }
502}
503
504impl ops::DerefMut for StylistStylesheetSet {
505 fn deref_mut(&mut self) -> &mut Self::Target {
506 &mut self.0
507 }
508}
509
510#[cfg_attr(feature = "servo", derive(MallocSizeOf))]
518pub struct Stylist {
519 device: Device,
532
533 stylesheets: StylistStylesheetSet,
535
536 #[cfg_attr(feature = "servo", ignore_malloc_size_of = "XXX: how to handle this?")]
538 author_data_cache: CascadeDataCache<CascadeData>,
539
540 #[cfg_attr(feature = "servo", ignore_malloc_size_of = "defined in selectors")]
542 quirks_mode: QuirksMode,
543
544 cascade_data: DocumentCascadeData,
548
549 author_styles_enabled: AuthorStylesEnabled,
551
552 rule_tree: RuleTree,
554
555 script_custom_properties: CustomPropertyScriptRegistry,
558
559 #[cfg_attr(feature = "servo", ignore_malloc_size_of = "Arc")]
561 initial_values_for_custom_properties: ComputedCustomProperties,
562
563 initial_values_for_custom_properties_flags: ComputedValueFlags,
565
566 num_rebuilds: usize,
568}
569
570#[derive(Clone, Copy, PartialEq)]
572pub enum RuleInclusion {
573 All,
576 DefaultOnly,
579}
580
581#[cfg(feature = "gecko")]
582impl From<StyleRuleInclusion> for RuleInclusion {
583 fn from(value: StyleRuleInclusion) -> Self {
584 match value {
585 StyleRuleInclusion::All => RuleInclusion::All,
586 StyleRuleInclusion::DefaultOnly => RuleInclusion::DefaultOnly,
587 }
588 }
589}
590
591#[derive(Clone, Copy, Eq, PartialEq)]
596enum ScopeMatchesShadowHost {
597 NotApplicable,
598 No,
599 Yes,
600}
601
602impl Default for ScopeMatchesShadowHost {
603 fn default() -> Self {
604 Self::NotApplicable
605 }
606}
607
608impl ScopeMatchesShadowHost {
609 fn nest_for_scope(&mut self, matches_shadow_host: bool) {
610 match *self {
611 Self::NotApplicable => {
612 *self = if matches_shadow_host {
614 Self::Yes
615 } else {
616 Self::No
617 };
618 },
619 Self::Yes if !matches_shadow_host => {
620 *self = Self::No;
622 },
623 _ => (),
624 }
625 }
626}
627
628#[derive(Copy, Clone)]
635enum NestedDeclarationsContext {
636 Style,
637 Scope,
638}
639
640struct ContainingRuleState {
643 layer_name: LayerName,
644 layer_id: LayerId,
645 container_condition_id: ContainerConditionId,
646 in_starting_style: bool,
647 scope_condition_id: ScopeConditionId,
648 scope_matches_shadow_host: ScopeMatchesShadowHost,
649 ancestor_selector_lists: SmallVec<[SelectorList<SelectorImpl>; 2]>,
650 nested_declarations_context: NestedDeclarationsContext,
651}
652
653impl Default for ContainingRuleState {
654 fn default() -> Self {
655 Self {
656 layer_name: LayerName::new_empty(),
657 layer_id: LayerId::root(),
658 container_condition_id: ContainerConditionId::none(),
659 in_starting_style: false,
660 ancestor_selector_lists: Default::default(),
661 scope_condition_id: ScopeConditionId::none(),
662 scope_matches_shadow_host: Default::default(),
663 nested_declarations_context: NestedDeclarationsContext::Style,
664 }
665 }
666}
667
668struct SavedContainingRuleState {
669 ancestor_selector_lists_len: usize,
670 layer_name_len: usize,
671 layer_id: LayerId,
672 container_condition_id: ContainerConditionId,
673 in_starting_style: bool,
674 scope_condition_id: ScopeConditionId,
675 scope_matches_shadow_host: ScopeMatchesShadowHost,
676 nested_declarations_context: NestedDeclarationsContext,
677}
678
679impl ContainingRuleState {
680 fn save(&self) -> SavedContainingRuleState {
681 SavedContainingRuleState {
682 ancestor_selector_lists_len: self.ancestor_selector_lists.len(),
683 layer_name_len: self.layer_name.0.len(),
684 layer_id: self.layer_id,
685 container_condition_id: self.container_condition_id,
686 in_starting_style: self.in_starting_style,
687 scope_condition_id: self.scope_condition_id,
688 scope_matches_shadow_host: self.scope_matches_shadow_host,
689 nested_declarations_context: self.nested_declarations_context,
690 }
691 }
692
693 fn restore(&mut self, saved: &SavedContainingRuleState) {
694 debug_assert!(self.layer_name.0.len() >= saved.layer_name_len);
695 debug_assert!(self.ancestor_selector_lists.len() >= saved.ancestor_selector_lists_len);
696 self.ancestor_selector_lists
697 .truncate(saved.ancestor_selector_lists_len);
698 self.layer_name.0.truncate(saved.layer_name_len);
699 self.layer_id = saved.layer_id;
700 self.container_condition_id = saved.container_condition_id;
701 self.in_starting_style = saved.in_starting_style;
702 self.scope_condition_id = saved.scope_condition_id;
703 self.scope_matches_shadow_host = saved.scope_matches_shadow_host;
704 self.nested_declarations_context = saved.nested_declarations_context;
705 }
706}
707
708type ReplacedSelectors = SmallVec<[Selector<SelectorImpl>; 4]>;
709
710impl Stylist {
711 #[inline]
715 pub fn new(device: Device, quirks_mode: QuirksMode) -> Self {
716 Self {
717 device,
718 quirks_mode,
719 stylesheets: StylistStylesheetSet::new(),
720 author_data_cache: CascadeDataCache::new(),
721 cascade_data: Default::default(),
722 author_styles_enabled: AuthorStylesEnabled::Yes,
723 rule_tree: RuleTree::new(),
724 script_custom_properties: Default::default(),
725 initial_values_for_custom_properties: Default::default(),
726 initial_values_for_custom_properties_flags: Default::default(),
727 num_rebuilds: 0,
728 }
729 }
730
731 #[inline]
733 pub fn cascade_data(&self) -> &DocumentCascadeData {
734 &self.cascade_data
735 }
736
737 #[inline]
739 pub fn author_styles_enabled(&self) -> AuthorStylesEnabled {
740 self.author_styles_enabled
741 }
742
743 #[inline]
745 pub fn iter_origins(&self) -> DocumentCascadeDataIter<'_> {
746 self.cascade_data.iter_origins()
747 }
748
749 pub fn remove_unique_author_data_cache_entries(&mut self) {
752 self.author_data_cache.take_unused();
753 }
754
755 pub fn get_custom_property_registration(&self, name: &Atom) -> &PropertyRegistrationData {
758 if let Some(registration) = self.custom_property_script_registry().get(name) {
759 return ®istration.data;
760 }
761 for (data, _) in self.iter_origins() {
762 if let Some(registration) = data.custom_property_registrations.get(name) {
763 return ®istration.data;
764 }
765 }
766 PropertyRegistrationData::unregistered()
767 }
768
769 pub fn get_custom_property_initial_values(&self) -> &ComputedCustomProperties {
771 &self.initial_values_for_custom_properties
772 }
773
774 pub fn get_custom_property_initial_values_flags(&self) -> ComputedValueFlags {
776 self.initial_values_for_custom_properties_flags
777 }
778
779 pub fn rebuild_initial_values_for_custom_properties(&mut self) {
782 let mut initial_values = ComputedCustomProperties::default();
783 let initial_values_flags;
784 {
785 let mut seen_names = PrecomputedHashSet::default();
786 let mut rule_cache_conditions = RuleCacheConditions::default();
787 let context = computed::Context::new_for_initial_at_property_value(
788 self,
789 &mut rule_cache_conditions,
790 );
791
792 for (k, v) in self.custom_property_script_registry().properties().iter() {
793 seen_names.insert(k.clone());
794 let Ok(value) = v.compute_initial_value(&context) else {
795 continue;
796 };
797 let map = if v.inherits() {
798 &mut initial_values.inherited
799 } else {
800 &mut initial_values.non_inherited
801 };
802 map.insert(k, value);
803 }
804 for (data, _) in self.iter_origins() {
805 for (k, v) in data.custom_property_registrations.iter() {
806 if seen_names.insert(k.clone()) {
807 let last_value = &v.last().unwrap().0;
808 let Ok(value) = last_value.compute_initial_value(&context) else {
809 continue;
810 };
811 let map = if last_value.inherits() {
812 &mut initial_values.inherited
813 } else {
814 &mut initial_values.non_inherited
815 };
816 map.insert(k, value);
817 }
818 }
819 }
820 initial_values_flags = context.builder.flags();
821 }
822 self.initial_values_for_custom_properties_flags = initial_values_flags;
823 self.initial_values_for_custom_properties = initial_values;
824 }
825
826 pub fn rebuild_author_data<S>(
828 &mut self,
829 old_data: &CascadeData,
830 collection: SheetCollectionFlusher<S>,
831 guard: &SharedRwLockReadGuard,
832 ) -> Result<Option<Arc<CascadeData>>, AllocErr>
833 where
834 S: StylesheetInDocument + PartialEq + 'static,
835 {
836 self.author_data_cache
837 .lookup(&self.device, self.quirks_mode, collection, guard, old_data)
838 }
839
840 #[inline]
842 pub fn iter_extra_data_origins(&self) -> ExtraStyleDataIterator<'_> {
843 ExtraStyleDataIterator(self.cascade_data.iter_origins())
844 }
845
846 #[inline]
848 pub fn iter_extra_data_origins_rev(&self) -> ExtraStyleDataIterator<'_> {
849 ExtraStyleDataIterator(self.cascade_data.iter_origins_rev())
850 }
851
852 pub fn num_selectors(&self) -> usize {
854 self.cascade_data
855 .iter_origins()
856 .map(|(d, _)| d.num_selectors)
857 .sum()
858 }
859
860 pub fn num_declarations(&self) -> usize {
862 self.cascade_data
863 .iter_origins()
864 .map(|(d, _)| d.num_declarations)
865 .sum()
866 }
867
868 pub fn num_rebuilds(&self) -> usize {
870 self.num_rebuilds
871 }
872
873 pub fn num_revalidation_selectors(&self) -> usize {
875 self.cascade_data
876 .iter_origins()
877 .map(|(data, _)| data.selectors_for_cache_revalidation.len())
878 .sum()
879 }
880
881 pub fn num_invalidations(&self) -> usize {
883 self.cascade_data
884 .iter_origins()
885 .map(|(data, _)| {
886 data.invalidation_map.len() + data.relative_selector_invalidation_map.len()
887 })
888 .sum()
889 }
890
891 pub fn has_document_state_dependency(&self, state: DocumentState) -> bool {
894 self.cascade_data
895 .iter_origins()
896 .any(|(d, _)| d.document_state_dependencies.intersects(state))
897 }
898
899 pub fn flush<E>(
902 &mut self,
903 guards: &StylesheetGuards,
904 document_element: Option<E>,
905 snapshots: Option<&SnapshotMap>,
906 ) -> bool
907 where
908 E: TElement,
909 {
910 if !self.stylesheets.has_changed() {
911 return false;
912 }
913
914 self.num_rebuilds += 1;
915
916 let flusher = self.stylesheets.flush(document_element, snapshots);
917
918 let had_invalidations = flusher.had_invalidations();
919
920 self.cascade_data
921 .rebuild(&self.device, self.quirks_mode, flusher, guards)
922 .unwrap_or_else(|_| warn!("OOM in Stylist::flush"));
923
924 self.rebuild_initial_values_for_custom_properties();
925
926 had_invalidations
927 }
928
929 pub fn insert_stylesheet_before(
931 &mut self,
932 sheet: StylistSheet,
933 before_sheet: StylistSheet,
934 guard: &SharedRwLockReadGuard,
935 ) {
936 self.stylesheets
937 .insert_stylesheet_before(Some(&self.device), sheet, before_sheet, guard)
938 }
939
940 pub fn force_stylesheet_origins_dirty(&mut self, origins: OriginSet) {
946 self.stylesheets.force_dirty(origins)
947 }
948
949 pub fn set_author_styles_enabled(&mut self, enabled: AuthorStylesEnabled) {
951 self.author_styles_enabled = enabled;
952 }
953
954 pub fn stylesheets_have_changed(&self) -> bool {
956 self.stylesheets.has_changed()
957 }
958
959 pub fn append_stylesheet(&mut self, sheet: StylistSheet, guard: &SharedRwLockReadGuard) {
961 self.stylesheets
962 .append_stylesheet(Some(&self.device), sheet, guard)
963 }
964
965 pub fn remove_stylesheet(&mut self, sheet: StylistSheet, guard: &SharedRwLockReadGuard) {
967 self.stylesheets
968 .remove_stylesheet(Some(&self.device), sheet, guard)
969 }
970
971 pub fn rule_changed(
973 &mut self,
974 sheet: &StylistSheet,
975 rule: &CssRule,
976 guard: &SharedRwLockReadGuard,
977 change_kind: RuleChangeKind,
978 ) {
979 self.stylesheets
980 .rule_changed(Some(&self.device), sheet, rule, guard, change_kind)
981 }
982
983 #[inline]
985 pub fn sheet_count(&self, origin: Origin) -> usize {
986 self.stylesheets.sheet_count(origin)
987 }
988
989 #[inline]
991 pub fn sheet_at(&self, origin: Origin, index: usize) -> Option<&StylistSheet> {
992 self.stylesheets.get(origin, index)
993 }
994
995 pub fn any_applicable_rule_data<E, F>(&self, element: E, mut f: F) -> bool
998 where
999 E: TElement,
1000 F: FnMut(&CascadeData) -> bool,
1001 {
1002 if f(&self.cascade_data.user_agent.cascade_data) {
1003 return true;
1004 }
1005
1006 let mut maybe = false;
1007
1008 let doc_author_rules_apply =
1009 element.each_applicable_non_document_style_rule_data(|data, _| {
1010 maybe = maybe || f(&*data);
1011 });
1012
1013 if maybe || f(&self.cascade_data.user) {
1014 return true;
1015 }
1016
1017 doc_author_rules_apply && f(&self.cascade_data.author)
1018 }
1019
1020 pub fn for_each_cascade_data_with_scope<'a, E, F>(&'a self, element: E, mut f: F)
1022 where
1023 E: TElement + 'a,
1024 F: FnMut(&'a CascadeData, Option<E>),
1025 {
1026 f(&self.cascade_data.user_agent.cascade_data, None);
1027 element.each_applicable_non_document_style_rule_data(|data, scope| {
1028 f(data, Some(scope));
1029 });
1030 f(&self.cascade_data.user, None);
1031 f(&self.cascade_data.author, None);
1032 }
1033
1034 pub fn precomputed_values_for_pseudo<E>(
1037 &self,
1038 guards: &StylesheetGuards,
1039 pseudo: &PseudoElement,
1040 parent: Option<&ComputedValues>,
1041 ) -> Arc<ComputedValues>
1042 where
1043 E: TElement,
1044 {
1045 debug_assert!(pseudo.is_precomputed());
1046
1047 let rule_node = self.rule_node_for_precomputed_pseudo(guards, pseudo, vec![]);
1048
1049 self.precomputed_values_for_pseudo_with_rule_node::<E>(guards, pseudo, parent, rule_node)
1050 }
1051
1052 pub fn precomputed_values_for_pseudo_with_rule_node<E>(
1058 &self,
1059 guards: &StylesheetGuards,
1060 pseudo: &PseudoElement,
1061 parent: Option<&ComputedValues>,
1062 rules: StrongRuleNode,
1063 ) -> Arc<ComputedValues>
1064 where
1065 E: TElement,
1066 {
1067 self.compute_pseudo_element_style_with_inputs::<E>(
1068 CascadeInputs {
1069 rules: Some(rules),
1070 visited_rules: None,
1071 flags: Default::default(),
1072 },
1073 pseudo,
1074 guards,
1075 parent,
1076 None,
1077 )
1078 }
1079
1080 pub fn rule_node_for_precomputed_pseudo(
1086 &self,
1087 guards: &StylesheetGuards,
1088 pseudo: &PseudoElement,
1089 mut extra_declarations: Vec<ApplicableDeclarationBlock>,
1090 ) -> StrongRuleNode {
1091 let mut declarations_with_extra;
1092 let declarations = match self
1093 .cascade_data
1094 .user_agent
1095 .precomputed_pseudo_element_decls
1096 .get(pseudo)
1097 {
1098 Some(declarations) => {
1099 if !extra_declarations.is_empty() {
1100 declarations_with_extra = declarations.clone();
1101 declarations_with_extra.append(&mut extra_declarations);
1102 &*declarations_with_extra
1103 } else {
1104 &**declarations
1105 }
1106 },
1107 None => &[],
1108 };
1109
1110 self.rule_tree.insert_ordered_rules_with_important(
1111 declarations.into_iter().map(|a| a.clone().for_rule_tree()),
1112 guards,
1113 )
1114 }
1115
1116 #[cfg(feature = "servo")]
1121 pub fn style_for_anonymous<E>(
1122 &self,
1123 guards: &StylesheetGuards,
1124 pseudo: &PseudoElement,
1125 parent_style: &ComputedValues,
1126 ) -> Arc<ComputedValues>
1127 where
1128 E: TElement,
1129 {
1130 self.precomputed_values_for_pseudo::<E>(guards, &pseudo, Some(parent_style))
1131 }
1132
1133 pub fn lazily_compute_pseudo_element_style<E>(
1141 &self,
1142 guards: &StylesheetGuards,
1143 element: E,
1144 pseudo: &PseudoElement,
1145 rule_inclusion: RuleInclusion,
1146 originating_element_style: &ComputedValues,
1147 is_probe: bool,
1148 matching_fn: Option<&dyn Fn(&PseudoElement) -> bool>,
1149 ) -> Option<Arc<ComputedValues>>
1150 where
1151 E: TElement,
1152 {
1153 let cascade_inputs = self.lazy_pseudo_rules(
1154 guards,
1155 element,
1156 originating_element_style,
1157 pseudo,
1158 is_probe,
1159 rule_inclusion,
1160 matching_fn,
1161 )?;
1162
1163 Some(self.compute_pseudo_element_style_with_inputs(
1164 cascade_inputs,
1165 pseudo,
1166 guards,
1167 Some(originating_element_style),
1168 Some(element),
1169 ))
1170 }
1171
1172 pub fn compute_pseudo_element_style_with_inputs<E>(
1177 &self,
1178 inputs: CascadeInputs,
1179 pseudo: &PseudoElement,
1180 guards: &StylesheetGuards,
1181 parent_style: Option<&ComputedValues>,
1182 element: Option<E>,
1183 ) -> Arc<ComputedValues>
1184 where
1185 E: TElement,
1186 {
1187 self.cascade_style_and_visited(
1200 element,
1201 Some(pseudo),
1202 inputs,
1203 guards,
1204 parent_style,
1205 parent_style,
1206 FirstLineReparenting::No,
1207 None,
1208 &mut RuleCacheConditions::default(),
1209 )
1210 }
1211
1212 pub fn cascade_style_and_visited<E>(
1225 &self,
1226 element: Option<E>,
1227 pseudo: Option<&PseudoElement>,
1228 inputs: CascadeInputs,
1229 guards: &StylesheetGuards,
1230 parent_style: Option<&ComputedValues>,
1231 layout_parent_style: Option<&ComputedValues>,
1232 first_line_reparenting: FirstLineReparenting,
1233 rule_cache: Option<&RuleCache>,
1234 rule_cache_conditions: &mut RuleCacheConditions,
1235 ) -> Arc<ComputedValues>
1236 where
1237 E: TElement,
1238 {
1239 debug_assert!(pseudo.is_some() || element.is_some(), "Huh?");
1240
1241 let visited_rules = match inputs.visited_rules.as_ref() {
1244 Some(rules) => Some(rules),
1245 None => {
1246 if parent_style.and_then(|s| s.visited_style()).is_some() {
1247 Some(inputs.rules.as_ref().unwrap_or(self.rule_tree.root()))
1248 } else {
1249 None
1250 }
1251 },
1252 };
1253
1254 let mut implemented_pseudo = None;
1255 properties::cascade::<E>(
1262 &self,
1263 pseudo.or_else(|| {
1264 implemented_pseudo = element.unwrap().implemented_pseudo_element();
1265 implemented_pseudo.as_ref()
1266 }),
1267 inputs.rules.as_ref().unwrap_or(self.rule_tree.root()),
1268 guards,
1269 parent_style,
1270 layout_parent_style,
1271 first_line_reparenting,
1272 visited_rules,
1273 inputs.flags,
1274 rule_cache,
1275 rule_cache_conditions,
1276 element,
1277 )
1278 }
1279
1280 fn lazy_pseudo_rules<E>(
1285 &self,
1286 guards: &StylesheetGuards,
1287 element: E,
1288 originating_element_style: &ComputedValues,
1289 pseudo: &PseudoElement,
1290 is_probe: bool,
1291 rule_inclusion: RuleInclusion,
1292 matching_fn: Option<&dyn Fn(&PseudoElement) -> bool>,
1293 ) -> Option<CascadeInputs>
1294 where
1295 E: TElement,
1296 {
1297 debug_assert!(pseudo.is_lazy());
1298
1299 let mut selector_caches = SelectorCaches::default();
1300 let needs_selector_flags = if rule_inclusion == RuleInclusion::DefaultOnly {
1303 NeedsSelectorFlags::No
1304 } else {
1305 NeedsSelectorFlags::Yes
1306 };
1307
1308 let mut declarations = ApplicableDeclarationList::new();
1309 let mut matching_context = MatchingContext::<'_, E::Impl>::new(
1310 MatchingMode::ForStatelessPseudoElement,
1311 None,
1312 &mut selector_caches,
1313 self.quirks_mode,
1314 needs_selector_flags,
1315 MatchingForInvalidation::No,
1316 );
1317
1318 matching_context.pseudo_element_matching_fn = matching_fn;
1319 matching_context.extra_data.originating_element_style = Some(originating_element_style);
1320
1321 self.push_applicable_declarations(
1322 element,
1323 Some(&pseudo),
1324 None,
1325 None,
1326 Default::default(),
1327 rule_inclusion,
1328 &mut declarations,
1329 &mut matching_context,
1330 );
1331
1332 if declarations.is_empty() && is_probe {
1333 return None;
1334 }
1335
1336 let rules = self.rule_tree.compute_rule_node(&mut declarations, guards);
1337
1338 let mut visited_rules = None;
1339 if originating_element_style.visited_style().is_some() {
1340 let mut declarations = ApplicableDeclarationList::new();
1341 let mut selector_caches = SelectorCaches::default();
1342
1343 let mut matching_context = MatchingContext::<'_, E::Impl>::new_for_visited(
1344 MatchingMode::ForStatelessPseudoElement,
1345 None,
1346 &mut selector_caches,
1347 VisitedHandlingMode::RelevantLinkVisited,
1348 selectors::matching::IncludeStartingStyle::No,
1349 self.quirks_mode,
1350 needs_selector_flags,
1351 MatchingForInvalidation::No,
1352 );
1353 matching_context.pseudo_element_matching_fn = matching_fn;
1354 matching_context.extra_data.originating_element_style = Some(originating_element_style);
1355
1356 self.push_applicable_declarations(
1357 element,
1358 Some(&pseudo),
1359 None,
1360 None,
1361 Default::default(),
1362 rule_inclusion,
1363 &mut declarations,
1364 &mut matching_context,
1365 );
1366 if !declarations.is_empty() {
1367 let rule_node = self.rule_tree.insert_ordered_rules_with_important(
1368 declarations.drain(..).map(|a| a.for_rule_tree()),
1369 guards,
1370 );
1371 if rule_node != *self.rule_tree.root() {
1372 visited_rules = Some(rule_node);
1373 }
1374 }
1375 }
1376
1377 Some(CascadeInputs {
1378 rules: Some(rules),
1379 visited_rules,
1380 flags: matching_context.extra_data.cascade_input_flags,
1381 })
1382 }
1383
1384 pub fn set_device(&mut self, device: Device, guards: &StylesheetGuards) -> OriginSet {
1395 self.device = device;
1396 self.media_features_change_changed_style(guards, &self.device)
1397 }
1398
1399 pub fn media_features_change_changed_style(
1403 &self,
1404 guards: &StylesheetGuards,
1405 device: &Device,
1406 ) -> OriginSet {
1407 debug!("Stylist::media_features_change_changed_style {:?}", device);
1408
1409 let mut origins = OriginSet::empty();
1410 let stylesheets = self.stylesheets.iter();
1411
1412 for (stylesheet, origin) in stylesheets {
1413 if origins.contains(origin.into()) {
1414 continue;
1415 }
1416
1417 let guard = guards.for_origin(origin);
1418 let origin_cascade_data = self.cascade_data.borrow_for_origin(origin);
1419
1420 let affected_changed = !origin_cascade_data.media_feature_affected_matches(
1421 stylesheet,
1422 guard,
1423 device,
1424 self.quirks_mode,
1425 );
1426
1427 if affected_changed {
1428 origins |= origin;
1429 }
1430 }
1431
1432 origins
1433 }
1434
1435 pub fn quirks_mode(&self) -> QuirksMode {
1437 self.quirks_mode
1438 }
1439
1440 pub fn set_quirks_mode(&mut self, quirks_mode: QuirksMode) {
1442 if self.quirks_mode == quirks_mode {
1443 return;
1444 }
1445 self.quirks_mode = quirks_mode;
1446 self.force_stylesheet_origins_dirty(OriginSet::all());
1447 }
1448
1449 pub fn push_applicable_declarations<E>(
1451 &self,
1452 element: E,
1453 pseudo_element: Option<&PseudoElement>,
1454 style_attribute: Option<ArcBorrow<Locked<PropertyDeclarationBlock>>>,
1455 smil_override: Option<ArcBorrow<Locked<PropertyDeclarationBlock>>>,
1456 animation_declarations: AnimationDeclarations,
1457 rule_inclusion: RuleInclusion,
1458 applicable_declarations: &mut ApplicableDeclarationList,
1459 context: &mut MatchingContext<E::Impl>,
1460 ) where
1461 E: TElement,
1462 {
1463 let mut cur = element;
1464 let mut pseudos = SmallVec::new();
1465 if let Some(pseudo) = pseudo_element {
1466 pseudos.push(pseudo.clone());
1467 }
1468 while let Some(p) = cur.implemented_pseudo_element() {
1469 pseudos.push(p);
1470 let Some(parent_pseudo) = cur.pseudo_element_originating_element() else {
1471 break;
1472 };
1473 cur = parent_pseudo;
1474 }
1475 RuleCollector::new(
1476 self,
1477 element,
1478 pseudos,
1479 style_attribute,
1480 smil_override,
1481 animation_declarations,
1482 rule_inclusion,
1483 applicable_declarations,
1484 context,
1485 )
1486 .collect_all();
1487 }
1488
1489 #[inline]
1492 pub fn may_have_rules_for_id<E>(&self, id: &WeakAtom, element: E) -> bool
1493 where
1494 E: TElement,
1495 {
1496 match self.quirks_mode().classes_and_ids_case_sensitivity() {
1499 CaseSensitivity::AsciiCaseInsensitive => return true,
1500 CaseSensitivity::CaseSensitive => {},
1501 }
1502
1503 self.any_applicable_rule_data(element, |data| data.mapped_ids.contains(id))
1504 }
1505
1506 #[inline]
1514 fn lookup_element_dependent_at_rule<'a, T, F, E>(
1515 &'a self,
1516 element: E,
1517 find_in: F,
1518 ) -> Option<&'a T>
1519 where
1520 E: TElement + 'a,
1521 F: Fn(&'a CascadeData) -> Option<&'a T>,
1522 {
1523 macro_rules! try_find_in {
1524 ($data:expr) => {
1525 if let Some(thing) = find_in(&$data) {
1526 return Some(thing);
1527 }
1528 };
1529 }
1530
1531 let mut result = None;
1532 let doc_rules_apply =
1533 element.each_applicable_non_document_style_rule_data(|data, _host| {
1534 if result.is_none() {
1535 result = find_in(data);
1536 }
1537 });
1538
1539 if result.is_some() {
1540 return result;
1541 }
1542
1543 if doc_rules_apply {
1544 try_find_in!(self.cascade_data.author);
1545 }
1546 try_find_in!(self.cascade_data.user);
1547 try_find_in!(self.cascade_data.user_agent.cascade_data);
1548
1549 None
1550 }
1551
1552 #[inline]
1554 pub fn lookup_keyframes<'a, E>(
1555 &'a self,
1556 name: &Atom,
1557 element: E,
1558 ) -> Option<&'a KeyframesAnimation>
1559 where
1560 E: TElement + 'a,
1561 {
1562 self.lookup_element_dependent_at_rule(element, |data| data.animations.get(name))
1563 }
1564
1565 #[inline]
1567 #[cfg(feature = "gecko")]
1568 pub fn lookup_position_try<'a, E>(
1569 &'a self,
1570 name: &Atom,
1571 element: E,
1572 ) -> Option<&'a Arc<Locked<PositionTryRule>>>
1573 where
1574 E: TElement + 'a,
1575 {
1576 self.lookup_element_dependent_at_rule(element, |data| {
1577 data.extra_data.position_try_rules.get(name)
1578 })
1579 }
1580
1581 pub fn match_revalidation_selectors<E>(
1584 &self,
1585 element: E,
1586 bloom: Option<&BloomFilter>,
1587 selector_caches: &mut SelectorCaches,
1588 needs_selector_flags: NeedsSelectorFlags,
1589 ) -> RevalidationResult
1590 where
1591 E: TElement,
1592 {
1593 let mut matching_context = MatchingContext::new(
1596 MatchingMode::Normal,
1597 bloom,
1598 selector_caches,
1599 self.quirks_mode,
1600 needs_selector_flags,
1601 MatchingForInvalidation::No,
1602 );
1603
1604 let mut result = RevalidationResult::default();
1610 let mut relevant_attributes = &mut result.relevant_attributes;
1611 let selectors_matched = &mut result.selectors_matched;
1612
1613 let matches_document_rules =
1614 element.each_applicable_non_document_style_rule_data(|data, host| {
1615 matching_context.with_shadow_host(Some(host), |matching_context| {
1616 data.selectors_for_cache_revalidation.lookup(
1617 element,
1618 self.quirks_mode,
1619 Some(&mut relevant_attributes),
1620 |selector_and_hashes| {
1621 selectors_matched.push(matches_selector(
1622 &selector_and_hashes.selector,
1623 selector_and_hashes.selector_offset,
1624 Some(&selector_and_hashes.hashes),
1625 &element,
1626 matching_context,
1627 ));
1628 true
1629 },
1630 );
1631 })
1632 });
1633
1634 for (data, origin) in self.cascade_data.iter_origins() {
1635 if origin == Origin::Author && !matches_document_rules {
1636 continue;
1637 }
1638
1639 data.selectors_for_cache_revalidation.lookup(
1640 element,
1641 self.quirks_mode,
1642 Some(&mut relevant_attributes),
1643 |selector_and_hashes| {
1644 selectors_matched.push(matches_selector(
1645 &selector_and_hashes.selector,
1646 selector_and_hashes.selector_offset,
1647 Some(&selector_and_hashes.hashes),
1648 &element,
1649 &mut matching_context,
1650 ));
1651 true
1652 },
1653 );
1654 }
1655
1656 result
1657 }
1658
1659 pub fn revalidate_scopes<E: TElement>(
1661 &self,
1662 element: &E,
1663 selector_caches: &mut SelectorCaches,
1664 needs_selector_flags: NeedsSelectorFlags,
1665 ) -> ScopeRevalidationResult {
1666 let mut matching_context = MatchingContext::new(
1667 MatchingMode::Normal,
1668 None,
1669 selector_caches,
1670 self.quirks_mode,
1671 needs_selector_flags,
1672 MatchingForInvalidation::No,
1673 );
1674
1675 let mut result = ScopeRevalidationResult::default();
1676 let matches_document_rules =
1677 element.each_applicable_non_document_style_rule_data(|data, host| {
1678 matching_context.with_shadow_host(Some(host), |matching_context| {
1679 data.revalidate_scopes(element, matching_context, &mut result);
1680 })
1681 });
1682
1683 for (data, origin) in self.cascade_data.iter_origins() {
1684 if origin == Origin::Author && !matches_document_rules {
1685 continue;
1686 }
1687
1688 data.revalidate_scopes(element, &mut matching_context, &mut result);
1689 }
1690
1691 result
1692 }
1693
1694 pub fn compute_for_declarations<E>(
1702 &self,
1703 guards: &StylesheetGuards,
1704 parent_style: &ComputedValues,
1705 declarations: Arc<Locked<PropertyDeclarationBlock>>,
1706 ) -> Arc<ComputedValues>
1707 where
1708 E: TElement,
1709 {
1710 let block = declarations.read_with(guards.author);
1711
1712 properties::apply_declarations::<E, _>(
1719 &self,
1720 None,
1721 self.rule_tree.root(),
1722 guards,
1723 block.declaration_importance_iter().map(|(declaration, _)| {
1724 (
1725 declaration,
1726 CascadePriority::new(
1727 CascadeLevel::same_tree_author_normal(),
1728 LayerOrder::root(),
1729 ),
1730 )
1731 }),
1732 Some(parent_style),
1733 Some(parent_style),
1734 FirstLineReparenting::No,
1735 CascadeMode::Unvisited {
1736 visited_rules: None,
1737 },
1738 Default::default(),
1739 None,
1740 &mut Default::default(),
1741 None,
1742 )
1743 }
1744
1745 #[inline]
1747 pub fn device(&self) -> &Device {
1748 &self.device
1749 }
1750
1751 #[inline]
1753 pub fn device_mut(&mut self) -> &mut Device {
1754 &mut self.device
1755 }
1756
1757 #[inline]
1759 pub fn rule_tree(&self) -> &RuleTree {
1760 &self.rule_tree
1761 }
1762
1763 #[inline]
1765 pub fn custom_property_script_registry(&self) -> &CustomPropertyScriptRegistry {
1766 &self.script_custom_properties
1767 }
1768
1769 #[inline]
1771 pub fn custom_property_script_registry_mut(&mut self) -> &mut CustomPropertyScriptRegistry {
1772 &mut self.script_custom_properties
1773 }
1774
1775 #[cfg(feature = "gecko")]
1777 pub fn add_size_of(&self, ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes) {
1778 self.cascade_data.add_size_of(ops, sizes);
1779 self.author_data_cache.add_size_of(ops, sizes);
1780 sizes.mRuleTree += self.rule_tree.size_of(ops);
1781
1782 }
1784
1785 pub fn shutdown() {
1787 let _entries = UA_CASCADE_DATA_CACHE.lock().unwrap().take_all();
1788 }
1789}
1790
1791#[derive(Clone, Debug, Deref, MallocSizeOf)]
1793pub struct LayerOrderedVec<T>(Vec<(T, LayerId)>);
1794impl<T> Default for LayerOrderedVec<T> {
1795 fn default() -> Self {
1796 Self(Default::default())
1797 }
1798}
1799
1800#[derive(Clone, Debug, Deref, MallocSizeOf)]
1802pub struct LayerOrderedMap<T>(PrecomputedHashMap<Atom, SmallVec<[(T, LayerId); 1]>>);
1803impl<T> Default for LayerOrderedMap<T> {
1804 fn default() -> Self {
1805 Self(Default::default())
1806 }
1807}
1808
1809#[cfg(feature = "gecko")]
1810impl<T: 'static> LayerOrderedVec<T> {
1811 fn clear(&mut self) {
1812 self.0.clear();
1813 }
1814 fn push(&mut self, v: T, id: LayerId) {
1815 self.0.push((v, id));
1816 }
1817 fn sort(&mut self, layers: &[CascadeLayer]) {
1818 self.0
1819 .sort_by_key(|&(_, ref id)| layers[id.0 as usize].order)
1820 }
1821}
1822
1823impl<T: 'static> LayerOrderedMap<T> {
1824 fn shrink_if_needed(&mut self) {
1825 self.0.shrink_if_needed();
1826 }
1827 fn clear(&mut self) {
1828 self.0.clear();
1829 }
1830 fn try_insert(&mut self, name: Atom, v: T, id: LayerId) -> Result<(), AllocErr> {
1831 self.try_insert_with(name, v, id, |_, _| Ordering::Equal)
1832 }
1833 fn try_insert_with(
1834 &mut self,
1835 name: Atom,
1836 v: T,
1837 id: LayerId,
1838 cmp: impl Fn(&T, &T) -> Ordering,
1839 ) -> Result<(), AllocErr> {
1840 self.0.try_reserve(1)?;
1841 let vec = self.0.entry(name).or_default();
1842 if let Some(&mut (ref mut val, ref last_id)) = vec.last_mut() {
1843 if *last_id == id {
1844 if cmp(&val, &v) != Ordering::Greater {
1845 *val = v;
1846 }
1847 return Ok(());
1848 }
1849 }
1850 vec.push((v, id));
1851 Ok(())
1852 }
1853 fn sort(&mut self, layers: &[CascadeLayer]) {
1854 self.sort_with(layers, |_, _| Ordering::Equal)
1855 }
1856 fn sort_with(&mut self, layers: &[CascadeLayer], cmp: impl Fn(&T, &T) -> Ordering) {
1857 for (_, v) in self.0.iter_mut() {
1858 v.sort_by(|&(ref v1, ref id1), &(ref v2, ref id2)| {
1859 let order1 = layers[id1.0 as usize].order;
1860 let order2 = layers[id2.0 as usize].order;
1861 order1.cmp(&order2).then_with(|| cmp(v1, v2))
1862 })
1863 }
1864 }
1865 pub fn get(&self, name: &Atom) -> Option<&T> {
1867 let vec = self.0.get(name)?;
1868 Some(&vec.last()?.0)
1869 }
1870}
1871
1872#[derive(Clone, Debug, MallocSizeOf)]
1876pub struct PageRuleData {
1877 pub layer: LayerId,
1879 #[ignore_malloc_size_of = "Arc, stylesheet measures as primary ref"]
1881 pub rule: Arc<Locked<PageRule>>,
1882}
1883
1884#[derive(Clone, Debug, Default, MallocSizeOf)]
1886pub struct PageRuleMap {
1887 pub rules: PrecomputedHashMap<Atom, SmallVec<[PageRuleData; 1]>>,
1889}
1890
1891#[cfg(feature = "gecko")]
1892impl PageRuleMap {
1893 #[inline]
1894 fn clear(&mut self) {
1895 self.rules.clear();
1896 }
1897
1898 pub fn match_and_append_rules(
1902 &self,
1903 matched_rules: &mut Vec<ApplicableDeclarationBlock>,
1904 origin: Origin,
1905 guards: &StylesheetGuards,
1906 cascade_data: &DocumentCascadeData,
1907 name: &Option<Atom>,
1908 pseudos: PagePseudoClassFlags,
1909 ) {
1910 let level = match origin {
1911 Origin::UserAgent => CascadeLevel::UANormal,
1912 Origin::User => CascadeLevel::UserNormal,
1913 Origin::Author => CascadeLevel::same_tree_author_normal(),
1914 };
1915 let cascade_data = cascade_data.borrow_for_origin(origin);
1916 let start = matched_rules.len();
1917
1918 self.match_and_add_rules(
1919 matched_rules,
1920 level,
1921 guards,
1922 cascade_data,
1923 &atom!(""),
1924 pseudos,
1925 );
1926 if let Some(name) = name {
1927 self.match_and_add_rules(matched_rules, level, guards, cascade_data, name, pseudos);
1928 }
1929
1930 matched_rules[start..].sort_by_key(|block| block.sort_key());
1933 }
1934
1935 fn match_and_add_rules(
1936 &self,
1937 extra_declarations: &mut Vec<ApplicableDeclarationBlock>,
1938 level: CascadeLevel,
1939 guards: &StylesheetGuards,
1940 cascade_data: &CascadeData,
1941 name: &Atom,
1942 pseudos: PagePseudoClassFlags,
1943 ) {
1944 let rules = match self.rules.get(name) {
1945 Some(rules) => rules,
1946 None => return,
1947 };
1948 for data in rules.iter() {
1949 let rule = data.rule.read_with(level.guard(&guards));
1950 let specificity = match rule.match_specificity(pseudos) {
1951 Some(specificity) => specificity,
1952 None => continue,
1953 };
1954 let block = rule.block.clone();
1955 extra_declarations.push(ApplicableDeclarationBlock::new(
1956 StyleSource::from_declarations(block),
1957 0,
1958 level,
1959 specificity,
1960 cascade_data.layer_order_for(data.layer),
1961 ScopeProximity::infinity(), ));
1963 }
1964 }
1965}
1966
1967impl MallocShallowSizeOf for PageRuleMap {
1968 fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
1969 self.rules.shallow_size_of(ops)
1970 }
1971}
1972
1973#[derive(Clone, Debug, Default)]
1976#[cfg_attr(feature = "servo", derive(MallocSizeOf))]
1977pub struct ExtraStyleData {
1978 #[cfg(feature = "gecko")]
1980 pub font_faces: LayerOrderedVec<Arc<Locked<FontFaceRule>>>,
1981
1982 #[cfg(feature = "gecko")]
1984 pub font_feature_values: LayerOrderedVec<Arc<FontFeatureValuesRule>>,
1985
1986 #[cfg(feature = "gecko")]
1988 pub font_palette_values: LayerOrderedVec<Arc<FontPaletteValuesRule>>,
1989
1990 #[cfg(feature = "gecko")]
1992 pub counter_styles: LayerOrderedMap<Arc<Locked<CounterStyleRule>>>,
1993
1994 #[cfg(feature = "gecko")]
1996 pub position_try_rules: LayerOrderedMap<Arc<Locked<PositionTryRule>>>,
1997
1998 #[cfg(feature = "gecko")]
2000 pub pages: PageRuleMap,
2001}
2002
2003#[cfg(feature = "gecko")]
2004impl ExtraStyleData {
2005 fn add_font_face(&mut self, rule: &Arc<Locked<FontFaceRule>>, layer: LayerId) {
2007 self.font_faces.push(rule.clone(), layer);
2008 }
2009
2010 fn add_font_feature_values(&mut self, rule: &Arc<FontFeatureValuesRule>, layer: LayerId) {
2012 self.font_feature_values.push(rule.clone(), layer);
2013 }
2014
2015 fn add_font_palette_values(&mut self, rule: &Arc<FontPaletteValuesRule>, layer: LayerId) {
2017 self.font_palette_values.push(rule.clone(), layer);
2018 }
2019
2020 fn add_counter_style(
2022 &mut self,
2023 guard: &SharedRwLockReadGuard,
2024 rule: &Arc<Locked<CounterStyleRule>>,
2025 layer: LayerId,
2026 ) -> Result<(), AllocErr> {
2027 let name = rule.read_with(guard).name().0.clone();
2028 self.counter_styles.try_insert(name, rule.clone(), layer)
2029 }
2030
2031 fn add_position_try(
2033 &mut self,
2034 guard: &SharedRwLockReadGuard,
2035 rule: &Arc<Locked<PositionTryRule>>,
2036 layer: LayerId,
2037 ) -> Result<(), AllocErr> {
2038 let name = rule.read_with(guard).name.0.clone();
2039 self.position_try_rules
2040 .try_insert(name, rule.clone(), layer)
2041 }
2042
2043 fn add_page(
2045 &mut self,
2046 guard: &SharedRwLockReadGuard,
2047 rule: &Arc<Locked<PageRule>>,
2048 layer: LayerId,
2049 ) -> Result<(), AllocErr> {
2050 let page_rule = rule.read_with(guard);
2051 let mut add_rule = |name| {
2052 let vec = self.pages.rules.entry(name).or_default();
2053 vec.push(PageRuleData {
2054 layer,
2055 rule: rule.clone(),
2056 });
2057 };
2058 if page_rule.selectors.0.is_empty() {
2059 add_rule(atom!(""));
2060 } else {
2061 for selector in page_rule.selectors.as_slice() {
2062 add_rule(selector.name.0.clone());
2063 }
2064 }
2065 Ok(())
2066 }
2067
2068 fn sort_by_layer(&mut self, layers: &[CascadeLayer]) {
2069 self.font_faces.sort(layers);
2070 self.font_feature_values.sort(layers);
2071 self.font_palette_values.sort(layers);
2072 self.counter_styles.sort(layers);
2073 self.position_try_rules.sort(layers);
2074 }
2075
2076 fn clear(&mut self) {
2077 self.font_faces.clear();
2078 self.font_feature_values.clear();
2079 self.font_palette_values.clear();
2080 self.counter_styles.clear();
2081 self.position_try_rules.clear();
2082 self.pages.clear();
2083 }
2084}
2085
2086fn compare_keyframes_in_same_layer(v1: &KeyframesAnimation, v2: &KeyframesAnimation) -> Ordering {
2089 if v1.vendor_prefix.is_some() == v2.vendor_prefix.is_some() {
2090 Ordering::Equal
2091 } else if v2.vendor_prefix.is_some() {
2092 Ordering::Greater
2093 } else {
2094 Ordering::Less
2095 }
2096}
2097
2098pub struct ExtraStyleDataIterator<'a>(DocumentCascadeDataIter<'a>);
2100
2101impl<'a> Iterator for ExtraStyleDataIterator<'a> {
2102 type Item = (&'a ExtraStyleData, Origin);
2103
2104 fn next(&mut self) -> Option<Self::Item> {
2105 self.0.next().map(|d| (&d.0.extra_data, d.1))
2106 }
2107}
2108
2109#[cfg(feature = "gecko")]
2110impl MallocSizeOf for ExtraStyleData {
2111 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
2113 let mut n = 0;
2114 n += self.font_faces.shallow_size_of(ops);
2115 n += self.font_feature_values.shallow_size_of(ops);
2116 n += self.font_palette_values.shallow_size_of(ops);
2117 n += self.counter_styles.shallow_size_of(ops);
2118 n += self.position_try_rules.shallow_size_of(ops);
2119 n += self.pages.shallow_size_of(ops);
2120 n
2121 }
2122}
2123
2124#[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
2126#[derive(Clone, Debug)]
2127struct RevalidationSelectorAndHashes {
2128 #[cfg_attr(
2129 feature = "gecko",
2130 ignore_malloc_size_of = "CssRules have primary refs, we measure there"
2131 )]
2132 selector: Selector<SelectorImpl>,
2133 selector_offset: usize,
2134 hashes: AncestorHashes,
2135}
2136
2137impl RevalidationSelectorAndHashes {
2138 fn new(selector: Selector<SelectorImpl>, hashes: AncestorHashes) -> Self {
2139 let selector_offset = {
2140 let mut index = 0;
2144 let mut iter = selector.iter();
2145
2146 for _ in &mut iter {
2151 index += 1; }
2153
2154 match iter.next_sequence() {
2155 Some(Combinator::PseudoElement) => index + 1, _ => 0,
2157 }
2158 };
2159
2160 RevalidationSelectorAndHashes {
2161 selector,
2162 selector_offset,
2163 hashes,
2164 }
2165 }
2166}
2167
2168impl SelectorMapEntry for RevalidationSelectorAndHashes {
2169 fn selector(&self) -> SelectorIter<'_, SelectorImpl> {
2170 self.selector.iter_from(self.selector_offset)
2171 }
2172}
2173
2174struct StylistSelectorVisitor<'a> {
2177 passed_rightmost_selector: bool,
2180
2181 needs_revalidation: &'a mut bool,
2183
2184 in_selector_list_of: SelectorListKind,
2187
2188 mapped_ids: &'a mut PrecomputedHashSet<Atom>,
2191
2192 nth_of_mapped_ids: &'a mut PrecomputedHashSet<Atom>,
2195
2196 attribute_dependencies: &'a mut PrecomputedHashSet<LocalName>,
2198
2199 nth_of_class_dependencies: &'a mut PrecomputedHashSet<Atom>,
2202
2203 nth_of_attribute_dependencies: &'a mut PrecomputedHashSet<LocalName>,
2207
2208 nth_of_custom_state_dependencies: &'a mut PrecomputedHashSet<AtomIdent>,
2212
2213 state_dependencies: &'a mut ElementState,
2215
2216 nth_of_state_dependencies: &'a mut ElementState,
2219
2220 document_state_dependencies: &'a mut DocumentState,
2222}
2223
2224fn component_needs_revalidation(
2225 c: &Component<SelectorImpl>,
2226 passed_rightmost_selector: bool,
2227) -> bool {
2228 match *c {
2229 Component::ID(_) => {
2230 passed_rightmost_selector
2236 },
2237 Component::AttributeInNoNamespaceExists { .. }
2238 | Component::AttributeInNoNamespace { .. }
2239 | Component::AttributeOther(_)
2240 | Component::Empty
2241 | Component::Nth(_)
2242 | Component::NthOf(_)
2243 | Component::Has(_) => true,
2244 Component::NonTSPseudoClass(ref p) => p.needs_cache_revalidation(),
2245 _ => false,
2246 }
2247}
2248
2249impl<'a> StylistSelectorVisitor<'a> {
2250 fn visit_nested_selector(
2251 &mut self,
2252 in_selector_list_of: SelectorListKind,
2253 selector: &Selector<SelectorImpl>,
2254 ) {
2255 let old_passed_rightmost_selector = self.passed_rightmost_selector;
2256 let old_in_selector_list_of = self.in_selector_list_of;
2257
2258 self.passed_rightmost_selector = false;
2259 self.in_selector_list_of = in_selector_list_of;
2260 let _ret = selector.visit(self);
2261 debug_assert!(_ret, "We never return false");
2262
2263 self.passed_rightmost_selector = old_passed_rightmost_selector;
2264 self.in_selector_list_of = old_in_selector_list_of;
2265 }
2266}
2267
2268impl<'a> SelectorVisitor for StylistSelectorVisitor<'a> {
2269 type Impl = SelectorImpl;
2270
2271 fn visit_complex_selector(&mut self, combinator: Option<Combinator>) -> bool {
2272 *self.needs_revalidation =
2273 *self.needs_revalidation || combinator.map_or(false, |c| c.is_sibling());
2274
2275 self.passed_rightmost_selector = self.passed_rightmost_selector
2279 || !matches!(combinator, None | Some(Combinator::PseudoElement));
2280
2281 true
2282 }
2283
2284 fn visit_selector_list(
2285 &mut self,
2286 list_kind: SelectorListKind,
2287 list: &[Selector<Self::Impl>],
2288 ) -> bool {
2289 let in_selector_list_of = self.in_selector_list_of | list_kind;
2290 for selector in list {
2291 self.visit_nested_selector(in_selector_list_of, selector);
2292 }
2293 true
2294 }
2295
2296 fn visit_relative_selector_list(
2297 &mut self,
2298 list: &[selectors::parser::RelativeSelector<Self::Impl>],
2299 ) -> bool {
2300 let in_selector_list_of = self.in_selector_list_of | SelectorListKind::HAS;
2301 for selector in list {
2302 self.visit_nested_selector(in_selector_list_of, &selector.selector);
2303 }
2304 true
2305 }
2306
2307 fn visit_attribute_selector(
2308 &mut self,
2309 _ns: &NamespaceConstraint<&Namespace>,
2310 name: &LocalName,
2311 lower_name: &LocalName,
2312 ) -> bool {
2313 if self.in_selector_list_of.relevant_to_nth_of_dependencies() {
2314 self.nth_of_attribute_dependencies.insert(name.clone());
2315 if name != lower_name {
2316 self.nth_of_attribute_dependencies
2317 .insert(lower_name.clone());
2318 }
2319 }
2320
2321 self.attribute_dependencies.insert(name.clone());
2322 if name != lower_name {
2323 self.attribute_dependencies.insert(lower_name.clone());
2324 }
2325
2326 true
2327 }
2328
2329 fn visit_simple_selector(&mut self, s: &Component<SelectorImpl>) -> bool {
2330 *self.needs_revalidation = *self.needs_revalidation
2331 || component_needs_revalidation(s, self.passed_rightmost_selector);
2332
2333 match *s {
2334 Component::NonTSPseudoClass(NonTSPseudoClass::CustomState(ref name)) => {
2335 if self.in_selector_list_of.relevant_to_nth_of_dependencies() {
2341 self.nth_of_custom_state_dependencies.insert(name.0.clone());
2342 }
2343 },
2344 Component::NonTSPseudoClass(ref p) => {
2345 self.state_dependencies.insert(p.state_flag());
2346 self.document_state_dependencies
2347 .insert(p.document_state_flag());
2348
2349 if self.in_selector_list_of.relevant_to_nth_of_dependencies() {
2350 self.nth_of_state_dependencies.insert(p.state_flag());
2351 }
2352 },
2353 Component::ID(ref id) => {
2354 if !self.passed_rightmost_selector {
2366 self.mapped_ids.insert(id.0.clone());
2367 }
2368
2369 if self.in_selector_list_of.relevant_to_nth_of_dependencies() {
2370 self.nth_of_mapped_ids.insert(id.0.clone());
2371 }
2372 },
2373 Component::Class(ref class)
2374 if self.in_selector_list_of.relevant_to_nth_of_dependencies() =>
2375 {
2376 self.nth_of_class_dependencies.insert(class.0.clone());
2377 },
2378 _ => {},
2379 }
2380
2381 true
2382 }
2383}
2384
2385#[derive(Clone, Debug, Default, MallocSizeOf)]
2387struct GenericElementAndPseudoRules<Map> {
2388 element_map: Map,
2390
2391 pseudos_map: PerPseudoElementMap<Self>,
2398}
2399
2400impl<Map: Default + MallocSizeOf> GenericElementAndPseudoRules<Map> {
2401 #[inline(always)]
2402 fn for_insertion<'a>(&mut self, pseudo_elements: &[&'a PseudoElement]) -> &mut Map {
2403 let mut current = self;
2404 for &pseudo_element in pseudo_elements {
2405 debug_assert!(
2406 !pseudo_element.is_precomputed()
2407 && !pseudo_element.is_unknown_webkit_pseudo_element(),
2408 "Precomputed pseudos should end up in precomputed_pseudo_element_decls, \
2409 and unknown webkit pseudos should be discarded before getting here"
2410 );
2411
2412 current = current
2413 .pseudos_map
2414 .get_or_insert_with(pseudo_element, Default::default);
2415 }
2416
2417 &mut current.element_map
2418 }
2419
2420 #[inline]
2421 fn rules(&self, pseudo_elements: &[PseudoElement]) -> Option<&Map> {
2422 let mut current = self;
2423 for pseudo in pseudo_elements {
2424 current = current.pseudos_map.get(&pseudo)?;
2425 }
2426 Some(¤t.element_map)
2427 }
2428
2429 #[cfg(feature = "gecko")]
2431 fn add_size_of(&self, ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes) {
2432 sizes.mElementAndPseudosMaps += self.element_map.size_of(ops);
2433
2434 for elem in self.pseudos_map.iter() {
2435 sizes.mElementAndPseudosMaps += MallocSizeOf::size_of(elem, ops);
2436 }
2437 }
2438}
2439
2440type ElementAndPseudoRules = GenericElementAndPseudoRules<SelectorMap<Rule>>;
2441type PartMap = PrecomputedHashMap<Atom, SmallVec<[Rule; 1]>>;
2442type PartElementAndPseudoRules = GenericElementAndPseudoRules<PartMap>;
2443
2444impl ElementAndPseudoRules {
2445 fn clear(&mut self) {
2447 self.element_map.clear();
2448 self.pseudos_map.clear();
2449 }
2450
2451 fn shrink_if_needed(&mut self) {
2452 self.element_map.shrink_if_needed();
2453 for pseudo in self.pseudos_map.iter_mut() {
2454 pseudo.shrink_if_needed();
2455 }
2456 }
2457}
2458
2459impl PartElementAndPseudoRules {
2460 fn clear(&mut self) {
2462 self.element_map.clear();
2463 self.pseudos_map.clear();
2464 }
2465}
2466
2467#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, PartialOrd, Ord)]
2469pub struct LayerId(u16);
2470
2471impl LayerId {
2472 pub const fn root() -> Self {
2474 Self(0)
2475 }
2476}
2477
2478#[derive(Clone, Debug, MallocSizeOf)]
2479struct CascadeLayer {
2480 id: LayerId,
2481 order: LayerOrder,
2482 children: Vec<LayerId>,
2483}
2484
2485impl CascadeLayer {
2486 const fn root() -> Self {
2487 Self {
2488 id: LayerId::root(),
2489 order: LayerOrder::root(),
2490 children: vec![],
2491 }
2492 }
2493}
2494
2495#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, PartialOrd, Ord)]
2498pub struct ContainerConditionId(u16);
2499
2500impl ContainerConditionId {
2501 pub const fn none() -> Self {
2503 Self(0)
2504 }
2505}
2506
2507#[derive(Clone, Debug, MallocSizeOf)]
2508struct ContainerConditionReference {
2509 parent: ContainerConditionId,
2510 #[ignore_malloc_size_of = "Arc"]
2511 condition: Option<Arc<ContainerCondition>>,
2512}
2513
2514impl ContainerConditionReference {
2515 const fn none() -> Self {
2516 Self {
2517 parent: ContainerConditionId::none(),
2518 condition: None,
2519 }
2520 }
2521}
2522
2523#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, PartialOrd, Ord)]
2526pub struct ScopeConditionId(u16);
2527
2528impl ScopeConditionId {
2529 pub fn new(id: u16) -> Self {
2531 Self(id)
2532 }
2533
2534 pub const fn none() -> Self {
2536 Self(0)
2537 }
2538}
2539
2540#[derive(Clone, Debug, MallocSizeOf)]
2542pub struct ScopeConditionReference {
2543 parent: ScopeConditionId,
2545 condition: Option<ScopeBoundsWithHashes>,
2547 #[ignore_malloc_size_of = "Raw ptr behind the scenes"]
2550 implicit_scope_root: StylistImplicitScopeRoot,
2551 is_trivial: bool,
2553}
2554
2555impl ScopeConditionReference {
2556 pub fn new(
2558 parent: ScopeConditionId,
2559 condition: Option<ScopeBoundsWithHashes>,
2560 implicit_scope_root: ImplicitScopeRoot,
2561 is_trivial: bool,
2562 ) -> Self {
2563 Self {
2564 parent,
2565 condition,
2566 implicit_scope_root: StylistImplicitScopeRoot::Normal(implicit_scope_root),
2567 is_trivial,
2568 }
2569 }
2570
2571 pub const fn none() -> Self {
2573 Self {
2574 parent: ScopeConditionId::none(),
2575 condition: None,
2576 implicit_scope_root: StylistImplicitScopeRoot::default_const(),
2577 is_trivial: true,
2578 }
2579 }
2580}
2581
2582pub struct ScopeRootCandidates {
2584 pub candidates: Vec<ScopeRootCandidate>,
2586 pub is_trivial: bool,
2588}
2589
2590impl Default for ScopeRootCandidates {
2591 fn default() -> Self {
2592 Self {
2593 candidates: vec![],
2594 is_trivial: true,
2595 }
2596 }
2597}
2598
2599impl ScopeRootCandidates {
2600 fn empty(is_trivial: bool) -> Self {
2601 Self {
2602 candidates: vec![],
2603 is_trivial,
2604 }
2605 }
2606}
2607
2608#[derive(Clone, Debug, MallocSizeOf)]
2610pub struct ScopeBoundWithHashes {
2611 #[ignore_malloc_size_of = "Arc"]
2613 selectors: SelectorList<SelectorImpl>,
2614 hashes: SmallVec<[AncestorHashes; 1]>,
2615}
2616
2617impl ScopeBoundWithHashes {
2618 fn new(quirks_mode: QuirksMode, selectors: SelectorList<SelectorImpl>) -> Self {
2619 let mut hashes = SmallVec::with_capacity(selectors.len());
2620 for selector in selectors.slice() {
2621 hashes.push(AncestorHashes::new(selector, quirks_mode));
2622 }
2623 Self { selectors, hashes }
2624 }
2625
2626 fn new_no_hash(selectors: SelectorList<SelectorImpl>) -> Self {
2627 let hashes = selectors
2628 .slice()
2629 .iter()
2630 .map(|_| AncestorHashes {
2631 packed_hashes: [0, 0, 0],
2632 })
2633 .collect();
2634 Self { selectors, hashes }
2635 }
2636}
2637
2638#[derive(Clone, Debug, MallocSizeOf)]
2640pub struct ScopeBoundsWithHashes {
2641 start: Option<ScopeBoundWithHashes>,
2643 end: Option<ScopeBoundWithHashes>,
2645}
2646
2647impl ScopeBoundsWithHashes {
2648 fn new(
2650 quirks_mode: QuirksMode,
2651 start: Option<SelectorList<SelectorImpl>>,
2652 end: Option<SelectorList<SelectorImpl>>,
2653 ) -> Self {
2654 Self {
2655 start: start.map(|selectors| ScopeBoundWithHashes::new(quirks_mode, selectors)),
2656 end: end.map(|selectors| ScopeBoundWithHashes::new(quirks_mode, selectors)),
2657 }
2658 }
2659
2660 pub fn new_no_hash(
2662 start: Option<SelectorList<SelectorImpl>>,
2663 end: Option<SelectorList<SelectorImpl>>,
2664 ) -> Self {
2665 Self {
2666 start: start.map(|selectors| ScopeBoundWithHashes::new_no_hash(selectors)),
2667 end: end.map(|selectors| ScopeBoundWithHashes::new_no_hash(selectors)),
2668 }
2669 }
2670
2671 fn selectors_for<'a>(
2672 bound_with_hashes: Option<&'a ScopeBoundWithHashes>,
2673 ) -> impl Iterator<Item = &'a Selector<SelectorImpl>> {
2674 bound_with_hashes
2675 .map(|b| b.selectors.slice().iter())
2676 .into_iter()
2677 .flatten()
2678 }
2679
2680 fn start_selectors<'a>(&'a self) -> impl Iterator<Item = &'a Selector<SelectorImpl>> {
2681 Self::selectors_for(self.start.as_ref())
2682 }
2683
2684 fn end_selectors<'a>(&'a self) -> impl Iterator<Item = &'a Selector<SelectorImpl>> {
2685 Self::selectors_for(self.end.as_ref())
2686 }
2687
2688 fn is_trivial(&self) -> bool {
2689 fn scope_bound_is_trivial(bound: &Option<ScopeBoundWithHashes>, default: bool) -> bool {
2690 bound.as_ref().map_or(default, |bound| {
2691 scope_selector_list_is_trivial(&bound.selectors)
2692 })
2693 }
2694
2695 scope_bound_is_trivial(&self.start, false) && scope_bound_is_trivial(&self.end, true)
2697 }
2698}
2699
2700pub fn scope_root_candidates<E>(
2702 scope_conditions: &[ScopeConditionReference],
2703 id: ScopeConditionId,
2704 element: &E,
2705 override_matches_shadow_host_for_part: bool,
2706 scope_subject_map: &ScopeSubjectMap,
2707 context: &mut MatchingContext<SelectorImpl>,
2708) -> ScopeRootCandidates
2709where
2710 E: TElement,
2711{
2712 let condition_ref = &scope_conditions[id.0 as usize];
2713 let bounds = match condition_ref.condition {
2714 None => return ScopeRootCandidates::default(),
2715 Some(ref c) => c,
2716 };
2717 let outer_result = scope_root_candidates(
2721 scope_conditions,
2722 condition_ref.parent,
2723 element,
2724 override_matches_shadow_host_for_part,
2725 scope_subject_map,
2726 context,
2727 );
2728
2729 let is_trivial = condition_ref.is_trivial && outer_result.is_trivial;
2730 let is_outermost_scope = condition_ref.parent == ScopeConditionId::none();
2731 if !is_outermost_scope && outer_result.candidates.is_empty() {
2732 return ScopeRootCandidates::empty(is_trivial);
2733 }
2734
2735 let (root_target, matches_shadow_host) = if let Some(start) = bounds.start.as_ref() {
2736 if let Some(filter) = context.bloom_filter {
2737 if !start
2742 .hashes
2743 .iter()
2744 .any(|entry| selector_may_match(entry, filter))
2745 {
2746 return ScopeRootCandidates::empty(is_trivial);
2747 }
2748 }
2749 (
2750 ScopeTarget::Selector(&start.selectors),
2751 scope_start_matches_shadow_host(&start.selectors),
2752 )
2753 } else {
2754 let implicit_root = condition_ref.implicit_scope_root;
2755 match implicit_root {
2756 StylistImplicitScopeRoot::Normal(r) => (
2757 ScopeTarget::Implicit(r.element(context.current_host.clone())),
2758 r.matches_shadow_host(),
2759 ),
2760 StylistImplicitScopeRoot::Cached(index) => {
2761 let host = context
2762 .current_host
2763 .expect("Cached implicit scope for light DOM implicit scope");
2764 match E::implicit_scope_for_sheet_in_shadow_root(host, index) {
2765 None => return ScopeRootCandidates::empty(is_trivial),
2766 Some(root) => (
2767 ScopeTarget::Implicit(root.element(context.current_host.clone())),
2768 root.matches_shadow_host(),
2769 ),
2770 }
2771 },
2772 }
2773 };
2774 let matches_shadow_host = override_matches_shadow_host_for_part || matches_shadow_host;
2777
2778 let potential_scope_roots = if is_outermost_scope {
2779 collect_scope_roots(
2780 *element,
2781 None,
2782 context,
2783 &root_target,
2784 matches_shadow_host,
2785 scope_subject_map,
2786 )
2787 } else {
2788 let mut result = vec![];
2789 for activation in outer_result.candidates {
2790 let mut this_result = collect_scope_roots(
2791 *element,
2792 Some(activation.root),
2793 context,
2794 &root_target,
2795 matches_shadow_host,
2796 scope_subject_map,
2797 );
2798 result.append(&mut this_result);
2799 }
2800 result
2801 };
2802
2803 if potential_scope_roots.is_empty() {
2804 return ScopeRootCandidates::empty(is_trivial);
2805 }
2806
2807 let candidates = if let Some(end) = bounds.end.as_ref() {
2808 let mut result = vec![];
2809 for scope_root in potential_scope_roots {
2811 if end
2812 .selectors
2813 .slice()
2814 .iter()
2815 .zip(end.hashes.iter())
2816 .all(|(selector, hashes)| {
2817 if let Some(filter) = context.bloom_filter {
2819 if !selector_may_match(hashes, filter) {
2820 return true;
2822 }
2823 }
2824
2825 !element_is_outside_of_scope(
2826 selector,
2827 *element,
2828 scope_root.root,
2829 context,
2830 matches_shadow_host,
2831 )
2832 })
2833 {
2834 result.push(scope_root);
2835 }
2836 }
2837 result
2838 } else {
2839 potential_scope_roots
2840 };
2841
2842 ScopeRootCandidates {
2843 candidates,
2844 is_trivial,
2845 }
2846}
2847
2848#[derive(Copy, Clone, Debug, MallocSizeOf)]
2851enum StylistImplicitScopeRoot {
2852 Normal(ImplicitScopeRoot),
2853 Cached(usize),
2854}
2855unsafe impl Sync for StylistImplicitScopeRoot {}
2857
2858impl StylistImplicitScopeRoot {
2859 const fn default_const() -> Self {
2860 Self::Normal(ImplicitScopeRoot::DocumentElement)
2862 }
2863}
2864
2865impl Default for StylistImplicitScopeRoot {
2866 fn default() -> Self {
2867 Self::default_const()
2868 }
2869}
2870
2871#[derive(Debug, Clone, MallocSizeOf)]
2877pub struct CascadeData {
2878 normal_rules: ElementAndPseudoRules,
2881
2882 featureless_host_rules: Option<Box<ElementAndPseudoRules>>,
2886
2887 slotted_rules: Option<Box<ElementAndPseudoRules>>,
2895
2896 part_rules: Option<Box<PartElementAndPseudoRules>>,
2901
2902 invalidation_map: InvalidationMap,
2904
2905 relative_selector_invalidation_map: InvalidationMap,
2907
2908 additional_relative_selector_invalidation_map: AdditionalRelativeSelectorInvalidationMap,
2909
2910 attribute_dependencies: PrecomputedHashSet<LocalName>,
2915
2916 nth_of_class_dependencies: PrecomputedHashSet<Atom>,
2920
2921 nth_of_attribute_dependencies: PrecomputedHashSet<LocalName>,
2925
2926 nth_of_custom_state_dependencies: PrecomputedHashSet<AtomIdent>,
2930
2931 state_dependencies: ElementState,
2935
2936 nth_of_state_dependencies: ElementState,
2939
2940 document_state_dependencies: DocumentState,
2944
2945 mapped_ids: PrecomputedHashSet<Atom>,
2950
2951 nth_of_mapped_ids: PrecomputedHashSet<Atom>,
2955
2956 #[ignore_malloc_size_of = "Arc"]
2960 selectors_for_cache_revalidation: SelectorMap<RevalidationSelectorAndHashes>,
2961
2962 animations: LayerOrderedMap<KeyframesAnimation>,
2965
2966 #[ignore_malloc_size_of = "Arc"]
2969 custom_property_registrations: LayerOrderedMap<Arc<PropertyRegistration>>,
2970
2971 layer_id: FxHashMap<LayerName, LayerId>,
2973
2974 layers: SmallVec<[CascadeLayer; 1]>,
2976
2977 container_conditions: SmallVec<[ContainerConditionReference; 1]>,
2979
2980 scope_conditions: SmallVec<[ScopeConditionReference; 1]>,
2982
2983 scope_subject_map: ScopeSubjectMap,
2985
2986 effective_media_query_results: EffectiveMediaQueryResults,
2988
2989 extra_data: ExtraStyleData,
2991
2992 rules_source_order: u32,
2995
2996 num_selectors: usize,
2998
2999 num_declarations: usize,
3001}
3002
3003lazy_static! {
3004 static ref IMPLICIT_SCOPE: SelectorList<SelectorImpl> = {
3005 let list = SelectorList::implicit_scope();
3009 list.mark_as_intentionally_leaked();
3010 list
3011 };
3012}
3013
3014fn scope_start_matches_shadow_host(start: &SelectorList<SelectorImpl>) -> bool {
3015 start
3018 .slice()
3019 .iter()
3020 .any(|s| s.matches_featureless_host(true).may_match())
3021}
3022
3023pub fn replace_parent_selector_with_implicit_scope(
3025 selectors: &SelectorList<SelectorImpl>,
3026) -> SelectorList<SelectorImpl> {
3027 selectors.replace_parent_selector(&IMPLICIT_SCOPE)
3028}
3029
3030impl CascadeData {
3031 pub fn new() -> Self {
3033 Self {
3034 normal_rules: ElementAndPseudoRules::default(),
3035 featureless_host_rules: None,
3036 slotted_rules: None,
3037 part_rules: None,
3038 invalidation_map: InvalidationMap::new(),
3039 relative_selector_invalidation_map: InvalidationMap::new(),
3040 additional_relative_selector_invalidation_map:
3041 AdditionalRelativeSelectorInvalidationMap::new(),
3042 nth_of_mapped_ids: PrecomputedHashSet::default(),
3043 nth_of_class_dependencies: PrecomputedHashSet::default(),
3044 nth_of_attribute_dependencies: PrecomputedHashSet::default(),
3045 nth_of_custom_state_dependencies: PrecomputedHashSet::default(),
3046 nth_of_state_dependencies: ElementState::empty(),
3047 attribute_dependencies: PrecomputedHashSet::default(),
3048 state_dependencies: ElementState::empty(),
3049 document_state_dependencies: DocumentState::empty(),
3050 mapped_ids: PrecomputedHashSet::default(),
3051 selectors_for_cache_revalidation: SelectorMap::new(),
3052 animations: Default::default(),
3053 custom_property_registrations: Default::default(),
3054 layer_id: Default::default(),
3055 layers: smallvec::smallvec![CascadeLayer::root()],
3056 container_conditions: smallvec::smallvec![ContainerConditionReference::none()],
3057 scope_conditions: smallvec::smallvec![ScopeConditionReference::none()],
3058 scope_subject_map: Default::default(),
3059 extra_data: ExtraStyleData::default(),
3060 effective_media_query_results: EffectiveMediaQueryResults::new(),
3061 rules_source_order: 0,
3062 num_selectors: 0,
3063 num_declarations: 0,
3064 }
3065 }
3066
3067 pub fn rebuild<'a, S>(
3070 &mut self,
3071 device: &Device,
3072 quirks_mode: QuirksMode,
3073 collection: SheetCollectionFlusher<S>,
3074 guard: &SharedRwLockReadGuard,
3075 ) -> Result<(), AllocErr>
3076 where
3077 S: StylesheetInDocument + PartialEq + 'static,
3078 {
3079 if !collection.dirty() {
3080 return Ok(());
3081 }
3082
3083 let validity = collection.data_validity();
3084
3085 match validity {
3086 DataValidity::Valid => {},
3087 DataValidity::CascadeInvalid => self.clear_cascade_data(),
3088 DataValidity::FullyInvalid => self.clear(),
3089 }
3090
3091 let mut result = Ok(());
3092
3093 collection.each(|index, stylesheet, rebuild_kind| {
3094 result = self.add_stylesheet(
3095 device,
3096 quirks_mode,
3097 stylesheet,
3098 index,
3099 guard,
3100 rebuild_kind,
3101 None,
3102 );
3103 result.is_ok()
3104 });
3105
3106 self.did_finish_rebuild();
3107
3108 result
3109 }
3110
3111 pub fn invalidation_map(&self) -> &InvalidationMap {
3113 &self.invalidation_map
3114 }
3115
3116 pub fn relative_selector_invalidation_map(&self) -> &InvalidationMap {
3118 &self.relative_selector_invalidation_map
3119 }
3120
3121 pub fn relative_invalidation_map_attributes(
3123 &self,
3124 ) -> &AdditionalRelativeSelectorInvalidationMap {
3125 &self.additional_relative_selector_invalidation_map
3126 }
3127
3128 #[inline]
3131 pub fn has_state_dependency(&self, state: ElementState) -> bool {
3132 self.state_dependencies.intersects(state)
3133 }
3134
3135 #[inline]
3138 pub fn has_nth_of_custom_state_dependency(&self, state: &AtomIdent) -> bool {
3139 self.nth_of_custom_state_dependencies.contains(state)
3140 }
3141
3142 #[inline]
3145 pub fn has_nth_of_state_dependency(&self, state: ElementState) -> bool {
3146 self.nth_of_state_dependencies.intersects(state)
3147 }
3148
3149 #[inline]
3152 pub fn might_have_attribute_dependency(&self, local_name: &LocalName) -> bool {
3153 self.attribute_dependencies.contains(local_name)
3154 }
3155
3156 #[inline]
3159 pub fn might_have_nth_of_id_dependency(&self, id: &Atom) -> bool {
3160 self.nth_of_mapped_ids.contains(id)
3161 }
3162
3163 #[inline]
3166 pub fn might_have_nth_of_class_dependency(&self, class: &Atom) -> bool {
3167 self.nth_of_class_dependencies.contains(class)
3168 }
3169
3170 #[inline]
3173 pub fn might_have_nth_of_attribute_dependency(&self, local_name: &LocalName) -> bool {
3174 self.nth_of_attribute_dependencies.contains(local_name)
3175 }
3176
3177 #[inline]
3179 pub fn normal_rules(&self, pseudo_elements: &[PseudoElement]) -> Option<&SelectorMap<Rule>> {
3180 self.normal_rules.rules(pseudo_elements)
3181 }
3182
3183 #[inline]
3185 pub fn featureless_host_rules(
3186 &self,
3187 pseudo_elements: &[PseudoElement],
3188 ) -> Option<&SelectorMap<Rule>> {
3189 self.featureless_host_rules
3190 .as_ref()
3191 .and_then(|d| d.rules(pseudo_elements))
3192 }
3193
3194 pub fn any_featureless_host_rules(&self) -> bool {
3196 self.featureless_host_rules.is_some()
3197 }
3198
3199 #[inline]
3201 pub fn slotted_rules(&self, pseudo_elements: &[PseudoElement]) -> Option<&SelectorMap<Rule>> {
3202 self.slotted_rules
3203 .as_ref()
3204 .and_then(|d| d.rules(pseudo_elements))
3205 }
3206
3207 pub fn any_slotted_rule(&self) -> bool {
3209 self.slotted_rules.is_some()
3210 }
3211
3212 #[inline]
3214 pub fn part_rules(&self, pseudo_elements: &[PseudoElement]) -> Option<&PartMap> {
3215 self.part_rules
3216 .as_ref()
3217 .and_then(|d| d.rules(pseudo_elements))
3218 }
3219
3220 pub fn any_part_rule(&self) -> bool {
3222 self.part_rules.is_some()
3223 }
3224
3225 #[inline]
3226 fn layer_order_for(&self, id: LayerId) -> LayerOrder {
3227 self.layers[id.0 as usize].order
3228 }
3229
3230 pub(crate) fn container_condition_matches<E>(
3231 &self,
3232 mut id: ContainerConditionId,
3233 stylist: &Stylist,
3234 element: E,
3235 context: &mut MatchingContext<E::Impl>,
3236 ) -> bool
3237 where
3238 E: TElement,
3239 {
3240 loop {
3241 let condition_ref = &self.container_conditions[id.0 as usize];
3242 let condition = match condition_ref.condition {
3243 None => return true,
3244 Some(ref c) => c,
3245 };
3246 let matches = condition
3247 .matches(
3248 stylist,
3249 element,
3250 context.extra_data.originating_element_style,
3251 &mut context.extra_data.cascade_input_flags,
3252 )
3253 .to_bool(false);
3254 if !matches {
3255 return false;
3256 }
3257 id = condition_ref.parent;
3258 }
3259 }
3260
3261 pub(crate) fn find_scope_proximity_if_matching<E: TElement>(
3262 &self,
3263 rule: &Rule,
3264 element: E,
3265 context: &mut MatchingContext<E::Impl>,
3266 ) -> ScopeProximity {
3267 context
3268 .extra_data
3269 .cascade_input_flags
3270 .insert(ComputedValueFlags::CONSIDERED_NONTRIVIAL_SCOPED_STYLE);
3271
3272 let result = scope_root_candidates(
3276 &self.scope_conditions,
3277 rule.scope_condition_id,
3278 &element,
3279 rule.selector.is_part(),
3280 &self.scope_subject_map,
3281 context,
3282 );
3283 for candidate in result.candidates {
3284 if context.nest_for_scope(Some(candidate.root), |context| {
3285 matches_selector(&rule.selector, 0, Some(&rule.hashes), &element, context)
3286 }) {
3287 return candidate.proximity;
3288 }
3289 }
3290 ScopeProximity::infinity()
3291 }
3292
3293 fn did_finish_rebuild(&mut self) {
3294 self.shrink_maps_if_needed();
3295 self.compute_layer_order();
3296 }
3297
3298 fn shrink_maps_if_needed(&mut self) {
3299 self.normal_rules.shrink_if_needed();
3300 if let Some(ref mut host_rules) = self.featureless_host_rules {
3301 host_rules.shrink_if_needed();
3302 }
3303 if let Some(ref mut slotted_rules) = self.slotted_rules {
3304 slotted_rules.shrink_if_needed();
3305 }
3306 self.animations.shrink_if_needed();
3307 self.custom_property_registrations.shrink_if_needed();
3308 self.invalidation_map.shrink_if_needed();
3309 self.relative_selector_invalidation_map.shrink_if_needed();
3310 self.additional_relative_selector_invalidation_map
3311 .shrink_if_needed();
3312 self.attribute_dependencies.shrink_if_needed();
3313 self.nth_of_attribute_dependencies.shrink_if_needed();
3314 self.nth_of_custom_state_dependencies.shrink_if_needed();
3315 self.nth_of_class_dependencies.shrink_if_needed();
3316 self.nth_of_mapped_ids.shrink_if_needed();
3317 self.mapped_ids.shrink_if_needed();
3318 self.layer_id.shrink_if_needed();
3319 self.selectors_for_cache_revalidation.shrink_if_needed();
3320 self.scope_subject_map.shrink_if_needed();
3321 }
3322
3323 fn compute_layer_order(&mut self) {
3324 debug_assert_ne!(
3325 self.layers.len(),
3326 0,
3327 "There should be at least the root layer!"
3328 );
3329 if self.layers.len() == 1 {
3330 return; }
3332 let (first, remaining) = self.layers.split_at_mut(1);
3333 let root = &mut first[0];
3334 let mut order = LayerOrder::first();
3335 compute_layer_order_for_subtree(root, remaining, &mut order);
3336
3337 fn compute_layer_order_for_subtree(
3340 parent: &mut CascadeLayer,
3341 remaining_layers: &mut [CascadeLayer],
3342 order: &mut LayerOrder,
3343 ) {
3344 for child in parent.children.iter() {
3345 debug_assert!(
3346 parent.id < *child,
3347 "Children are always registered after parents"
3348 );
3349 let child_index = (child.0 - parent.id.0 - 1) as usize;
3350 let (first, remaining) = remaining_layers.split_at_mut(child_index + 1);
3351 let child = &mut first[child_index];
3352 compute_layer_order_for_subtree(child, remaining, order);
3353 }
3354
3355 if parent.id != LayerId::root() {
3356 parent.order = *order;
3357 order.inc();
3358 }
3359 }
3360 #[cfg(feature = "gecko")]
3361 self.extra_data.sort_by_layer(&self.layers);
3362 self.animations
3363 .sort_with(&self.layers, compare_keyframes_in_same_layer);
3364 self.custom_property_registrations.sort(&self.layers)
3365 }
3366
3367 fn collect_applicable_media_query_results_into<S>(
3376 device: &Device,
3377 stylesheet: &S,
3378 guard: &SharedRwLockReadGuard,
3379 results: &mut Vec<MediaListKey>,
3380 contents_list: &mut StyleSheetContentList,
3381 ) where
3382 S: StylesheetInDocument + 'static,
3383 {
3384 if !stylesheet.enabled() || !stylesheet.is_effective_for_device(device, guard) {
3385 return;
3386 }
3387
3388 debug!(" + {:?}", stylesheet);
3389 let contents = stylesheet.contents();
3390 results.push(contents.to_media_list_key());
3391
3392 contents_list.push(StylesheetContentsPtr(unsafe {
3394 Arc::from_raw_addrefed(contents)
3395 }));
3396
3397 for rule in stylesheet.effective_rules(device, guard) {
3398 match *rule {
3399 CssRule::Import(ref lock) => {
3400 let import_rule = lock.read_with(guard);
3401 debug!(" + {:?}", import_rule.stylesheet.media(guard));
3402 results.push(import_rule.to_media_list_key());
3403 },
3404 CssRule::Media(ref media_rule) => {
3405 debug!(" + {:?}", media_rule.media_queries.read_with(guard));
3406 results.push(media_rule.to_media_list_key());
3407 },
3408 _ => {},
3409 }
3410 }
3411 }
3412
3413 fn note_scope_selector_for_invalidation(
3414 &mut self,
3415 quirks_mode: QuirksMode,
3416 inner_scope_dependencies: &Option<Arc<servo_arc::HeaderSlice<(), Dependency>>>,
3417 dependency_vector: &mut Vec<Dependency>,
3418 s: &Selector<SelectorImpl>,
3419 scope_kind: ScopeDependencyInvalidationKind,
3420 ) -> Result<(), AllocErr> {
3421 let mut new_inner_dependencies = note_selector_for_invalidation(
3422 &s.clone(),
3423 quirks_mode,
3424 &mut self.invalidation_map,
3425 &mut self.relative_selector_invalidation_map,
3426 &mut self.additional_relative_selector_invalidation_map,
3427 inner_scope_dependencies.as_ref(),
3428 Some(scope_kind),
3429 )?;
3430 let mut _unused = false;
3431 let mut visitor = StylistSelectorVisitor {
3432 needs_revalidation: &mut _unused,
3433 passed_rightmost_selector: true,
3434 in_selector_list_of: SelectorListKind::default(),
3435 mapped_ids: &mut self.mapped_ids,
3436 nth_of_mapped_ids: &mut self.nth_of_mapped_ids,
3437 attribute_dependencies: &mut self.attribute_dependencies,
3438 nth_of_class_dependencies: &mut self.nth_of_class_dependencies,
3439 nth_of_attribute_dependencies: &mut self.nth_of_attribute_dependencies,
3440 nth_of_custom_state_dependencies: &mut self.nth_of_custom_state_dependencies,
3441 state_dependencies: &mut self.state_dependencies,
3442 nth_of_state_dependencies: &mut self.nth_of_state_dependencies,
3443 document_state_dependencies: &mut self.document_state_dependencies,
3444 };
3445 s.visit(&mut visitor);
3446 new_inner_dependencies.as_mut().map(|dep| {
3447 dependency_vector.append(dep);
3448 });
3449 Ok(())
3450 }
3451
3452 fn add_styles(
3453 &mut self,
3454 selectors: &SelectorList<SelectorImpl>,
3455 declarations: &Arc<Locked<PropertyDeclarationBlock>>,
3456 ancestor_selectors: Option<&SelectorList<SelectorImpl>>,
3457 containing_rule_state: &ContainingRuleState,
3458 mut replaced_selectors: Option<&mut ReplacedSelectors>,
3459 guard: &SharedRwLockReadGuard,
3460 rebuild_kind: SheetRebuildKind,
3461 mut precomputed_pseudo_element_decls: Option<&mut PrecomputedPseudoElementDeclarations>,
3462 quirks_mode: QuirksMode,
3463 ) -> Result<(), AllocErr> {
3464 self.num_declarations += declarations.read_with(guard).len();
3465 for selector in selectors.slice() {
3466 self.num_selectors += 1;
3467
3468 let pseudo_elements = selector.pseudo_elements();
3469 let inner_pseudo_element = pseudo_elements.get(0);
3470 if let Some(pseudo) = inner_pseudo_element {
3471 if pseudo.is_precomputed() {
3472 debug_assert!(selector.is_universal());
3473 debug_assert!(ancestor_selectors.is_none());
3474 debug_assert_eq!(containing_rule_state.layer_id, LayerId::root());
3475 debug_assert_eq!(
3477 containing_rule_state.scope_condition_id,
3478 ScopeConditionId::none()
3479 );
3480 precomputed_pseudo_element_decls
3481 .as_mut()
3482 .expect("Expected precomputed declarations for the UA level")
3483 .get_or_insert_with(pseudo, Vec::new)
3484 .push(ApplicableDeclarationBlock::new(
3485 StyleSource::from_declarations(declarations.clone()),
3486 self.rules_source_order,
3487 CascadeLevel::UANormal,
3488 selector.specificity(),
3489 LayerOrder::root(),
3490 ScopeProximity::infinity(),
3491 ));
3492 continue;
3493 }
3494 if pseudo_elements
3495 .iter()
3496 .any(|p| p.is_unknown_webkit_pseudo_element())
3497 {
3498 continue;
3499 }
3500 }
3501
3502 debug_assert!(!pseudo_elements
3503 .iter()
3504 .any(|p| p.is_precomputed() || p.is_unknown_webkit_pseudo_element()));
3505
3506 let selector = match ancestor_selectors {
3507 Some(ref s) => selector.replace_parent_selector(&s),
3508 None => selector.clone(),
3509 };
3510
3511 let hashes = AncestorHashes::new(&selector, quirks_mode);
3512
3513 let rule = Rule::new(
3514 selector,
3515 hashes,
3516 StyleSource::from_declarations(declarations.clone()),
3517 self.rules_source_order,
3518 containing_rule_state.layer_id,
3519 containing_rule_state.container_condition_id,
3520 containing_rule_state.in_starting_style,
3521 containing_rule_state.scope_condition_id,
3522 );
3523
3524 if let Some(ref mut replaced_selectors) = replaced_selectors {
3525 replaced_selectors.push(rule.selector.clone())
3526 }
3527
3528 if rebuild_kind.should_rebuild_invalidation() {
3529 let innermost_dependency = note_selector_for_invalidation(
3530 &rule.selector,
3531 quirks_mode,
3532 &mut self.invalidation_map,
3533 &mut self.relative_selector_invalidation_map,
3534 &mut self.additional_relative_selector_invalidation_map,
3535 None,
3536 None,
3537 )?;
3538 let mut needs_revalidation = false;
3539 let mut visitor = StylistSelectorVisitor {
3540 needs_revalidation: &mut needs_revalidation,
3541 passed_rightmost_selector: false,
3542 in_selector_list_of: SelectorListKind::default(),
3543 mapped_ids: &mut self.mapped_ids,
3544 nth_of_mapped_ids: &mut self.nth_of_mapped_ids,
3545 attribute_dependencies: &mut self.attribute_dependencies,
3546 nth_of_class_dependencies: &mut self.nth_of_class_dependencies,
3547 nth_of_attribute_dependencies: &mut self.nth_of_attribute_dependencies,
3548 nth_of_custom_state_dependencies: &mut self.nth_of_custom_state_dependencies,
3549 state_dependencies: &mut self.state_dependencies,
3550 nth_of_state_dependencies: &mut self.nth_of_state_dependencies,
3551 document_state_dependencies: &mut self.document_state_dependencies,
3552 };
3553 rule.selector.visit(&mut visitor);
3554
3555 if needs_revalidation {
3556 self.selectors_for_cache_revalidation.insert(
3557 RevalidationSelectorAndHashes::new(
3558 rule.selector.clone(),
3559 rule.hashes.clone(),
3560 ),
3561 quirks_mode,
3562 )?;
3563 }
3564
3565 let mut scope_idx = containing_rule_state.scope_condition_id;
3566 let mut inner_scope_dependencies: Option<ThinArc<(), Dependency>> =
3567 innermost_dependency
3568 .map(|dep_vec| ThinArc::from_header_and_iter((), dep_vec.into_iter()));
3569
3570 while scope_idx != ScopeConditionId::none() {
3571 let cur_scope = self.scope_conditions[scope_idx.0 as usize].clone();
3572
3573 if let Some(cond) = cur_scope.condition.as_ref() {
3574 let mut dependency_vector: Vec<Dependency> = Vec::new();
3575
3576 if cond.start.is_none() {
3577 dependency_vector.push(Dependency::new(
3578 IMPLICIT_SCOPE.slice()[0].clone(),
3579 0,
3580 inner_scope_dependencies.clone(),
3581 DependencyInvalidationKind::Scope(
3582 ScopeDependencyInvalidationKind::ImplicitScope,
3583 ),
3584 ));
3585 }
3586
3587 for s in cond.start_selectors() {
3588 self.note_scope_selector_for_invalidation(
3589 quirks_mode,
3590 &inner_scope_dependencies,
3591 &mut dependency_vector,
3592 s,
3593 ScopeDependencyInvalidationKind::ExplicitScope,
3594 )?;
3595 }
3596
3597 for s in cond.end_selectors() {
3599 self.note_scope_selector_for_invalidation(
3600 quirks_mode,
3601 &inner_scope_dependencies,
3602 &mut dependency_vector,
3603 s,
3604 ScopeDependencyInvalidationKind::ScopeEnd,
3605 )?;
3606 }
3607
3608 inner_scope_dependencies = Some(ThinArc::from_header_and_iter(
3609 (),
3610 dependency_vector.into_iter(),
3611 ));
3612 }
3613 scope_idx = cur_scope.parent;
3614 }
3615 }
3616
3617 if let Some(parts) = rule.selector.parts() {
3621 let map = self
3628 .part_rules
3629 .get_or_insert_with(|| Box::new(Default::default()))
3630 .for_insertion(&pseudo_elements);
3631 map.try_reserve(1)?;
3632 let vec = map.entry(parts.last().unwrap().clone().0).or_default();
3633 vec.try_reserve(1)?;
3634 vec.push(rule);
3635 } else {
3636 let scope_matches_shadow_host =
3637 containing_rule_state.scope_matches_shadow_host == ScopeMatchesShadowHost::Yes;
3638 let matches_featureless_host_only = match rule
3639 .selector
3640 .matches_featureless_host(scope_matches_shadow_host)
3641 {
3642 MatchesFeaturelessHost::Only => true,
3643 MatchesFeaturelessHost::Yes => {
3644 self.featureless_host_rules
3646 .get_or_insert_with(|| Box::new(Default::default()))
3647 .for_insertion(&pseudo_elements)
3648 .insert(rule.clone(), quirks_mode)?;
3649 false
3650 },
3651 MatchesFeaturelessHost::Never => false,
3652 };
3653
3654 let rules = if matches_featureless_host_only {
3661 self.featureless_host_rules
3662 .get_or_insert_with(|| Box::new(Default::default()))
3663 } else if rule.selector.is_slotted() {
3664 self.slotted_rules
3665 .get_or_insert_with(|| Box::new(Default::default()))
3666 } else {
3667 &mut self.normal_rules
3668 }
3669 .for_insertion(&pseudo_elements);
3670 rules.insert(rule, quirks_mode)?;
3671 }
3672 }
3673 self.rules_source_order += 1;
3674 Ok(())
3675 }
3676
3677 fn add_rule_list<S>(
3678 &mut self,
3679 rules: std::slice::Iter<CssRule>,
3680 device: &Device,
3681 quirks_mode: QuirksMode,
3682 stylesheet: &S,
3683 sheet_index: usize,
3684 guard: &SharedRwLockReadGuard,
3685 rebuild_kind: SheetRebuildKind,
3686 containing_rule_state: &mut ContainingRuleState,
3687 mut precomputed_pseudo_element_decls: Option<&mut PrecomputedPseudoElementDeclarations>,
3688 ) -> Result<(), AllocErr>
3689 where
3690 S: StylesheetInDocument + 'static,
3691 {
3692 for rule in rules {
3693 let mut handled = true;
3696 let mut list_for_nested_rules = None;
3697 match *rule {
3698 CssRule::Style(ref locked) => {
3699 let style_rule = locked.read_with(guard);
3700 let has_nested_rules = style_rule.rules.is_some();
3701 let mut replaced_selectors = ReplacedSelectors::new();
3702 let ancestor_selectors = containing_rule_state.ancestor_selector_lists.last();
3703 let collect_replaced_selectors =
3704 has_nested_rules && ancestor_selectors.is_some();
3705 self.add_styles(
3706 &style_rule.selectors,
3707 &style_rule.block,
3708 ancestor_selectors,
3709 &containing_rule_state,
3710 if collect_replaced_selectors {
3711 Some(&mut replaced_selectors)
3712 } else {
3713 None
3714 },
3715 guard,
3716 rebuild_kind,
3717 precomputed_pseudo_element_decls.as_deref_mut(),
3718 quirks_mode,
3719 )?;
3720 if has_nested_rules {
3721 handled = false;
3722 list_for_nested_rules = Some(if collect_replaced_selectors {
3723 SelectorList::from_iter(replaced_selectors.drain(..))
3724 } else {
3725 style_rule.selectors.clone()
3726 });
3727 }
3728 },
3729 CssRule::NestedDeclarations(ref rule) => {
3730 if let Some(ref ancestor_selectors) =
3731 containing_rule_state.ancestor_selector_lists.last()
3732 {
3733 let decls = &rule.read_with(guard).block;
3734 let selectors = match containing_rule_state.nested_declarations_context {
3735 NestedDeclarationsContext::Style => ancestor_selectors,
3736 NestedDeclarationsContext::Scope => &*IMPLICIT_SCOPE,
3737 };
3738 self.add_styles(
3739 selectors,
3740 decls,
3741 None,
3742 &containing_rule_state,
3743 None,
3744 guard,
3745 SheetRebuildKind::CascadeOnly,
3748 precomputed_pseudo_element_decls.as_deref_mut(),
3749 quirks_mode,
3750 )?;
3751 }
3752 },
3753 CssRule::Keyframes(ref keyframes_rule) => {
3754 debug!("Found valid keyframes rule: {:?}", *keyframes_rule);
3755 let keyframes_rule = keyframes_rule.read_with(guard);
3756 let name = keyframes_rule.name.as_atom().clone();
3757 let animation = KeyframesAnimation::from_keyframes(
3758 &keyframes_rule.keyframes,
3759 keyframes_rule.vendor_prefix.clone(),
3760 guard,
3761 );
3762 self.animations.try_insert_with(
3763 name,
3764 animation,
3765 containing_rule_state.layer_id,
3766 compare_keyframes_in_same_layer,
3767 )?;
3768 },
3769 CssRule::Property(ref registration) => {
3770 self.custom_property_registrations.try_insert(
3771 registration.name.0.clone(),
3772 Arc::clone(registration),
3773 containing_rule_state.layer_id,
3774 )?;
3775 },
3776 #[cfg(feature = "gecko")]
3777 CssRule::FontFace(ref rule) => {
3778 self.extra_data
3789 .add_font_face(rule, containing_rule_state.layer_id);
3790 },
3791 #[cfg(feature = "gecko")]
3792 CssRule::FontFeatureValues(ref rule) => {
3793 self.extra_data
3794 .add_font_feature_values(rule, containing_rule_state.layer_id);
3795 },
3796 #[cfg(feature = "gecko")]
3797 CssRule::FontPaletteValues(ref rule) => {
3798 self.extra_data
3799 .add_font_palette_values(rule, containing_rule_state.layer_id);
3800 },
3801 #[cfg(feature = "gecko")]
3802 CssRule::CounterStyle(ref rule) => {
3803 self.extra_data.add_counter_style(
3804 guard,
3805 rule,
3806 containing_rule_state.layer_id,
3807 )?;
3808 },
3809 #[cfg(feature = "gecko")]
3810 CssRule::PositionTry(ref rule) => {
3811 self.extra_data.add_position_try(
3812 guard,
3813 rule,
3814 containing_rule_state.layer_id,
3815 )?;
3816 },
3817 #[cfg(feature = "gecko")]
3818 CssRule::Page(ref rule) => {
3819 self.extra_data
3820 .add_page(guard, rule, containing_rule_state.layer_id)?;
3821 handled = false;
3822 },
3823 _ => {
3824 handled = false;
3825 },
3826 }
3827
3828 if handled {
3829 if cfg!(debug_assertions) {
3832 let mut effective = false;
3833 let children = EffectiveRulesIterator::children(
3834 rule,
3835 device,
3836 quirks_mode,
3837 guard,
3838 &mut effective,
3839 );
3840 debug_assert!(children.is_none());
3841 debug_assert!(effective);
3842 }
3843 continue;
3844 }
3845
3846 let mut effective = false;
3847 let children =
3848 EffectiveRulesIterator::children(rule, device, quirks_mode, guard, &mut effective);
3849
3850 if !effective {
3851 continue;
3852 }
3853
3854 fn maybe_register_layer(data: &mut CascadeData, layer: &LayerName) -> LayerId {
3855 if let Some(id) = data.layer_id.get(layer) {
3859 return *id;
3860 }
3861 let id = LayerId(data.layers.len() as u16);
3862
3863 let parent_layer_id = if layer.layer_names().len() > 1 {
3864 let mut parent = layer.clone();
3865 parent.0.pop();
3866
3867 *data
3868 .layer_id
3869 .get_mut(&parent)
3870 .expect("Parent layers should be registered before child layers")
3871 } else {
3872 LayerId::root()
3873 };
3874
3875 data.layers[parent_layer_id.0 as usize].children.push(id);
3876 data.layers.push(CascadeLayer {
3877 id,
3878 order: LayerOrder::first(),
3881 children: vec![],
3882 });
3883
3884 data.layer_id.insert(layer.clone(), id);
3885
3886 id
3887 }
3888
3889 fn maybe_register_layers(
3890 data: &mut CascadeData,
3891 name: Option<&LayerName>,
3892 containing_rule_state: &mut ContainingRuleState,
3893 ) {
3894 let anon_name;
3895 let name = match name {
3896 Some(name) => name,
3897 None => {
3898 anon_name = LayerName::new_anonymous();
3899 &anon_name
3900 },
3901 };
3902 for name in name.layer_names() {
3903 containing_rule_state.layer_name.0.push(name.clone());
3904 containing_rule_state.layer_id =
3905 maybe_register_layer(data, &containing_rule_state.layer_name);
3906 }
3907 debug_assert_ne!(containing_rule_state.layer_id, LayerId::root());
3908 }
3909
3910 let saved_containing_rule_state = containing_rule_state.save();
3911 match *rule {
3912 CssRule::Import(ref lock) => {
3913 let import_rule = lock.read_with(guard);
3914 if rebuild_kind.should_rebuild_invalidation() {
3915 self.effective_media_query_results
3916 .saw_effective(import_rule);
3917 }
3918 match import_rule.layer {
3919 ImportLayer::Named(ref name) => {
3920 maybe_register_layers(self, Some(name), containing_rule_state)
3921 },
3922 ImportLayer::Anonymous => {
3923 maybe_register_layers(self, None, containing_rule_state)
3924 },
3925 ImportLayer::None => {},
3926 }
3927 },
3928 CssRule::Media(ref media_rule) => {
3929 if rebuild_kind.should_rebuild_invalidation() {
3930 self.effective_media_query_results
3931 .saw_effective(&**media_rule);
3932 }
3933 },
3934 CssRule::LayerBlock(ref rule) => {
3935 maybe_register_layers(self, rule.name.as_ref(), containing_rule_state);
3936 },
3937 CssRule::LayerStatement(ref rule) => {
3938 for name in &*rule.names {
3939 maybe_register_layers(self, Some(name), containing_rule_state);
3940 containing_rule_state.restore(&saved_containing_rule_state);
3942 }
3943 },
3944 CssRule::Style(..) => {
3945 containing_rule_state.nested_declarations_context =
3946 NestedDeclarationsContext::Style;
3947 if let Some(s) = list_for_nested_rules {
3948 containing_rule_state.ancestor_selector_lists.push(s);
3949 }
3950 },
3951 CssRule::Container(ref rule) => {
3952 let id = ContainerConditionId(self.container_conditions.len() as u16);
3953 self.container_conditions.push(ContainerConditionReference {
3954 parent: containing_rule_state.container_condition_id,
3955 condition: Some(rule.condition.clone()),
3956 });
3957 containing_rule_state.container_condition_id = id;
3958 },
3959 CssRule::StartingStyle(..) => {
3960 containing_rule_state.in_starting_style = true;
3961 },
3962 CssRule::Scope(ref rule) => {
3963 containing_rule_state.nested_declarations_context =
3964 NestedDeclarationsContext::Scope;
3965 let id = ScopeConditionId(self.scope_conditions.len() as u16);
3966 let mut matches_shadow_host = false;
3967 let implicit_scope_root = if let Some(start) = rule.bounds.start.as_ref() {
3968 matches_shadow_host = scope_start_matches_shadow_host(start);
3969 StylistImplicitScopeRoot::default()
3971 } else {
3972 if let Some(root) = stylesheet.implicit_scope_root() {
3975 matches_shadow_host = root.matches_shadow_host();
3976 match root {
3977 ImplicitScopeRoot::InLightTree(_)
3978 | ImplicitScopeRoot::Constructed
3979 | ImplicitScopeRoot::DocumentElement => {
3980 StylistImplicitScopeRoot::Normal(root)
3981 },
3982 ImplicitScopeRoot::ShadowHost(_)
3983 | ImplicitScopeRoot::InShadowTree(_) => {
3984 StylistImplicitScopeRoot::Cached(sheet_index)
3991 },
3992 }
3993 } else {
3994 StylistImplicitScopeRoot::default()
3996 }
3997 };
3998
3999 let replaced =
4000 {
4001 let start = rule.bounds.start.as_ref().map(|selector| {
4002 match containing_rule_state.ancestor_selector_lists.last() {
4003 Some(s) => selector.replace_parent_selector(s),
4004 None => selector.clone(),
4005 }
4006 });
4007 let implicit_scope_selector = &*IMPLICIT_SCOPE;
4008 let end = rule.bounds.end.as_ref().map(|selector| {
4009 selector.replace_parent_selector(implicit_scope_selector)
4010 });
4011 containing_rule_state
4012 .ancestor_selector_lists
4013 .push(implicit_scope_selector.clone());
4014 ScopeBoundsWithHashes::new(quirks_mode, start, end)
4015 };
4016
4017 if let Some(selectors) = replaced.start.as_ref() {
4018 self.scope_subject_map
4019 .add_bound_start(&selectors.selectors, quirks_mode);
4020 }
4021
4022 let is_trivial = replaced.is_trivial();
4023 self.scope_conditions.push(ScopeConditionReference {
4024 parent: containing_rule_state.scope_condition_id,
4025 condition: Some(replaced),
4026 implicit_scope_root,
4027 is_trivial,
4028 });
4029 containing_rule_state
4030 .scope_matches_shadow_host
4031 .nest_for_scope(matches_shadow_host);
4032 containing_rule_state.scope_condition_id = id;
4033 },
4034 _ => {},
4036 }
4037
4038 if let Some(children) = children {
4039 self.add_rule_list(
4040 children,
4041 device,
4042 quirks_mode,
4043 stylesheet,
4044 sheet_index,
4045 guard,
4046 rebuild_kind,
4047 containing_rule_state,
4048 precomputed_pseudo_element_decls.as_deref_mut(),
4049 )?;
4050 }
4051
4052 containing_rule_state.restore(&saved_containing_rule_state);
4053 }
4054
4055 Ok(())
4056 }
4057
4058 fn add_stylesheet<S>(
4060 &mut self,
4061 device: &Device,
4062 quirks_mode: QuirksMode,
4063 stylesheet: &S,
4064 sheet_index: usize,
4065 guard: &SharedRwLockReadGuard,
4066 rebuild_kind: SheetRebuildKind,
4067 mut precomputed_pseudo_element_decls: Option<&mut PrecomputedPseudoElementDeclarations>,
4068 ) -> Result<(), AllocErr>
4069 where
4070 S: StylesheetInDocument + 'static,
4071 {
4072 if !stylesheet.enabled() || !stylesheet.is_effective_for_device(device, guard) {
4073 return Ok(());
4074 }
4075
4076 let contents = stylesheet.contents();
4077
4078 if rebuild_kind.should_rebuild_invalidation() {
4079 self.effective_media_query_results.saw_effective(contents);
4080 }
4081
4082 let mut state = ContainingRuleState::default();
4083 self.add_rule_list(
4084 contents.rules(guard).iter(),
4085 device,
4086 quirks_mode,
4087 stylesheet,
4088 sheet_index,
4089 guard,
4090 rebuild_kind,
4091 &mut state,
4092 precomputed_pseudo_element_decls.as_deref_mut(),
4093 )?;
4094
4095 Ok(())
4096 }
4097
4098 pub fn media_feature_affected_matches<S>(
4101 &self,
4102 stylesheet: &S,
4103 guard: &SharedRwLockReadGuard,
4104 device: &Device,
4105 quirks_mode: QuirksMode,
4106 ) -> bool
4107 where
4108 S: StylesheetInDocument + 'static,
4109 {
4110 use crate::invalidation::media_queries::PotentiallyEffectiveMediaRules;
4111
4112 let effective_now = stylesheet.is_effective_for_device(device, guard);
4113
4114 let effective_then = self
4115 .effective_media_query_results
4116 .was_effective(stylesheet.contents());
4117
4118 if effective_now != effective_then {
4119 debug!(
4120 " > Stylesheet {:?} changed -> {}, {}",
4121 stylesheet.media(guard),
4122 effective_then,
4123 effective_now
4124 );
4125 return false;
4126 }
4127
4128 if !effective_now {
4129 return true;
4130 }
4131
4132 let mut iter = stylesheet.iter_rules::<PotentiallyEffectiveMediaRules>(device, guard);
4133
4134 while let Some(rule) = iter.next() {
4135 match *rule {
4136 CssRule::Style(..)
4137 | CssRule::NestedDeclarations(..)
4138 | CssRule::Namespace(..)
4139 | CssRule::FontFace(..)
4140 | CssRule::Container(..)
4141 | CssRule::CounterStyle(..)
4142 | CssRule::Supports(..)
4143 | CssRule::Keyframes(..)
4144 | CssRule::Margin(..)
4145 | CssRule::Page(..)
4146 | CssRule::Property(..)
4147 | CssRule::Document(..)
4148 | CssRule::LayerBlock(..)
4149 | CssRule::LayerStatement(..)
4150 | CssRule::FontPaletteValues(..)
4151 | CssRule::FontFeatureValues(..)
4152 | CssRule::Scope(..)
4153 | CssRule::StartingStyle(..)
4154 | CssRule::PositionTry(..) => {
4155 continue;
4157 },
4158 CssRule::Import(ref lock) => {
4159 let import_rule = lock.read_with(guard);
4160 let effective_now = match import_rule.stylesheet.media(guard) {
4161 Some(m) => m.evaluate(device, quirks_mode),
4162 None => true,
4163 };
4164 let effective_then = self
4165 .effective_media_query_results
4166 .was_effective(import_rule);
4167 if effective_now != effective_then {
4168 debug!(
4169 " > @import rule {:?} changed {} -> {}",
4170 import_rule.stylesheet.media(guard),
4171 effective_then,
4172 effective_now
4173 );
4174 return false;
4175 }
4176
4177 if !effective_now {
4178 iter.skip_children();
4179 }
4180 },
4181 CssRule::Media(ref media_rule) => {
4182 let mq = media_rule.media_queries.read_with(guard);
4183 let effective_now = mq.evaluate(device, quirks_mode);
4184 let effective_then = self
4185 .effective_media_query_results
4186 .was_effective(&**media_rule);
4187
4188 if effective_now != effective_then {
4189 debug!(
4190 " > @media rule {:?} changed {} -> {}",
4191 mq, effective_then, effective_now
4192 );
4193 return false;
4194 }
4195
4196 if !effective_now {
4197 iter.skip_children();
4198 }
4199 },
4200 }
4201 }
4202
4203 true
4204 }
4205
4206 pub fn custom_property_registrations(&self) -> &LayerOrderedMap<Arc<PropertyRegistration>> {
4208 &self.custom_property_registrations
4209 }
4210
4211 fn revalidate_scopes<E: TElement>(
4212 &self,
4213 element: &E,
4214 matching_context: &mut MatchingContext<E::Impl>,
4215 result: &mut ScopeRevalidationResult,
4216 ) {
4217 for condition_id in 1..self.scope_conditions.len() {
4224 let condition = &self.scope_conditions[condition_id];
4225 let matches = if condition.is_trivial {
4226 continue;
4229 } else {
4230 let result = scope_root_candidates(
4231 &self.scope_conditions,
4232 ScopeConditionId(condition_id as u16),
4233 element,
4234 false,
4236 &self.scope_subject_map,
4237 matching_context,
4238 );
4239 !result.candidates.is_empty()
4240 };
4241 result.scopes_matched.push(matches);
4242 }
4243 }
4244
4245 fn clear_cascade_data(&mut self) {
4247 self.normal_rules.clear();
4248 if let Some(ref mut slotted_rules) = self.slotted_rules {
4249 slotted_rules.clear();
4250 }
4251 if let Some(ref mut part_rules) = self.part_rules {
4252 part_rules.clear();
4253 }
4254 if let Some(ref mut host_rules) = self.featureless_host_rules {
4255 host_rules.clear();
4256 }
4257 self.animations.clear();
4258 self.custom_property_registrations.clear();
4259 self.layer_id.clear();
4260 self.layers.clear();
4261 self.layers.push(CascadeLayer::root());
4262 self.container_conditions.clear();
4263 self.container_conditions
4264 .push(ContainerConditionReference::none());
4265 self.scope_conditions.clear();
4266 self.scope_conditions.push(ScopeConditionReference::none());
4267 #[cfg(feature = "gecko")]
4268 self.extra_data.clear();
4269 self.rules_source_order = 0;
4270 self.num_selectors = 0;
4271 self.num_declarations = 0;
4272 }
4273
4274 fn clear(&mut self) {
4275 self.clear_cascade_data();
4276 self.invalidation_map.clear();
4277 self.relative_selector_invalidation_map.clear();
4278 self.additional_relative_selector_invalidation_map.clear();
4279 self.attribute_dependencies.clear();
4280 self.nth_of_attribute_dependencies.clear();
4281 self.nth_of_custom_state_dependencies.clear();
4282 self.nth_of_class_dependencies.clear();
4283 self.state_dependencies = ElementState::empty();
4284 self.nth_of_state_dependencies = ElementState::empty();
4285 self.document_state_dependencies = DocumentState::empty();
4286 self.mapped_ids.clear();
4287 self.nth_of_mapped_ids.clear();
4288 self.selectors_for_cache_revalidation.clear();
4289 self.effective_media_query_results.clear();
4290 self.scope_subject_map.clear();
4291 }
4292}
4293
4294impl CascadeDataCacheEntry for CascadeData {
4295 fn rebuild<S>(
4296 device: &Device,
4297 quirks_mode: QuirksMode,
4298 collection: SheetCollectionFlusher<S>,
4299 guard: &SharedRwLockReadGuard,
4300 old: &Self,
4301 ) -> Result<Arc<Self>, AllocErr>
4302 where
4303 S: StylesheetInDocument + PartialEq + 'static,
4304 {
4305 debug_assert!(collection.dirty(), "We surely need to do something?");
4306 let mut updatable_entry = match collection.data_validity() {
4308 DataValidity::Valid | DataValidity::CascadeInvalid => old.clone(),
4309 DataValidity::FullyInvalid => Self::new(),
4310 };
4311 updatable_entry.rebuild(device, quirks_mode, collection, guard)?;
4312 Ok(Arc::new(updatable_entry))
4313 }
4314
4315 #[cfg(feature = "gecko")]
4316 fn add_size_of(&self, ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes) {
4317 self.normal_rules.add_size_of(ops, sizes);
4318 if let Some(ref slotted_rules) = self.slotted_rules {
4319 slotted_rules.add_size_of(ops, sizes);
4320 }
4321 if let Some(ref part_rules) = self.part_rules {
4322 part_rules.add_size_of(ops, sizes);
4323 }
4324 if let Some(ref host_rules) = self.featureless_host_rules {
4325 host_rules.add_size_of(ops, sizes);
4326 }
4327 sizes.mInvalidationMap += self.invalidation_map.size_of(ops);
4328 sizes.mRevalidationSelectors += self.selectors_for_cache_revalidation.size_of(ops);
4329 sizes.mOther += self.animations.size_of(ops);
4330 sizes.mOther += self.effective_media_query_results.size_of(ops);
4331 sizes.mOther += self.extra_data.size_of(ops);
4332 }
4333}
4334
4335impl Default for CascadeData {
4336 fn default() -> Self {
4337 CascadeData::new()
4338 }
4339}
4340
4341#[derive(Clone, Debug, MallocSizeOf)]
4344pub struct Rule {
4345 #[ignore_malloc_size_of = "CssRules have primary refs, we measure there"]
4350 pub selector: Selector<SelectorImpl>,
4351
4352 pub hashes: AncestorHashes,
4354
4355 pub source_order: u32,
4359
4360 pub layer_id: LayerId,
4362
4363 pub container_condition_id: ContainerConditionId,
4365
4366 pub is_starting_style: bool,
4368
4369 pub scope_condition_id: ScopeConditionId,
4371
4372 #[ignore_malloc_size_of = "Secondary ref. Primary ref is in StyleRule under Stylesheet."]
4374 pub style_source: StyleSource,
4375}
4376
4377impl SelectorMapEntry for Rule {
4378 fn selector(&self) -> SelectorIter<'_, SelectorImpl> {
4379 self.selector.iter()
4380 }
4381}
4382
4383impl Rule {
4384 pub fn specificity(&self) -> u32 {
4386 self.selector.specificity()
4387 }
4388
4389 pub fn to_applicable_declaration_block(
4392 &self,
4393 level: CascadeLevel,
4394 cascade_data: &CascadeData,
4395 scope_proximity: ScopeProximity,
4396 ) -> ApplicableDeclarationBlock {
4397 ApplicableDeclarationBlock::new(
4398 self.style_source.clone(),
4399 self.source_order,
4400 level,
4401 self.specificity(),
4402 cascade_data.layer_order_for(self.layer_id),
4403 scope_proximity,
4404 )
4405 }
4406
4407 pub fn new(
4409 selector: Selector<SelectorImpl>,
4410 hashes: AncestorHashes,
4411 style_source: StyleSource,
4412 source_order: u32,
4413 layer_id: LayerId,
4414 container_condition_id: ContainerConditionId,
4415 is_starting_style: bool,
4416 scope_condition_id: ScopeConditionId,
4417 ) -> Self {
4418 Self {
4419 selector,
4420 hashes,
4421 style_source,
4422 source_order,
4423 layer_id,
4424 container_condition_id,
4425 is_starting_style,
4426 scope_condition_id,
4427 }
4428 }
4429}
4430
4431size_of_test!(Rule, 40);
4436
4437pub fn needs_revalidation_for_testing(s: &Selector<SelectorImpl>) -> bool {
4439 let mut needs_revalidation = false;
4440 let mut mapped_ids = Default::default();
4441 let mut nth_of_mapped_ids = Default::default();
4442 let mut attribute_dependencies = Default::default();
4443 let mut nth_of_class_dependencies = Default::default();
4444 let mut nth_of_attribute_dependencies = Default::default();
4445 let mut nth_of_custom_state_dependencies = Default::default();
4446 let mut state_dependencies = ElementState::empty();
4447 let mut nth_of_state_dependencies = ElementState::empty();
4448 let mut document_state_dependencies = DocumentState::empty();
4449 let mut visitor = StylistSelectorVisitor {
4450 passed_rightmost_selector: false,
4451 needs_revalidation: &mut needs_revalidation,
4452 in_selector_list_of: SelectorListKind::default(),
4453 mapped_ids: &mut mapped_ids,
4454 nth_of_mapped_ids: &mut nth_of_mapped_ids,
4455 attribute_dependencies: &mut attribute_dependencies,
4456 nth_of_class_dependencies: &mut nth_of_class_dependencies,
4457 nth_of_attribute_dependencies: &mut nth_of_attribute_dependencies,
4458 nth_of_custom_state_dependencies: &mut nth_of_custom_state_dependencies,
4459 state_dependencies: &mut state_dependencies,
4460 nth_of_state_dependencies: &mut nth_of_state_dependencies,
4461 document_state_dependencies: &mut document_state_dependencies,
4462 };
4463 s.visit(&mut visitor);
4464 needs_revalidation
4465}