Bug 1442817 - Add another variant of nsDocument::FlushPendingNotifications which are able to skip to flushing throttled animations. r?emilio,birtles draft
authorHiroyuki Ikezoe <hikezoe@mozilla.com>
Fri, 09 Mar 2018 06:41:30 +0900
changeset 765093 75e7be11eebb20fb6af98d976287f18ee23de62a
parent 764977 55d91695f4bb951c224005155baef054a786c1f7
child 765094 23719dafbf57297c21c5f691b227678558b8e735
push id101970
push userhikezoe@mozilla.com
push dateFri, 09 Mar 2018 00:58:32 +0000
reviewersemilio, birtles
bugs1442817
milestone60.0a1
Bug 1442817 - Add another variant of nsDocument::FlushPendingNotifications which are able to skip to flushing throttled animations. r?emilio,birtles MozReview-Commit-ID: BZ9yAoAmWBB
dom/base/nsDocument.cpp
dom/base/nsIDocument.h
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -7574,69 +7574,79 @@ nsIDocument::CreateEvent(const nsAString
   e->mFlags.mBubbles = false;
   e->mFlags.mCancelable = false;
   return ev.forget();
 }
 
 void
 nsIDocument::FlushPendingNotifications(FlushType aType)
 {
+ mozilla::ChangesToFlush flush(aType, aType >= FlushType::Style);
+  FlushPendingNotifications(flush);
+}
+
+void
+nsIDocument::FlushPendingNotifications(mozilla::ChangesToFlush aFlush)
+{
+  FlushType flushType = aFlush.mFlushType;
+
   nsDocumentOnStack dos(this);
 
   // We need to flush the sink for non-HTML documents (because the XML
   // parser still does insertion with deferred notifications).  We
   // also need to flush the sink if this is a layout-related flush, to
   // make sure that layout is started as needed.  But we can skip that
   // part if we have no presshell or if it's already done an initial
   // reflow.
   if ((!IsHTMLDocument() ||
-       (aType > FlushType::ContentAndNotify && mPresShell &&
+       (flushType > FlushType::ContentAndNotify && mPresShell &&
         !mPresShell->DidInitialize())) &&
       (mParser || mWeakSink)) {
     nsCOMPtr<nsIContentSink> sink;
     if (mParser) {
       sink = mParser->GetContentSink();
     } else {
       sink = do_QueryReferent(mWeakSink);
       if (!sink) {
         mWeakSink = nullptr;
       }
     }
     // Determine if it is safe to flush the sink notifications
     // by determining if it safe to flush all the presshells.
-    if (sink && (aType == FlushType::Content || IsSafeToFlush())) {
-      sink->FlushPendingNotifications(aType);
+    if (sink && (flushType == FlushType::Content || IsSafeToFlush())) {
+      sink->FlushPendingNotifications(flushType);
     }
   }
 
   // Should we be flushing pending binding constructors in here?
 
-  if (aType <= FlushType::ContentAndNotify) {
+  if (flushType <= FlushType::ContentAndNotify) {
     // Nothing to do here
     return;
   }
 
   // If we have a parent we must flush the parent too to ensure that our
   // container is reflowed if its size was changed.  But if it's not safe to
   // flush ourselves, then don't flush the parent, since that can cause things
   // like resizes of our frame's widget, which we can't handle while flushing
   // is unsafe.
   // Since media queries mean that a size change of our container can
   // affect style, we need to promote a style flush on ourself to a
   // layout flush on our parent, since we need our container to be the
   // correct size to determine the correct style.
   if (mParentDocument && IsSafeToFlush()) {
-    FlushType parentType = aType;
-    if (aType >= FlushType::Style)
-      parentType = std::max(FlushType::Layout, aType);
-    mParentDocument->FlushPendingNotifications(parentType);
+    mozilla::ChangesToFlush parentFlush = aFlush;
+    if (flushType >= FlushType::Style) {
+      parentFlush.mFlushType = std::max(FlushType::Layout, flushType);
+    }
+    mParentDocument->FlushPendingNotifications(parentFlush);
   }
 
   if (nsIPresShell* shell = GetShell()) {
-    shell->FlushPendingNotifications(aType);
+    shell->FlushPendingNotifications(aFlush);
   }
 }
 
 static bool
 Copy(nsIDocument* aDocument, void* aData)
 {
   nsTArray<nsCOMPtr<nsIDocument> >* resources =
     static_cast<nsTArray<nsCOMPtr<nsIDocument> >* >(aData);
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -1733,16 +1733,24 @@ public:
 
   /**
    * Flush notifications for this document and its parent documents
    * (since those may affect the layout of this one).
    */
   void FlushPendingNotifications(mozilla::FlushType aType);
 
   /**
+   * Another variant of the above FlushPendingNotifications.  This function
+   * takes a ChangesToFlush to specify whether throttled animations are flushed
+   * or not.
+   * If in doublt, use the above FlushPendingNotifications.
+   */
+  void FlushPendingNotifications(mozilla::ChangesToFlush aFlush);
+
+  /**
    * Calls FlushPendingNotifications on any external resources this document
    * has. If this document has no external resources or is an external resource
    * itself this does nothing. This should only be called with
    * aType >= FlushType::Style.
    */
   virtual void FlushExternalResources(mozilla::FlushType aType) = 0;
 
   nsBindingManager* BindingManager() const