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