Bug 1285474: stylo: Add nsINode method for knowing if the current document is using Servo's style back-end. draft
authorEmilio Cobos Álvarez <ecoal95@gmail.com>
Fri, 08 Jul 2016 00:02:56 -0700
changeset 386460 35e2027080148068bd56f5f3d397b809d4acb82c
parent 386035 99bbc46fd34c6cb6db24ec5e8b8bd973614c0163
child 386461 817acfbf7f114aa2b3293e51148d9f30e4a52fba
push id22708
push userbmo:ealvarez@mozilla.com
push dateMon, 11 Jul 2016 22:25:04 +0000
bugs1285474
milestone50.0a1
Bug 1285474: stylo: Add nsINode method for knowing if the current document is using Servo's style back-end. MozReview-Commit-ID: 3sRE7BZj1tu
dom/base/nsIDocument.h
dom/base/nsINode.cpp
dom/base/nsINode.h
layout/base/RestyleManager.cpp
layout/base/RestyleTracker.cpp
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -1077,16 +1077,20 @@ public:
    * Get this document's CSSLoader.  This is guaranteed to not return null.
    */
   mozilla::css::Loader* CSSLoader() const {
     return mCSSLoader;
   }
 
   mozilla::StyleBackendType GetStyleBackendType() const;
 
+  bool IsStyledByServo() const {
+    return GetStyleBackendType() == mozilla::StyleBackendType::Servo;
+  }
+
   /**
    * Get this document's StyleImageLoader.  This is guaranteed to not return null.
    */
   mozilla::css::ImageLoader* StyleImageLoader() const {
     return mStyleImageLoader;
   }
 
   /**
--- a/dom/base/nsINode.cpp
+++ b/dom/base/nsINode.cpp
@@ -3059,8 +3059,16 @@ nsINode::IsApzAware() const
   return IsNodeApzAware();
 }
 
 bool
 nsINode::IsNodeApzAwareInternal() const
 {
   return EventTarget::IsApzAware();
 }
+
+#ifdef MOZ_STYLO
+bool
+nsINode::IsStyledByServo() const
+{
+  return OwnerDoc()->IsStyledByServo();
+}
+#endif
--- a/dom/base/nsINode.h
+++ b/dom/base/nsINode.h
@@ -962,16 +962,54 @@ public:
   using nsIDOMEventTarget::AddSystemEventListener;
 
   virtual bool IsApzAware() const override;
 
   virtual nsPIDOMWindowOuter* GetOwnerGlobalForBindings() override;
   virtual nsIGlobalObject* GetOwnerGlobal() const override;
 
   /**
+   * Returns true if this is a node belonging to a document that uses the Servo
+   * style system.
+   */
+#ifdef MOZ_STYLO
+  bool IsStyledByServo() const;
+#else
+  bool IsStyledByServo() const { return false; }
+#endif
+
+  inline bool IsDirtyForServo() const
+  {
+    MOZ_ASSERT(IsStyledByServo());
+    return HasFlag(NODE_IS_DIRTY_FOR_SERVO);
+  }
+
+  inline bool HasDirtyDescendantsForServo() const
+  {
+    MOZ_ASSERT(IsStyledByServo());
+    return HasFlag(NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO);
+  }
+
+  inline void SetIsDirtyForServo() {
+    MOZ_ASSERT(IsStyledByServo());
+    SetFlags(NODE_IS_DIRTY_FOR_SERVO);
+  }
+
+  inline void SetHasDirtyDescendantsForServo() {
+    MOZ_ASSERT(IsStyledByServo());
+    SetFlags(NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO);
+  }
+
+  inline void SetIsDirtyAndHasDirtyDescendantsForServo() {
+    MOZ_ASSERT(IsStyledByServo());
+    SetFlags(NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO | NODE_IS_DIRTY_FOR_SERVO);
+  }
+
+
+  /**
    * Adds a mutation observer to be notified when this node, or any of its
    * descendants, are modified. The node will hold a weak reference to the
    * observer, which means that it is the responsibility of the observer to
    * remove itself in case it dies before the node.  If an observer is added
    * while observers are being notified, it may also be notified.  In general,
    * adding observers while inside a notification is not a good idea.  An
    * observer that is already observing the node must not be added without
    * being removed first.
--- a/layout/base/RestyleManager.cpp
+++ b/layout/base/RestyleManager.cpp
@@ -644,17 +644,17 @@ RestyleManager::StyleChangeReflow(nsIFra
   do {
     mPresContext->PresShell()->FrameNeedsReflow(aFrame, dirtyType, dirtyBits,
                                                 rootHandling);
     aFrame = nsLayoutUtils::GetNextContinuationOrIBSplitSibling(aFrame);
   } while (aFrame);
 }
 
 void
-RestyleManager::AddSubtreeToOverflowTracker(nsIFrame* aFrame) 
+RestyleManager::AddSubtreeToOverflowTracker(nsIFrame* aFrame)
 {
   if (aFrame->FrameMaintainsOverflow()) {
     mOverflowChangedTracker.AddFrame(aFrame,
                                      OverflowChangedTracker::CHILDREN_CHANGED);
   }
   nsIFrame::ChildListIterator lists(aFrame);
   for (; !lists.IsDone(); lists.Next()) {
     for (nsIFrame* child : lists.CurrentList()) {
@@ -2600,16 +2600,17 @@ ElementRestyler::ElementRestyler(nsPresC
   , mKidsDesiredA11yNotifications(mDesiredA11yNotifications)
   , mOurA11yNotification(eDontNotify)
   , mVisibleKidsOfHiddenElement(aVisibleKidsOfHiddenElement)
 #endif
 #ifdef RESTYLE_LOGGING
   , mLoggingDepth(aRestyleTracker.LoggingDepth() + 1)
 #endif
 {
+  MOZ_ASSERT_IF(mContent, !mContent->IsStyledByServo());
 }
 
 ElementRestyler::ElementRestyler(const ElementRestyler& aParentRestyler,
                                  nsIFrame* aFrame,
                                  uint32_t aConstructorFlags)
   : mPresContext(aParentRestyler.mPresContext)
   , mFrame(aFrame)
   , mParentContent(aParentRestyler.mContent)
@@ -2634,16 +2635,17 @@ ElementRestyler::ElementRestyler(const E
   , mKidsDesiredA11yNotifications(mDesiredA11yNotifications)
   , mOurA11yNotification(eDontNotify)
   , mVisibleKidsOfHiddenElement(aParentRestyler.mVisibleKidsOfHiddenElement)
 #endif
 #ifdef RESTYLE_LOGGING
   , mLoggingDepth(aParentRestyler.mLoggingDepth + 1)
 #endif
 {
+  MOZ_ASSERT_IF(mContent, !mContent->IsStyledByServo());
   if (aConstructorFlags & FOR_OUT_OF_FLOW_CHILD) {
     // Note that the out-of-flow may not be a geometric descendant of
     // the frame where we started the reresolve.  Therefore, even if
     // mHintsHandled already includes nsChangeHint_AllReflowHints we
     // don't want to pass that on to the out-of-flow reresolve, since
     // that can lead to the out-of-flow not getting reflowed when it
     // should be (eg a reresolve starting at <body> that involves
     // reflowing the <body> would miss reflowing fixed-pos nodes that
@@ -2682,16 +2684,17 @@ ElementRestyler::ElementRestyler(ParentC
   , mKidsDesiredA11yNotifications(mDesiredA11yNotifications)
   , mOurA11yNotification(eDontNotify)
   , mVisibleKidsOfHiddenElement(aParentRestyler.mVisibleKidsOfHiddenElement)
 #endif
 #ifdef RESTYLE_LOGGING
   , mLoggingDepth(aParentRestyler.mLoggingDepth + 1)
 #endif
 {
+  MOZ_ASSERT_IF(mContent, !mContent->IsStyledByServo());
 }
 
 ElementRestyler::ElementRestyler(nsPresContext* aPresContext,
                                  nsIContent* aContent,
                                  nsStyleChangeList* aChangeList,
                                  nsChangeHint aHintsHandledByAncestors,
                                  RestyleTracker& aRestyleTracker,
                                  nsTArray<nsCSSSelector*>& aSelectorsForDescendants,
@@ -2881,29 +2884,31 @@ ElementRestyler::ConditionallyRestyleChi
 }
 
 void
 ElementRestyler::ConditionallyRestyleChildren(nsIFrame* aFrame,
                                               Element* aRestyleRoot)
 {
   MOZ_ASSERT(aFrame->GetContent());
   MOZ_ASSERT(aFrame->GetContent()->IsElement());
+  MOZ_ASSERT(!aFrame->GetContent()->IsStyledByServo());
 
   ConditionallyRestyleUndisplayedDescendants(aFrame, aRestyleRoot);
   ConditionallyRestyleContentChildren(aFrame, aRestyleRoot);
 }
 
 // The structure of this method parallels RestyleContentChildren.
 // If you update this method, you probably want to update that one too.
 void
 ElementRestyler::ConditionallyRestyleContentChildren(nsIFrame* aFrame,
                                                      Element* aRestyleRoot)
 {
   MOZ_ASSERT(aFrame->GetContent());
   MOZ_ASSERT(aFrame->GetContent()->IsElement());
+  MOZ_ASSERT(!aFrame->GetContent()->IsStyledByServo());
 
   if (aFrame->GetContent()->HasFlag(mRestyleTracker.RootBit())) {
     aRestyleRoot = aFrame->GetContent()->AsElement();
   }
 
   for (nsIFrame* f = aFrame; f;
        f = GetNextContinuationWithSameStyle(f, f->StyleContext())) {
     nsIFrame::ChildListIterator lists(f);
@@ -2978,24 +2983,24 @@ void
 ElementRestyler::ConditionallyRestyleUndisplayedNodes(
     UndisplayedNode* aUndisplayed,
     nsIContent* aUndisplayedParent,
     const uint8_t aDisplay,
     Element* aRestyleRoot)
 {
   MOZ_ASSERT(aDisplay == NS_STYLE_DISPLAY_NONE ||
              aDisplay == NS_STYLE_DISPLAY_CONTENTS);
-
   if (!aUndisplayed) {
     return;
   }
 
   if (aUndisplayedParent &&
       aUndisplayedParent->IsElement() &&
       aUndisplayedParent->HasFlag(mRestyleTracker.RootBit())) {
+    MOZ_ASSERT(!aUndisplayedParent->IsStyledByServo());
     aRestyleRoot = aUndisplayedParent->AsElement();
   }
 
   for (UndisplayedNode* undisplayed = aUndisplayed; undisplayed;
        undisplayed = undisplayed->mNext) {
 
     if (!undisplayed->mContent->IsElement()) {
       continue;
@@ -3012,16 +3017,17 @@ ElementRestyler::ConditionallyRestyleUnd
     }
   }
 }
 
 void
 ElementRestyler::ConditionallyRestyleContentDescendants(Element* aElement,
                                                         Element* aRestyleRoot)
 {
+  MOZ_ASSERT(!aElement->IsStyledByServo());
   if (aElement->HasFlag(mRestyleTracker.RootBit())) {
     aRestyleRoot = aElement;
   }
 
   FlattenedChildIterator it(aElement);
   for (nsIContent* n = it.GetNextChild(); n; n = it.GetNextChild()) {
     if (n->IsElement()) {
       Element* e = n->AsElement();
@@ -3042,16 +3048,17 @@ ElementRestyler::ConditionallyRestyle(ns
   }
 
   return ConditionallyRestyle(aFrame->GetContent()->AsElement(), aRestyleRoot);
 }
 
 bool
 ElementRestyler::ConditionallyRestyle(Element* aElement, Element* aRestyleRoot)
 {
+  MOZ_ASSERT(!aElement->IsStyledByServo());
   LOG_RESTYLE("considering element %s for eRestyle_SomeDescendants",
               ElementTagToString(aElement).get());
   LOG_RESTYLE_INDENT();
 
   if (aElement->HasFlag(mRestyleTracker.RootBit())) {
     aRestyleRoot = aElement;
   }
 
--- a/layout/base/RestyleTracker.cpp
+++ b/layout/base/RestyleTracker.cpp
@@ -163,28 +163,30 @@ RestyleTracker::DoProcessRestyles()
 
     // loop so that we process any restyle events generated by processing
     while (mPendingRestyles.Count()) {
       if (mHaveLaterSiblingRestyles) {
         // Convert them to individual restyles on all the later siblings
         AutoTArray<RefPtr<Element>, RESTYLE_ARRAY_STACKSIZE> laterSiblingArr;
         for (auto iter = mPendingRestyles.Iter(); !iter.Done(); iter.Next()) {
           auto element = static_cast<dom::Element*>(iter.Key());
+          MOZ_ASSERT(!element->IsStyledByServo(), "Should not have Servo-styled elements here");
           // Only collect the entries that actually need restyling by us (and
           // haven't, for example, already been restyled).
           // It's important to not mess with the flags on entries not in our
           // document.
           if (element->GetComposedDoc() == Document() &&
               element->HasFlag(RestyleBit()) &&
               (iter.Data()->mRestyleHint & eRestyle_LaterSiblings)) {
             laterSiblingArr.AppendElement(element);
           }
         }
         for (uint32_t i = 0; i < laterSiblingArr.Length(); ++i) {
           Element* element = laterSiblingArr[i];
+          MOZ_ASSERT(!element->IsStyledByServo());
           for (nsIContent* sibling = element->GetNextSibling();
                sibling;
                sibling = sibling->GetNextSibling()) {
             if (sibling->IsElement()) {
               LOG_RESTYLE("adding pending restyle for %s due to "
                           "eRestyle_LaterSiblings hint on %s",
                           FrameTagToString(sibling->AsElement()).get(),
                           FrameTagToString(element->AsElement()).get());