Bug 1177819. Replace the warning about anon content being passed into frame construction with an assert plus whitelisting of the known-OK cases. r=dholbert
authorBoris Zbarsky <bzbarsky@mit.edu>
Thu, 23 Jul 2015 11:51:09 -0400
changeset 254341 e32f059e60c91ea6cb901777958d31b9a1c9cd88
parent 254340 e12159b9f8911eac74c09fd14c92905296b1b7a6
child 254342 40164bf735347371cdb633cce33d2517f6a15640
push id29099
push userryanvm@gmail.com
push dateThu, 23 Jul 2015 20:03:55 +0000
treeherdermozilla-central@cb8bdb8ffaef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs1177819
milestone42.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1177819. Replace the warning about anon content being passed into frame construction with an assert plus whitelisting of the known-OK cases. r=dholbert
dom/base/nsGkAtomList.h
dom/svg/SVGUseElement.cpp
editor/libeditor/nsHTMLAnonymousUtils.cpp
layout/base/nsCSSFrameConstructor.cpp
layout/generic/nsCanvasFrame.cpp
layout/generic/nsGfxScrollFrame.cpp
--- a/dom/base/nsGkAtomList.h
+++ b/dom/base/nsGkAtomList.h
@@ -2074,16 +2074,17 @@ GK_ATOM(animationsOfAfterProperty, "Anim
 GK_ATOM(transitionsProperty, "TransitionsProperty")        // FrameTransitions*
 GK_ATOM(transitionsOfBeforeProperty, "TransitionsOfBeforeProperty") // FrameTransitions*
 GK_ATOM(transitionsOfAfterProperty, "TransitionsOfAfterProperty") // FrameTransitions*
 GK_ATOM(genConInitializerProperty, "QuoteNodeProperty")
 GK_ATOM(labelMouseDownPtProperty, "LabelMouseDownPtProperty")
 GK_ATOM(baseURIProperty, "baseURIProperty")
 GK_ATOM(lockedStyleStates, "lockedStyleStates")
 GK_ATOM(apzCallbackTransform, "apzCallbackTransform")
+GK_ATOM(restylableAnonymousNode, "restylableAnonymousNode")
 
 // Languages for lang-specific transforms
 GK_ATOM(Japanese, "ja")
 GK_ATOM(Chinese, "zh-CN")
 GK_ATOM(Taiwanese, "zh-TW")
 GK_ATOM(HongKongChinese, "zh-HK")
 GK_ATOM(Unicode, "x-unicode")
 
--- a/dom/svg/SVGUseElement.cpp
+++ b/dom/svg/SVGUseElement.cpp
@@ -263,16 +263,26 @@ SVGUseElement::CreateAnonymousContent()
   nsNodeUtils::Clone(targetContent, true, nodeInfoManager, unused,
                      getter_AddRefs(newnode));
 
   nsCOMPtr<nsIContent> newcontent = do_QueryInterface(newnode);
 
   if (!newcontent)
     return nullptr;
 
+#ifdef DEBUG
+  // Our anonymous clone can get restyled by various things
+  // (e.g. SMIL).  Reconstructing its frame is OK, though, because
+  // it's going to be our _only_ child in the frame tree, so can't get
+  // mis-ordered with anything.
+  newcontent->SetProperty(nsGkAtoms::restylableAnonymousNode,
+                          reinterpret_cast<void*>(true));
+#endif // DEBUG
+
+
   if (newcontent->IsSVGElement(nsGkAtoms::symbol)) {
     nsIDocument *document = GetComposedDoc();
     if (!document)
       return nullptr;
 
     nsNodeInfoManager *nodeInfoManager = document->NodeInfoManager();
     if (!nodeInfoManager)
       return nullptr;
--- a/editor/libeditor/nsHTMLAnonymousUtils.cpp
+++ b/editor/libeditor/nsHTMLAnonymousUtils.cpp
@@ -183,16 +183,25 @@ nsHTMLEditor::CreateAnonymousElement(con
   }
 
   nsElementDeletionObserver* observer =
     new nsElementDeletionObserver(newContent, parentContent);
   NS_ADDREF(observer); // NodeWillBeDestroyed releases.
   parentContent->AddMutationObserver(observer);
   newContent->AddMutationObserver(observer);
 
+#ifdef DEBUG
+  // Editor anonymous content gets passed to RecreateFramesFor... which can't
+  // _really_ deal with anonymous content (because it can't get the frame tree
+  // ordering right).  But for us the ordering doesn't matter so this is sort of
+  // ok.
+  newContent->SetProperty(nsGkAtoms::restylableAnonymousNode,
+			  reinterpret_cast<void*>(true));
+#endif // DEBUG
+
   // display the element
   ps->RecreateFramesFor(newContent);
 
   newElement.forget(aReturn);
   return NS_OK;
 }
 
 // Removes event listener and calls DeleteRefToAnonymousNode.
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -6561,17 +6561,18 @@ nsCSSFrameConstructor::GetInsertionPrevS
     if (aStartSkipChild) {
       iter.Seek(aStartSkipChild);
     } else {
       iter.Seek(aChild);
     }
   } else {
     // Prime the iterator for the call to FindPreviousSibling.
     iter.GetNextChild();
-    NS_WARNING("Someone passed native anonymous content directly into frame "
+    MOZ_ASSERT(aChild->GetProperty(nsGkAtoms::restylableAnonymousNode),
+               "Someone passed native anonymous content directly into frame "
                "construction.  Stop doing that!");
   }
 
   // Note that FindPreviousSibling is passed the iterator by value, so that
   // the later usage of the iterator starts from the same place.
   uint8_t childDisplay = UNSET_DISPLAY;
   nsIFrame* prevSibling =
     FindPreviousSibling(iter, iter.Get(), childDisplay, aInsertion->mParentFrame);
--- a/layout/generic/nsCanvasFrame.cpp
+++ b/layout/generic/nsCanvasFrame.cpp
@@ -140,16 +140,25 @@ nsCanvasFrame::CreateAnonymousContent(ns
                                                    mDummyTouchListener, false);
     mSelectionCaretsEndElement->AddEventListener(NS_LITERAL_STRING("touchstart"),
                                                  mDummyTouchListener, false);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   // Create the custom content container.
   mCustomContentContainer = doc->CreateHTMLElement(nsGkAtoms::div);
+#ifdef DEBUG
+  // We restyle our mCustomContentContainer, even though it's root anonymous
+  // content.  Normally that's not OK because the frame constructor doesn't know
+  // how to order the frame tree in such cases, but we make this work for this
+  // particular case, so it's OK.
+  mCustomContentContainer->SetProperty(nsGkAtoms::restylableAnonymousNode,
+                                       reinterpret_cast<void*>(true));
+#endif // DEBUG
+
   aElements.AppendElement(mCustomContentContainer);
 
   // XXX add :moz-native-anonymous or will that be automatically set?
   rv = mCustomContentContainer->SetAttr(kNameSpaceID_None, nsGkAtoms::_class,
                                         NS_LITERAL_STRING("moz-custom-content-container"),
                                         true);
   NS_ENSURE_SUCCESS(rv, rv);
 
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -3834,31 +3834,47 @@ ScrollFrameHelper::CreateAnonymousConten
   nodeInfo = nodeInfoManager->GetNodeInfo(nsGkAtoms::scrollbar, nullptr,
                                           kNameSpaceID_XUL,
                                           nsIDOMNode::ELEMENT_NODE);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   if (canHaveHorizontal) {
     nsRefPtr<NodeInfo> ni = nodeInfo;
     NS_TrustedNewXULElement(getter_AddRefs(mHScrollbarContent), ni.forget());
+#ifdef DEBUG
+    // Scrollbars can get restyled by theme changes.  Whether such a restyle
+    // will actually reconstruct them correctly if it involves a frame
+    // reconstruct... I don't know.  :(
+    mHScrollbarContent->SetProperty(nsGkAtoms::restylableAnonymousNode,
+                                    reinterpret_cast<void*>(true));
+#endif // DEBUG
+
     mHScrollbarContent->SetAttr(kNameSpaceID_None, nsGkAtoms::orient,
                                 NS_LITERAL_STRING("horizontal"), false);
     mHScrollbarContent->SetAttr(kNameSpaceID_None, nsGkAtoms::clickthrough,
                                 NS_LITERAL_STRING("always"), false);
     if (mIsRoot) {
       mHScrollbarContent->SetAttr(kNameSpaceID_None, nsGkAtoms::root_,
                                   NS_LITERAL_STRING("true"), false);
     }
     if (!aElements.AppendElement(mHScrollbarContent))
       return NS_ERROR_OUT_OF_MEMORY;
   }
 
   if (canHaveVertical) {
     nsRefPtr<NodeInfo> ni = nodeInfo;
     NS_TrustedNewXULElement(getter_AddRefs(mVScrollbarContent), ni.forget());
+#ifdef DEBUG
+    // Scrollbars can get restyled by theme changes.  Whether such a restyle
+    // will actually reconstruct them correctly if it involves a frame
+    // reconstruct... I don't know.  :(
+    mVScrollbarContent->SetProperty(nsGkAtoms::restylableAnonymousNode,
+                                    reinterpret_cast<void*>(true));
+#endif // DEBUG
+
     mVScrollbarContent->SetAttr(kNameSpaceID_None, nsGkAtoms::orient,
                                 NS_LITERAL_STRING("vertical"), false);
     mVScrollbarContent->SetAttr(kNameSpaceID_None, nsGkAtoms::clickthrough,
                                 NS_LITERAL_STRING("always"), false);
     if (mIsRoot) {
       mVScrollbarContent->SetAttr(kNameSpaceID_None, nsGkAtoms::root_,
                                   NS_LITERAL_STRING("true"), false);
     }