Fix crashiness of IntersectionObservers.

Mozilla hashtables -still- suck.
This commit is contained in:
wolfbeast
2018-12-24 01:58:16 +01:00
parent bfedd7d40c
commit 3cf7e874fe
2 changed files with 25 additions and 21 deletions
+20 -19
View File
@@ -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;
}
+5 -2
View File
@@ -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;
};