Bug 1897322 - More consistently deal with pres shell style observers. r=smaug

Much like we deal with resize events.

Differential Revision: https://phabricator.services.mozilla.com/D210776
This commit is contained in:
Emilio Cobos Álvarez 2024-05-17 11:56:36 +00:00
parent 7fbd4d55e5
commit a774f79b6b
3 changed files with 20 additions and 19 deletions

View file

@ -7110,7 +7110,7 @@ void Document::DeletePresShell() {
// objects for @font-face rules that came from the style set. There's no need
// to call EnsureStyleFlush either, the shell is going away anyway, so there's
// no point on it.
MarkUserFontSetDirty();
mFontFaceSetDirty = true;
if (IsEditingOn()) {
TurnEditingOff();

View file

@ -10218,8 +10218,10 @@ bool PresShell::RemovePostRefreshObserver(nsAPostRefreshObserver* aObserver) {
void PresShell::DoObserveStyleFlushes() {
MOZ_ASSERT(!ObservingStyleFlushes());
if (MOZ_UNLIKELY(IsDestroying())) {
return;
}
mObservingStyleFlushes = true;
if (MOZ_LIKELY(!mDocument->GetBFCacheEntry())) {
mPresContext->RefreshDriver()->AddStyleFlushObserver(this);
}

View file

@ -2195,13 +2195,12 @@ void nsRefreshDriver::DispatchResizeEvents() {
if (!mPresContext || !mPresContext->GetPresShell()) {
break;
}
// Make sure to not process observers which might have been removed
// during previous iterations.
// Make sure to not process observers which might have been removed during
// previous iterations.
if (!mResizeEventFlushObservers.RemoveElement(presShell)) {
continue;
}
// MOZ_KnownLive because 'observers' is guaranteed to
// keep it alive.
// MOZ_KnownLive because 'observers' is guaranteed to keep it alive.
//
// Fixing https://bugzilla.mozilla.org/show_bug.cgi?id=1620312 on its own
// won't help here, because 'observers' is non-const and we have the
@ -2211,26 +2210,26 @@ void nsRefreshDriver::DispatchResizeEvents() {
}
void nsRefreshDriver::FlushLayoutOnPendingDocsAndFixUpFocus() {
AutoTArray<PresShell*, 16> observers;
AutoTArray<RefPtr<PresShell>, 16> observers;
observers.AppendElements(mStyleFlushObservers);
for (uint32_t j = observers.Length();
j && mPresContext && mPresContext->GetPresShell(); --j) {
// Make sure to not process observers which might have been removed
// during previous iterations.
PresShell* rawPresShell = observers[j - 1];
if (!mStyleFlushObservers.RemoveElement(rawPresShell)) {
for (RefPtr<PresShell>& presShell : Reversed(observers)) {
if (!mPresContext || !mPresContext->GetPresShell()) {
break;
}
// Make sure to not process observers which might have been removed during
// previous iterations.
if (!mStyleFlushObservers.RemoveElement(presShell)) {
continue;
}
LogPresShellObserver::Run run(rawPresShell, this);
RefPtr<PresShell> presShell = rawPresShell;
LogPresShellObserver::Run run(presShell, this);
presShell->mWasLastReflowInterrupted = false;
const ChangesToFlush ctf(FlushType::InterruptibleLayout, false);
presShell->FlushPendingNotifications(ctf);
const bool fixedUpFocus = presShell->FixUpFocus();
// MOZ_KnownLive because 'observers' is guaranteed to keep it alive.
MOZ_KnownLive(presShell)->FlushPendingNotifications(ctf);
const bool fixedUpFocus = MOZ_KnownLive(presShell)->FixUpFocus();
if (fixedUpFocus) {
presShell->FlushPendingNotifications(ctf);
MOZ_KnownLive(presShell)->FlushPendingNotifications(ctf);
}
// This is a bit subtle: We intentionally mark the pres shell as not
// observing style flushes here, rather than above the flush, so that