Bug 1363805 - Part 1: Add a flag to nsIDocument::FlushPendingNotifications. r?heycam draft
authorWei-Cheng Pan <wpan@mozilla.com>
Tue, 23 May 2017 10:27:13 +0800
changeset 669666 4030aa16da689d8aecd7e4069f30e8ad8fa03a3a
parent 669596 7e962631ba4298bcefa571008661983d77c3e652
child 669667 3bd27b2d96d733a182657591f7f34a530336dc68
push id81392
push userbmo:wpan@mozilla.com
push dateMon, 25 Sep 2017 07:20:33 +0000
reviewersheycam
bugs1363805
milestone58.0a1
Bug 1363805 - Part 1: Add a flag to nsIDocument::FlushPendingNotifications. r?heycam This flag indicates that document can flush parent-document only or need to do the normal flushing. MozReview-Commit-ID: L9KZA6jNsOz
dom/base/FlushType.h
dom/base/nsDocument.cpp
dom/base/nsDocument.h
dom/base/nsIDocument.h
--- a/dom/base/FlushType.h
+++ b/dom/base/FlushType.h
@@ -33,16 +33,25 @@ enum class FlushType : uint8_t {
                               but allow it to be interrupted (so
                               an incomplete layout may result) */
   Layout           = 7, /* As above, but layout must run to
                            completion */
   Display          = 8, /* As above, plus flush painting */
   Count
 };
 
+/**
+ * This is the enum used by nsIDocument::FlushPendingNotifications to decide
+ * whether the current document is skippable.
+ */
+enum class FlushTarget : uint8_t {
+  Normal = 0,     /* Flush current and parent documents. */
+  ParentOnly = 1  /* Skip current document, only flush its parent. */
+};
+
 struct ChangesToFlush {
   ChangesToFlush(FlushType aFlushType, bool aFlushAnimations)
     : mFlushType(aFlushType)
     , mFlushAnimations(aFlushAnimations)
   {}
 
   FlushType mFlushType;
   bool mFlushAnimations;
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -8315,17 +8315,17 @@ nsIDocument::CreateEvent(const nsAString
   }
   WidgetEvent* e = ev->WidgetEventPtr();
   e->mFlags.mBubbles = false;
   e->mFlags.mCancelable = false;
   return ev.forget();
 }
 
 void
-nsDocument::FlushPendingNotifications(FlushType aType)
+nsDocument::FlushPendingNotifications(FlushType aType, FlushTarget aTarget)
 {
   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
@@ -8365,21 +8365,23 @@ nsDocument::FlushPendingNotifications(Fl
   // 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);
-  }
-
-  if (nsIPresShell* shell = GetShell()) {
-    shell->FlushPendingNotifications(aType);
+    mParentDocument->FlushPendingNotifications(parentType, FlushTarget::Normal);
+  }
+
+  if (aTarget == FlushTarget::Normal) {
+    if (nsIPresShell* shell = GetShell()) {
+      shell->FlushPendingNotifications(aType);
+    }
   }
 }
 
 static bool
 Copy(nsIDocument* aDocument, void* aData)
 {
   nsTArray<nsCOMPtr<nsIDocument> >* resources =
     static_cast<nsTArray<nsCOMPtr<nsIDocument> >* >(aData);
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -568,17 +568,19 @@ public:
 
   virtual void StyleRuleChanged(mozilla::StyleSheet* aStyleSheet,
                                 mozilla::css::Rule* aStyleRule) override;
   virtual void StyleRuleAdded(mozilla::StyleSheet* aStyleSheet,
                               mozilla::css::Rule* aStyleRule) override;
   virtual void StyleRuleRemoved(mozilla::StyleSheet* aStyleSheet,
                                 mozilla::css::Rule* aStyleRule) override;
 
-  virtual void FlushPendingNotifications(mozilla::FlushType aType) override;
+  virtual void FlushPendingNotifications(mozilla::FlushType aType,
+                                         mozilla::FlushTarget aTarget
+                                           = mozilla::FlushTarget::Normal) override;
   virtual void FlushExternalResources(mozilla::FlushType aType) override;
   virtual void SetXMLDeclaration(const char16_t *aVersion,
                                  const char16_t *aEncoding,
                                  const int32_t aStandalone) override;
   virtual void GetXMLDeclaration(nsAString& aVersion,
                                  nsAString& aEncoding,
                                  nsAString& Standalone) override;
   virtual bool IsScriptEnabled() override;
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -1634,17 +1634,19 @@ public:
                               mozilla::css::Rule* aStyleRule) = 0;
   virtual void StyleRuleRemoved(mozilla::StyleSheet* aStyleSheet,
                                 mozilla::css::Rule* aStyleRule) = 0;
 
   /**
    * Flush notifications for this document and its parent documents
    * (since those may affect the layout of this one).
    */
-  virtual void FlushPendingNotifications(mozilla::FlushType aType) = 0;
+  virtual void FlushPendingNotifications(mozilla::FlushType aType,
+                                         mozilla::FlushTarget aTarget
+                                           = mozilla::FlushTarget::Normal) = 0;
 
   /**
    * 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;