Bug 1404316 - Use the nsContentUtils machinery for identifying document-level NAC in GetFlattenedTreeParentNodeInternal. r=emilio, a=ritu
authorBobby Holley <bobbyholley@gmail.com>
Fri, 29 Sep 2017 12:06:21 -0700
changeset 434536 999ba109c2fb5e0e5376565b95785ab3e53ca877
parent 434535 dd575194b4f1e73c089ebe9fa71b6b2515d81dcb
child 434537 5eccbe7a7bf822d3d3c1c0f4735bf9d1c4bbe594
push id1567
push userjlorenzo@mozilla.com
push dateThu, 02 Nov 2017 12:36:05 +0000
treeherdermozilla-release@e512c14a0406 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio, ritu
bugs1404316
milestone57.0
Bug 1404316 - Use the nsContentUtils machinery for identifying document-level NAC in GetFlattenedTreeParentNodeInternal. r=emilio, a=ritu MozReview-Commit-ID: 74UMBeZBZcw
dom/base/FragmentOrElement.cpp
--- a/dom/base/FragmentOrElement.cpp
+++ b/dom/base/FragmentOrElement.cpp
@@ -159,58 +159,53 @@ nsIContent::GetFlattenedTreeParentNodeIn
 {
   nsINode* parentNode = GetParentNode();
   if (!parentNode || !parentNode->IsContent()) {
     MOZ_ASSERT(!parentNode || parentNode == OwnerDoc());
     return parentNode;
   }
   nsIContent* parent = parentNode->AsContent();
 
+  // When getting the flattened tree parent for style, we return null
+  // for any "document level" native anonymous content subtree root.
+  // This is NAC generated by an ancestor frame of the document element's
+  // primary frame, and includes scrollbar elements created by the root
+  // scroll frame, and the "custom content container" and accessible caret
+  // generated by the nsCanvasFrame.  We distinguish document level NAC
+  // from NAC generated by the root element's primary frame below.
   if (aType == eForStyle &&
       IsRootOfNativeAnonymousSubtree() &&
       OwnerDoc()->GetRootElement() == parent) {
     // First, check if this is generated ::before/::after content for the root.
     // If it is, we know what to do.
     if (IsGeneratedContentContainerForBefore() ||
         IsGeneratedContentContainerForAfter()) {
       return parent;
     }
 
-    // When getting the flattened tree parent for style, we return null
-    // for any "document level" native anonymous content subtree root.
-    // This is NAC generated by an ancestor frame of the document element's
-    // primary frame, and includes scrollbar elements created by the root
-    // scroll frame, and the "custom content container" and accessible caret
-    // generated by the nsCanvasFrame.  We distinguish document level NAC
-    // from NAC generated by the root element's primary frame below.
-    nsIFrame* parentFrame = parent->GetPrimaryFrame();
-    if (!parentFrame) {
-      // If the root element has no primary frame, it means it can't have
-      // generated any NAC itself.  Thus any NAC we have here must have
-      // been generated by an ancestor frame.
-      //
-      // If we are in here, then either the root element is display:none, or
-      // we are in the middle of constructing the root of the frame tree and
-      // we are trying to eagerly restyle document level NAC in
-      // nsCSSFrameConstructor::GetAnonymousContent before the root
-      // element's frame has been constructed.
-      return OwnerDoc();
+    AutoTArray<nsIContent*, 8> rootElementNAC;
+    nsContentUtils::AppendNativeAnonymousChildren(
+        parent, rootElementNAC, nsIContent::eSkipDocumentLevelNativeAnonymousContent);
+    bool isDocLevelNAC = !rootElementNAC.Contains(this);
+
+#ifdef DEBUG
+    {
+      // The code below would be slightly more direct, but it gets the wrong
+      // answer when the root scrollframe is being bootstrapped and we're
+      // trying to style the scrollbars (since GetRootScrollFrame() still returns
+      // null at that point). Verify that the results match otherwise.
+      AutoTArray<nsIContent*, 8> docLevelNAC;
+      nsContentUtils::AppendDocumentLevelNativeAnonymousContentTo(OwnerDoc(), docLevelNAC);
+      nsIPresShell* shell = OwnerDoc()->GetShell();
+      MOZ_ASSERT_IF(shell && shell->GetRootScrollFrame(),
+                    isDocLevelNAC == docLevelNAC.Contains(this));
     }
-    nsIAnonymousContentCreator* creator = do_QueryFrame(parentFrame);
-    if (!creator) {
-      // If the root element does have a frame, but does not implement
-      // nsIAnonymousContentCreator, then this must be document level NAC.
-      return OwnerDoc();
-    }
-    AutoTArray<nsIContent*, 8> elements;
-    creator->AppendAnonymousContentTo(elements, 0);
-    if (!elements.Contains(this)) {
-      // If the root element does have a frame, and also does implement
-      // nsIAnonymousContentCreator, but didn't create this node, then
-      // it must be document level NAC.
+#endif
+
+    if (isDocLevelNAC) {
       return OwnerDoc();
     }
   }
 
   if (parent && nsContentUtils::HasDistributedChildren(parent) &&
       nsContentUtils::IsInSameAnonymousTree(parent, this)) {
     // This node is distributed to insertion points, thus we
     // need to consult the destination insertion points list to