Bug 1331047: Also traverse native anonymous content in the style system. r?bholley
MozReview-Commit-ID: 6wTqBAqTH69
--- 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)