mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-30 19:17:31 +09:00
Rewrite IntersectionObserver list handling to be more robust.
Tag #935.
This commit is contained in:
parent
9222116f26
commit
dc2cf8544d
3 changed files with 40 additions and 8 deletions
|
|
@ -162,6 +162,11 @@ DOMIntersectionObserver::Observe(Element& aTarget)
|
||||||
void
|
void
|
||||||
DOMIntersectionObserver::Unobserve(Element& aTarget)
|
DOMIntersectionObserver::Unobserve(Element& aTarget)
|
||||||
{
|
{
|
||||||
|
if (!mObservationTargets.Contains(&aTarget)) {
|
||||||
|
// You're not on the list, buddy!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (mObservationTargets.Length() == 1) {
|
if (mObservationTargets.Length() == 1) {
|
||||||
Disconnect();
|
Disconnect();
|
||||||
return;
|
return;
|
||||||
|
|
@ -188,7 +193,7 @@ DOMIntersectionObserver::Connect()
|
||||||
}
|
}
|
||||||
|
|
||||||
mConnected = true;
|
mConnected = true;
|
||||||
if(mDocument) {
|
if (mDocument) {
|
||||||
mDocument->AddIntersectionObserver(this);
|
mDocument->AddIntersectionObserver(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -293,12 +298,25 @@ DOMIntersectionObserver::Update(nsIDocument* aDocument, DOMHighResTimeStamp time
|
||||||
if (rootFrame) {
|
if (rootFrame) {
|
||||||
nsPresContext* presContext = rootFrame->PresContext();
|
nsPresContext* presContext = rootFrame->PresContext();
|
||||||
while (!presContext->IsRootContentDocument()) {
|
while (!presContext->IsRootContentDocument()) {
|
||||||
presContext = rootFrame->PresContext()->GetParentPresContext();
|
// Walk up the tree
|
||||||
rootFrame = presContext->PresShell()->GetRootScrollFrame();
|
presContext = presContext->GetParentPresContext();
|
||||||
|
if (!presContext) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
nsIFrame* rootScrollFrame = presContext->PresShell()->GetRootScrollFrame();
|
||||||
|
if (rootScrollFrame) {
|
||||||
|
rootFrame = rootScrollFrame;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
root = rootFrame->GetContent()->AsElement();
|
root = rootFrame->GetContent()->AsElement();
|
||||||
nsIScrollableFrame* scrollFrame = do_QueryFrame(rootFrame);
|
nsIScrollableFrame* scrollFrame = do_QueryFrame(rootFrame);
|
||||||
rootRect = scrollFrame->GetScrollPortRect();
|
// If we end up with a null root frame for some reason, we'll proceed
|
||||||
|
// with an empty root intersection rect.
|
||||||
|
if (scrollFrame) {
|
||||||
|
rootRect = scrollFrame->GetScrollPortRect();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,9 @@ protected:
|
||||||
class DOMIntersectionObserver final : public nsISupports,
|
class DOMIntersectionObserver final : public nsISupports,
|
||||||
public nsWrapperCache
|
public nsWrapperCache
|
||||||
{
|
{
|
||||||
virtual ~DOMIntersectionObserver() { }
|
virtual ~DOMIntersectionObserver() {
|
||||||
|
Disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DOMIntersectionObserver(already_AddRefed<nsPIDOMWindowInner>&& aOwner,
|
DOMIntersectionObserver(already_AddRefed<nsPIDOMWindowInner>&& aOwner,
|
||||||
|
|
|
||||||
|
|
@ -12313,6 +12313,10 @@ nsDocument::RemoveIntersectionObserver(DOMIntersectionObserver* aObserver)
|
||||||
void
|
void
|
||||||
nsDocument::UpdateIntersectionObservations()
|
nsDocument::UpdateIntersectionObservations()
|
||||||
{
|
{
|
||||||
|
if (mIntersectionObservers.IsEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
DOMHighResTimeStamp time = 0;
|
DOMHighResTimeStamp time = 0;
|
||||||
if (nsPIDOMWindowInner* window = GetInnerWindow()) {
|
if (nsPIDOMWindowInner* window = GetInnerWindow()) {
|
||||||
Performance* perf = window->GetPerformance();
|
Performance* perf = window->GetPerformance();
|
||||||
|
|
@ -12320,9 +12324,15 @@ nsDocument::UpdateIntersectionObservations()
|
||||||
time = perf->Now();
|
time = perf->Now();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
nsTArray<RefPtr<DOMIntersectionObserver>> observers(mIntersectionObservers.Count());
|
||||||
for (auto iter = mIntersectionObservers.Iter(); !iter.Done(); iter.Next()) {
|
for (auto iter = mIntersectionObservers.Iter(); !iter.Done(); iter.Next()) {
|
||||||
DOMIntersectionObserver* observer = iter.Get()->GetKey();
|
DOMIntersectionObserver* observer = iter.Get()->GetKey();
|
||||||
observer->Update(this, time);
|
observers.AppendElement(observer);
|
||||||
|
}
|
||||||
|
for (const auto& observer : observers) {
|
||||||
|
if (observer) {
|
||||||
|
observer->Update(this, time);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -12335,7 +12345,7 @@ nsDocument::ScheduleIntersectionObserverNotification()
|
||||||
|
|
||||||
nsCOMPtr<nsIRunnable> notification = NewRunnableMethod(this,
|
nsCOMPtr<nsIRunnable> notification = NewRunnableMethod(this,
|
||||||
&nsDocument::NotifyIntersectionObservers);
|
&nsDocument::NotifyIntersectionObservers);
|
||||||
NS_DispatchToCurrentThread(notification);
|
NS_DispatchToCurrentThread(notification.forget());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -12347,7 +12357,9 @@ nsDocument::NotifyIntersectionObservers()
|
||||||
observers.AppendElement(observer);
|
observers.AppendElement(observer);
|
||||||
}
|
}
|
||||||
for (const auto& observer : observers) {
|
for (const auto& observer : observers) {
|
||||||
observer->Notify();
|
if (observer) {
|
||||||
|
observer->Notify();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue