Bug 1363805 - Part 2: Add a flag to note that a child has LaterSiblings hint. r?heycam draft
authorWei-Cheng Pan <wpan@mozilla.com>
Wed, 13 Sep 2017 16:47:03 +0800
changeset 669667 3bd27b2d96d733a182657591f7f34a530336dc68
parent 669666 4030aa16da689d8aecd7e4069f30e8ad8fa03a3a
child 669668 5031dfd2ef2f60255e5fc3ba624d2447d11efaed
push id81392
push userbmo:wpan@mozilla.com
push dateMon, 25 Sep 2017 07:20:33 +0000
reviewersheycam
bugs1363805
milestone58.0a1
Bug 1363805 - Part 2: Add a flag to note that a child has LaterSiblings hint. r?heycam This flag is only used by nsComputedDOMStyle. MozReview-Commit-ID: 2EzIYXCt5Rj
dom/base/Element.h
layout/base/RestyleTracker.cpp
layout/base/RestyleTracker.h
--- a/dom/base/Element.h
+++ b/dom/base/Element.h
@@ -134,33 +134,36 @@ enum {
   // is, has an animation-only style change pending _and_ that style
   // change will attempt to restyle descendants).
   ELEMENT_IS_POTENTIAL_ANIMATION_ONLY_RESTYLE_ROOT = ELEMENT_SHARED_RESTYLE_BIT_4,
 
   // Set if this element has a pending restyle with an eRestyle_SomeDescendants
   // restyle hint.
   ELEMENT_IS_CONDITIONAL_RESTYLE_ANCESTOR = ELEMENT_FLAG_BIT(4),
 
+  // Set if a child element has later-sibling restyle hint. This is needed for
+  // nsComputedDOMStyle to decide when should we need to flush style (only used
+  // in Gecko).
+  ELEMENT_HAS_CHILD_WITH_LATER_SIBLINGS_HINT = ELEMENT_FLAG_BIT(5),
+
   // Just the HAS_PENDING bits, for convenience
   ELEMENT_PENDING_RESTYLE_FLAGS =
     ELEMENT_HAS_PENDING_RESTYLE |
     ELEMENT_HAS_PENDING_ANIMATION_ONLY_RESTYLE,
 
   // Just the IS_POTENTIAL bits, for convenience
   ELEMENT_POTENTIAL_RESTYLE_ROOT_FLAGS =
     ELEMENT_IS_POTENTIAL_RESTYLE_ROOT |
     ELEMENT_IS_POTENTIAL_ANIMATION_ONLY_RESTYLE_ROOT,
 
   // All of the restyle bits together, for convenience.
   ELEMENT_ALL_RESTYLE_FLAGS = ELEMENT_PENDING_RESTYLE_FLAGS |
                               ELEMENT_POTENTIAL_RESTYLE_ROOT_FLAGS |
                               ELEMENT_IS_CONDITIONAL_RESTYLE_ANCESTOR,
 
-  // ELEMENT_FLAG_BIT(5) is currently unused
-
   // Remaining bits are for subclasses
   ELEMENT_TYPE_SPECIFIC_BITS_OFFSET = NODE_TYPE_SPECIFIC_BITS_OFFSET + 6
 };
 
 #undef ELEMENT_FLAG_BIT
 
 // Make sure we have space for our bits
 ASSERT_NODE_FLAGS_SPACE(ELEMENT_TYPE_SPECIFIC_BITS_OFFSET);
@@ -1810,17 +1813,18 @@ inline const mozilla::dom::Element* nsIN
 {
   MOZ_ASSERT(IsElement());
   return static_cast<const mozilla::dom::Element*>(this);
 }
 
 inline void nsINode::UnsetRestyleFlagsIfGecko()
 {
   if (IsElement() && !AsElement()->IsStyledByServo()) {
-    UnsetFlags(ELEMENT_ALL_RESTYLE_FLAGS);
+    UnsetFlags(ELEMENT_ALL_RESTYLE_FLAGS |
+               ELEMENT_HAS_CHILD_WITH_LATER_SIBLINGS_HINT);
   }
 }
 
 /**
  * Macros to implement Clone(). _elementName is the class for which to implement
  * Clone.
  */
 #define NS_IMPL_ELEMENT_CLONE(_elementName)                                 \
--- a/layout/base/RestyleTracker.cpp
+++ b/layout/base/RestyleTracker.cpp
@@ -202,16 +202,20 @@ RestyleTracker::DoProcessRestyles()
           RestyleData* data;
 #ifdef DEBUG
           bool found =
 #endif
             mPendingRestyles.Get(element, &data);
           NS_ASSERTION(found, "Where did our entry go?");
           data->mRestyleHint =
             nsRestyleHint(data->mRestyleHint & ~eRestyle_LaterSiblings);
+
+          if (Element* parent = element->GetFlattenedTreeParentElement()) {
+            parent->UnsetFlags(ELEMENT_HAS_CHILD_WITH_LATER_SIBLINGS_HINT);
+          }
         }
 
         LOG_RESTYLE("%d pending restyles after expanding out "
                     "eRestyle_LaterSiblings", mPendingRestyles.Count());
 
         mHaveLaterSiblingRestyles = false;
       }
 
--- a/layout/base/RestyleTracker.h
+++ b/layout/base/RestyleTracker.h
@@ -351,16 +351,25 @@ RestyleTracker::AddPendingRestyle(Elemen
       // PostRecreateFramesFor, so we need to track it here.
       MOZ_ASSERT(curData, "expected to find a RestyleData for cur");
       if (curData) {
         curData->mDescendants.AppendElement(aElement);
       }
     }
   }
 
+  // If we need to restyle later siblings, we will need a flag on parent to note
+  // that some children need restyle for nsComputedDOMStyle.
+  if (aRestyleHint & eRestyle_LaterSiblings) {
+    nsIContent* parent = aElement->GetFlattenedTreeParent();
+    if (parent && parent->IsElement()) {
+      parent->SetFlags(ELEMENT_HAS_CHILD_WITH_LATER_SIBLINGS_HINT);
+    }
+  }
+
   mHaveLaterSiblingRestyles =
     mHaveLaterSiblingRestyles || (aRestyleHint & eRestyle_LaterSiblings) != 0;
   return hadRestyleLaterSiblings;
 }
 
 } // namespace mozilla
 
 #endif /* mozilla_RestyleTracker_h */