Bug 1272409 - Part 4: Integrate ResizeObserver with Document and reflow. r=dholbert,smaug
☠☠ backed out by 3791fc50da34 ☠ ☠
authorFariskhi Vidyan <farislab@gmail.com>
Thu, 25 Apr 2019 18:30:16 +0000
changeset 530200 224dad4cbdc349744e785e727bae745e5a798a49
parent 530199 72775dbf35c88a564ec0839a9113e83fe17b4e5f
child 530201 2ad8260489d690f7615abb7fe27890bdb430de9a
push id11265
push userffxbld-merge
push dateMon, 13 May 2019 10:53:39 +0000
treeherdermozilla-beta@77e0fe8dbdd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert, smaug
bugs1272409
milestone68.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 1272409 - Part 4: Integrate ResizeObserver with Document and reflow. r=dholbert,smaug Depends on D27617 Differential Revision: https://phabricator.services.mozilla.com/D27618
dom/base/Document.cpp
dom/base/Document.h
dom/base/ResizeObserver.cpp
layout/base/PresShell.cpp
--- a/dom/base/Document.cpp
+++ b/dom/base/Document.cpp
@@ -71,16 +71,18 @@
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/Event.h"
 #include "mozilla/dom/FeaturePolicy.h"
 #include "mozilla/dom/FramingChecker.h"
 #include "mozilla/dom/HTMLSharedElement.h"
 #include "mozilla/dom/Navigator.h"
 #include "mozilla/dom/Performance.h"
 #include "mozilla/dom/TreeOrderedArrayInlines.h"
+#include "mozilla/dom/ResizeObserver.h"
+#include "mozilla/dom/ResizeObserverController.h"
 #include "mozilla/dom/ServiceWorkerContainer.h"
 #include "mozilla/dom/ScriptLoader.h"
 #include "mozilla/dom/ShadowIncludingTreeIterator.h"
 #include "mozilla/dom/StyleSheetList.h"
 #include "mozilla/dom/SVGUseElement.h"
 #include "mozilla/net/CookieSettings.h"
 #include "nsGenericHTMLElement.h"
 #include "mozilla/dom/CDATASection.h"
@@ -1734,16 +1736,20 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
   for (MediaQueryList* mql = tmp->mDOMMediaQueryLists.getFirst(); mql;
        mql = static_cast<LinkedListElement<MediaQueryList>*>(mql)->getNext()) {
     if (mql->HasListeners() &&
         NS_SUCCEEDED(mql->CheckCurrentGlobalCorrectness())) {
       NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mDOMMediaQueryLists item");
       cb.NoteXPCOMChild(mql);
     }
   }
+
+  if (tmp->mResizeObserverController) {
+    tmp->mResizeObserverController->Traverse(cb);
+  }
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(Document)
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(Document)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Document)
   tmp->mInUnlinkOrDeletion = true;
@@ -1845,16 +1851,20 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Do
   for (MediaQueryList* mql = tmp->mDOMMediaQueryLists.getFirst(); mql;) {
     MediaQueryList* next =
         static_cast<LinkedListElement<MediaQueryList>*>(mql)->getNext();
     mql->Disconnect();
     mql = next;
   }
 
   tmp->mInUnlinkOrDeletion = false;
+
+  if (tmp->mResizeObserverController) {
+    tmp->mResizeObserverController->Unlink();
+  }
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 nsresult Document::Init() {
   if (mCSSLoader || mStyleImageLoader || mNodeInfoManager || mScriptLoader) {
     return NS_ERROR_ALREADY_INITIALIZED;
   }
 
   // Force initialization.
@@ -12438,16 +12448,32 @@ FlashClassification Document::DocumentFl
 
   if (mFlashClassification == FlashClassification::Unknown) {
     mFlashClassification = DocumentFlashClassificationInternal();
   }
 
   return mFlashClassification;
 }
 
+void Document::AddResizeObserver(ResizeObserver* aResizeObserver) {
+  if (!mResizeObserverController) {
+    mResizeObserverController = MakeUnique<ResizeObserverController>(this);
+  }
+
+  mResizeObserverController->AddResizeObserver(aResizeObserver);
+}
+
+void Document::ScheduleResizeObserversNotification() const {
+  if (!mResizeObserverController) {
+    return;
+  }
+
+  mResizeObserverController->ScheduleNotification();
+}
+
 /**
  * Initializes |mIsThirdPartyForFlashClassifier| if necessary and returns its
  * value. The value returned represents whether this document should be
  * considered Third-Party.
  *
  * A top-level document cannot be a considered Third-Party; only subdocuments
  * may. For a subdocument to be considered Third-Party, it must meet ANY ONE
  * of the following requirements:
--- a/dom/base/Document.h
+++ b/dom/base/Document.h
@@ -238,16 +238,18 @@ class ChannelEventQueue;
     }                                                \
   }
 
 namespace mozilla {
 namespace dom {
 
 class Document;
 class DOMStyleSheetSetList;
+class ResizeObserver;
+class ResizeObserverController;
 
 // Document states
 
 // RTL locale: specific to the XUL localedir attribute
 #define NS_DOCUMENT_STATE_RTL_LOCALE NS_DEFINE_EVENT_STATE_MACRO(0)
 // Window activation status
 #define NS_DOCUMENT_STATE_WINDOW_INACTIVE NS_DEFINE_EVENT_STATE_MACRO(1)
 
@@ -3530,16 +3532,20 @@ class Document : public nsINode,
   // determine whether some code is being called from a tracking script.
   void NoteScriptTrackingStatus(const nsACString& aURL, bool isTracking);
   bool IsScriptTracking(const nsACString& aURL) const;
 
   // For more information on Flash classification, see
   // toolkit/components/url-classifier/flash-block-lists.rst
   FlashClassification DocumentFlashClassification();
 
+  // ResizeObserver usage.
+  void AddResizeObserver(ResizeObserver* aResizeObserver);
+  void ScheduleResizeObserversNotification() const;
+
   /**
    * Localization
    *
    * For more information on DocumentL10n see
    * intl/l10n/docs/fluent_tutorial.rst
    */
 
  public:
@@ -4019,16 +4025,18 @@ class Document : public nsINode,
   TimeStamp mLastFocusTime;
 
   EventStates mDocumentState;
 
   RefPtr<Promise> mReadyForIdle;
 
   RefPtr<FeaturePolicy> mFeaturePolicy;
 
+  UniquePtr<ResizeObserverController> mResizeObserverController;
+
   // True if BIDI is enabled.
   bool mBidiEnabled : 1;
   // True if we may need to recompute the language prefs for this document.
   bool mMayNeedFontPrefsUpdate : 1;
   // True if a MathML element has ever been owned by this document.
   bool mMathMLEnabled : 1;
 
   // True if this document is the initial document for a window.  This should
--- a/dom/base/ResizeObserver.cpp
+++ b/dom/base/ResizeObserver.cpp
@@ -75,17 +75,17 @@ already_AddRefed<ResizeObserver> ResizeO
   Document* document = window->GetExtantDoc();
 
   if (!document) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   RefPtr<ResizeObserver> observer = new ResizeObserver(window.forget(), aCb);
-  // TODO: Add the new ResizeObserver to document here in the later patch.
+  document->AddResizeObserver(observer);
 
   return observer.forget();
 }
 
 void ResizeObserver::Observe(Element& aTarget, ErrorResult& aRv) {
   RefPtr<ResizeObservation> observation;
 
   if (mObservationMap.Get(&aTarget, getter_AddRefs(observation))) {
@@ -101,17 +101,17 @@ void ResizeObserver::Observe(Element& aT
   observation = new ResizeObservation(aTarget);
 
   mObservationMap.Put(&aTarget, observation);
   mObservationList.insertBack(observation);
 
   // Per the spec, we need to trigger notification in event loop that
   // contains ResizeObserver observe call even when resize/reflow does
   // not happen.
-  // TODO: Implement the notification scheduling in the later patch.
+  aTarget.OwnerDoc()->ScheduleResizeObserversNotification();
 }
 
 void ResizeObserver::Unobserve(Element& aTarget, ErrorResult& aRv) {
   RefPtr<ResizeObservation> observation;
   if (!mObservationMap.Remove(&aTarget, getter_AddRefs(observation))) {
     return;
   }
 
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -8985,16 +8985,20 @@ void PresShell::DidDoReflow(bool aInterr
   HandlePostedReflowCallbacks(aInterruptible);
 
   nsCOMPtr<nsIDocShell> docShell = mPresContext->GetDocShell();
   if (docShell) {
     DOMHighResTimeStamp now = GetPerformanceNowUnclamped();
     docShell->NotifyReflowObservers(aInterruptible, mLastReflowStart, now);
   }
 
+  if (!mPresContext->HasPendingInterrupt()) {
+    mDocument->ScheduleResizeObserversNotification();
+  }
+
   if (sSynthMouseMove) {
     SynthesizeMouseMove(false);
   }
 
   mPresContext->NotifyMissingFonts();
 }
 
 DOMHighResTimeStamp nsIPresShell::GetPerformanceNowUnclamped() {