--- a/servo/components/style/stylesheets/origin.rs
+++ b/servo/components/style/stylesheets/origin.rs
@@ -1,22 +1,146 @@
/* 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/. */
///! [CSS cascade origins](https://drafts.csswg.org/css-cascade/#cascading-origins).
+use std::marker::PhantomData;
+use std::mem::transmute;
+
/// Each style rule has an origin, which determines where it enters the cascade.
///
/// https://drafts.csswg.org/css-cascade/#cascading-origins
#[derive(Clone, PartialEq, Eq, Copy, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum Origin {
/// https://drafts.csswg.org/css-cascade/#cascade-origin-us
UserAgent,
/// https://drafts.csswg.org/css-cascade/#cascade-origin-author
Author,
/// https://drafts.csswg.org/css-cascade/#cascade-origin-user
User,
}
+/// An object that stores a `T` for each origin of the CSS cascade.
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+#[derive(Debug, Default)]
+pub struct PerOrigin<T> {
+ /// Data for `Origin::UserAgent`.
+ pub user_agent: T,
+
+ /// Data for `Origin::Author`.
+ pub author: T,
+
+ /// Data for `Origin::User`.
+ pub user: T,
+}
+
+impl<T> PerOrigin<T> {
+ /// Returns a reference to the per-origin data for the specified origin.
+ #[inline]
+ pub fn borrow_for_origin(&self, origin: &Origin) -> &T {
+ match *origin {
+ Origin::UserAgent => &self.user_agent,
+ Origin::Author => &self.author,
+ Origin::User => &self.user,
+ }
+ }
+
+ /// Returns a mutable reference to the per-origin data for the specified
+ /// origin.
+ #[inline]
+ pub fn borrow_mut_for_origin(&mut self, origin: &Origin) -> &mut T {
+ match *origin {
+ Origin::UserAgent => &mut self.user_agent,
+ Origin::Author => &mut self.author,
+ Origin::User => &mut self.user,
+ }
+ }
+
+ /// Iterates over references to per-origin extra style data, from highest
+ /// level (user) to lowest (user agent).
+ pub fn iter_origins(&self) -> PerOriginIter<T> {
+ PerOriginIter {
+ data: &self,
+ cur: 0,
+ }
+ }
+
+ /// Iterates over mutable references to per-origin extra style data, from
+ /// highest level (user) to lowest (user agent).
+ pub fn iter_mut_origins(&mut self) -> PerOriginIterMut<T> {
+ PerOriginIterMut {
+ data: self,
+ cur: 0,
+ _marker: PhantomData,
+ }
+ }
+}
+
+/// An object that can be cleared.
+pub trait PerOriginClear {
+ /// Clears the object.
+ fn clear(&mut self);
+}
+
+impl<T> PerOriginClear for PerOrigin<T> where T : PerOriginClear {
+ fn clear(&mut self) {
+ self.user_agent.clear();
+ self.author.clear();
+ self.user.clear();
+ }
+}
+
+/// Iterator over `PerOrigin<T>`, from highest level (user) to lowest
+/// (user agent).
+///
+/// We rely on this specific order for correctly looking up @font-face,
+/// @counter-style and @keyframes rules.
+pub struct PerOriginIter<'a, T: 'a> {
+ data: &'a PerOrigin<T>,
+ cur: usize,
+}
+
+impl<'a, T> Iterator for PerOriginIter<'a, T> where T: 'a {
+ type Item = (&'a T, Origin);
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let result = match self.cur {
+ 0 => (&self.data.user, Origin::User),
+ 1 => (&self.data.author, Origin::Author),
+ 2 => (&self.data.user_agent, Origin::UserAgent),
+ _ => return None,
+ };
+ self.cur += 1;
+ Some(result)
+ }
+}
+
+/// Like `PerOriginIter<T>`, but iterates over mutable references to the
+/// per-origin data.
+///
+/// We must use unsafe code here since it's not possible for the borrow
+/// checker to know that we are safely returning a different reference
+/// each time from `next()`.
+pub struct PerOriginIterMut<'a, T: 'a> {
+ data: *mut PerOrigin<T>,
+ cur: usize,
+ _marker: PhantomData<&'a mut PerOrigin<T>>,
+}
+
+impl<'a, T> Iterator for PerOriginIterMut<'a, T> where T: 'a {
+ type Item = (&'a mut T, Origin);
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let result = match self.cur {
+ 0 => (unsafe { transmute(&mut (*self.data).user) }, Origin::User),
+ 1 => (unsafe { transmute(&mut (*self.data).author) }, Origin::Author),
+ 2 => (unsafe { transmute(&mut (*self.data).user_agent) }, Origin::UserAgent),
+ _ => return None,
+ };
+ self.cur += 1;
+ Some(result)
+ }
+}
--- a/servo/components/style/stylist.rs
+++ b/servo/components/style/stylist.rs
@@ -35,17 +35,18 @@ use selectors::visitor::SelectorVisitor;
use servo_arc::{Arc, ArcBorrow};
use shared_lock::{Locked, SharedRwLockReadGuard, StylesheetGuards};
use smallvec::VecLike;
use std::fmt::Debug;
use style_traits::viewport::ViewportConstraints;
#[cfg(feature = "gecko")]
use stylesheets::{CounterStyleRule, FontFaceRule};
use stylesheets::{CssRule, StyleRule};
-use stylesheets::{StylesheetInDocument, Origin, UserAgentStylesheets};
+use stylesheets::{StylesheetInDocument, Origin, PerOrigin, PerOriginClear};
+use stylesheets::UserAgentStylesheets;
use stylesheets::keyframes_rule::KeyframesAnimation;
use stylesheets::viewport_rule::{self, MaybeNew, ViewportRule};
use thread_state;
pub use ::fnv::FnvHashMap;
/// This structure holds all the selectors and device characteristics
/// for a given document. The selectors are converted into `Rule`s
@@ -85,17 +86,17 @@ pub struct Stylist {
/// If true, the stylist is in a cleared state (e.g. just-constructed, or
/// had clear() called on it with no following rebuild()).
is_cleared: bool,
/// Selector maps for all of the style sheets in the stylist, after
/// evalutaing media rules against the current device, split out per
/// cascade level.
- cascade_data: CascadeData,
+ cascade_data: PerOrigin<CascadeData>,
/// The rule tree, that stores the results of selector matching.
rule_tree: RuleTree,
/// Applicable declarations for a given non-eagerly cascaded pseudo-element.
/// These are eagerly computed once, and then used to resolve the new
/// computed values on the fly on layout.
///
@@ -105,100 +106,16 @@ pub struct Stylist {
/// A monotonically increasing counter to represent the order on which a
/// style rule appears in a stylesheet, needed to sort them by source order.
rules_source_order: u32,
/// The total number of times the stylist has been rebuilt.
num_rebuilds: usize,
}
-/// This struct holds data which users of Stylist may want to extract
-/// from stylesheets which can be done at the same time as updating.
-#[cfg(feature = "gecko")]
-#[derive(Default)]
-pub struct ExtraStyleData {
- /// Extra data from user agent stylesheets
- user_agent: PerOriginExtraStyleData,
- /// Extra data from author stylesheets
- author: PerOriginExtraStyleData,
- /// Extra data from user stylesheets
- user: PerOriginExtraStyleData,
-}
-
-/// This struct holds data which users of Stylist may want to extract
-/// from stylesheets which can be done at the same time as updating.
-#[cfg(feature = "gecko")]
-#[derive(Default)]
-pub struct PerOriginExtraStyleData {
- /// A list of effective font-face rules and their origin.
- pub font_faces: Vec<Arc<Locked<FontFaceRule>>>,
- /// A map of effective counter-style rules.
- pub counter_styles: PrecomputedHashMap<Atom, Arc<Locked<CounterStyleRule>>>,
-}
-
-#[cfg(feature = "gecko")]
-impl ExtraStyleData {
- /// Clear the internal data.
- pub fn clear(&mut self) {
- self.user_agent.clear();
- self.author.clear();
- self.user.clear();
- }
-
- /// Returns a reference to the per-origin extra style data for
- /// the specified origin.
- #[inline]
- pub fn borrow_mut_for_origin(&mut self, origin: &Origin) -> &mut PerOriginExtraStyleData {
- match *origin {
- Origin::UserAgent => &mut self.user_agent,
- Origin::Author => &mut self.author,
- Origin::User => &mut self.user,
- }
- }
-
- /// Iterates over the per-origin extra style data, from highest level (user)
- /// to lowest (user agent).
- pub fn iter_origins(&self) -> ExtraStyleDataIter {
- ExtraStyleDataIter {
- extra_style_data: &self,
- cur: 0,
- }
- }
-}
-
-#[cfg(feature = "gecko")]
-impl PerOriginExtraStyleData {
- /// Clears the stored @font-face and @counter-style rules.
- fn clear(&mut self) {
- self.font_faces.clear();
- self.counter_styles.clear();
- }
-
- /// Add the given @font-face rule.
- fn add_font_face(&mut self, rule: &Arc<Locked<FontFaceRule>>) {
- self.font_faces.push(rule.clone());
- }
-
- /// Add the given @counter-style rule.
- fn add_counter_style(&mut self, guard: &SharedRwLockReadGuard,
- rule: &Arc<Locked<CounterStyleRule>>) {
- let name = rule.read_with(guard).mName.raw::<nsIAtom>().into();
- self.counter_styles.insert(name, rule.clone());
- }
-}
-
-#[allow(missing_docs)]
-#[cfg(feature = "servo")]
-pub struct ExtraStyleData;
-
-#[cfg(feature = "servo")]
-impl ExtraStyleData {
- fn clear(&mut self) {}
-}
-
/// What cascade levels to include when styling elements.
#[derive(Copy, Clone, PartialEq)]
pub enum RuleInclusion {
/// Include rules for style sheets at all cascade levels. This is the
/// normal rule inclusion mode.
All,
/// Only include rules from UA and user level sheets. Used to implement
/// `getDefaultComputedStyle`.
@@ -224,63 +141,63 @@ impl Stylist {
Stylist {
viewport_constraints: None,
device: device,
is_device_dirty: true,
is_cleared: true,
quirks_mode: quirks_mode,
effective_media_query_results: EffectiveMediaQueryResults::new(),
- cascade_data: CascadeData::new(),
+ cascade_data: Default::default(),
precomputed_pseudo_element_decls: PerPseudoElementMap::default(),
rules_source_order: 0,
rule_tree: RuleTree::new(),
num_rebuilds: 0,
}
// FIXME: Add iso-8859-9.css when the document’s encoding is ISO-8859-8.
}
/// Returns the number of selectors.
pub fn num_selectors(&self) -> usize {
- self.cascade_data.iter_origins().map(|d| d.num_selectors).sum()
+ self.cascade_data.iter_origins().map(|(d, _)| d.num_selectors).sum()
}
/// Returns the number of declarations.
pub fn num_declarations(&self) -> usize {
- self.cascade_data.iter_origins().map(|d| d.num_declarations).sum()
+ self.cascade_data.iter_origins().map(|(d, _)| d.num_declarations).sum()
}
/// Returns the number of times the stylist has been rebuilt.
pub fn num_rebuilds(&self) -> usize {
self.num_rebuilds
}
/// Returns the number of revalidation_selectors.
pub fn num_revalidation_selectors(&self) -> usize {
self.cascade_data.iter_origins()
- .map(|d| d.selectors_for_cache_revalidation.len()).sum()
+ .map(|(d, _)| d.selectors_for_cache_revalidation.len()).sum()
}
/// Returns the number of entries in invalidation maps.
pub fn num_invalidations(&self) -> usize {
self.cascade_data.iter_origins()
- .map(|d| d.invalidation_map.len()).sum()
+ .map(|(d, _)| d.invalidation_map.len()).sum()
}
/// Invokes `f` with the `InvalidationMap` for each origin.
///
/// NOTE(heycam) This might be better as an `iter_invalidation_maps`, once
/// we have `impl trait` and can return that easily without bothering to
/// create a whole new iterator type.
pub fn each_invalidation_map<F>(&self, mut f: F)
where F: FnMut(&InvalidationMap)
{
- for origin_cascade_data in self.cascade_data.iter_origins() {
- f(&origin_cascade_data.invalidation_map)
+ for (data, _) in self.cascade_data.iter_origins() {
+ f(&data.invalidation_map)
}
}
/// Clear the stylist's state, effectively resetting it to more or less
/// the state Stylist::new creates.
///
/// We preserve the state of the following members:
/// device: Someone might have set this on us.
@@ -319,17 +236,17 @@ impl Stylist {
/// device is dirty, which means we need to re-evaluate media queries.
pub fn rebuild<'a, I, S>(
&mut self,
doc_stylesheets: I,
guards: &StylesheetGuards,
ua_stylesheets: Option<&UserAgentStylesheets>,
stylesheets_changed: bool,
author_style_disabled: bool,
- extra_data: &mut ExtraStyleData
+ extra_data: &mut PerOrigin<ExtraStyleData>
) -> bool
where
I: Iterator<Item = &'a S> + Clone,
S: StylesheetInDocument + ToMediaListKey + 'static,
{
debug_assert!(!self.is_cleared || self.is_device_dirty);
self.is_cleared = false;
@@ -399,17 +316,17 @@ impl Stylist {
/// either clear() or rebuild(), with the latter done lazily, instead.
pub fn update<'a, I, S>(
&mut self,
doc_stylesheets: I,
guards: &StylesheetGuards,
ua_stylesheets: Option<&UserAgentStylesheets>,
stylesheets_changed: bool,
author_style_disabled: bool,
- extra_data: &mut ExtraStyleData
+ extra_data: &mut PerOrigin<ExtraStyleData>
) -> bool
where
I: Iterator<Item = &'a S> + Clone,
S: StylesheetInDocument + ToMediaListKey + 'static,
{
debug_assert!(!self.is_cleared || self.is_device_dirty);
// We have to do a dirtiness check before clearing, because if
@@ -421,17 +338,17 @@ impl Stylist {
self.rebuild(doc_stylesheets, guards, ua_stylesheets, stylesheets_changed,
author_style_disabled, extra_data)
}
fn add_stylesheet<S>(
&mut self,
stylesheet: &S,
guard: &SharedRwLockReadGuard,
- _extra_data: &mut ExtraStyleData
+ _extra_data: &mut PerOrigin<ExtraStyleData>
)
where
S: StylesheetInDocument + ToMediaListKey + 'static,
{
if !stylesheet.enabled() ||
!stylesheet.is_effective_for_device(&self.device, guard) {
return;
}
@@ -569,21 +486,21 @@ impl Stylist {
-> bool {
if self.is_cleared || self.is_device_dirty {
// We can't tell what attributes are in our style rules until
// we rebuild.
true
} else if *local_name == local_name!("style") {
self.cascade_data
.iter_origins()
- .any(|d| d.style_attribute_dependency)
+ .any(|(d, _)| d.style_attribute_dependency)
} else {
self.cascade_data
.iter_origins()
- .any(|d| {
+ .any(|(d, _)| {
d.attribute_dependencies
.might_contain_hash(local_name.get_hash())
})
}
}
/// Returns whether the given ElementState bit might be relied upon by a
/// selector of some rule in the stylist.
@@ -597,17 +514,17 @@ impl Stylist {
}
}
/// Returns whether the given ElementState bit is relied upon by a selector
/// of some rule in the stylist.
pub fn has_state_dependency(&self, state: ElementState) -> bool {
self.cascade_data
.iter_origins()
- .any(|d| d.state_dependencies.intersects(state))
+ .any(|(d, _)| d.state_dependencies.intersects(state))
}
/// Computes the style for a given "precomputed" pseudo-element, taking the
/// universal rules and applying them.
///
/// If `inherit_all` is true, then all properties are inherited from the
/// parent; otherwise, non-inherited properties are reset to their initial
/// values. The flow constructor uses this flag when constructing anonymous
@@ -847,33 +764,39 @@ impl Stylist {
Some(layout_parent_style),
visited_values,
None,
font_metrics,
cascade_flags,
self.quirks_mode)
}
+ fn has_rules_for_pseudo(&self, pseudo: &PseudoElement) -> bool {
+ self.cascade_data
+ .iter_origins()
+ .any(|(d, _)| d.has_rules_for_pseudo(pseudo))
+ }
+
/// Computes the cascade inputs for a lazily-cascaded pseudo-element.
///
/// See the documentation on lazy pseudo-elements in
/// docs/components/style.md
pub fn lazy_pseudo_rules<E>(&self,
guards: &StylesheetGuards,
element: &E,
pseudo: &PseudoElement,
is_probe: bool,
rule_inclusion: RuleInclusion)
-> CascadeInputs
where E: TElement
{
let pseudo = pseudo.canonical();
debug_assert!(pseudo.is_lazy());
- if !self.cascade_data.has_rules_for_pseudo(&pseudo) {
+ if !self.has_rules_for_pseudo(&pseudo) {
return CascadeInputs::default()
}
// Apply the selector flags. We should be in sequential mode
// already, so we can directly apply the parent flags.
let mut set_selector_flags = |element: &E, flags: ElementSelectorFlags| {
if cfg!(feature = "servo") {
// Servo calls this function from the worker, but only for internal
@@ -1319,32 +1242,32 @@ impl Stylist {
}
/// Given an id, returns whether there might be any rules for that id in any
/// of our rule maps.
#[inline]
pub fn may_have_rules_for_id(&self, id: &Atom) -> bool {
self.cascade_data
.iter_origins()
- .any(|d| d.mapped_ids.might_contain_hash(id.get_hash()))
+ .any(|(d, _)| d.mapped_ids.might_contain_hash(id.get_hash()))
}
/// Return whether the device is dirty, that is, whether the screen size or
/// media type have changed (for now).
#[inline]
pub fn is_device_dirty(&self) -> bool {
self.is_device_dirty
}
/// Returns the registered `@keyframes` animation for the specified name.
#[inline]
pub fn get_animation(&self, name: &Atom) -> Option<&KeyframesAnimation> {
self.cascade_data
.iter_origins()
- .filter_map(|d| d.animations.get(name))
+ .filter_map(|(d, _)| d.animations.get(name))
.next()
}
/// Computes the match results of a given element against the set of
/// revalidation selectors.
pub fn match_revalidation_selectors<E, F>(&self,
element: &E,
bloom: Option<&BloomFilter>,
@@ -1359,18 +1282,18 @@ impl Stylist {
MatchingContext::new(MatchingMode::Normal, bloom, self.quirks_mode);
// Note that, by the time we're revalidating, we're guaranteed that the
// candidate and the entry have the same id, classes, and local name.
// This means we're guaranteed to get the same rulehash buckets for all
// the lookups, which means that the bitvecs are comparable. We verify
// this in the caller by asserting that the bitvecs are same-length.
let mut results = BitVec::new();
- for origin_cascade_data in self.cascade_data.iter_origins() {
- origin_cascade_data.selectors_for_cache_revalidation.lookup(
+ for (data, _) in self.cascade_data.iter_origins() {
+ data.selectors_for_cache_revalidation.lookup(
*element, self.quirks_mode, &mut |selector_and_hashes| {
results.push(matches_selector(&selector_and_hashes.selector,
selector_and_hashes.selector_offset,
Some(&selector_and_hashes.hashes),
element,
&mut matching_context,
flags_setter));
true
@@ -1426,16 +1349,54 @@ impl Stylist {
}
/// Accessor for a shared reference to the rule tree.
pub fn rule_tree(&self) -> &RuleTree {
&self.rule_tree
}
}
+/// This struct holds data which users of Stylist may want to extract
+/// from stylesheets which can be done at the same time as updating.
+#[derive(Default)]
+pub struct ExtraStyleData {
+ /// A list of effective font-face rules and their origin.
+ #[cfg(feature = "gecko")]
+ pub font_faces: Vec<Arc<Locked<FontFaceRule>>>,
+
+ /// A map of effective counter-style rules.
+ #[cfg(feature = "gecko")]
+ pub counter_styles: PrecomputedHashMap<Atom, Arc<Locked<CounterStyleRule>>>,
+}
+
+#[cfg(feature = "gecko")]
+impl ExtraStyleData {
+ /// Add the given @font-face rule.
+ fn add_font_face(&mut self, rule: &Arc<Locked<FontFaceRule>>) {
+ self.font_faces.push(rule.clone());
+ }
+
+ /// Add the given @counter-style rule.
+ fn add_counter_style(&mut self, guard: &SharedRwLockReadGuard,
+ rule: &Arc<Locked<CounterStyleRule>>) {
+ let name = rule.read_with(guard).mName.raw::<nsIAtom>().into();
+ self.counter_styles.insert(name, rule.clone());
+ }
+}
+
+impl PerOriginClear for ExtraStyleData {
+ fn clear(&mut self) {
+ #[cfg(feature = "gecko")]
+ {
+ self.font_faces.clear();
+ self.counter_styles.clear();
+ }
+ }
+}
+
/// SelectorMapEntry implementation for use in our revalidation selector map.
#[derive(Clone, Debug)]
struct RevalidationSelectorAndHashes {
selector: Selector<SelectorImpl>,
selector_offset: usize,
hashes: AncestorHashes,
}
@@ -1594,121 +1555,21 @@ impl<'a> SelectorVisitor for StylistSele
}
_ => {},
}
true
}
}
-/// Data resulting from performing the CSS cascade.
-#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
-#[derive(Debug)]
-struct CascadeData {
- /// Rules from user agent stylesheets
- user_agent: PerOriginCascadeData,
- /// Rules from author stylesheets
- author: PerOriginCascadeData,
- /// Rules from user stylesheets
- user: PerOriginCascadeData,
-}
-
-impl CascadeData {
- fn new() -> Self {
- CascadeData {
- user_agent: PerOriginCascadeData::new(),
- author: PerOriginCascadeData::new(),
- user: PerOriginCascadeData::new(),
- }
- }
-
- #[inline]
- fn borrow_mut_for_origin(&mut self, origin: &Origin) -> &mut PerOriginCascadeData {
- match *origin {
- Origin::UserAgent => &mut self.user_agent,
- Origin::Author => &mut self.author,
- Origin::User => &mut self.user,
- }
- }
-
- fn clear(&mut self) {
- self.user_agent.clear();
- self.author.clear();
- self.user.clear();
- }
-
- fn has_rules_for_pseudo(&self, pseudo: &PseudoElement) -> bool {
- self.iter_origins().any(|d| d.has_rules_for_pseudo(pseudo))
- }
-
- fn iter_origins(&self) -> CascadeDataIter {
- CascadeDataIter {
- cascade_data: &self,
- cur: 0,
- }
- }
-}
-
-/// Iterator over `PerOriginCascadeData`, from highest level (user) to lowest
-/// (user agent).
-///
-/// We rely on this specific order for correctly looking up animations
-/// (prioritizing rules at higher cascade levels), among other things.
-struct CascadeDataIter<'a> {
- cascade_data: &'a CascadeData,
- cur: usize,
-}
-
-impl<'a> Iterator for CascadeDataIter<'a> {
- type Item = &'a PerOriginCascadeData;
-
- fn next(&mut self) -> Option<&'a PerOriginCascadeData> {
- let result = match self.cur {
- 0 => &self.cascade_data.user,
- 1 => &self.cascade_data.author,
- 2 => &self.cascade_data.user_agent,
- _ => return None,
- };
- self.cur += 1;
- Some(result)
- }
-}
-
-/// Iterator over `PerOriginExtraStyleData`, from highest level (user) to lowest
-/// (user agent).
-///
-/// We rely on this specific order for correctly looking up the @font-face
-/// and @counter-style rules.
-#[cfg(feature = "gecko")]
-pub struct ExtraStyleDataIter<'a> {
- extra_style_data: &'a ExtraStyleData,
- cur: usize,
-}
-
-#[cfg(feature = "gecko")]
-impl<'a> Iterator for ExtraStyleDataIter<'a> {
- type Item = (&'a PerOriginExtraStyleData, Origin);
-
- fn next(&mut self) -> Option<(&'a PerOriginExtraStyleData, Origin)> {
- let result = match self.cur {
- 0 => (&self.extra_style_data.user, Origin::User),
- 1 => (&self.extra_style_data.author, Origin::Author),
- 2 => (&self.extra_style_data.user_agent, Origin::UserAgent),
- _ => return None,
- };
- self.cur += 1;
- Some(result)
- }
-}
-
/// Data resulting from performing the CSS cascade that is specific to a given
/// origin.
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[derive(Debug)]
-struct PerOriginCascadeData {
+struct CascadeData {
/// Rules from stylesheets at this `CascadeData`'s origin.
element_map: SelectorMap<Rule>,
/// Rules from stylesheets at this `CascadeData`'s origin that correspond
/// to a given pseudo-element.
pseudos_map: PerPseudoElementMap<SelectorMap<Rule>>,
/// A map with all the animations at this `CascadeData`'s origin, indexed
@@ -1753,17 +1614,17 @@ struct PerOriginCascadeData {
/// The total number of selectors.
num_selectors: usize,
/// The total number of declarations.
num_declarations: usize,
}
-impl PerOriginCascadeData {
+impl CascadeData {
fn new() -> Self {
Self {
element_map: SelectorMap::new(),
pseudos_map: PerPseudoElementMap::default(),
animations: Default::default(),
invalidation_map: InvalidationMap::new(),
attribute_dependencies: NonCountingBloomFilter::new(),
style_attribute_dependency: false,
@@ -1778,32 +1639,40 @@ impl PerOriginCascadeData {
#[inline]
fn borrow_for_pseudo(&self, pseudo: Option<&PseudoElement>) -> Option<&SelectorMap<Rule>> {
match pseudo {
Some(pseudo) => self.pseudos_map.get(&pseudo.canonical()),
None => Some(&self.element_map),
}
}
+ fn has_rules_for_pseudo(&self, pseudo: &PseudoElement) -> bool {
+ self.pseudos_map.get(pseudo).is_some()
+ }
+}
+
+impl PerOriginClear for CascadeData {
fn clear(&mut self) {
self.element_map = SelectorMap::new();
self.pseudos_map = Default::default();
self.animations = Default::default();
self.invalidation_map.clear();
self.attribute_dependencies.clear();
self.style_attribute_dependency = false;
self.state_dependencies = ElementState::empty();
self.mapped_ids.clear();
self.selectors_for_cache_revalidation = SelectorMap::new();
self.num_selectors = 0;
self.num_declarations = 0;
}
+}
- fn has_rules_for_pseudo(&self, pseudo: &PseudoElement) -> bool {
- self.pseudos_map.get(pseudo).is_some()
+impl Default for CascadeData {
+ fn default() -> Self {
+ CascadeData::new()
}
}
/// A rule, that wraps a style rule, but represents a single selector of the
/// rule.
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[derive(Clone, Debug)]
pub struct Rule {