Bug 1064843 part 5 - Ensure frames behave properly for unknown child list id passed into SetInitialChildList. r=dholbert
authorXidorn Quan <quanxunzhen@gmail.com>
Thu, 28 Jan 2016 10:11:00 +1100
changeset 281986 4e8764d61e1d88bd1c486095e42f0ca83c05daf5
parent 281985 f767402068c92cc568c88e514b34def948d201d0
child 281987 aa9137c2014540a644be0f41192e3f81bd5221f5
push id70997
push userxquan@mozilla.com
push dateWed, 27 Jan 2016 23:11:47 +0000
treeherdermozilla-inbound@c991d2a17bb7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs1064843
milestone47.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 1064843 part 5 - Ensure frames behave properly for unknown child list id passed into SetInitialChildList. r=dholbert Note that nsMathMLContainerFrame and its subclasses are unchanged since they are not target of fullscreen (and thus no backdrop frame), and they have an assertion to ensure we really don't pass any unexpected list in.
layout/forms/nsFieldSetFrame.cpp
layout/forms/nsListControlFrame.cpp
layout/forms/nsTextControlFrame.cpp
layout/generic/nsBlockFrame.cpp
layout/generic/nsColumnSetFrame.cpp
layout/generic/nsContainerFrame.cpp
layout/generic/nsFirstLetterFrame.cpp
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsRubyTextContainerFrame.cpp
layout/generic/nsViewportFrame.cpp
layout/generic/nsViewportFrame.h
layout/tables/nsTableFrame.cpp
layout/tables/nsTableOuterFrame.cpp
layout/xul/nsBoxFrame.cpp
layout/xul/nsMenuFrame.cpp
layout/xul/nsMenuPopupFrame.cpp
layout/xul/nsSliderFrame.cpp
--- a/layout/forms/nsFieldSetFrame.cpp
+++ b/layout/forms/nsFieldSetFrame.cpp
@@ -658,18 +658,19 @@ nsFieldSetFrame::Reflow(nsPresContext*  
   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
 }
 
 #ifdef DEBUG
 void
 nsFieldSetFrame::SetInitialChildList(ChildListID    aListID,
                                      nsFrameList&   aChildList)
 {
-  nsContainerFrame::SetInitialChildList(kPrincipalList, aChildList);
-  MOZ_ASSERT(GetInner());
+  nsContainerFrame::SetInitialChildList(aListID, aChildList);
+  MOZ_ASSERT(aListID != kPrincipalList || GetInner(),
+             "Setting principal child list should populate our inner frame");
 }
 void
 nsFieldSetFrame::AppendFrames(ChildListID    aListID,
                               nsFrameList&   aFrameList)
 {
   MOZ_CRASH("nsFieldSetFrame::AppendFrames not supported");
 }
 
--- a/layout/forms/nsListControlFrame.cpp
+++ b/layout/forms/nsListControlFrame.cpp
@@ -927,21 +927,23 @@ nsListControlFrame::HandleEvent(nsPresCo
 }
 
 
 //---------------------------------------------------------
 void
 nsListControlFrame::SetInitialChildList(ChildListID    aListID,
                                         nsFrameList&   aChildList)
 {
-  // First check to see if all the content has been added
-  mIsAllContentHere = mContent->IsDoneAddingChildren();
-  if (!mIsAllContentHere) {
-    mIsAllFramesHere    = false;
-    mHasBeenInitialized = false;
+  if (aListID == kPrincipalList) {
+    // First check to see if all the content has been added
+    mIsAllContentHere = mContent->IsDoneAddingChildren();
+    if (!mIsAllContentHere) {
+      mIsAllFramesHere    = false;
+      mHasBeenInitialized = false;
+    }
   }
   nsHTMLScrollFrame::SetInitialChildList(aListID, aChildList);
 
   // If all the content is here now check
   // to see if all the frames have been created
   /*if (mIsAllContentHere) {
     // If all content and frames are here
     // the reset/initialize
--- a/layout/forms/nsTextControlFrame.cpp
+++ b/layout/forms/nsTextControlFrame.cpp
@@ -1219,23 +1219,24 @@ nsTextControlFrame::GetMaxLength(int32_t
 
 // END IMPLEMENTING NS_IFORMCONTROLFRAME
 
 void
 nsTextControlFrame::SetInitialChildList(ChildListID     aListID,
                                         nsFrameList&    aChildList)
 {
   nsContainerFrame::SetInitialChildList(aListID, aChildList);
-
-  nsIFrame* first = GetFirstPrincipalChild();
+  if (aListID != kPrincipalList) {
+    return;
+  }
 
   // Mark the scroll frame as being a reflow root. This will allow
   // incremental reflows to be initiated at the scroll frame, rather
   // than descending from the root frame of the frame hierarchy.
-  if (first) {
+  if (nsIFrame* first = GetFirstPrincipalChild()) {
     first->AddStateBits(NS_FRAME_REFLOW_ROOT);
 
     nsCOMPtr<nsITextControlElement> txtCtrl = do_QueryInterface(GetContent());
     NS_ASSERTION(txtCtrl, "Content not a text control element");
     txtCtrl->InitializeKeyboardEventListeners();
 
     nsPoint* contentScrollPos = static_cast<nsPoint*>
       (Properties().Get(ContentScrollPos()));
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -6790,28 +6790,22 @@ nsBlockFrame::Init(nsIContent*       aCo
     AddStateBits(NS_FRAME_FONT_INFLATION_FLOW_ROOT);
   }
 }
 
 void
 nsBlockFrame::SetInitialChildList(ChildListID     aListID,
                                   nsFrameList&    aChildList)
 {
-  NS_ASSERTION(aListID != kPrincipalList ||
-               (GetStateBits() & (NS_BLOCK_FRAME_HAS_INSIDE_BULLET |
-                                  NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET)) == 0,
-               "how can we have a bullet already?");
-
-  if (kAbsoluteList == aListID) {
-    nsContainerFrame::SetInitialChildList(aListID, aChildList);
-  }
-  else if (kFloatList == aListID) {
+  if (kFloatList == aListID) {
     mFloats.SetFrames(aChildList);
-  }
-  else {
+  } else if (kPrincipalList == aListID) {
+    NS_ASSERTION((GetStateBits() & (NS_BLOCK_FRAME_HAS_INSIDE_BULLET |
+                                    NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET)) == 0,
+                 "how can we have a bullet already?");
     nsPresContext* presContext = PresContext();
 
 #ifdef DEBUG
     // The only times a block that is an anonymous box is allowed to have a
     // first-letter frame are when it's the block inside a non-anonymous cell,
     // the block inside a fieldset, button or column set, or a scrolled content
     // block, except for <select>.  Note that this means that blocks which are
     // the anonymous block in {ib} splits do NOT get first-letter frames.
@@ -6889,16 +6883,18 @@ nsBlockFrame::SetInitialChildList(ChildL
         Properties().Set(InsideBulletProperty(), bullet);
         AddStateBits(NS_BLOCK_FRAME_HAS_INSIDE_BULLET);
       } else {
         nsFrameList* bulletList = new (shell) nsFrameList(bullet, bullet);
         Properties().Set(OutsideBulletProperty(), bulletList);
         AddStateBits(NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET);
       }
     }
+  } else {
+    nsContainerFrame::SetInitialChildList(aListID, aChildList);
   }
 }
 
 bool
 nsBlockFrame::BulletIsEmpty() const
 {
   NS_ASSERTION(mContent->GetPrimaryFrame()->StyleDisplay()->mDisplay ==
                  NS_STYLE_DISPLAY_LIST_ITEM && HasOutsideBullet(),
--- a/layout/generic/nsColumnSetFrame.cpp
+++ b/layout/generic/nsColumnSetFrame.cpp
@@ -1135,19 +1135,18 @@ nsColumnSetFrame::BuildDisplayList(nsDis
   }
 }
 
 #ifdef DEBUG
 void
 nsColumnSetFrame::SetInitialChildList(ChildListID     aListID,
                                       nsFrameList&    aChildList)
 {
-  MOZ_ASSERT(aListID == kPrincipalList, "unexpected child list");
-  MOZ_ASSERT(aChildList.OnlyChild(),
-             "initial child list must have exactly one child");
+  MOZ_ASSERT(aListID != kPrincipalList || aChildList.OnlyChild(),
+             "initial principal child list must have exactly one child");
   nsContainerFrame::SetInitialChildList(kPrincipalList, aChildList);
 }
 
 void
 nsColumnSetFrame::AppendFrames(ChildListID     aListID,
                                nsFrameList&    aFrameList)
 {
   MOZ_CRASH("unsupported operation");
--- a/layout/generic/nsContainerFrame.cpp
+++ b/layout/generic/nsContainerFrame.cpp
@@ -58,23 +58,26 @@ nsContainerFrame::Init(nsIContent*      
       AddStateBits(NS_FRAME_HAS_CHILD_WITH_VIEW);
   }
 }
 
 void
 nsContainerFrame::SetInitialChildList(ChildListID  aListID,
                                       nsFrameList& aChildList)
 {
-  MOZ_ASSERT(mFrames.IsEmpty(),
-             "unexpected second call to SetInitialChildList");
-  MOZ_ASSERT(aListID == kPrincipalList, "unexpected child list");
 #ifdef DEBUG
   nsFrame::VerifyDirtyBitSet(aChildList);
 #endif
-  mFrames.SetFrames(aChildList);
+  if (aListID == kPrincipalList) {
+    MOZ_ASSERT(mFrames.IsEmpty(),
+               "unexpected second call to SetInitialChildList");
+    mFrames.SetFrames(aChildList);
+  } else {
+    MOZ_ASSERT_UNREACHABLE("Unexpected child list");
+  }
 }
 
 void
 nsContainerFrame::AppendFrames(ChildListID  aListID,
                                nsFrameList& aFrameList)
 {
   MOZ_ASSERT(aListID == kPrincipalList || aListID == kNoReflowPrincipalList,
              "unexpected child list");
--- a/layout/generic/nsFirstLetterFrame.cpp
+++ b/layout/generic/nsFirstLetterFrame.cpp
@@ -75,16 +75,18 @@ nsFirstLetterFrame::Init(nsIContent*    
 
   nsContainerFrame::Init(aContent, aParent, aPrevInFlow);
 }
 
 void
 nsFirstLetterFrame::SetInitialChildList(ChildListID  aListID,
                                         nsFrameList& aChildList)
 {
+  MOZ_ASSERT(aListID == kPrincipalList, "Principal child list is the only "
+             "list that nsFirstLetterFrame should set via this function");
   RestyleManager* restyleManager = PresContext()->RestyleManager();
 
   for (nsFrameList::Enumerator e(aChildList); !e.AtEnd(); e.Next()) {
     NS_ASSERTION(e.get()->GetParent() == this, "Unexpected parent");
     restyleManager->ReparentStyleContext(e.get());
     nsLayoutUtils::MarkDescendantsDirty(e.get());
   }
 
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -1308,17 +1308,19 @@ nsXULScrollFrame::DestroyFrom(nsIFrame* 
   nsBoxFrame::DestroyFrom(aDestructRoot);
 }
 
 void
 nsXULScrollFrame::SetInitialChildList(ChildListID     aListID,
                                       nsFrameList&    aChildList)
 {
   nsBoxFrame::SetInitialChildList(aListID, aChildList);
-  mHelper.ReloadChildFrames();
+  if (aListID == kPrincipalList) {
+    mHelper.ReloadChildFrames();
+  }
 }
 
 
 void
 nsXULScrollFrame::AppendFrames(ChildListID     aListID,
                                nsFrameList&    aFrameList)
 {
   nsBoxFrame::AppendFrames(aListID, aFrameList);
--- a/layout/generic/nsRubyTextContainerFrame.cpp
+++ b/layout/generic/nsRubyTextContainerFrame.cpp
@@ -62,17 +62,19 @@ nsRubyTextContainerFrame::IsFrameOfType(
   return nsRubyTextContainerFrameSuper::IsFrameOfType(aFlags);
 }
 
 /* virtual */ void
 nsRubyTextContainerFrame::SetInitialChildList(ChildListID aListID,
                                               nsFrameList& aChildList)
 {
   nsRubyTextContainerFrameSuper::SetInitialChildList(aListID, aChildList);
-  UpdateSpanFlag();
+  if (aListID == kPrincipalList) {
+    UpdateSpanFlag();
+  }
 }
 
 /* virtual */ void
 nsRubyTextContainerFrame::AppendFrames(ChildListID aListID,
                                        nsFrameList& aFrameList)
 {
   nsRubyTextContainerFrameSuper::AppendFrames(aListID, aFrameList);
   UpdateSpanFlag();
--- a/layout/generic/nsViewportFrame.cpp
+++ b/layout/generic/nsViewportFrame.cpp
@@ -152,24 +152,16 @@ ViewportFrame::BuildDisplayListForTopLay
         BuildDisplayListForTopLayerFrame(aBuilder, frame, aList);
       }
     }
   }
 }
 
 #ifdef DEBUG
 void
-ViewportFrame::SetInitialChildList(ChildListID     aListID,
-                                   nsFrameList&    aChildList)
-{
-  nsFrame::VerifyDirtyBitSet(aChildList);
-  nsContainerFrame::SetInitialChildList(aListID, aChildList);
-}
-
-void
 ViewportFrame::AppendFrames(ChildListID     aListID,
                             nsFrameList&    aFrameList)
 {
   NS_ASSERTION(aListID == kPrincipalList, "unexpected child list");
   NS_ASSERTION(GetChildList(aListID).IsEmpty(), "Shouldn't have any kids!");
   nsContainerFrame::AppendFrames(aListID, aFrameList);
 }
 
--- a/layout/generic/nsViewportFrame.h
+++ b/layout/generic/nsViewportFrame.h
@@ -43,18 +43,16 @@ public:
     nsIFrame* firstChild = mFrames.FirstChild();
     if (firstChild) {
       return firstChild->GetWritingMode();
     }
     return nsIFrame::GetWritingMode();
   }
 
 #ifdef DEBUG
-  virtual void SetInitialChildList(ChildListID     aListID,
-                                   nsFrameList&    aChildList) override;
   virtual void AppendFrames(ChildListID     aListID,
                             nsFrameList&    aFrameList) override;
   virtual void InsertFrames(ChildListID     aListID,
                             nsIFrame*       aPrevFrame,
                             nsFrameList&    aFrameList) override;
   virtual void RemoveFrame(ChildListID     aListID,
                            nsIFrame*       aOldFrame) override;
 #endif
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -311,19 +311,23 @@ nsTableFrame::UnregisterPositionedTableP
 }
 
 // XXX this needs to be cleaned up so that the frame constructor breaks out col group
 // frames into a separate child list, bug 343048.
 void
 nsTableFrame::SetInitialChildList(ChildListID     aListID,
                                   nsFrameList&    aChildList)
 {
+  if (aListID != kPrincipalList) {
+    nsContainerFrame::SetInitialChildList(aListID, aChildList);
+    return;
+  }
+
   MOZ_ASSERT(mFrames.IsEmpty() && mColGroups.IsEmpty(),
              "unexpected second call to SetInitialChildList");
-  MOZ_ASSERT(aListID == kPrincipalList, "unexpected child list");
 
   // XXXbz the below code is an icky cesspit that's only needed in its current
   // form for two reasons:
   // 1) Both rowgroups and column groups come in on the principal child list.
   while (aChildList.NotEmpty()) {
     nsIFrame* childFrame = aChildList.FirstChild();
     aChildList.RemoveFirstChild();
     const nsStyleDisplay* childDisplay = childFrame->StyleDisplay();
--- a/layout/tables/nsTableOuterFrame.cpp
+++ b/layout/tables/nsTableOuterFrame.cpp
@@ -87,30 +87,28 @@ nsTableOuterFrame::GetChildLists(nsTArra
   nsContainerFrame::GetChildLists(aLists);
   mCaptionFrames.AppendIfNonempty(aLists, kCaptionList);
 }
 
 void 
 nsTableOuterFrame::SetInitialChildList(ChildListID     aListID,
                                        nsFrameList&    aChildList)
 {
-  MOZ_ASSERT(kCaptionList == aListID || aListID == kPrincipalList,
-             "unexpected child list");
-  MOZ_ASSERT(GetChildList(aListID).IsEmpty(),
-             "already have child frames in SetInitialChildList");
-
   if (kCaptionList == aListID) {
     // the frame constructor already checked for table-caption display type
+    MOZ_ASSERT(mCaptionFrames.IsEmpty(),
+               "already have child frames in CaptionList");
     mCaptionFrames.SetFrames(aChildList);
   } else {
-    MOZ_ASSERT(aChildList.FirstChild() &&
-               aChildList.FirstChild() == aChildList.LastChild() &&
-               nsGkAtoms::tableFrame == aChildList.FirstChild()->GetType(),
-               "expected a single table frame");
-    mFrames.SetFrames(aChildList);
+    MOZ_ASSERT(kPrincipalList != aListID ||
+               (aChildList.FirstChild() &&
+                aChildList.FirstChild() == aChildList.LastChild() &&
+                nsGkAtoms::tableFrame == aChildList.FirstChild()->GetType()),
+               "expected a single table frame in principal child list");
+    nsContainerFrame::SetInitialChildList(aListID, aChildList);
   }
 }
 
 void
 nsTableOuterFrame::AppendFrames(ChildListID     aListID,
                                 nsFrameList&    aFrameList)
 {
   // We only have two child frames: the inner table and a caption frame.
--- a/layout/xul/nsBoxFrame.cpp
+++ b/layout/xul/nsBoxFrame.cpp
@@ -143,21 +143,23 @@ nsBoxFrame::~nsBoxFrame()
 {
 }
 
 void
 nsBoxFrame::SetInitialChildList(ChildListID     aListID,
                                 nsFrameList&    aChildList)
 {
   nsContainerFrame::SetInitialChildList(aListID, aChildList);
-  // initialize our list of infos.
-  nsBoxLayoutState state(PresContext());
-  CheckBoxOrder();
-  if (mLayoutManager)
-    mLayoutManager->ChildrenSet(this, state, mFrames.FirstChild());
+  if (aListID == kPrincipalList) {
+    // initialize our list of infos.
+    nsBoxLayoutState state(PresContext());
+    CheckBoxOrder();
+    if (mLayoutManager)
+      mLayoutManager->ChildrenSet(this, state, mFrames.FirstChild());
+  }
 }
 
 /* virtual */ void
 nsBoxFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
 {
   nsContainerFrame::DidSetStyleContext(aOldStyleContext);
 
   // The values that CacheAttributes() computes depend on our style,
--- a/layout/xul/nsMenuFrame.cpp
+++ b/layout/xul/nsMenuFrame.cpp
@@ -310,18 +310,18 @@ nsMenuFrame::SetPopupFrame(nsFrameList& 
     }
   }
 }
 
 void
 nsMenuFrame::SetInitialChildList(ChildListID     aListID,
                                  nsFrameList&    aChildList)
 {
-  NS_ASSERTION(!HasPopup(), "SetInitialChildList called twice?");
   if (aListID == kPrincipalList || aListID == kPopupList) {
+    NS_ASSERTION(!HasPopup(), "SetInitialChildList called twice?");
     SetPopupFrame(aChildList);
   }
   nsBoxFrame::SetInitialChildList(aListID, aChildList);
 }
 
 void
 nsMenuFrame::DestroyFrom(nsIFrame* aDestructRoot)
 {
--- a/layout/xul/nsMenuPopupFrame.cpp
+++ b/layout/xul/nsMenuPopupFrame.cpp
@@ -389,18 +389,19 @@ void nsXULPopupShownEvent::CancelListene
 
 NS_IMPL_ISUPPORTS_INHERITED(nsXULPopupShownEvent, nsRunnable, nsIDOMEventListener);
 
 void
 nsMenuPopupFrame::SetInitialChildList(ChildListID  aListID,
                                       nsFrameList& aChildList)
 {
   // unless the list is empty, indicate that children have been generated.
-  if (aChildList.NotEmpty())
+  if (aListID == kPrincipalList && aChildList.NotEmpty()) {
     mGeneratedChildren = true;
+  }
   nsBoxFrame::SetInitialChildList(aListID, aChildList);
 }
 
 bool
 nsMenuPopupFrame::IsLeaf() const
 {
   if (mGeneratedChildren)
     return false;
--- a/layout/xul/nsSliderFrame.cpp
+++ b/layout/xul/nsSliderFrame.cpp
@@ -885,17 +885,19 @@ nsSliderFrame::GetType() const
   return nsGkAtoms::sliderFrame;
 }
 
 void
 nsSliderFrame::SetInitialChildList(ChildListID     aListID,
                                    nsFrameList&    aChildList)
 {
   nsBoxFrame::SetInitialChildList(aListID, aChildList);
-  AddListener();
+  if (aListID == kPrincipalList) {
+    AddListener();
+  }
 }
 
 nsresult
 nsSliderMediator::HandleEvent(nsIDOMEvent* aEvent)
 {
   // Only process the event if the thumb is not being dragged.
   if (mSlider && !mSlider->isDraggingThumb())
     return mSlider->StartDrag(aEvent);