mirror of
https://github.com/servo/servo.git
synced 2025-07-23 07:13:52 +01:00
Avoid stylist flushes when sheets are appended and then removed again before flushing layout.
MozReview-Commit-ID: CHgbqfHnjwI
This commit is contained in:
parent
38ef515463
commit
1d6841b9fd
1 changed files with 21 additions and 14 deletions
|
@ -18,8 +18,11 @@ struct StylesheetSetEntry<S>
|
||||||
where
|
where
|
||||||
S: StylesheetInDocument + PartialEq + 'static,
|
S: StylesheetInDocument + PartialEq + 'static,
|
||||||
{
|
{
|
||||||
|
/// The sheet.
|
||||||
sheet: S,
|
sheet: S,
|
||||||
dirty: bool,
|
|
||||||
|
/// Whether this sheet has been part of at least one flush.
|
||||||
|
committed: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S> StylesheetSetEntry<S>
|
impl<S> StylesheetSetEntry<S>
|
||||||
|
@ -27,7 +30,7 @@ where
|
||||||
S: StylesheetInDocument + PartialEq + 'static,
|
S: StylesheetInDocument + PartialEq + 'static,
|
||||||
{
|
{
|
||||||
fn new(sheet: S) -> Self {
|
fn new(sheet: S) -> Self {
|
||||||
Self { sheet, dirty: true }
|
Self { sheet, committed: false }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,9 +242,9 @@ where
|
||||||
loop {
|
loop {
|
||||||
let potential_sheet = self.iter.next()?;
|
let potential_sheet = self.iter.next()?;
|
||||||
|
|
||||||
let dirty = mem::replace(&mut potential_sheet.dirty, false);
|
let committed = mem::replace(&mut potential_sheet.committed, true);
|
||||||
if dirty {
|
if !committed {
|
||||||
// If the sheet was dirty, we need to do a full rebuild anyway.
|
// If the sheet was uncommitted, we need to do a full rebuild anyway.
|
||||||
return Some((&potential_sheet.sheet, SheetRebuildKind::Full))
|
return Some((&potential_sheet.sheet, SheetRebuildKind::Full))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,19 +306,23 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove(&mut self, sheet: &S) {
|
fn remove(&mut self, sheet: &S) {
|
||||||
let old_len = self.entries.len();
|
let index = self.entries.iter().position(|entry| {
|
||||||
self.entries.retain(|entry| entry.sheet != *sheet);
|
entry.sheet == *sheet
|
||||||
if cfg!(feature = "servo") {
|
});
|
||||||
|
if cfg!(feature = "gecko") && index.is_none() {
|
||||||
// FIXME(emilio): Make Gecko's PresShell::AddUserSheet not suck.
|
// FIXME(emilio): Make Gecko's PresShell::AddUserSheet not suck.
|
||||||
//
|
return;
|
||||||
// Hopefully that's not necessary for correctness, just somewhat
|
|
||||||
// overkill.
|
|
||||||
debug_assert!(self.entries.len() != old_len, "Sheet not found?");
|
|
||||||
}
|
}
|
||||||
|
let sheet = self.entries.remove(index.unwrap());
|
||||||
// Removing sheets makes us tear down the whole cascade and invalidation
|
// Removing sheets makes us tear down the whole cascade and invalidation
|
||||||
// data.
|
// data, but only if the sheet has been involved in at least one flush.
|
||||||
|
// Checking whether the sheet has been committed allows us to avoid
|
||||||
|
// rebuilding the world when sites quickly append and remove a stylesheet.
|
||||||
|
// See bug 1434756.
|
||||||
|
if sheet.committed {
|
||||||
self.set_data_validity_at_least(OriginValidity::FullyInvalid);
|
self.set_data_validity_at_least(OriginValidity::FullyInvalid);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn contains(&self, sheet: &S) -> bool {
|
fn contains(&self, sheet: &S) -> bool {
|
||||||
self.entries.iter().any(|e| e.sheet == *sheet)
|
self.entries.iter().any(|e| e.sheet == *sheet)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue