Bug 1891597 - Simplify IntersectionObserver notifications. r=smaug

DOMIntersectionObserver::Update doesn't run script, so we can write this
code in a more straight-forward way.

Differential Revision: https://phabricator.services.mozilla.com/D207478
This commit is contained in:
Emilio Cobos Álvarez 2024-04-16 02:58:10 +00:00
parent 10438c2029
commit bcc3a3b993
3 changed files with 21 additions and 50 deletions

View file

@ -16422,48 +16422,34 @@ WindowContext* Document::GetWindowContextForPageUseCounters() const {
return wc;
}
void Document::UpdateIntersectionObservations(TimeStamp aNowTime) {
if (mIntersectionObservers.IsEmpty()) {
return;
}
void Document::UpdateIntersections(TimeStamp aNowTime) {
if (!mIntersectionObservers.IsEmpty()) {
DOMHighResTimeStamp time = 0;
if (nsPIDOMWindowInner* win = GetInnerWindow()) {
if (Performance* perf = win->GetPerformance()) {
time = perf->TimeStampToDOMHighResForRendering(aNowTime);
}
}
const auto observers = ToTArray<nsTArray<RefPtr<DOMIntersectionObserver>>>(
mIntersectionObservers);
for (const auto& observer : observers) {
if (observer) {
for (DOMIntersectionObserver* observer : mIntersectionObservers) {
observer->Update(*this, time);
}
Dispatch(NewRunnableMethod("Document::NotifyIntersectionObservers", this,
&Document::NotifyIntersectionObservers));
}
}
void Document::ScheduleIntersectionObserverNotification() {
if (mIntersectionObservers.IsEmpty()) {
return;
}
MOZ_RELEASE_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIRunnable> notification =
NewRunnableMethod("Document::NotifyIntersectionObservers", this,
&Document::NotifyIntersectionObservers);
Dispatch(notification.forget());
EnumerateSubDocuments([aNowTime](Document& aDoc) {
aDoc.UpdateIntersections(aNowTime);
return CallState::Continue;
});
}
void Document::NotifyIntersectionObservers() {
const auto observers = ToTArray<nsTArray<RefPtr<DOMIntersectionObserver>>>(
mIntersectionObservers);
for (const auto& observer : observers) {
if (observer) {
// MOZ_KnownLive because the 'observers' array guarantees to keep it
// alive.
MOZ_KnownLive(observer)->Notify();
}
}
}
DOMIntersectionObserver& Document::EnsureLazyLoadObserver() {

View file

@ -3709,8 +3709,9 @@ class Document : public nsINode,
return !mIntersectionObservers.IsEmpty();
}
void UpdateIntersectionObservations(TimeStamp aNowTime);
void ScheduleIntersectionObserverNotification();
// Update intersection observers in this document and all
// same-process subdocuments.
void UpdateIntersections(TimeStamp aNowTime);
MOZ_CAN_RUN_SCRIPT void NotifyIntersectionObservers();
DOMIntersectionObserver* GetLazyLoadObserver() { return mLazyLoadObserver; }

View file

@ -2228,23 +2228,7 @@ void nsRefreshDriver::RunFullscreenSteps() {
void nsRefreshDriver::UpdateIntersectionObservations(TimeStamp aNowTime) {
AUTO_PROFILER_LABEL_RELEVANT_FOR_JS("Compute intersections", LAYOUT);
AutoTArray<RefPtr<Document>, 32> documents;
if (mPresContext->Document()->HasIntersectionObservers()) {
documents.AppendElement(mPresContext->Document());
}
mPresContext->Document()->CollectDescendantDocuments(
documents, [](const Document* document) -> bool {
return document->HasIntersectionObservers();
});
for (const auto& doc : documents) {
doc->UpdateIntersectionObservations(aNowTime);
doc->ScheduleIntersectionObserverNotification();
}
mPresContext->Document()->UpdateIntersections(aNowTime);
mNeedToUpdateIntersectionObservations = false;
}