Bug 1331047: Also traverse native anonymous content in the style system. r?bholley draft
authorEmilio Cobos Álvarez <emilio@crisal.io>
Sat, 22 Apr 2017 22:33:16 +0200
changeset 568641 d236a7185f61f288a9983a8abec19a1c34b81613
parent 568509 0f5ba06c4c5959030a05cb852656d854065e2226
child 568642 83acbdfe1eac4df7e7f10536fcc8983a4019f8bb
push id55935
push userbmo:emilio+bugs@crisal.io
push dateWed, 26 Apr 2017 11:57:38 +0000
reviewersbholley
bugs1331047
milestone55.0a1
Bug 1331047: Also traverse native anonymous content in the style system. r?bholley MozReview-Commit-ID: 6wTqBAqTH69
dom/base/ChildIterator.cpp
dom/base/ChildIterator.h
--- a/dom/base/ChildIterator.cpp
+++ b/dom/base/ChildIterator.cpp
@@ -489,62 +489,16 @@ AllChildrenIterator::GetPreviousChild()
       return beforeContent;
     }
   }
 
   mPhase = eAtBegin;
   return nullptr;
 }
 
-static bool
-IsNativeAnonymousImplementationOfPseudoElement(nsIContent* aContent)
-{
-  // First, we need a frame. This leads to the tricky issue of what we can
-  // infer if the frame is null.
-  //
-  // Unlike regular nodes, native anonymous content (NAC) gets created during
-  // frame construction, which happens after the main style traversal. This
-  // means that we have to manually resolve style for those nodes shortly after
-  // they're created, either by (a) invoking ResolvePseudoElementStyle (for PE
-  // NAC), or (b) handing the subtree off to Servo for a mini-traversal (for
-  // non-PE NAC). We have assertions in nsCSSFrameConstructor that we don't do
-  // both.
-  //
-  // Once that happens, the NAC has a frame. So if we have no frame here,
-  // we're either not NAC, or in the process of doing (b). Either way, this
-  // isn't a PE.
-  nsIFrame* f = aContent->GetPrimaryFrame();
-  if (!f) {
-    return false;
-  }
-
-  // Get the pseudo type.
-  CSSPseudoElementType pseudoType = f->StyleContext()->GetPseudoType();
-
-  // In general nodes never get anonymous box style. However, there are a few
-  // special cases:
-  //
-  // * We somewhat-confusingly give text nodes a style context tagged with
-  //   ":-moz-text", so we need to check for the anonymous box case here.
-  // * The primary frame for table elements is an anonymous box that inherits
-  //   from the table's style.
-  if (pseudoType == CSSPseudoElementType::InheritingAnonBox) {
-    MOZ_ASSERT(f->StyleContext()->GetPseudo() == nsCSSAnonBoxes::mozText ||
-               f->StyleContext()->GetPseudo() == nsCSSAnonBoxes::tableWrapper);
-    return false;
-  }
-
-  MOZ_ASSERT(pseudoType != CSSPseudoElementType::NonInheritingAnonBox);
-
-  // Finally check the actual pseudo type.
-  bool isImpl = pseudoType != CSSPseudoElementType::NotPseudo;
-  MOZ_ASSERT_IF(isImpl, aContent->IsRootOfNativeAnonymousSubtree());
-  return isImpl;
-}
-
 /* static */ bool
 StyleChildrenIterator::IsNeeded(const Element* aElement)
 {
   // If the node is in an anonymous subtree, we conservatively return true to
   // handle insertion points.
   if (aElement->IsInAnonymousSubtree()) {
     return true;
   }
@@ -566,24 +520,13 @@ StyleChildrenIterator::IsNeeded(const El
 
   return false;
 }
 
 
 nsIContent*
 StyleChildrenIterator::GetNextChild()
 {
-  while (nsIContent* child = AllChildrenIterator::GetNextChild()) {
-    if (IsNativeAnonymousImplementationOfPseudoElement(child)) {
-      // Skip any native-anonymous children that are used to implement pseudo-
-      // elements. These match pseudo-element selectors instead of being
-      // considered a child of their host, and thus the style system needs to
-      // handle them separately.
-    } else {
-      return child;
-    }
-  }
-
-  return nullptr;
+  return AllChildrenIterator::GetNextChild();
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/base/ChildIterator.h
+++ b/dom/base/ChildIterator.h
@@ -250,22 +250,24 @@ private:
   // XXX we should really assert there are no frame tree changes as well, but
   // there's no easy way to do that.
   nsMutationGuard mMutationGuard;
 #endif
 };
 
 /**
  * StyleChildrenIterator traverses the children of the element from the
- * perspective of the style system, particularly the children we need to traverse
- * during restyle. This is identical to AllChildrenIterator with
- * (eAllChildren | eSkipDocumentLevelNativeAnonymousContent), _except_ that we
- * detect and skip any native anonymous children that are used to implement
- * pseudo-elements (since the style system needs to cascade those using
- * different algorithms).
+ * perspective of the style system, particularly the children we need to
+ * traverse during restyle.
+ *
+ * At present, this is identical to AllChildrenIterator with
+ * (eAllChildren | eSkipDocumentLevelNativeAnonymousContent). We used to have
+ * detect and skip any native anonymous children that are used to implement some
+ * special magic in here that went away, but we keep the separate class so
+ * we can reintroduce special magic back if needed.
  *
  * Note: it assumes that no mutation of the DOM or frame tree takes place during
  * iteration, and will break horribly if that is not true.
  */
 class StyleChildrenIterator : private AllChildrenIterator
 {
 public:
   explicit StyleChildrenIterator(const nsIContent* aContent)