Bug 504221 part 5. Switch from GetFirstChild to GetChildList (returning an nsFrameList). For now, keep a GetFirstChild shim so callers don't have to be updated. r=fantasai, r+sr=roc
authorBoris Zbarsky <bzbarsky@mit.edu>
Tue, 28 Jul 2009 08:51:09 -0400
changeset 30783 6ecb093df4d09ffb2e3cb1a00fde604985ded502
parent 30782 bab42673f96dd3edb65f0e26417704c9cef8abee
child 30784 59d3822ae12d76f3318ca794484dda01f07839b0
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfantasai, r
bugs504221
milestone1.9.2a1pre
Bug 504221 part 5. Switch from GetFirstChild to GetChildList (returning an nsFrameList). For now, keep a GetFirstChild shim so callers don't have to be updated. r=fantasai, r+sr=roc
layout/forms/nsComboboxControlFrame.cpp
layout/forms/nsComboboxControlFrame.h
layout/generic/nsAbsoluteContainingBlock.h
layout/generic/nsBlockFrame.cpp
layout/generic/nsBlockFrame.h
layout/generic/nsContainerFrame.cpp
layout/generic/nsContainerFrame.h
layout/generic/nsFrame.cpp
layout/generic/nsFrame.h
layout/generic/nsHTMLFrame.cpp
layout/generic/nsIFrame.h
layout/generic/nsInlineFrame.cpp
layout/generic/nsInlineFrame.h
layout/generic/nsViewportFrame.cpp
layout/generic/nsViewportFrame.h
layout/tables/nsTableFrame.cpp
layout/tables/nsTableFrame.h
layout/tables/nsTableOuterFrame.cpp
layout/tables/nsTableOuterFrame.h
layout/xul/base/src/nsMenuFrame.cpp
layout/xul/base/src/nsMenuFrame.h
--- a/layout/forms/nsComboboxControlFrame.cpp
+++ b/layout/forms/nsComboboxControlFrame.cpp
@@ -1225,23 +1225,23 @@ nsComboboxControlFrame::Destroy()
   // Cleanup frames in popup child list
   mPopupFrames.DestroyFrames();
   nsContentUtils::DestroyAnonymousContent(&mDisplayContent);
   nsContentUtils::DestroyAnonymousContent(&mButtonContent);
   nsBlockFrame::Destroy();
 }
 
 
-nsIFrame*
-nsComboboxControlFrame::GetFirstChild(nsIAtom* aListName) const
+nsFrameList
+nsComboboxControlFrame::GetChildList(nsIAtom* aListName) const
 {
   if (nsGkAtoms::selectPopupList == aListName) {
-    return mPopupFrames.FirstChild();
+    return mPopupFrames;
   }
-  return nsBlockFrame::GetFirstChild(aListName);
+  return nsBlockFrame::GetChildList(aListName);
 }
 
 NS_IMETHODIMP
 nsComboboxControlFrame::SetInitialChildList(nsIAtom*        aListName,
                                             nsIFrame*       aChildList)
 {
   nsresult rv = NS_OK;
   if (nsGkAtoms::selectPopupList == aListName) {
--- a/layout/forms/nsComboboxControlFrame.h
+++ b/layout/forms/nsComboboxControlFrame.h
@@ -136,17 +136,17 @@ public:
     return nsBlockFrame::IsFrameOfType(aFlags &
       ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock));
   }
 
 #ifdef NS_DEBUG
   NS_IMETHOD GetFrameName(nsAString& aResult) const;
 #endif
   virtual void Destroy();
-  virtual nsIFrame* GetFirstChild(nsIAtom* aListName) const;
+  virtual nsFrameList GetChildList(nsIAtom* aListName) const;
   NS_IMETHOD SetInitialChildList(nsIAtom*        aListName,
                                  nsIFrame*       aChildList);
   virtual nsIAtom* GetAdditionalChildListName(PRInt32 aIndex) const;
 
   virtual nsIFrame* GetContentInsertionFrame();
 
   // nsIFormControlFrame
   virtual nsresult SetFormProperty(nsIAtom* aName, const nsAString& aValue);
--- a/layout/generic/nsAbsoluteContainingBlock.h
+++ b/layout/generic/nsAbsoluteContainingBlock.h
@@ -79,17 +79,17 @@ public:
                  mChildListName == nsGkAtoms::fixedList,
                  "should either represent position:fixed or absolute content");
   }
 
 #ifdef DEBUG
   nsIAtom* GetChildListName() const { return mChildListName; }
 #endif
 
-  nsIFrame* GetFirstChild() const { return mAbsoluteFrames.FirstChild(); }
+  const nsFrameList& GetChildList() const { return mAbsoluteFrames; }
 
   nsresult SetInitialChildList(nsIFrame*       aDelegatingFrame,
                                nsIAtom*        aListName,
                                nsIFrame*       aChildList);
   nsresult AppendFrames(nsIFrame*      aDelegatingFrame,
                         nsIAtom*       aListName,
                         nsIFrame*      aFrameList);
   nsresult InsertFrames(nsIFrame*      aDelegatingFrame,
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -508,39 +508,42 @@ nsBlockFrame::GetBaseline() const
   if (nsLayoutUtils::GetLastLineBaseline(this, &result))
     return result;
   return nsFrame::GetBaseline();
 }
 
 /////////////////////////////////////////////////////////////////////////////
 // Child frame enumeration
 
-nsIFrame*
-nsBlockFrame::GetFirstChild(nsIAtom* aListName) const
+nsFrameList
+nsBlockFrame::GetChildList(nsIAtom* aListName) const
 {
   if (nsGkAtoms::absoluteList == aListName) {
-    return mAbsoluteContainer.GetFirstChild();
+    return mAbsoluteContainer.GetChildList();
   }
   else if (nsnull == aListName) {
+    // XXXbz once we start using mFrames, or some other sane storage for our
+    // in-flow kids, we could switch GetChildList to returning a |const
+    // nsFrameList&|.
     return (mLines.empty()) ? nsnull : mLines.front()->mFirstChild;
   }
   else if (aListName == nsGkAtoms::overflowList) {
     nsLineList* overflowLines = GetOverflowLines();
     return overflowLines ? overflowLines->front()->mFirstChild : nsnull;
   }
   else if (aListName == nsGkAtoms::overflowOutOfFlowList) {
-    return GetOverflowOutOfFlows().FirstChild();
+    return GetOverflowOutOfFlows();
   }
   else if (aListName == nsGkAtoms::floatList) {
-    return mFloats.FirstChild();
+    return mFloats;
   }
   else if (aListName == nsGkAtoms::bulletList) {
     return (HaveOutsideBullet()) ? mBullet : nsnull;
   }
-  return nsContainerFrame::GetFirstChild(aListName);;
+  return nsContainerFrame::GetChildList(aListName);
 }
 
 nsIFrame*
 nsBlockFrame::GetLastChild(nsIAtom* aListName) const
 {
   if (aListName) {
     return nsBlockFrameSuper::GetLastChild(aListName);
   }
@@ -6159,18 +6162,19 @@ nsBlockFrame::BuildDisplayList(nsDisplay
 #endif
 
   DisplayBorderBackgroundOutline(aBuilder, aLists);
 
   if (GetPrevInFlow()) {
     DisplayOverflowContainers(aBuilder, aDirtyRect, aLists);
   }
 
-  aBuilder->MarkFramesForDisplayList(this, mFloats.FirstChild(), aDirtyRect);
-  aBuilder->MarkFramesForDisplayList(this, mAbsoluteContainer.GetFirstChild(), aDirtyRect);
+  aBuilder->MarkFramesForDisplayList(this, mFloats, aDirtyRect);
+  aBuilder->MarkFramesForDisplayList(this, mAbsoluteContainer.GetChildList(),
+                                     aDirtyRect);
 
   // Don't use the line cursor if we might have a descendant placeholder ...
   // it might skip lines that contain placeholders but don't themselves
   // intersect with the dirty area.
   nsLineBox* cursor = GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO
     ? nsnull : GetFirstLineContaining(aDirtyRect.y);
   line_iterator line_end = end_lines();
   nsresult rv = NS_OK;
--- a/layout/generic/nsBlockFrame.h
+++ b/layout/generic/nsBlockFrame.h
@@ -171,17 +171,17 @@ public:
                                  nsIFrame*       aChildList);
   NS_IMETHOD  AppendFrames(nsIAtom*        aListName,
                            nsIFrame*       aFrameList);
   NS_IMETHOD  InsertFrames(nsIAtom*        aListName,
                            nsIFrame*       aPrevFrame,
                            nsIFrame*       aFrameList);
   NS_IMETHOD  RemoveFrame(nsIAtom*        aListName,
                           nsIFrame*       aOldFrame);
-  virtual nsIFrame* GetFirstChild(nsIAtom* aListName) const;
+  virtual nsFrameList GetChildList(nsIAtom* aListName) const;
   virtual nsIFrame* GetLastChild(nsIAtom* aListName) const;
   virtual nscoord GetBaseline() const;
   virtual nsIAtom* GetAdditionalChildListName(PRInt32 aIndex) const;
   virtual void Destroy();
   virtual nsSplittableType GetSplittableType() const;
   virtual PRBool IsContainingBlock() const;
   virtual PRBool IsFloatContainingBlock() const;
   NS_IMETHOD BuildDisplayList(nsDisplayListBuilder*   aBuilder,
--- a/layout/generic/nsContainerFrame.cpp
+++ b/layout/generic/nsContainerFrame.cpp
@@ -306,38 +306,44 @@ nsContainerFrame::Destroy()
 
   // Destroy the frame and remove the flow pointers
   nsSplittableFrame::Destroy();
 }
 
 /////////////////////////////////////////////////////////////////////////////
 // Child frame enumeration
 
-nsIFrame*
-nsContainerFrame::GetFirstChild(nsIAtom* aListName) const
+nsFrameList
+nsContainerFrame::GetChildList(nsIAtom* aListName) const
 {
   // We only know about the unnamed principal child list and the overflow
-  // list
+  // lists
   if (nsnull == aListName) {
-    return mFrames.FirstChild();
-  } else if (nsGkAtoms::overflowList == aListName) {
+    return mFrames;
+  }
+
+  if (nsGkAtoms::overflowList == aListName) {
     nsFrameList* frameList = GetOverflowFrames();
-    return frameList ? frameList->FirstChild() : nsnull;
-  } else if (nsGkAtoms::overflowContainersList == aListName) {
+    return frameList ? *frameList : nsFrameList::EmptyList();
+  }
+
+  if (nsGkAtoms::overflowContainersList == aListName) {
     nsFrameList* list = GetPropTableFrames(PresContext(),
                           nsGkAtoms::overflowContainersProperty);
-    return (list) ? list->FirstChild() : nsnull;
-  } else if (nsGkAtoms::excessOverflowContainersList == aListName) {
+    return list ? *list : nsFrameList::EmptyList();
+  }
+
+  if (nsGkAtoms::excessOverflowContainersList == aListName) {
     nsFrameList* list = GetPropTableFrames(PresContext(),
                           nsGkAtoms::excessOverflowContainersProperty);
-    return (list) ? list->FirstChild() : nsnull;
+    return list ? *list : nsFrameList::EmptyList();
 
-  } else {
-    return nsnull;
   }
+
+  return nsFrameList::EmptyList();
 }
 
 #define NS_CONTAINER_FRAME_OVERFLOW_LIST_INDEX                   0
 #define NS_CONTAINER_FRAME_OVERFLOW_CONTAINERS_LIST_INDEX        1
 #define NS_CONTAINER_FRAME_EXCESS_OVERFLOW_CONTAINERS_LIST_INDEX 2
 // If adding/removing lists, don't forget to update count in .h file
 
 
--- a/layout/generic/nsContainerFrame.h
+++ b/layout/generic/nsContainerFrame.h
@@ -82,17 +82,17 @@ public:
   NS_IMETHOD AppendFrames(nsIAtom*  aListName,
                           nsIFrame* aFrameList);
   NS_IMETHOD InsertFrames(nsIAtom*  aListName,
                           nsIFrame* aPrevFrame,
                           nsIFrame* aFrameList);
   NS_IMETHOD RemoveFrame(nsIAtom*  aListName,
                          nsIFrame* aOldFrame);
 
-  virtual nsIFrame* GetFirstChild(nsIAtom* aListName) const;
+  virtual nsFrameList GetChildList(nsIAtom* aListName) const;
   virtual nsIAtom* GetAdditionalChildListName(PRInt32 aIndex) const;
   virtual void Destroy();
   virtual void ChildIsDirty(nsIFrame* aChild);
 
   virtual PRBool IsLeaf() const;
   virtual PRBool PeekOffsetNoAmount(PRBool aForward, PRInt32* aOffset);
   virtual PRBool PeekOffsetCharacter(PRBool aForward, PRInt32* aOffset);
   
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -754,20 +754,20 @@ nsFrame::GetBaseline() const
 
 nsIAtom*
 nsFrame::GetAdditionalChildListName(PRInt32 aIndex) const
 {
   NS_PRECONDITION(aIndex >= 0, "invalid index number");
   return nsnull;
 }
 
-nsIFrame*
-nsFrame::GetFirstChild(nsIAtom* aListName) const
-{
-  return nsnull;
+nsFrameList
+nsFrame::GetChildList(nsIAtom* aListName) const
+{
+  return nsFrameList::EmptyList();
 }
 
 static nsIFrame*
 GetActiveSelectionFrame(nsIFrame* aFrame)
 {
   nsIView* mouseGrabber;
   aFrame->PresContext()->GetPresShell()->
     GetViewManager()->GetMouseEventGrabber(mouseGrabber);
--- a/layout/generic/nsFrame.h
+++ b/layout/generic/nsFrame.h
@@ -174,17 +174,17 @@ public:
                           nsIFrame*       aOldFrame);
   virtual void Destroy();
   virtual nsStyleContext* GetAdditionalStyleContext(PRInt32 aIndex) const;
   virtual void SetAdditionalStyleContext(PRInt32 aIndex,
                                          nsStyleContext* aStyleContext);
   NS_IMETHOD  SetParent(const nsIFrame* aParent);
   virtual nscoord GetBaseline() const;
   virtual nsIAtom* GetAdditionalChildListName(PRInt32 aIndex) const;
-  virtual nsIFrame* GetFirstChild(nsIAtom* aListName) const;
+  virtual nsFrameList GetChildList(nsIAtom* aListName) const;
   NS_IMETHOD  HandleEvent(nsPresContext* aPresContext, 
                           nsGUIEvent*     aEvent,
                           nsEventStatus*  aEventStatus);
   NS_IMETHOD  GetContentForEvent(nsPresContext* aPresContext,
                                  nsEvent* aEvent,
                                  nsIContent** aContent);
   NS_IMETHOD  GetCursor(const nsPoint&    aPoint,
                         nsIFrame::Cursor& aCursor);
--- a/layout/generic/nsHTMLFrame.cpp
+++ b/layout/generic/nsHTMLFrame.cpp
@@ -102,17 +102,17 @@ public:
                           nsIFrame*       aFrameList);
   NS_IMETHOD InsertFrames(nsIAtom*        aListName,
                           nsIFrame*       aPrevFrame,
                           nsIFrame*       aFrameList);
   NS_IMETHOD RemoveFrame(nsIAtom*        aListName,
                          nsIFrame*       aOldFrame);
 
   virtual nsIAtom* GetAdditionalChildListName(PRInt32 aIndex) const;
-  virtual nsIFrame* GetFirstChild(nsIAtom* aListName) const;
+  virtual nsFrameList GetChildList(nsIAtom* aListName) const;
 
   virtual nscoord GetMinWidth(nsIRenderingContext *aRenderingContext);
   virtual nscoord GetPrefWidth(nsIRenderingContext *aRenderingContext);
   NS_IMETHOD Reflow(nsPresContext*          aPresContext,
                     nsHTMLReflowMetrics&     aDesiredSize,
                     const nsHTMLReflowState& aReflowState,
                     nsReflowStatus&          aStatus);
   virtual PRBool IsContainingBlock() const { return PR_TRUE; }
@@ -378,23 +378,23 @@ nsIAtom*
 CanvasFrame::GetAdditionalChildListName(PRInt32 aIndex) const
 {
   if (CANVAS_ABS_POS_CHILD_LIST == aIndex)
     return nsGkAtoms::absoluteList;
 
   return nsHTMLContainerFrame::GetAdditionalChildListName(aIndex);
 }
 
-nsIFrame*
-CanvasFrame::GetFirstChild(nsIAtom* aListName) const
+nsFrameList
+CanvasFrame::GetChildList(nsIAtom* aListName) const
 {
   if (nsGkAtoms::absoluteList == aListName)
-    return mAbsoluteContainer.GetFirstChild();
+    return mAbsoluteContainer.GetChildList();
 
-  return nsHTMLContainerFrame::GetFirstChild(aListName);
+  return nsHTMLContainerFrame::GetChildList(aListName);
 }
 
 nsRect CanvasFrame::CanvasArea() const
 {
   nsRect result(GetOverflowRect());
 
   nsIScrollableFrame *scrollableFrame = do_QueryFrame(GetParent());
   if (scrollableFrame) {
@@ -472,17 +472,18 @@ CanvasFrame::BuildDisplayList(nsDisplayL
                               const nsDisplayListSet& aLists)
 {
   nsresult rv;
 
   if (GetPrevInFlow()) {
     DisplayOverflowContainers(aBuilder, aDirtyRect, aLists);
   }
 
-  aBuilder->MarkFramesForDisplayList(this, mAbsoluteContainer.GetFirstChild(), aDirtyRect);
+  aBuilder->MarkFramesForDisplayList(this, mAbsoluteContainer.GetChildList(),
+                                     aDirtyRect);
   
   // Force a background to be shown. We may have a background propagated to us,
   // in which case GetStyleBackground wouldn't have the right background
   // and the code in nsFrame::DisplayBorderBackgroundOutline might not give us
   // a background.
   // We don't have any border or outline, and our background draws over
   // the overflow area, so just add nsDisplayCanvasBackground instead of
   // calling DisplayBorderBackgroundOutline.
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -843,24 +843,33 @@ public:
    * NULL pointer if there are no more named child lists.
    *
    * Note that the list is only the additional named child lists and does not
    * include the unnamed principal child list.
    */
   virtual nsIAtom* GetAdditionalChildListName(PRInt32 aIndex) const = 0;
 
   /**
-   * Get the first child frame from the specified child list.
+   * Get the specified child list.
    *
    * @param   aListName the name of the child list. A NULL pointer for the atom
    *            name means the unnamed principal child list
-   * @return  the child frame, or NULL if there is no such child
+   * @return  the child list.  If this is an unknown list name, an empty list
+   *            will be returned.
    * @see     #GetAdditionalListName()
    */
-  virtual nsIFrame* GetFirstChild(nsIAtom* aListName) const = 0;
+  // XXXbz if all our frame storage were actually backed by nsFrameList, we
+  // could make this return a const reference...  nsBlockFrame is the only real
+  // culprit here.  Make sure to assign the return value of this function into
+  // a |const nsFrameList&|, not an nsFrameList.
+  virtual nsFrameList GetChildList(nsIAtom* aListName) const = 0;
+  // XXXbz this method should go away
+  nsIFrame* GetFirstChild(nsIAtom* aListName) const {
+    return GetChildList(aListName).FirstChild();
+  }
 
   /**
    * Get the last child frame from the specified child list.
    *
    * @param   aListName the name of the child list. A NULL pointer for the atom
    *            name means the unnamed principal child list
    * @return  the child frame, or NULL if there is no such child
    * @see     #GetAdditionalListName()
--- a/layout/generic/nsInlineFrame.cpp
+++ b/layout/generic/nsInlineFrame.cpp
@@ -1143,36 +1143,37 @@ nsPositionedInlineFrame::RemoveFrame(nsI
   return rv;
 }
 
 NS_IMETHODIMP
 nsPositionedInlineFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                           const nsRect&           aDirtyRect,
                                           const nsDisplayListSet& aLists)
 {
-  aBuilder->MarkFramesForDisplayList(this, mAbsoluteContainer.GetFirstChild(), aDirtyRect);
+  aBuilder->MarkFramesForDisplayList(this, mAbsoluteContainer.GetChildList(),
+				     aDirtyRect);
   return nsHTMLContainerFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists);
 }
 
 nsIAtom*
 nsPositionedInlineFrame::GetAdditionalChildListName(PRInt32 aIndex) const
 {
   if (0 == aIndex) {
     return nsGkAtoms::absoluteList;
   }
   return nsnull;
 }
 
-nsIFrame*
-nsPositionedInlineFrame::GetFirstChild(nsIAtom* aListName) const
+nsFrameList
+nsPositionedInlineFrame::GetChildList(nsIAtom* aListName) const
 {
   if (nsGkAtoms::absoluteList == aListName)
-    return mAbsoluteContainer.GetFirstChild();
+    return mAbsoluteContainer.GetChildList();
 
-  return nsInlineFrame::GetFirstChild(aListName);
+  return nsInlineFrame::GetChildList(aListName);
 }
 
 nsIAtom*
 nsPositionedInlineFrame::GetType() const
 {
   return nsGkAtoms::positionedInlineFrame;
 }
 
--- a/layout/generic/nsInlineFrame.h
+++ b/layout/generic/nsInlineFrame.h
@@ -267,17 +267,17 @@ public:
                          nsIFrame*       aOldFrame);
 
   NS_IMETHOD BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                               const nsRect&           aDirtyRect,
                               const nsDisplayListSet& aLists);
 
   virtual nsIAtom* GetAdditionalChildListName(PRInt32 aIndex) const;
 
-  virtual nsIFrame* GetFirstChild(nsIAtom* aListName) const;
+  virtual nsFrameList GetChildList(nsIAtom* aListName) const;
 
   NS_IMETHOD Reflow(nsPresContext*          aPresContext,
                     nsHTMLReflowMetrics&     aDesiredSize,
                     const nsHTMLReflowState& aReflowState,
                     nsReflowStatus&          aStatus);
   
   virtual nsIAtom* GetType() const;
 
--- a/layout/generic/nsViewportFrame.cpp
+++ b/layout/generic/nsViewportFrame.cpp
@@ -92,17 +92,18 @@ NS_IMETHODIMP
 ViewportFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists)
 {
   // We don't need any special painting or event handling. We just need to
   // mark our visible out-of-flow frames (i.e., the fixed position frames) so
   // that display list construction is guaranteed to recurse into their
   // ancestors.
-  aBuilder->MarkFramesForDisplayList(this, mFixedContainer.GetFirstChild(), aDirtyRect);
+  aBuilder->MarkFramesForDisplayList(this, mFixedContainer.GetChildList(),
+                                     aDirtyRect);
 
   nsIFrame* kid = mFrames.FirstChild();
   if (!kid)
     return NS_OK;
 
   // make the kid's BorderBackground our own. This ensures that the canvas
   // frame's background becomes our own background and therefore appears
   // below negative z-index elements.
@@ -115,17 +116,17 @@ ViewportFrame::AppendFrames(nsIAtom*    
 {
   nsresult rv = NS_OK;
 
   if (nsGkAtoms::fixedList == aListName) {
     rv = mFixedContainer.AppendFrames(this, aListName, aFrameList);
   }
   else {
     NS_ASSERTION(!aListName, "unexpected child list");
-    NS_ASSERTION(!GetFirstChild(nsnull), "Shouldn't have any kids!");
+    NS_ASSERTION(GetChildList(nsnull).IsEmpty(), "Shouldn't have any kids!");
     rv = nsContainerFrame::AppendFrames(aListName, aFrameList);
   }
 
   return rv;
 }
 
 NS_IMETHODIMP
 ViewportFrame::InsertFrames(nsIAtom*        aListName,
@@ -134,17 +135,17 @@ ViewportFrame::InsertFrames(nsIAtom*    
 {
   nsresult rv = NS_OK;
 
   if (nsGkAtoms::fixedList == aListName) {
     rv = mFixedContainer.InsertFrames(this, aListName, aPrevFrame, aFrameList);
   }
   else {
     NS_ASSERTION(!aListName, "unexpected child list");
-    NS_ASSERTION(!GetFirstChild(nsnull), "Shouldn't have any kids!");
+    NS_ASSERTION(GetChildList(nsnull).IsEmpty(), "Shouldn't have any kids!");
     rv = nsContainerFrame::InsertFrames(aListName, aPrevFrame, aFrameList);
   }
 
   return rv;
 }
 
 NS_IMETHODIMP
 ViewportFrame::RemoveFrame(nsIAtom*        aListName,
@@ -170,23 +171,23 @@ ViewportFrame::GetAdditionalChildListNam
 
   if (0 == aIndex) {
     return nsGkAtoms::fixedList;
   }
 
   return nsnull;
 }
 
-nsIFrame*
-ViewportFrame::GetFirstChild(nsIAtom* aListName) const
+nsFrameList
+ViewportFrame::GetChildList(nsIAtom* aListName) const
 {
   if (nsGkAtoms::fixedList == aListName)
-    return mFixedContainer.GetFirstChild();
+    return mFixedContainer.GetChildList();
 
-  return nsContainerFrame::GetFirstChild(aListName);
+  return nsContainerFrame::GetChildList(aListName);
 }
 
 /* virtual */ nscoord
 ViewportFrame::GetMinWidth(nsIRenderingContext *aRenderingContext)
 {
   nscoord result;
   DISPLAY_MIN_WIDTH(this, result);
   if (mFrames.IsEmpty())
@@ -299,18 +300,18 @@ ViewportFrame::Reflow(nsPresContext*    
                           : kidHeight;
 
   // Make a copy of the reflow state and change the computed width and height
   // to reflect the available space for the fixed items
   nsHTMLReflowState reflowState(aReflowState);
   nsPoint offset = AdjustReflowStateForScrollbars(&reflowState);
   
 #ifdef DEBUG
-  nsIFrame* f = mFixedContainer.GetFirstChild();
-  NS_ASSERTION(!f || (offset.x == 0 && offset.y == 0),
+  NS_ASSERTION(mFixedContainer.GetChildList().IsEmpty() ||
+               (offset.x == 0 && offset.y == 0),
                "We don't handle correct positioning of fixed frames with "
                "scrollbars in odd positions");
 #endif
 
   // Just reflow all the fixed-pos frames.
   rv = mFixedContainer.Reflow(this, aPresContext, reflowState, aStatus,
                               reflowState.ComputedWidth(),
                               reflowState.ComputedHeight(),
--- a/layout/generic/nsViewportFrame.h
+++ b/layout/generic/nsViewportFrame.h
@@ -81,17 +81,17 @@ public:
                           nsIFrame*       aPrevFrame,
                           nsIFrame*       aFrameList);
 
   NS_IMETHOD RemoveFrame(nsIAtom*        aListName,
                          nsIFrame*       aOldFrame);
 
   virtual nsIAtom* GetAdditionalChildListName(PRInt32 aIndex) const;
 
-  virtual nsIFrame* GetFirstChild(nsIAtom* aListName) const;
+  virtual nsFrameList GetChildList(nsIAtom* aListName) const;
 
   NS_IMETHOD BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                               const nsRect&           aDirtyRect,
                               const nsDisplayListSet& aLists);
 
   virtual nscoord GetMinWidth(nsIRenderingContext *aRenderingContext);
   virtual nscoord GetPrefWidth(nsIRenderingContext *aRenderingContext);
   NS_IMETHOD Reflow(nsPresContext*          aPresContext,
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -1209,24 +1209,24 @@ nsTableFrame::InsertRowGroups(nsIFrame* 
   Dump(PR_TRUE, PR_TRUE, PR_TRUE);
 #endif
 }
 
 
 /////////////////////////////////////////////////////////////////////////////
 // Child frame enumeration
 
-nsIFrame*
-nsTableFrame::GetFirstChild(nsIAtom* aListName) const
+nsFrameList
+nsTableFrame::GetChildList(nsIAtom* aListName) const
 {
   if (aListName == nsGkAtoms::colGroupList) {
-    return mColGroups.FirstChild();
-  }
-
-  return nsHTMLContainerFrame::GetFirstChild(aListName);
+    return mColGroups;
+  }
+
+  return nsHTMLContainerFrame::GetChildList(aListName);
 }
 
 nsIAtom*
 nsTableFrame::GetAdditionalChildListName(PRInt32 aIndex) const
 {
   if (aIndex == NS_TABLE_FRAME_COLGROUP_LIST_INDEX) {
     return nsGkAtoms::colGroupList;
   }
--- a/layout/tables/nsTableFrame.h
+++ b/layout/tables/nsTableFrame.h
@@ -255,20 +255,17 @@ public:
   PRBool IsRowGroup(PRInt32 aDisplayType) const;
 
   /** Initialize the table frame with a set of children.
     * @see nsIFrame::SetInitialChildList 
     */
   NS_IMETHOD SetInitialChildList(nsIAtom*        aListName,
                                  nsIFrame*       aChildList);
 
-  /** return the first child belonging to the list aListName. 
-    * @see nsIFrame::GetFirstChild
-    */
-  virtual nsIFrame* GetFirstChild(nsIAtom* aListName) const;
+  virtual nsFrameList GetChildList(nsIAtom* aListName) const;
 
   /** @see nsIFrame::GetAdditionalChildListName */
   virtual nsIAtom* GetAdditionalChildListName(PRInt32 aIndex) const;
 
   NS_IMETHOD BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                               const nsRect&           aDirtyRect,
                               const nsDisplayListSet& aLists);
 
--- a/layout/tables/nsTableOuterFrame.cpp
+++ b/layout/tables/nsTableOuterFrame.cpp
@@ -210,26 +210,26 @@ nsTableOuterFrame::IsContainingBlock() c
 
 void
 nsTableOuterFrame::Destroy()
 {
   mCaptionFrames.DestroyFrames();
   nsHTMLContainerFrame::Destroy();
 }
 
-nsIFrame*
-nsTableOuterFrame::GetFirstChild(nsIAtom* aListName) const
+nsFrameList
+nsTableOuterFrame::GetChildList(nsIAtom* aListName) const
 {
   if (nsGkAtoms::captionList == aListName) {
-    return mCaptionFrames.FirstChild();
+    return mCaptionFrames;
   }
   if (!aListName) {
-    return mFrames.FirstChild();
+    return mFrames;
   }
-  return nsnull;
+  return nsFrameList::EmptyList();
 }
 
 nsIAtom*
 nsTableOuterFrame::GetAdditionalChildListName(PRInt32 aIndex) const
 {
   if (aIndex == NS_TABLE_FRAME_CAPTION_LIST_INDEX) {
     return nsGkAtoms::captionList;
   }
--- a/layout/tables/nsTableOuterFrame.h
+++ b/layout/tables/nsTableOuterFrame.h
@@ -100,17 +100,17 @@ public:
 
   virtual void Destroy();
   
   virtual PRBool IsContainingBlock() const;
 
   NS_IMETHOD SetInitialChildList(nsIAtom*        aListName,
                                  nsIFrame*       aChildList);
  
-  virtual nsIFrame* GetFirstChild(nsIAtom* aListName) const;
+  virtual nsFrameList GetChildList(nsIAtom* aListName) const;
 
   virtual nsIAtom* GetAdditionalChildListName(PRInt32 aIndex) const;
 
   NS_IMETHOD AppendFrames(nsIAtom*        aListName,
                           nsIFrame*       aFrameList);
 
   NS_IMETHOD InsertFrames(nsIAtom*        aListName,
                           nsIFrame*       aPrevFrame,
--- a/layout/xul/base/src/nsMenuFrame.cpp
+++ b/layout/xul/base/src/nsMenuFrame.cpp
@@ -320,23 +320,23 @@ nsMenuFrame::~nsMenuFrame()
     gAltText = nsnull;
     delete gModifierSeparator;
     gModifierSeparator = nsnull;
   }
 }
 
 // The following methods are all overridden to ensure that the menupopup frame
 // is placed in the appropriate list.
-nsIFrame*
-nsMenuFrame::GetFirstChild(nsIAtom* aListName) const
+nsFrameList
+nsMenuFrame::GetChildList(nsIAtom* aListName) const
 {
   if (nsGkAtoms::popupList == aListName) {
     return mPopupFrame;
   }
-  return nsBoxFrame::GetFirstChild(aListName);
+  return nsBoxFrame::GetChildList(aListName);
 }
 
 nsIFrame*
 nsMenuFrame::SetPopupFrame(nsIFrame* aChildList)
 {
   // Check for a menupopup and move it to mPopupFrame
   nsFrameList frames(aChildList);
   nsIFrame* frame = frames.FirstChild();
--- a/layout/xul/base/src/nsMenuFrame.h
+++ b/layout/xul/base/src/nsMenuFrame.h
@@ -125,17 +125,17 @@ public:
   NS_IMETHOD SetDebug(nsBoxLayoutState& aState, PRBool aDebug);
 #endif
 
   NS_IMETHOD IsActive(PRBool& aResult) { aResult = PR_TRUE; return NS_OK; }
 
   // The following methods are all overridden so that the menupopup
   // can be stored in a separate list, so that it doesn't impact reflow of the
   // actual menu item at all.
-  virtual nsIFrame* GetFirstChild(nsIAtom* aListName) const;
+  virtual nsFrameList GetChildList(nsIAtom* aListName) const;
   NS_IMETHOD SetInitialChildList(nsIAtom*        aListName,
                                  nsIFrame*       aChildList);
   virtual nsIAtom* GetAdditionalChildListName(PRInt32 aIndex) const;
   virtual void Destroy();
 
   // Overridden to prevent events from going to children of the menu.
   NS_IMETHOD BuildDisplayListForChildren(nsDisplayListBuilder*   aBuilder,
                                          const nsRect&           aDirtyRect,