Bug 1359311 - (intersection-observer) Send update notifications in same order as observed. r=smaug
authorTobias Schneider <schneider@jancona.com>
Sun, 25 Jun 2017 19:35:21 -0700
changeset 414819 c285e406afb2651d39e1a6d1fb9400b65f23e4d3
parent 414818 421f828a2d9d02f6fb89c19318eb4958ec6a8a99
child 414820 070644025bdd7ce8e5c15d507e7cd9d669f9578a
push id7566
push usermtabara@mozilla.com
push dateWed, 02 Aug 2017 08:25:16 +0000
treeherdermozilla-beta@86913f512c3c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1359311
milestone56.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1359311 - (intersection-observer) Send update notifications in same order as observed. r=smaug
dom/base/DOMIntersectionObserver.cpp
dom/base/DOMIntersectionObserver.h
testing/web-platform/meta/intersection-observer/multiple-targets.html.ini
--- a/dom/base/DOMIntersectionObserver.cpp
+++ b/dom/base/DOMIntersectionObserver.cpp
@@ -145,41 +145,41 @@ void
 DOMIntersectionObserver::GetThresholds(nsTArray<double>& aRetVal)
 {
   aRetVal = mThresholds;
 }
 
 void
 DOMIntersectionObserver::Observe(Element& aTarget)
 {
-  if (mObservationTargets.EnsureInserted(&aTarget)) {
-    // A new entry was created.
-    aTarget.RegisterIntersectionObserver(this);
-    Connect();
+  if (mObservationTargets.Contains(&aTarget)) {
+    return;
   }
+  aTarget.RegisterIntersectionObserver(this);
+  mObservationTargets.AppendElement(&aTarget);
+  Connect();
 }
 
 void
 DOMIntersectionObserver::Unobserve(Element& aTarget)
 {
-  if (mObservationTargets.Count() == 1) {
+  if (mObservationTargets.Length() == 1) {
     Disconnect();
     return;
   }
-
-  mObservationTargets.RemoveEntry(&aTarget);
+ 
+  mObservationTargets.RemoveElement(&aTarget);
   aTarget.UnregisterIntersectionObserver(this);
 }
 
 void
 DOMIntersectionObserver::UnlinkTarget(Element& aTarget)
 {
-  if (mObservationTargets.EnsureRemoved(&aTarget) &&
-      mObservationTargets.Count() == 0) {
-    // We removed the last entry.
+  mObservationTargets.RemoveElement(&aTarget);
+  if (mObservationTargets.Length() == 0) {
     Disconnect();
   }
 }
 
 void
 DOMIntersectionObserver::Connect()
 {
   if (mConnected) {
@@ -195,18 +195,18 @@ DOMIntersectionObserver::Connect()
 void
 DOMIntersectionObserver::Disconnect()
 {
   if (!mConnected) {
     return;
   }
 
   mConnected = false;
-  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);
     target->UnregisterIntersectionObserver(this);
   }
   mObservationTargets.Clear();
   if (mDocument) {
     mDocument->RemoveIntersectionObserver(this);
   }
 }
 
@@ -320,18 +320,18 @@ DOMIntersectionObserver::Update(nsIDocum
     } else if (value.IsPercentLengthUnit()) {
       coord.SetPercentValue(value.GetPercentValue());
     } else {
       MOZ_ASSERT_UNREACHABLE("invalid length unit");
     }
     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;
     bool isSameDoc = root && root->GetComposedDoc() == target->GetComposedDoc();
 
     if (rootFrame && targetFrame) {
       // If mRoot is set we are testing intersection with a container element
       // instead of the implicit root.
@@ -496,17 +496,17 @@ DOMIntersectionObserver::QueueIntersecti
 void
 DOMIntersectionObserver::Notify()
 {
   if (!mQueuedEntries.Length()) {
     return;
   }
   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;
     }
   }
   mQueuedEntries.Clear();
   mCallback->Call(this, entries, *this);
 }
 
--- a/dom/base/DOMIntersectionObserver.h
+++ b/dom/base/DOMIntersectionObserver.h
@@ -174,17 +174,20 @@ protected:
                                       double aIntersectionRatio);
 
   nsCOMPtr<nsPIDOMWindowInner>                    mOwner;
   RefPtr<nsIDocument>                             mDocument;
   RefPtr<mozilla::dom::IntersectionCallback>      mCallback;
   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;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(DOMIntersectionObserver, NS_DOM_INTERSECTION_OBSERVER_IID)
 
 } // namespace dom
 } // namespace mozilla
--- a/testing/web-platform/meta/intersection-observer/multiple-targets.html.ini
+++ b/testing/web-platform/meta/intersection-observer/multiple-targets.html.ini
@@ -1,3 +1,2 @@
 [multiple-targets.html]
   type: testharness
-  disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1359311