media_queries.rs (4421B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 5 //! Code related to the invalidation of media-query-affected rules. 6 7 use crate::context::QuirksMode; 8 use crate::derives::*; 9 use crate::media_queries::Device; 10 use crate::shared_lock::SharedRwLockReadGuard; 11 use crate::stylesheets::{CustomMediaMap, DocumentRule, ImportRule, MediaRule}; 12 use crate::stylesheets::{NestedRuleIterationCondition, StylesheetContents, SupportsRule}; 13 use rustc_hash::FxHashSet; 14 15 /// A key for a given media query result. 16 /// 17 /// NOTE: It happens to be the case that all the media lists we care about 18 /// happen to have a stable address, so we can just use an opaque pointer to 19 /// represent them. 20 /// 21 /// Also, note that right now when a rule or stylesheet is removed, we do a full 22 /// style flush, so there's no need to worry about other item created with the 23 /// same pointer address. 24 /// 25 /// If this changes, though, we may need to remove the item from the cache if 26 /// present before it goes away. 27 #[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, PartialEq)] 28 pub struct MediaListKey(usize); 29 30 impl MediaListKey { 31 /// Create a MediaListKey from a raw usize. 32 pub fn from_raw(k: usize) -> Self { 33 MediaListKey(k) 34 } 35 } 36 37 /// A trait to get a given `MediaListKey` for a given item that can hold a 38 /// `MediaList`. 39 pub trait ToMediaListKey: Sized { 40 /// Get a `MediaListKey` for this item. This key needs to uniquely identify 41 /// the item. 42 fn to_media_list_key(&self) -> MediaListKey { 43 MediaListKey(self as *const Self as usize) 44 } 45 } 46 47 impl ToMediaListKey for StylesheetContents {} 48 impl ToMediaListKey for ImportRule {} 49 impl ToMediaListKey for MediaRule {} 50 51 /// A struct that holds the result of a media query evaluation pass for the 52 /// media queries that evaluated successfully. 53 #[derive(Clone, Debug, MallocSizeOf, PartialEq)] 54 pub struct EffectiveMediaQueryResults { 55 /// The set of media lists that matched last time. 56 set: FxHashSet<MediaListKey>, 57 } 58 59 impl EffectiveMediaQueryResults { 60 /// Trivially constructs an empty `EffectiveMediaQueryResults`. 61 pub fn new() -> Self { 62 Self { 63 set: FxHashSet::default(), 64 } 65 } 66 67 /// Resets the results, using an empty key. 68 pub fn clear(&mut self) { 69 self.set.clear() 70 } 71 72 /// Returns whether a given item was known to be effective when the results 73 /// were cached. 74 pub fn was_effective<T>(&self, item: &T) -> bool 75 where 76 T: ToMediaListKey, 77 { 78 self.set.contains(&item.to_media_list_key()) 79 } 80 81 /// Notices that an effective item has been seen, and caches it as matching. 82 pub fn saw_effective<T>(&mut self, item: &T) 83 where 84 T: ToMediaListKey, 85 { 86 // NOTE(emilio): We can't assert that we don't cache the same item twice 87 // because of stylesheet reusing... shrug. 88 self.set.insert(item.to_media_list_key()); 89 } 90 } 91 92 /// A filter that filters over effective rules, but allowing all potentially 93 /// effective `@media` rules. 94 pub struct PotentiallyEffectiveMediaRules; 95 96 impl NestedRuleIterationCondition for PotentiallyEffectiveMediaRules { 97 fn process_import( 98 _: &SharedRwLockReadGuard, 99 _: &Device, 100 _: QuirksMode, 101 _: &CustomMediaMap, 102 _: &ImportRule, 103 ) -> bool { 104 true 105 } 106 107 fn process_media( 108 _: &SharedRwLockReadGuard, 109 _: &Device, 110 _: QuirksMode, 111 _: &CustomMediaMap, 112 _: &MediaRule, 113 ) -> bool { 114 true 115 } 116 117 /// Whether we should process the nested rules in a given `@-moz-document` rule. 118 fn process_document( 119 guard: &SharedRwLockReadGuard, 120 device: &Device, 121 quirks_mode: QuirksMode, 122 rule: &DocumentRule, 123 ) -> bool { 124 use crate::stylesheets::EffectiveRules; 125 EffectiveRules::process_document(guard, device, quirks_mode, rule) 126 } 127 128 /// Whether we should process the nested rules in a given `@supports` rule. 129 fn process_supports( 130 guard: &SharedRwLockReadGuard, 131 device: &Device, 132 quirks_mode: QuirksMode, 133 rule: &SupportsRule, 134 ) -> bool { 135 use crate::stylesheets::EffectiveRules; 136 EffectiveRules::process_supports(guard, device, quirks_mode, rule) 137 } 138 }