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