mirror of
https://github.com/servo/servo.git
synced 2025-06-17 21:04:28 +00:00
130 lines
4.2 KiB
Rust
130 lines
4.2 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 https://mozilla.org/MPL/2.0/. */
|
|
|
|
//! Code related to the invalidation of media-query-affected rules.
|
|
|
|
use crate::context::QuirksMode;
|
|
use crate::media_queries::Device;
|
|
use crate::shared_lock::SharedRwLockReadGuard;
|
|
use crate::stylesheets::{DocumentRule, ImportRule, MediaRule};
|
|
use crate::stylesheets::{NestedRuleIterationCondition, Stylesheet, SupportsRule};
|
|
use fxhash::FxHashSet;
|
|
|
|
/// 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.
|
|
fn to_media_list_key(&self) -> MediaListKey {
|
|
MediaListKey(self as *const Self as usize)
|
|
}
|
|
}
|
|
|
|
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: FxHashSet<MediaListKey>,
|
|
}
|
|
|
|
impl EffectiveMediaQueryResults {
|
|
/// Trivially constructs an empty `EffectiveMediaQueryResults`.
|
|
pub fn new() -> Self {
|
|
Self {
|
|
set: FxHashSet::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 crate::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 crate::stylesheets::EffectiveRules;
|
|
EffectiveRules::process_supports(guard, device, quirks_mode, rule)
|
|
}
|
|
}
|