servo/components/style/invalidation/media_queries.rs
Emilio Cobos Álvarez cb31e782aa
style: Share user agent cascade data across documents.
MozReview-Commit-ID: KcyuTHD0bt9
Signed-off-by: Emilio Cobos Álvarez <emilio@crisal.io>
2017-09-15 09:26:23 +02:00

143 lines
4.4 KiB
Rust

/* 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, PartialEq)]
#[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
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, PartialEq)]
#[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
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)
}
}