diff options
Diffstat (limited to 'dom/base/Element.cpp')
-rw-r--r-- | dom/base/Element.cpp | 45 |
1 files changed, 28 insertions, 17 deletions
diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp index 092755590..52d06b0f8 100644 --- a/dom/base/Element.cpp +++ b/dom/base/Element.cpp @@ -3912,44 +3912,55 @@ Element::ClearDataset() slots->mDataset = nullptr; } -nsTArray<Element::nsDOMSlots::IntersectionObserverRegistration>* +nsDataHashtable<nsPtrHashKey<DOMIntersectionObserver>, int32_t>* Element::RegisteredIntersectionObservers() { nsDOMSlots* slots = DOMSlots(); return &slots->mRegisteredIntersectionObservers; } +enum nsPreviousIntersectionThreshold { + eUninitialized = -2, + eNonIntersecting = -1 +}; + void Element::RegisterIntersectionObserver(DOMIntersectionObserver* aObserver) { - RegisteredIntersectionObservers()->AppendElement( - nsDOMSlots::IntersectionObserverRegistration { aObserver, -1 }); + nsDataHashtable<nsPtrHashKey<DOMIntersectionObserver>, int32_t>* observers = + RegisteredIntersectionObservers(); + if (observers->Contains(aObserver)) { + return; + } + + // Value can be: + // -2: Makes sure next calculated threshold always differs, leading to a + // notification task being scheduled. + // -1: Non-intersecting. + // >= 0: Intersecting, valid index of aObserver->mThresholds. + RegisteredIntersectionObservers()->Put(aObserver, eUninitialized); } void Element::UnregisterIntersectionObserver(DOMIntersectionObserver* aObserver) { - nsTArray<nsDOMSlots::IntersectionObserverRegistration>* observers = + nsDataHashtable<nsPtrHashKey<DOMIntersectionObserver>, int32_t>* observers = RegisteredIntersectionObservers(); - for (uint32_t i = 0; i < observers->Length(); ++i) { - nsDOMSlots::IntersectionObserverRegistration reg = observers->ElementAt(i); - if (reg.observer == aObserver) { - observers->RemoveElementAt(i); - break; - } - } + observers->Remove(aObserver); } bool Element::UpdateIntersectionObservation(DOMIntersectionObserver* aObserver, int32_t aThreshold) { - nsTArray<nsDOMSlots::IntersectionObserverRegistration>* observers = + nsDataHashtable<nsPtrHashKey<DOMIntersectionObserver>, int32_t>* observers = RegisteredIntersectionObservers(); - for (auto& reg : *observers) { - if (reg.observer == aObserver && reg.previousThreshold != aThreshold) { - reg.previousThreshold = aThreshold; - return true; - } + if (!observers->Contains(aObserver)) { + return false; + } + int32_t previousThreshold = observers->Get(aObserver); + if (previousThreshold != aThreshold) { + observers->Put(aObserver, aThreshold); + return true; } return false; } |