mirror of
https://github.com/ManchildProductions/UXP-Fixed.git
synced 2026-05-27 00:08:56 +00:00
Fix crashiness of IntersectionObservers.
Mozilla hashtables -still- suck.
This commit is contained in:
@@ -155,30 +155,29 @@ DOMIntersectionObserver::Observe(Element& aTarget)
|
||||
return;
|
||||
}
|
||||
aTarget.RegisterIntersectionObserver(this);
|
||||
mObservationTargets.PutEntry(&aTarget);
|
||||
mObservationTargets.AppendElement(&aTarget);
|
||||
Connect();
|
||||
}
|
||||
|
||||
void
|
||||
DOMIntersectionObserver::Unobserve(Element& aTarget)
|
||||
{
|
||||
if (UnlinkTarget(aTarget)) {
|
||||
aTarget.UnregisterIntersectionObserver(this);
|
||||
if (mObservationTargets.Length() == 1) {
|
||||
Disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
mObservationTargets.RemoveElement(&aTarget);
|
||||
aTarget.UnregisterIntersectionObserver(this);
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
DOMIntersectionObserver::UnlinkTarget(Element& aTarget)
|
||||
{
|
||||
if (!mObservationTargets.Contains(&aTarget)) {
|
||||
return false;
|
||||
}
|
||||
if (mObservationTargets.Count() == 1) {
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
mObservationTargets.RemoveEntry(&aTarget);
|
||||
return true;
|
||||
mObservationTargets.RemoveElement(&aTarget);
|
||||
if (mObservationTargets.Length() == 0) {
|
||||
Disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -200,15 +199,17 @@ DOMIntersectionObserver::Disconnect()
|
||||
if (!mConnected) {
|
||||
return;
|
||||
}
|
||||
for (auto iter = mObservationTargets.Iter(); !iter.Done(); iter.Next()) {
|
||||
Element* target = iter.Get()->GetKey();
|
||||
|
||||
mConnected = false;
|
||||
|
||||
for (size_t i = 0; i < mObservationTargets.Length(); ++i) {
|
||||
Element* target = mObservationTargets.ElementAt(i);
|
||||
target->UnregisterIntersectionObserver(this);
|
||||
}
|
||||
mObservationTargets.Clear();
|
||||
if (mDocument) {
|
||||
mDocument->RemoveIntersectionObserver(this);
|
||||
}
|
||||
mConnected = false;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -318,8 +319,8 @@ DOMIntersectionObserver::Update(nsIDocument* aDocument, DOMHighResTimeStamp time
|
||||
rootMargin.Side(side) = nsLayoutUtils::ComputeCBDependentValue(basis, coord);
|
||||
}
|
||||
|
||||
for (auto iter = mObservationTargets.Iter(); !iter.Done(); iter.Next()) {
|
||||
Element* target = iter.Get()->GetKey();
|
||||
for (size_t i = 0; i < mObservationTargets.Length(); ++i) {
|
||||
Element* target = mObservationTargets.ElementAt(i);
|
||||
nsIFrame* targetFrame = target->GetPrimaryFrame();
|
||||
nsRect targetRect;
|
||||
Maybe<nsRect> intersectionRect;
|
||||
@@ -493,7 +494,7 @@ DOMIntersectionObserver::Notify()
|
||||
}
|
||||
mozilla::dom::Sequence<mozilla::OwningNonNull<DOMIntersectionObserverEntry>> entries;
|
||||
if (entries.SetCapacity(mQueuedEntries.Length(), mozilla::fallible)) {
|
||||
for (uint32_t i = 0; i < mQueuedEntries.Length(); ++i) {
|
||||
for (size_t i = 0; i < mQueuedEntries.Length(); ++i) {
|
||||
RefPtr<DOMIntersectionObserverEntry> next = mQueuedEntries[i];
|
||||
*entries.AppendElement(mozilla::fallible) = next;
|
||||
}
|
||||
|
||||
@@ -145,7 +145,7 @@ public:
|
||||
void Observe(Element& aTarget);
|
||||
void Unobserve(Element& aTarget);
|
||||
|
||||
bool UnlinkTarget(Element& aTarget);
|
||||
void UnlinkTarget(Element& aTarget);
|
||||
void Disconnect();
|
||||
|
||||
void TakeRecords(nsTArray<RefPtr<DOMIntersectionObserverEntry>>& aRetVal);
|
||||
@@ -172,7 +172,10 @@ protected:
|
||||
RefPtr<Element> mRoot;
|
||||
nsCSSRect mRootMargin;
|
||||
nsTArray<double> mThresholds;
|
||||
nsTHashtable<nsPtrHashKey<Element>> mObservationTargets;
|
||||
|
||||
// Holds raw pointers which are explicitly cleared by UnlinkTarget().
|
||||
nsTArray<Element*> mObservationTargets;
|
||||
|
||||
nsTArray<RefPtr<DOMIntersectionObserverEntry>> mQueuedEntries;
|
||||
bool mConnected;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user