mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
style: Simplify and improve the per origin stylesheet invalidation setup.
MozReview-Commit-ID: adDDRhNnOw Signed-off-by: Emilio Cobos Álvarez <emilio@crisal.io>
This commit is contained in:
parent
a98fd5e2b6
commit
e1517d62af
2 changed files with 25 additions and 62 deletions
|
@ -9,7 +9,7 @@ use invalidation::stylesheets::StylesheetInvalidationSet;
|
||||||
use media_queries::Device;
|
use media_queries::Device;
|
||||||
use shared_lock::SharedRwLockReadGuard;
|
use shared_lock::SharedRwLockReadGuard;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use stylesheets::{OriginSet, PerOrigin, StylesheetInDocument};
|
use stylesheets::{Origin, OriginSet, StylesheetInDocument};
|
||||||
|
|
||||||
/// Entry for a StylesheetSet. We don't bother creating a constructor, because
|
/// Entry for a StylesheetSet. We don't bother creating a constructor, because
|
||||||
/// there's no sensible defaults for the member variables.
|
/// there's no sensible defaults for the member variables.
|
||||||
|
@ -51,8 +51,11 @@ where
|
||||||
/// include recursive `@import` rules.
|
/// include recursive `@import` rules.
|
||||||
entries: Vec<StylesheetSetEntry<S>>,
|
entries: Vec<StylesheetSetEntry<S>>,
|
||||||
|
|
||||||
/// Per-origin stylesheet invalidation data.
|
/// The invalidations for stylesheets added or removed from this document.
|
||||||
invalidation_data: PerOrigin<InvalidationData>,
|
invalidations: StylesheetInvalidationSet,
|
||||||
|
|
||||||
|
/// The origins whose stylesheets have changed so far.
|
||||||
|
origins_dirty: OriginSet,
|
||||||
|
|
||||||
/// Has author style been disabled?
|
/// Has author style been disabled?
|
||||||
author_style_disabled: bool,
|
author_style_disabled: bool,
|
||||||
|
@ -66,7 +69,8 @@ where
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
StylesheetSet {
|
StylesheetSet {
|
||||||
entries: vec![],
|
entries: vec![],
|
||||||
invalidation_data: Default::default(),
|
invalidations: StylesheetInvalidationSet::new(),
|
||||||
|
origins_dirty: OriginSet::empty(),
|
||||||
author_style_disabled: false,
|
author_style_disabled: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,12 +101,10 @@ where
|
||||||
sheet: &S,
|
sheet: &S,
|
||||||
guard: &SharedRwLockReadGuard,
|
guard: &SharedRwLockReadGuard,
|
||||||
) {
|
) {
|
||||||
let origin = sheet.contents(guard).origin;
|
|
||||||
let data = self.invalidation_data.borrow_mut_for_origin(&origin);
|
|
||||||
if let Some(device) = device {
|
if let Some(device) = device {
|
||||||
data.invalidations.collect_invalidations_for(device, sheet, guard);
|
self.invalidations.collect_invalidations_for(device, sheet, guard);
|
||||||
}
|
}
|
||||||
data.dirty = true;
|
self.origins_dirty |= sheet.contents(guard).origin;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Appends a new stylesheet to the current set.
|
/// Appends a new stylesheet to the current set.
|
||||||
|
@ -169,15 +171,13 @@ where
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
self.author_style_disabled = disabled;
|
self.author_style_disabled = disabled;
|
||||||
self.invalidation_data.author.invalidations.invalidate_fully();
|
self.invalidations.invalidate_fully();
|
||||||
self.invalidation_data.author.dirty = true;
|
self.origins_dirty |= Origin::Author;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns whether the given set has changed from the last flush.
|
/// Returns whether the given set has changed from the last flush.
|
||||||
pub fn has_changed(&self) -> bool {
|
pub fn has_changed(&self) -> bool {
|
||||||
self.invalidation_data
|
!self.origins_dirty.is_empty()
|
||||||
.iter_origins()
|
|
||||||
.any(|(d, _)| d.dirty)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Flush the current set, unmarking it as dirty, and returns the damaged
|
/// Flush the current set, unmarking it as dirty, and returns the damaged
|
||||||
|
@ -189,40 +189,25 @@ where
|
||||||
where
|
where
|
||||||
E: TElement,
|
E: TElement,
|
||||||
{
|
{
|
||||||
|
use std::mem;
|
||||||
|
|
||||||
debug!("StylesheetSet::flush");
|
debug!("StylesheetSet::flush");
|
||||||
|
|
||||||
let mut origins = OriginSet::empty();
|
let have_invalidations = self.invalidations.flush(document_element);
|
||||||
let mut have_invalidations = false;
|
let origins = mem::replace(&mut self.origins_dirty, OriginSet::empty());
|
||||||
|
|
||||||
for (data, origin) in self.invalidation_data.iter_mut_origins() {
|
|
||||||
if data.dirty {
|
|
||||||
have_invalidations |= data.invalidations.flush(document_element);
|
|
||||||
data.dirty = false;
|
|
||||||
origins |= origin;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
(origins, have_invalidations)
|
(origins, have_invalidations)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Flush stylesheets, but without running any of the invalidation passes.
|
/// Flush stylesheets, but without running any of the invalidation passes.
|
||||||
///
|
|
||||||
/// FIXME(emilio): This should eventually disappear. Please keep this
|
|
||||||
/// Servo-only.
|
|
||||||
#[cfg(feature = "servo")]
|
#[cfg(feature = "servo")]
|
||||||
pub fn flush_without_invalidation(&mut self) -> (StylesheetIterator<S>, OriginSet) {
|
pub fn flush_without_invalidation(&mut self) -> OriginSet {
|
||||||
|
use std::mem;
|
||||||
|
|
||||||
debug!("StylesheetSet::flush_without_invalidation");
|
debug!("StylesheetSet::flush_without_invalidation");
|
||||||
|
|
||||||
let mut origins = OriginSet::empty();
|
self.invalidations.clear();
|
||||||
for (data, origin) in self.invalidation_data.iter_mut_origins() {
|
mem::replace(&mut self.origins_dirty, OriginSet::empty())
|
||||||
if data.dirty {
|
|
||||||
data.invalidations.clear();
|
|
||||||
data.dirty = false;
|
|
||||||
origins |= origin;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
(self.iter(), origins)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an iterator over the current list of stylesheets.
|
/// Returns an iterator over the current list of stylesheets.
|
||||||
|
@ -233,30 +218,7 @@ where
|
||||||
/// Mark the stylesheets for the specified origin as dirty, because
|
/// Mark the stylesheets for the specified origin as dirty, because
|
||||||
/// something external may have invalidated it.
|
/// something external may have invalidated it.
|
||||||
pub fn force_dirty(&mut self, origins: OriginSet) {
|
pub fn force_dirty(&mut self, origins: OriginSet) {
|
||||||
for origin in origins.iter() {
|
self.invalidations.invalidate_fully();
|
||||||
let data = self.invalidation_data.borrow_mut_for_origin(&origin);
|
self.origins_dirty |= origins;
|
||||||
data.invalidations.invalidate_fully();
|
|
||||||
data.dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
|
||||||
struct InvalidationData {
|
|
||||||
/// The stylesheet invalidations for this origin that we still haven't
|
|
||||||
/// processed.
|
|
||||||
invalidations: StylesheetInvalidationSet,
|
|
||||||
|
|
||||||
/// Whether the sheets for this origin in the `StylesheetSet`'s entry list
|
|
||||||
/// has changed since the last restyle.
|
|
||||||
dirty: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for InvalidationData {
|
|
||||||
fn default() -> Self {
|
|
||||||
InvalidationData {
|
|
||||||
invalidations: StylesheetInvalidationSet::new(),
|
|
||||||
dirty: false,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@ impl Origin {
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
/// A set of origins. This is equivalent to Gecko's OriginFlags.
|
/// A set of origins. This is equivalent to Gecko's OriginFlags.
|
||||||
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
pub flags OriginSet: u8 {
|
pub flags OriginSet: u8 {
|
||||||
/// https://drafts.csswg.org/css-cascade/#cascade-origin-user-agent
|
/// https://drafts.csswg.org/css-cascade/#cascade-origin-user-agent
|
||||||
const ORIGIN_USER_AGENT = Origin::UserAgent as u8,
|
const ORIGIN_USER_AGENT = Origin::UserAgent as u8,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue