Bug 508665 - part 4, Make nsCSSFrameConstructor use nsContainerFrame* for frames used as parent frames. r=roc
authorMats Palmgren <matspal@gmail.com>
Sat, 24 May 2014 22:20:40 +0000
changeset 184828 8aa36dab27656347b615b29223d26f4294b73e83
parent 184827 75c14b62556ece809d3c47612b6ed2948e29a35f
child 184829 18214a2cfdb3eea37354959ab6fae5b97bc4a1ee
push id43946
push usermpalmgren@mozilla.com
push dateSat, 24 May 2014 22:20:59 +0000
treeherdermozilla-inbound@db861719b5d0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs508665
milestone32.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 508665 - part 4, Make nsCSSFrameConstructor use nsContainerFrame* for frames used as parent frames. r=roc
layout/base/nsBidiPresUtils.cpp
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsCSSFrameConstructor.h
layout/forms/nsComboboxControlFrame.cpp
layout/forms/nsComboboxControlFrame.h
layout/forms/nsFieldSetFrame.cpp
layout/forms/nsGfxButtonControlFrame.cpp
layout/forms/nsHTMLButtonControlFrame.cpp
layout/forms/nsListControlFrame.cpp
layout/forms/nsListControlFrame.h
layout/forms/nsSelectsAreaFrame.cpp
layout/forms/nsSelectsAreaFrame.h
layout/generic/nsCanvasFrame.cpp
layout/generic/nsColumnSetFrame.cpp
layout/generic/nsFirstLetterFrame.cpp
layout/generic/nsFlexContainerFrame.cpp
layout/generic/nsFlexContainerFrame.h
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsGfxScrollFrame.h
layout/generic/nsGridContainerFrame.cpp
layout/generic/nsGridContainerFrame.h
layout/generic/nsHTMLParts.h
layout/generic/nsInlineFrame.cpp
layout/generic/nsInlineFrame.h
layout/generic/nsPageContentFrame.cpp
layout/generic/nsPageContentFrame.h
layout/generic/nsPageFrame.cpp
layout/generic/nsPageFrame.h
layout/generic/nsSimplePageSequenceFrame.cpp
layout/generic/nsSimplePageSequenceFrame.h
layout/generic/nsViewportFrame.cpp
layout/mathml/nsMathMLParts.h
layout/mathml/nsMathMLmtableFrame.cpp
layout/mathml/nsMathMLmtableFrame.h
layout/svg/nsSVGForeignObjectFrame.cpp
layout/svg/nsSVGForeignObjectFrame.h
layout/svg/nsSVGMarkerFrame.cpp
layout/svg/nsSVGMarkerFrame.h
layout/svg/nsSVGOuterSVGFrame.cpp
layout/svg/nsSVGOuterSVGFrame.h
layout/tables/nsTableCellFrame.cpp
layout/tables/nsTableColGroupFrame.cpp
layout/tables/nsTableColGroupFrame.h
layout/tables/nsTableFrame.cpp
layout/tables/nsTableFrame.h
layout/tables/nsTableOuterFrame.cpp
layout/tables/nsTableOuterFrame.h
layout/tables/nsTableRowFrame.cpp
layout/tables/nsTableRowFrame.h
layout/tables/nsTableRowGroupFrame.cpp
layout/tables/nsTableRowGroupFrame.h
layout/xul/nsDocElementBoxFrame.cpp
layout/xul/nsRootBoxFrame.cpp
--- a/layout/base/nsBidiPresUtils.cpp
+++ b/layout/base/nsBidiPresUtils.cpp
@@ -428,17 +428,17 @@ SplitInlineAncestors(nsIFrame* aParent,
 {
   nsPresContext *presContext = aParent->PresContext();
   nsIPresShell *presShell = presContext->PresShell();
   nsIFrame* frame = aFrame;
   nsIFrame* parent = aParent;
   nsIFrame* newParent;
 
   while (IsBidiSplittable(parent)) {
-    nsIFrame* grandparent = parent->GetParent();
+    nsContainerFrame* grandparent = parent->GetParent();
     NS_ASSERTION(grandparent, "Couldn't get parent's parent in nsBidiPresUtils::SplitInlineAncestors");
     
     // Split the child list after |frame|, unless it is the last child.
     if (!frame || frame->GetNextSibling()) {
     
       newParent = presShell->FrameConstructor()->
         CreateContinuingFrame(presContext, parent, grandparent, false);
 
@@ -535,17 +535,17 @@ CreateContinuation(nsIFrame*  aFrame,
   NS_PRECONDITION(aFrame, "null ptr");
 
   *aNewFrame = nullptr;
 
   nsPresContext *presContext = aFrame->PresContext();
   nsIPresShell *presShell = presContext->PresShell();
   NS_ASSERTION(presShell, "PresShell must be set on PresContext before calling nsBidiPresUtils::CreateContinuation");
 
-  nsIFrame* parent = aFrame->GetParent();
+  nsContainerFrame* parent = aFrame->GetParent();
   NS_ASSERTION(parent, "Couldn't get frame parent in nsBidiPresUtils::CreateContinuation");
 
   nsresult rv = NS_OK;
   
   // Have to special case floating first letter frames because the continuation
   // doesn't go in the first letter frame. The continuation goes with the rest
   // of the text that the first letter frame was made out of.
   if (parent->GetType() == nsGkAtoms::letterFrame &&
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -20,16 +20,18 @@
 #include "nsAbsoluteContainingBlock.h"
 #include "nsIAtom.h"
 #include "nsIFrameInlines.h"
 #include "nsGkAtoms.h"
 #include "nsPresContext.h"
 #include "nsIDocument.h"
 #include "nsTableFrame.h"
 #include "nsTableColFrame.h"
+#include "nsTableRowFrame.h"
+#include "nsTableCellFrame.h"
 #include "nsIDOMHTMLDocument.h"
 #include "nsHTMLParts.h"
 #include "nsIPresShell.h"
 #include "nsUnicharUtils.h"
 #include "nsStyleSet.h"
 #include "nsViewManager.h"
 #include "nsStyleConsts.h"
 #include "nsIDOMXULElement.h"
@@ -66,28 +68,32 @@
 #include "mozilla/dom/Element.h"
 #include "nsAutoLayoutPhase.h"
 #include "nsStyleStructInlines.h"
 #include "nsPageContentFrame.h"
 #include "RestyleManager.h"
 #include "StickyScrollContainer.h"
 #include "nsFieldSetFrame.h"
 #include "nsInlineFrame.h"
+#include "nsBlockFrame.h"
+#include "nsCanvasFrame.h"
+#include "nsFirstLetterFrame.h"
+#include "nsGfxScrollFrame.h"
+#include "nsPageFrame.h"
+#include "nsSimplePageSequenceFrame.h"
+#include "nsTableOuterFrame.h"
+#include "nsIScrollableFrame.h"
 
 #ifdef MOZ_XUL
 #include "nsIRootBox.h"
 #endif
 #ifdef ACCESSIBILITY
 #include "nsAccessibilityService.h"
 #endif
 
-#include "nsBlockFrame.h"
-
-#include "nsIScrollableFrame.h"
-
 #include "nsXBLService.h"
 
 #undef NOISY_FIRST_LETTER
 
 #include "nsMathMLParts.h"
 #include "mozilla/dom/SVGTests.h"
 #include "nsSVGUtils.h"
 
@@ -103,29 +109,29 @@ using namespace mozilla::dom;
 static const nsIFrame::ChildListID kPrincipalList = nsIFrame::kPrincipalList;
 
 nsIFrame*
 NS_NewHTMLCanvasFrame (nsIPresShell* aPresShell, nsStyleContext* aContext);
 
 nsIFrame*
 NS_NewHTMLVideoFrame (nsIPresShell* aPresShell, nsStyleContext* aContext);
 
-nsIFrame*
+nsContainerFrame*
 NS_NewSVGOuterSVGFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
-nsIFrame*
+nsContainerFrame*
 NS_NewSVGOuterSVGAnonChildFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewSVGInnerSVGFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewSVGPathGeometryFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewSVGGFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewSVGGenericContainerFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
-nsIFrame*
+nsContainerFrame*
 NS_NewSVGForeignObjectFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewSVGAFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewSVGSwitchFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewSVGTextFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
@@ -135,19 +141,19 @@ NS_NewSVGUseFrame(nsIPresShell* aPresShe
 nsIFrame*
 NS_NewSVGViewFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 extern nsIFrame*
 NS_NewSVGLinearGradientFrame(nsIPresShell *aPresShell, nsStyleContext* aContext);
 extern nsIFrame*
 NS_NewSVGRadialGradientFrame(nsIPresShell *aPresShell, nsStyleContext* aContext);
 extern nsIFrame*
 NS_NewSVGStopFrame(nsIPresShell *aPresShell, nsStyleContext* aContext);
-nsIFrame*
+nsContainerFrame*
 NS_NewSVGMarkerFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
-nsIFrame*
+nsContainerFrame*
 NS_NewSVGMarkerAnonChildFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 extern nsIFrame*
 NS_NewSVGImageFrame(nsIPresShell *aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewSVGClipPathFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewSVGFilterFrame(nsIPresShell *aPresShell, nsStyleContext* aContext);
 nsIFrame*
@@ -201,20 +207,20 @@ static FrameCtorDebugFlags gFlags[] = {
 #include "nsListItemFrame.h"
 #include "nsXULLabelFrame.h"
 
 //------------------------------------------------------------------
 
 nsIFrame*
 NS_NewAutoRepeatBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
-nsIFrame*
+nsContainerFrame*
 NS_NewRootBoxFrame (nsIPresShell* aPresShell, nsStyleContext* aContext);
 
-nsIFrame*
+nsContainerFrame*
 NS_NewDocElementBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
 nsIFrame*
 NS_NewThumbFrame (nsIPresShell* aPresShell, nsStyleContext* aContext);
 
 nsIFrame*
 NS_NewDeckFrame (nsIPresShell* aPresShell, nsStyleContext* aContext);
 
@@ -274,22 +280,22 @@ nsIFrame*
 NS_NewTitleBarFrame (nsIPresShell* aPresShell, nsStyleContext* aContext);
 
 nsIFrame*
 NS_NewResizerFrame (nsIPresShell* aPresShell, nsStyleContext* aContext);
 
 
 #endif
 
-nsIFrame*
-NS_NewHTMLScrollFrame (nsIPresShell* aPresShell, nsStyleContext* aContext, bool aIsRoot);
-
-nsIFrame*
-NS_NewXULScrollFrame (nsIPresShell* aPresShell, nsStyleContext* aContext,
-                      bool aIsRoot, bool aClipAllDescendants);
+nsHTMLScrollFrame*
+NS_NewHTMLScrollFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, bool aIsRoot);
+
+nsXULScrollFrame*
+NS_NewXULScrollFrame(nsIPresShell* aPresShell, nsStyleContext* aContext,
+                     bool aIsRoot, bool aClipAllDescendants);
 
 nsIFrame*
 NS_NewSliderFrame (nsIPresShell* aPresShell, nsStyleContext* aContext);
 
 nsIFrame*
 NS_NewScrollbarFrame (nsIPresShell* aPresShell, nsStyleContext* aContext);
 
 nsIFrame*
@@ -479,17 +485,17 @@ GetLastIBSplitSibling(nsIFrame* aFrame, 
       return static_cast<nsContainerFrame*>(frame);
     }
   }
   NS_NOTREACHED("unreachable code");
   return nullptr;
 }
 
 static void
-SetFrameIsIBSplit(nsIFrame* aFrame, nsIFrame* aIBSplitSibling)
+SetFrameIsIBSplit(nsContainerFrame* aFrame, nsIFrame* aIBSplitSibling)
 {
   NS_PRECONDITION(aFrame, "bad args!");
 
   // We should be the only continuation
   NS_ASSERTION(!aFrame->GetPrevContinuation(),
                "assigning ib-split sibling to other than first continuation!");
   NS_ASSERTION(!aFrame->GetNextContinuation() ||
                IsFramePartOfIBSplit(aFrame->GetNextContinuation()),
@@ -645,34 +651,34 @@ nsFrameItems::AddChild(nsIFrame* aChild)
 }
 
 // -----------------------------------------------------------
 
 // Structure used when constructing formatting object trees. Contains
 // state information needed for absolutely positioned elements
 struct nsAbsoluteItems : nsFrameItems {
   // containing block for absolutely positioned elements
-  nsIFrame* containingBlock;
-
-  nsAbsoluteItems(nsIFrame* aContainingBlock);
+  nsContainerFrame* containingBlock;
+
+  nsAbsoluteItems(nsContainerFrame* aContainingBlock);
 #ifdef DEBUG
   // XXXbz Does this need a debug-only assignment operator that nulls out the
   // childList in the nsAbsoluteItems we're copying?  Introducing a difference
   // between debug and non-debug behavior seems bad, so I guess not...
   ~nsAbsoluteItems() {
     NS_ASSERTION(!FirstChild(),
                  "Dangling child list.  Someone forgot to insert it?");
   }
 #endif
 
   // Appends the frame to the end of the list
   void AddChild(nsIFrame* aChild);
 };
 
-nsAbsoluteItems::nsAbsoluteItems(nsIFrame* aContainingBlock)
+nsAbsoluteItems::nsAbsoluteItems(nsContainerFrame* aContainingBlock)
   : containingBlock(aContainingBlock)
 {
 }
 
 // Additional behavior is that it sets the frame's NS_FRAME_OUT_OF_FLOW flag
 void
 nsAbsoluteItems::AddChild(nsIFrame* aChild)
 {
@@ -775,56 +781,56 @@ public:
 
   nsCOMArray<nsIContent>    mGeneratedTextNodesWithInitializer;
 
   TreeMatchContext          mTreeMatchContext;
 
   // Constructor
   // Use the passed-in history state.
   nsFrameConstructorState(nsIPresShell*          aPresShell,
-                          nsIFrame*              aFixedContainingBlock,
-                          nsIFrame*              aAbsoluteContainingBlock,
-                          nsIFrame*              aFloatContainingBlock,
+                          nsContainerFrame*      aFixedContainingBlock,
+                          nsContainerFrame*      aAbsoluteContainingBlock,
+                          nsContainerFrame*      aFloatContainingBlock,
                           nsILayoutHistoryState* aHistoryState);
   // Get the history state from the pres context's pres shell.
   nsFrameConstructorState(nsIPresShell*          aPresShell,
-                          nsIFrame*              aFixedContainingBlock,
-                          nsIFrame*              aAbsoluteContainingBlock,
-                          nsIFrame*              aFloatContainingBlock);
+                          nsContainerFrame*      aFixedContainingBlock,
+                          nsContainerFrame*      aAbsoluteContainingBlock,
+                          nsContainerFrame*      aFloatContainingBlock);
 
   ~nsFrameConstructorState();
 
   // Function to push the existing absolute containing block state and
   // create a new scope. Code that uses this function should get matching
   // logic in GetAbsoluteContainingBlock.
   // Also makes aNewAbsoluteContainingBlock the containing block for
   // fixed-pos elements if necessary.
   // aPositionedFrame is the frame whose style actually makes
   // aNewAbsoluteContainingBlock a containing block. E.g. for a scrollable element
   // aPositionedFrame is the element's primary frame and
   // aNewAbsoluteContainingBlock is the scrolled frame.
-  void PushAbsoluteContainingBlock(nsIFrame* aNewAbsoluteContainingBlock,
+  void PushAbsoluteContainingBlock(nsContainerFrame* aNewAbsoluteContainingBlock,
                                    nsIFrame* aPositionedFrame,
                                    nsFrameConstructorSaveState& aSaveState);
 
   // Function to push the existing float containing block state and
   // create a new scope. Code that uses this function should get matching
   // logic in GetFloatContainingBlock.
   // Pushing a null float containing block forbids any frames from being
   // floated until a new float containing block is pushed.
   // XXX we should get rid of null float containing blocks and teach the
   // various frame classes to deal with floats instead.
-  void PushFloatContainingBlock(nsIFrame* aNewFloatContainingBlock,
+  void PushFloatContainingBlock(nsContainerFrame* aNewFloatContainingBlock,
                                 nsFrameConstructorSaveState& aSaveState);
 
   // Function to return the proper geometric parent for a frame with display
   // struct given by aStyleDisplay and parent's frame given by
   // aContentParentFrame.
-  nsIFrame* GetGeometricParent(const nsStyleDisplay* aStyleDisplay,
-                               nsIFrame* aContentParentFrame) const;
+  nsContainerFrame* GetGeometricParent(const nsStyleDisplay* aStyleDisplay,
+                                       nsContainerFrame* aContentParentFrame) const;
 
   /**
    * Function to add a new frame to the right frame list.  This MUST be called
    * on frames before their children have been processed if the frames might
    * conceivably be out-of-flow; otherwise cleanup in error cases won't work
    * right.  Also, this MUST be called on frames after they have been
    * initialized.
    * @param aNewFrame the frame to add
@@ -838,17 +844,17 @@ public:
    *        floated
    * @param aIsOutOfFlowPopup pass true if the frame is an out-of-flow popup
    *        (XUL-only)
    */
   void AddChild(nsIFrame* aNewFrame,
                 nsFrameItems& aFrameItems,
                 nsIContent* aContent,
                 nsStyleContext* aStyleContext,
-                nsIFrame* aParentFrame,
+                nsContainerFrame* aParentFrame,
                 bool aCanBePositioned = true,
                 bool aCanBeFloated = true,
                 bool aIsOutOfFlowPopup = false,
                 bool aInsertAfter = false,
                 nsIFrame* aInsertAfterFrame = nullptr);
 
   /**
    * Function to return the fixed-pos element list.  Normally this will just hand back the
@@ -919,19 +925,19 @@ protected:
   // Our list of all pending bindings.  When we're done, we need to call
   // AddToAttachedQueue on all of them, in order.
   LinkedList<PendingBinding> mPendingBindings;
 
   PendingBinding* mCurrentPendingBindingInsertionPoint;
 };
 
 nsFrameConstructorState::nsFrameConstructorState(nsIPresShell*          aPresShell,
-                                                 nsIFrame*              aFixedContainingBlock,
-                                                 nsIFrame*              aAbsoluteContainingBlock,
-                                                 nsIFrame*              aFloatContainingBlock,
+                                                 nsContainerFrame*      aFixedContainingBlock,
+                                                 nsContainerFrame*      aAbsoluteContainingBlock,
+                                                 nsContainerFrame*      aFloatContainingBlock,
                                                  nsILayoutHistoryState* aHistoryState)
   : mPresContext(aPresShell->GetPresContext()),
     mPresShell(aPresShell),
     mFrameManager(aPresShell->FrameManager()),
 #ifdef MOZ_XUL
     mPopupItems(nullptr),
 #endif
     mFixedItems(aFixedContainingBlock),
@@ -955,19 +961,19 @@ nsFrameConstructorState::nsFrameConstruc
   if (rootBox) {
     mPopupItems.containingBlock = rootBox->GetPopupSetFrame();
   }
 #endif
   MOZ_COUNT_CTOR(nsFrameConstructorState);
 }
 
 nsFrameConstructorState::nsFrameConstructorState(nsIPresShell* aPresShell,
-                                                 nsIFrame*     aFixedContainingBlock,
-                                                 nsIFrame*     aAbsoluteContainingBlock,
-                                                 nsIFrame*     aFloatContainingBlock)
+                                                 nsContainerFrame* aFixedContainingBlock,
+                                                 nsContainerFrame* aAbsoluteContainingBlock,
+                                                 nsContainerFrame* aFloatContainingBlock)
   : mPresContext(aPresShell->GetPresContext()),
     mPresShell(aPresShell),
     mFrameManager(aPresShell->FrameManager()),
 #ifdef MOZ_XUL
     mPopupItems(nullptr),
 #endif
     mFixedItems(aFixedContainingBlock),
     mAbsoluteItems(aAbsoluteContainingBlock),
@@ -1021,30 +1027,30 @@ nsFrameConstructorState::~nsFrameConstru
       nsAutoPtr<PendingBinding> pendingBinding;
       pendingBinding = mPendingBindings.popFirst();
       bindingManager->AddToAttachedQueue(pendingBinding->mBinding);
     } while (!mPendingBindings.isEmpty());
     mCurrentPendingBindingInsertionPoint = nullptr;
   }
 }
 
-static nsIFrame*
-AdjustAbsoluteContainingBlock(nsIFrame* aContainingBlockIn)
+static nsContainerFrame*
+AdjustAbsoluteContainingBlock(nsContainerFrame* aContainingBlockIn)
 {
   if (!aContainingBlockIn) {
     return nullptr;
   }
 
   // Always use the container's first continuation. (Inline frames can have
   // non-fluid bidi continuations...)
-  return aContainingBlockIn->FirstContinuation();
+  return static_cast<nsContainerFrame*>(aContainingBlockIn->FirstContinuation());
 }
 
 void
-nsFrameConstructorState::PushAbsoluteContainingBlock(nsIFrame* aNewAbsoluteContainingBlock,
+nsFrameConstructorState::PushAbsoluteContainingBlock(nsContainerFrame* aNewAbsoluteContainingBlock,
                                                      nsIFrame* aPositionedFrame,
                                                      nsFrameConstructorSaveState& aSaveState)
 {
   aSaveState.mItems = &mAbsoluteItems;
   aSaveState.mSavedItems = mAbsoluteItems;
   aSaveState.mChildListID = nsIFrame::kAbsoluteList;
   aSaveState.mState = this;
   aSaveState.mSavedFixedPosIsAbsPos = mFixedPosIsAbsPos;
@@ -1067,36 +1073,36 @@ nsFrameConstructorState::PushAbsoluteCon
        aPositionedFrame->StyleDisplay()->HasPerspectiveStyle());
 
   if (aNewAbsoluteContainingBlock) {
     aNewAbsoluteContainingBlock->MarkAsAbsoluteContainingBlock();
   }
 }
 
 void
-nsFrameConstructorState::PushFloatContainingBlock(nsIFrame* aNewFloatContainingBlock,
+nsFrameConstructorState::PushFloatContainingBlock(nsContainerFrame* aNewFloatContainingBlock,
                                                   nsFrameConstructorSaveState& aSaveState)
 {
   NS_PRECONDITION(!aNewFloatContainingBlock ||
                   aNewFloatContainingBlock->IsFloatContainingBlock(),
                   "Please push a real float containing block!");
   NS_ASSERTION(!aNewFloatContainingBlock ||
                !ShouldSuppressFloatingOfDescendants(aNewFloatContainingBlock),
                "We should not push a frame that is supposed to _suppress_ "
                "floats as a float containing block!");
   aSaveState.mItems = &mFloatedItems;
   aSaveState.mSavedItems = mFloatedItems;
   aSaveState.mChildListID = nsIFrame::kFloatList;
   aSaveState.mState = this;
   mFloatedItems = nsAbsoluteItems(aNewFloatContainingBlock);
 }
 
-nsIFrame*
+nsContainerFrame*
 nsFrameConstructorState::GetGeometricParent(const nsStyleDisplay* aStyleDisplay,
-                                            nsIFrame* aContentParentFrame) const
+                                            nsContainerFrame* aContentParentFrame) const
 {
   NS_PRECONDITION(aStyleDisplay, "Must have display struct!");
 
   // If there is no container for a fixed, absolute, or floating root
   // frame, we will ignore the positioning.  This hack is originally
   // brought to you by the letter T: tables, since other roots don't
   // even call into this code.  See bug 178855.
   //
@@ -1134,17 +1140,17 @@ nsFrameConstructorState::GetGeometricPar
   return aContentParentFrame;
 }
 
 void
 nsFrameConstructorState::AddChild(nsIFrame* aNewFrame,
                                   nsFrameItems& aFrameItems,
                                   nsIContent* aContent,
                                   nsStyleContext* aStyleContext,
-                                  nsIFrame* aParentFrame,
+                                  nsContainerFrame* aParentFrame,
                                   bool aCanBePositioned,
                                   bool aCanBeFloated,
                                   bool aIsOutOfFlowPopup,
                                   bool aInsertAfter,
                                   nsIFrame* aInsertAfterFrame)
 {
   NS_PRECONDITION(!aNewFrame->GetNextSibling(), "Shouldn't happen");
 
@@ -1429,28 +1435,28 @@ bool IsBorderCollapse(nsIFrame* aFrame)
 // bits from aOldParent to aNewParent and then use the
 // nsFrameList::ApplySetParent?  That would still leave us doing two passes
 // over the list, of course; if we really wanted to we could factor out the
 // relevant part of ReparentFrameViewList, I suppose...  Or just get rid of
 // views, which would make most of this function go away.
 static void
 MoveChildrenTo(nsPresContext* aPresContext,
                nsIFrame* aOldParent,
-               nsIFrame* aNewParent,
+               nsContainerFrame* aNewParent,
                nsFrameList& aFrameList)
 {
   bool sameGrandParent = aOldParent->GetParent() == aNewParent->GetParent();
 
   if (aNewParent->HasView() || aOldParent->HasView() || !sameGrandParent) {
     // Move the frames into the new view
     nsContainerFrame::ReparentFrameViewList(aFrameList, aOldParent, aNewParent);
   }
 
   for (nsFrameList::Enumerator e(aFrameList); !e.AtEnd(); e.Next()) {
-    e.get()->SetParent(static_cast<nsContainerFrame*>(aNewParent)); // XXX static_cast will be removed in a later patch
+    e.get()->SetParent(aNewParent);
   }
 
   if (aNewParent->PrincipalChildList().IsEmpty() &&
       (aNewParent->GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
     aNewParent->SetInitialChildList(kPrincipalList, aFrameList);
   } else {
     aNewParent->AppendFrames(kPrincipalList, aFrameList);
   }
@@ -1746,17 +1752,17 @@ nsCSSFrameConstructor::CreateGeneratedCo
  * create a DOM node for each 'content' item and make those nodes the
  * children of the XML element. Then we create a frame subtree for
  * the XML element as if it were a regular child of
  * aParentFrame/aParentContent, giving the XML element the ::before or
  * ::after style.
  */
 void
 nsCSSFrameConstructor::CreateGeneratedContentItem(nsFrameConstructorState& aState,
-                                                  nsIFrame*        aParentFrame,
+                                                  nsContainerFrame* aParentFrame,
                                                   nsIContent*      aParentContent,
                                                   nsStyleContext*  aStyleContext,
                                                   nsCSSPseudoElements::Type aPseudoElement,
                                                   FrameConstructionItemList& aItems)
 {
   // XXXbz is this ever true?
   if (!aParentContent->IsElement()) {
     NS_ERROR("Bogus generated content parent");
@@ -1861,59 +1867,59 @@ nsCSSFrameConstructor::GetParentType(nsI
   }
   if (aFrameType == nsGkAtoms::tableColGroupFrame) {
     return eTypeColGroup;
   }
 
   return eTypeBlock;
 }
 
-static nsIFrame*
-AdjustCaptionParentFrame(nsIFrame* aParentFrame)
+static nsContainerFrame*
+AdjustCaptionParentFrame(nsContainerFrame* aParentFrame)
 {
   if (nsGkAtoms::tableFrame == aParentFrame->GetType()) {
-    return aParentFrame->GetParent();;
+    return aParentFrame->GetParent();
   }
   return aParentFrame;
 }
 
 /**
  * If the parent frame is a |tableFrame| and the child is a
  * |captionFrame|, then we want to insert the frames beneath the
  * |tableFrame|'s parent frame. Returns |true| if the parent frame
  * needed to be fixed up.
  */
 static bool
-GetCaptionAdjustedParent(nsIFrame*        aParentFrame,
-                         const nsIFrame*  aChildFrame,
-                         nsIFrame**       aAdjParentFrame)
+GetCaptionAdjustedParent(nsContainerFrame*  aParentFrame,
+                         const nsIFrame*    aChildFrame,
+                         nsContainerFrame** aAdjParentFrame)
 {
   *aAdjParentFrame = aParentFrame;
   bool haveCaption = false;
 
   if (nsGkAtoms::tableCaptionFrame == aChildFrame->GetType()) {
     haveCaption = true;
-    *aAdjParentFrame = AdjustCaptionParentFrame(aParentFrame);
+    *aAdjParentFrame = ::AdjustCaptionParentFrame(aParentFrame);
   }
   return haveCaption;
 }
 
 void
-nsCSSFrameConstructor::AdjustParentFrame(nsIFrame* &                  aParentFrame,
+nsCSSFrameConstructor::AdjustParentFrame(nsContainerFrame**           aParentFrame,
                                          const FrameConstructionData* aFCData,
                                          nsStyleContext*              aStyleContext)
 {
   NS_PRECONDITION(aStyleContext, "Must have child's style context");
   NS_PRECONDITION(aFCData, "Must have frame construction data");
 
   bool tablePart = ((aFCData->mBits & FCDATA_IS_TABLE_PART) != 0);
 
   if (tablePart && aStyleContext->StyleDisplay()->mDisplay ==
       NS_STYLE_DISPLAY_TABLE_CAPTION) {
-    aParentFrame = AdjustCaptionParentFrame(aParentFrame);
+    *aParentFrame = ::AdjustCaptionParentFrame(*aParentFrame);
   }
 }
 
 // Pull all the captions present in aItems out  into aCaptions
 static void
 PullOutCaptionFrames(nsFrameItems& aItems, nsFrameItems& aCaptions)
 {
   nsIFrame *child = aItems.FirstChild();
@@ -1930,17 +1936,17 @@ PullOutCaptionFrames(nsFrameItems& aItem
 
 // Construct the outer, inner table frames and the children frames for the table.
 // XXX Page break frames for pseudo table frames are not constructed to avoid the risk
 // associated with revising the pseudo frame mechanism. The long term solution
 // of having frames handle page-break-before/after will solve the problem.
 nsIFrame*
 nsCSSFrameConstructor::ConstructTable(nsFrameConstructorState& aState,
                                       FrameConstructionItem&   aItem,
-                                      nsIFrame*                aParentFrame,
+                                      nsContainerFrame*        aParentFrame,
                                       const nsStyleDisplay*    aDisplay,
                                       nsFrameItems&            aFrameItems)
 {
   NS_PRECONDITION(aDisplay->mDisplay == NS_STYLE_DISPLAY_TABLE ||
                   aDisplay->mDisplay == NS_STYLE_DISPLAY_INLINE_TABLE,
                   "Unexpected call");
 
   nsIContent* const content = aItem.mContent;
@@ -1948,31 +1954,31 @@ nsCSSFrameConstructor::ConstructTable(ns
   const uint32_t nameSpaceID = aItem.mNameSpaceID;
 
   // create the pseudo SC for the outer table as a child of the inner SC
   nsRefPtr<nsStyleContext> outerStyleContext;
   outerStyleContext = mPresShell->StyleSet()->
     ResolveAnonymousBoxStyle(nsCSSAnonBoxes::tableOuter, styleContext);
 
   // Create the outer table frame which holds the caption and inner table frame
-  nsIFrame* newFrame;
+  nsContainerFrame* newFrame;
   if (kNameSpaceID_MathML == nameSpaceID)
     newFrame = NS_NewMathMLmtableOuterFrame(mPresShell, outerStyleContext);
   else
     newFrame = NS_NewTableOuterFrame(mPresShell, outerStyleContext);
 
-  nsIFrame* geometricParent =
+  nsContainerFrame* geometricParent =
     aState.GetGeometricParent(outerStyleContext->StyleDisplay(),
                               aParentFrame);
 
   // Init the table outer frame
   InitAndRestoreFrame(aState, content, geometricParent, newFrame);
 
   // Create the inner table frame
-  nsIFrame* innerFrame;
+  nsContainerFrame* innerFrame;
   if (kNameSpaceID_MathML == nameSpaceID)
     innerFrame = NS_NewMathMLmtableFrame(mPresShell, styleContext);
   else
     innerFrame = NS_NewTableFrame(mPresShell, styleContext);
 
   InitAndRestoreFrame(aState, content, newFrame, innerFrame);
 
   // Put the newly created frames into the right child list
@@ -2022,17 +2028,17 @@ nsCSSFrameConstructor::ConstructTable(ns
 
   return newFrame;
 }
 
 static void
 MakeTablePartAbsoluteContainingBlockIfNeeded(nsFrameConstructorState&     aState,
                                              const nsStyleDisplay*        aDisplay,
                                              nsFrameConstructorSaveState& aAbsSaveState,
-                                             nsIFrame*                    aFrame)
+                                             nsContainerFrame*            aFrame)
 {
   // If we're positioned, then we need to become an absolute containing block
   // for any absolutely positioned children and register for post-reflow fixup.
   //
   // Note that usually if a frame type can be an absolute containing block, we
   // always set NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN, whether it actually is or not.
   // However, in this case flag serves the additional purpose of indicating that
   // the frame was registered with its table frame. This allows us to avoid the
@@ -2042,32 +2048,32 @@ MakeTablePartAbsoluteContainingBlockIfNe
     aState.PushAbsoluteContainingBlock(aFrame, aFrame, aAbsSaveState);
     nsTableFrame::RegisterPositionedTablePart(aFrame);
   }
 }
 
 nsIFrame*
 nsCSSFrameConstructor::ConstructTableRowOrRowGroup(nsFrameConstructorState& aState,
                                                    FrameConstructionItem&   aItem,
-                                                   nsIFrame*                aParentFrame,
+                                                   nsContainerFrame*        aParentFrame,
                                                    const nsStyleDisplay*    aDisplay,
                                                    nsFrameItems&            aFrameItems)
 {
   NS_PRECONDITION(aDisplay->mDisplay == NS_STYLE_DISPLAY_TABLE_ROW ||
                   aDisplay->mDisplay == NS_STYLE_DISPLAY_TABLE_ROW_GROUP ||
                   aDisplay->mDisplay == NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP ||
                   aDisplay->mDisplay == NS_STYLE_DISPLAY_TABLE_HEADER_GROUP,
                   "Unexpected call");
   MOZ_ASSERT(aItem.mStyleContext->StyleDisplay() == aDisplay,
              "Display style doesn't match style context");
   nsIContent* const content = aItem.mContent;
   nsStyleContext* const styleContext = aItem.mStyleContext;
   const uint32_t nameSpaceID = aItem.mNameSpaceID;
 
-  nsIFrame* newFrame;
+  nsContainerFrame* newFrame;
   if (aDisplay->mDisplay == NS_STYLE_DISPLAY_TABLE_ROW) {
     if (kNameSpaceID_MathML == nameSpaceID)
       newFrame = NS_NewMathMLmtrFrame(mPresShell, styleContext);
     else
       newFrame = NS_NewTableRowFrame(mPresShell, styleContext);
   } else {
     newFrame = NS_NewTableRowGroupFrame(mPresShell, styleContext);
   }
@@ -2095,17 +2101,17 @@ nsCSSFrameConstructor::ConstructTableRow
   newFrame->SetInitialChildList(kPrincipalList, childItems);
   aFrameItems.AddChild(newFrame);
   return newFrame;
 }
 
 nsIFrame*
 nsCSSFrameConstructor::ConstructTableCol(nsFrameConstructorState& aState,
                                          FrameConstructionItem&   aItem,
-                                         nsIFrame*                aParentFrame,
+                                         nsContainerFrame*        aParentFrame,
                                          const nsStyleDisplay*    aStyleDisplay,
                                          nsFrameItems&            aFrameItems)
 {
   nsIContent* const content = aItem.mContent;
   nsStyleContext* const styleContext = aItem.mStyleContext;
 
   nsTableColFrame* colFrame = NS_NewTableColFrame(mPresShell, styleContext);
   InitAndRestoreFrame(aState, content, aParentFrame, colFrame);
@@ -2127,29 +2133,29 @@ nsCSSFrameConstructor::ConstructTableCol
   }
 
   return colFrame;
 }
 
 nsIFrame*
 nsCSSFrameConstructor::ConstructTableCell(nsFrameConstructorState& aState,
                                           FrameConstructionItem&   aItem,
-                                          nsIFrame*                aParentFrame,
+                                          nsContainerFrame*        aParentFrame,
                                           const nsStyleDisplay*    aDisplay,
                                           nsFrameItems&            aFrameItems)
 {
   NS_PRECONDITION(aDisplay->mDisplay == NS_STYLE_DISPLAY_TABLE_CELL,
                   "Unexpected call");
 
   nsIContent* const content = aItem.mContent;
   nsStyleContext* const styleContext = aItem.mStyleContext;
   const uint32_t nameSpaceID = aItem.mNameSpaceID;
 
   bool borderCollapse = IsBorderCollapse(aParentFrame);
-  nsIFrame* newFrame;
+  nsContainerFrame* newFrame;
   // <mtable> is border separate in mathml.css and the MathML code doesn't implement
   // border collapse. For those users who style <mtable> with border collapse,
   // give them the default non-MathML table frames that understand border collapse.
   // This won't break us because MathML table frames are all subclasses of the default
   // table code, and so we can freely mix <mtable> with <mtr> or <tr>, <mtd> or <td>.
   // What will happen is just that non-MathML frames won't understand MathML attributes
   // and will therefore miss the special handling that the MathML code does.
   if (kNameSpaceID_MathML == nameSpaceID && !borderCollapse)
@@ -2165,17 +2171,17 @@ nsCSSFrameConstructor::ConstructTableCel
 
   // Resolve pseudo style and initialize the body cell frame
   nsRefPtr<nsStyleContext> innerPseudoStyle;
   innerPseudoStyle = mPresShell->StyleSet()->
     ResolveAnonymousBoxStyle(nsCSSAnonBoxes::cellContent, styleContext);
 
   // Create a block frame that will format the cell's content
   bool isBlock;
-  nsIFrame* cellInnerFrame;
+  nsContainerFrame* cellInnerFrame;
   if (kNameSpaceID_MathML == nameSpaceID) {
     cellInnerFrame = NS_NewMathMLmtdInnerFrame(mPresShell, innerPseudoStyle);
     isBlock = false;
   } else {
     cellInnerFrame = NS_NewBlockFormattingContext(mPresShell, innerPseudoStyle);
     isBlock = true;
   }
 
@@ -2452,17 +2458,17 @@ nsCSSFrameConstructor::ConstructDocEleme
   // either NONE, BLOCK, or TABLE.
 
   // contentFrame is the primary frame for the root element. newFrame
   // is the frame that will be the child of the initial containing block.
   // These are usually the same frame but they can be different, in
   // particular if the root frame is positioned, in which case
   // contentFrame is the out-of-flow frame and newFrame is the
   // placeholder.
-  nsIFrame* contentFrame;
+  nsContainerFrame* contentFrame;
   nsIFrame* newFrame;
   bool processChildren = false;
 
   // Check whether we need to build a XUL box or SVG root frame
 #ifdef MOZ_XUL
   if (aDocElement->IsXUL()) {
     contentFrame = NS_NewDocElementBoxFrame(mPresShell, styleContext);
     InitAndRestoreFrame(state, aDocElement, mDocElementContainingBlock,
@@ -2487,19 +2493,20 @@ nsCSSFrameConstructor::ConstructDocEleme
     static const FrameConstructionData rootSVGData = FCDATA_DECL(0, nullptr);
     already_AddRefed<nsStyleContext> extraRef =
       nsRefPtr<nsStyleContext>(styleContext).forget();
     FrameConstructionItem item(&rootSVGData, aDocElement,
                                aDocElement->Tag(), kNameSpaceID_SVG,
                                nullptr, extraRef, true, nullptr);
 
     nsFrameItems frameItems;
-    contentFrame = ConstructOuterSVG(state, item, mDocElementContainingBlock,
-                                     styleContext->StyleDisplay(),
-                                     frameItems);
+    contentFrame = static_cast<nsContainerFrame*>(
+      ConstructOuterSVG(state, item, mDocElementContainingBlock,
+                        styleContext->StyleDisplay(),
+                        frameItems));
     newFrame = frameItems.FirstChild();
     NS_ASSERTION(frameItems.OnlyChild(), "multiple root element frames");
   } else if (display->mDisplay == NS_STYLE_DISPLAY_FLEX) {
     contentFrame = NS_NewFlexContainerFrame(mPresShell, styleContext);
     InitAndRestoreFrame(state, aDocElement, mDocElementContainingBlock,
                         contentFrame);
     newFrame = contentFrame;
     processChildren = true;
@@ -2522,19 +2529,20 @@ nsCSSFrameConstructor::ConstructDocEleme
     already_AddRefed<nsStyleContext> extraRef =
       nsRefPtr<nsStyleContext>(styleContext).forget();
     FrameConstructionItem item(&rootTableData, aDocElement,
                                aDocElement->Tag(), kNameSpaceID_None,
                                nullptr, extraRef, true, nullptr);
 
     nsFrameItems frameItems;
     // if the document is a table then just populate it.
-    contentFrame = ConstructTable(state, item, mDocElementContainingBlock,
-                                  styleContext->StyleDisplay(),
-                                  frameItems);
+    contentFrame = static_cast<nsContainerFrame*>(
+      ConstructTable(state, item, mDocElementContainingBlock,
+                     styleContext->StyleDisplay(),
+                     frameItems));
     newFrame = frameItems.FirstChild();
     NS_ASSERTION(frameItems.OnlyChild(), "multiple root element frames");
   } else {
     MOZ_ASSERT(display->mDisplay == NS_STYLE_DISPLAY_BLOCK,
                "Unhandled display type for root element");
     contentFrame = NS_NewBlockFormattingContext(mPresShell, styleContext);
     nsFrameItems frameItems;
     // Use a null PendingBinding, since our binding is not in fact pending.
@@ -2600,23 +2608,20 @@ nsCSSFrameConstructor::ConstructRootFram
 
   // Set up our style rule observer.
   // XXXbz wouldn't this make more sense as part of presshell init?
   {
     styleSet->SetBindingManager(mDocument->BindingManager());
   }
 
   // --------- BUILD VIEWPORT -----------
-  nsIFrame*                 viewportFrame = nullptr;
-  nsRefPtr<nsStyleContext> viewportPseudoStyle;
-
-  viewportPseudoStyle =
+  nsRefPtr<nsStyleContext> viewportPseudoStyle =
     styleSet->ResolveAnonymousBoxStyle(nsCSSAnonBoxes::viewport, nullptr);
-
-  viewportFrame = NS_NewViewportFrame(mPresShell, viewportPseudoStyle);
+  ViewportFrame* viewportFrame =
+    NS_NewViewportFrame(mPresShell, viewportPseudoStyle);
 
   // XXXbz do we _have_ to pass a null content pointer to that frame?
   // Would it really kill us to pass in the root element or something?
   // What would that break?
   viewportFrame->Init(nullptr, nullptr, nullptr);
 
   // Bind the viewport frame to the root view
   nsView* rootView = mPresShell->GetViewManager()->GetRootView();
@@ -2705,20 +2710,20 @@ nsCSSFrameConstructor::SetUpDocElementCo
   //
   // The root frame serves two purposes:
   // - reserves space for any margins needed for the document element's frame
   // - renders the document element's background. This ensures the background covers
   //   the entire canvas as specified by the CSS2 spec
 
   nsPresContext* presContext = mPresShell->GetPresContext();
   bool isPaginated = presContext->IsRootPaginatedDocument();
-  nsIFrame* viewportFrame = mFixedContainingBlock;
+  nsContainerFrame* viewportFrame = mFixedContainingBlock;
   nsStyleContext* viewportPseudoStyle = viewportFrame->StyleContext();
 
-  nsIFrame* rootFrame = nullptr;
+  nsContainerFrame* rootFrame = nullptr;
   nsIAtom* rootPseudo;
 
   if (!isPaginated) {
 #ifdef MOZ_XUL
     if (aDocElement->IsXUL())
     {
       // pass a temporary stylecontext, the correct one will be set later
       rootFrame = NS_NewRootBoxFrame(mPresShell, viewportPseudoStyle);
@@ -2758,24 +2763,24 @@ nsCSSFrameConstructor::SetUpDocElementCo
   bool isScrollable = isPaginated ? presContext->HasPaginatedScrolling() : !isXUL;
 
   // We no longer need to do overflow propagation here. It's taken care of
   // when we construct frames for the element whose overflow might be
   // propagated
   NS_ASSERTION(!isScrollable || !isXUL,
                "XUL documents should never be scrollable - see above");
 
-  nsIFrame* newFrame = rootFrame;
+  nsContainerFrame* newFrame = rootFrame;
   nsRefPtr<nsStyleContext> rootPseudoStyle;
   // we must create a state because if the scrollbars are GFX it needs the
   // state to build the scrollbar frames.
   nsFrameConstructorState state(mPresShell, nullptr, nullptr, nullptr);
 
   // Start off with the viewport as parent; we'll adjust it as needed.
-  nsIFrame* parentFrame = viewportFrame;
+  nsContainerFrame* parentFrame = viewportFrame;
 
   nsStyleSet* styleSet = mPresShell->StyleSet();
   // If paginated, make sure we don't put scrollbars in
   if (!isScrollable) {
     rootPseudoStyle = styleSet->ResolveAnonymousBoxStyle(rootPseudo,
                                                          viewportPseudoStyle);
   } else {
       if (rootPseudo == nsCSSAnonBoxes::canvas) {
@@ -2817,21 +2822,21 @@ nsCSSFrameConstructor::SetUpDocElementCo
 
   rootFrame->SetStyleContextWithoutNotification(rootPseudoStyle);
   rootFrame->Init(aDocElement, parentFrame, nullptr);
 
   if (isScrollable) {
     FinishBuildingScrollFrame(parentFrame, rootFrame);
   }
 
-  if (isPaginated) { // paginated
+  if (isPaginated) {
     // Create the first page
     // Set the initial child lists
-    nsIFrame* canvasFrame;
-    nsIFrame* pageFrame =
+    nsContainerFrame* canvasFrame;
+    nsContainerFrame* pageFrame =
       ConstructPageFrame(mPresShell, presContext, rootFrame, nullptr,
                          canvasFrame);
     SetInitialSingleChild(rootFrame, pageFrame);
 
     // The eventual parent of the document element frame.
     // XXX should this be set for every new page (in ConstructPageFrame)?
     mDocElementContainingBlock = canvasFrame;
     mHasRootAbsPosContainingBlock = true;
@@ -2840,42 +2845,43 @@ nsCSSFrameConstructor::SetUpDocElementCo
   if (viewportFrame->GetStateBits() & NS_FRAME_FIRST_REFLOW) {
     SetInitialSingleChild(viewportFrame, newFrame);
   } else {
     nsFrameList newFrameList(newFrame, newFrame);
     viewportFrame->AppendFrames(kPrincipalList, newFrameList);
   }
 }
 
-nsIFrame*
+nsContainerFrame*
 nsCSSFrameConstructor::ConstructPageFrame(nsIPresShell*  aPresShell,
                                           nsPresContext* aPresContext,
-                                          nsIFrame*      aParentFrame,
+                                          nsContainerFrame* aParentFrame,
                                           nsIFrame*      aPrevPageFrame,
-                                          nsIFrame*&     aCanvasFrame)
+                                          nsContainerFrame*& aCanvasFrame)
 {
   nsStyleContext* parentStyleContext = aParentFrame->StyleContext();
   nsStyleSet *styleSet = aPresShell->StyleSet();
 
   nsRefPtr<nsStyleContext> pagePseudoStyle;
   pagePseudoStyle = styleSet->ResolveAnonymousBoxStyle(nsCSSAnonBoxes::page,
                                                        parentStyleContext);
 
-  nsIFrame* pageFrame = NS_NewPageFrame(aPresShell, pagePseudoStyle);
+  nsContainerFrame* pageFrame = NS_NewPageFrame(aPresShell, pagePseudoStyle);
 
   // Initialize the page frame and force it to have a view. This makes printing of
   // the pages easier and faster.
   pageFrame->Init(nullptr, aParentFrame, aPrevPageFrame);
 
   nsRefPtr<nsStyleContext> pageContentPseudoStyle;
   pageContentPseudoStyle =
     styleSet->ResolveAnonymousBoxStyle(nsCSSAnonBoxes::pageContent,
                                        pagePseudoStyle);
 
-  nsIFrame* pageContentFrame = NS_NewPageContentFrame(aPresShell, pageContentPseudoStyle);
+  nsContainerFrame* pageContentFrame =
+    NS_NewPageContentFrame(aPresShell, pageContentPseudoStyle);
 
   // Initialize the page content frame and force it to have a view. Also make it the
   // containing block for fixed elements which are repeated on every page.
   nsIFrame* prevPageContentFrame = nullptr;
   if (aPrevPageFrame) {
     prevPageContentFrame = aPrevPageFrame->GetFirstPrincipalChild();
     NS_ASSERTION(prevPageContentFrame, "missing page content frame");
   }
@@ -2899,23 +2905,23 @@ nsCSSFrameConstructor::ConstructPageFram
   }
   aCanvasFrame->Init(nullptr, pageContentFrame, prevCanvasFrame);
   SetInitialSingleChild(pageContentFrame, aCanvasFrame);
   return pageFrame;
 }
 
 /* static */
 nsIFrame*
-nsCSSFrameConstructor::CreatePlaceholderFrameFor(nsIPresShell*    aPresShell,
-                                                 nsIContent*      aContent,
-                                                 nsIFrame*        aFrame,
-                                                 nsStyleContext*  aStyleContext,
-                                                 nsIFrame*        aParentFrame,
-                                                 nsIFrame*        aPrevInFlow,
-                                                 nsFrameState     aTypeBit)
+nsCSSFrameConstructor::CreatePlaceholderFrameFor(nsIPresShell*     aPresShell,
+                                                 nsIContent*       aContent,
+                                                 nsIFrame*         aFrame,
+                                                 nsStyleContext*   aStyleContext,
+                                                 nsContainerFrame* aParentFrame,
+                                                 nsIFrame*         aPrevInFlow,
+                                                 nsFrameState      aTypeBit)
 {
   nsRefPtr<nsStyleContext> placeholderStyle = aPresShell->StyleSet()->
     ResolveStyleForNonElement(aStyleContext->GetParent());
 
   // The placeholder frame gets a pseudo style context
   nsPlaceholderFrame* placeholderFrame =
     (nsPlaceholderFrame*)NS_NewPlaceholderFrame(aPresShell, placeholderStyle,
                                                 aTypeBit);
@@ -2948,34 +2954,35 @@ ClearLazyBits(nsIContent* aStartContent,
        cur = cur->GetNextSibling()) {
     cur->UnsetFlags(NODE_DESCENDANTS_NEED_FRAMES | NODE_NEEDS_FRAME);
   }
 }
 
 nsIFrame*
 nsCSSFrameConstructor::ConstructSelectFrame(nsFrameConstructorState& aState,
                                             FrameConstructionItem&   aItem,
-                                            nsIFrame*                aParentFrame,
+                                            nsContainerFrame*        aParentFrame,
                                             const nsStyleDisplay*    aStyleDisplay,
                                             nsFrameItems&            aFrameItems)
 {
   nsIContent* const content = aItem.mContent;
   nsStyleContext* const styleContext = aItem.mStyleContext;
 
   // Construct a frame-based listbox or combobox
   dom::HTMLSelectElement* sel = dom::HTMLSelectElement::FromContent(content);
   MOZ_ASSERT(sel);
   if (sel->IsCombobox()) {
     // Construct a frame-based combo box.
     // The frame-based combo box is built out of three parts. A display area, a button and
     // a dropdown list. The display area and button are created through anonymous content.
     // The drop-down list's frame is created explicitly. The combobox frame shares its content
     // with the drop-down list.
     nsFrameState flags = NS_BLOCK_FLOAT_MGR;
-    nsIFrame* comboboxFrame = NS_NewComboboxControlFrame(mPresShell, styleContext, flags);
+    nsContainerFrame* comboboxFrame =
+      NS_NewComboboxControlFrame(mPresShell, styleContext, flags);
 
     // Save the history state so we don't restore during construction
     // since the complete tree is required before we restore.
     nsILayoutHistoryState *historyState = aState.mFrameState;
     aState.mFrameState = nullptr;
     // Initialize the combobox frame
     InitAndRestoreFrame(aState, content,
                         aState.GetGeometricParent(aStyleDisplay, aParentFrame),
@@ -2989,34 +2996,35 @@ nsCSSFrameConstructor::ConstructSelectFr
                  "doesn't implement nsIComboboxControlFrame");
 
     // Resolve pseudo element style for the dropdown list
     nsRefPtr<nsStyleContext> listStyle;
     listStyle = mPresShell->StyleSet()->
       ResolveAnonymousBoxStyle(nsCSSAnonBoxes::dropDownList, styleContext);
 
     // Create a listbox
-    nsIFrame* listFrame = NS_NewListControlFrame(mPresShell, listStyle);
+    nsContainerFrame* listFrame = NS_NewListControlFrame(mPresShell, listStyle);
 
     // Notify the listbox that it is being used as a dropdown list.
     nsIListControlFrame * listControlFrame = do_QueryFrame(listFrame);
     if (listControlFrame) {
       listControlFrame->SetComboboxFrame(comboboxFrame);
     }
     // Notify combobox that it should use the listbox as it's popup
     comboBox->SetDropDown(listFrame);
 
     NS_ASSERTION(!listFrame->IsPositioned(),
                  "Ended up with positioned dropdown list somehow.");
     NS_ASSERTION(!listFrame->IsFloating(),
                  "Ended up with floating dropdown list somehow.");
 
     // Initialize the scroll frame positioned. Note that it is NOT
     // initialized as absolutely positioned.
-    nsIFrame* scrolledFrame = NS_NewSelectsAreaFrame(mPresShell, styleContext, flags);
+    nsContainerFrame* scrolledFrame =
+      NS_NewSelectsAreaFrame(mPresShell, styleContext, flags);
 
     InitializeSelectFrame(aState, listFrame, scrolledFrame, content,
                           comboboxFrame, listStyle, true,
                           aItem.mPendingBinding, aFrameItems);
 
     NS_ASSERTION(listFrame->GetView(), "ListFrame's view is nullptr");
 
     // Create display and button frames from the combobox's anonymous content.
@@ -3040,19 +3048,19 @@ nsCSSFrameConstructor::ConstructSelectFr
     if (aState.mFrameState) {
       // Restore frame state for the entire subtree of |comboboxFrame|.
       RestoreFrameState(comboboxFrame, aState.mFrameState);
     }
     return comboboxFrame;
   }
 
   // Listbox, not combobox
-  nsIFrame* listFrame = NS_NewListControlFrame(mPresShell, styleContext);
-
-  nsIFrame* scrolledFrame = NS_NewSelectsAreaFrame(
+  nsContainerFrame* listFrame = NS_NewListControlFrame(mPresShell, styleContext);
+
+  nsContainerFrame* scrolledFrame = NS_NewSelectsAreaFrame(
       mPresShell, styleContext, NS_BLOCK_FLOAT_MGR);
 
   // ******* this code stolen from Initialze ScrollFrame ********
   // please adjust this code to use BuildScrollFrame.
 
   InitializeSelectFrame(aState, listFrame, scrolledFrame, content,
                         aParentFrame, styleContext, false,
                         aItem.mPendingBinding, aFrameItems);
@@ -3062,35 +3070,33 @@ nsCSSFrameConstructor::ConstructSelectFr
 
 /**
  * Used to be InitializeScrollFrame but now it's only used for the select tag
  * But the select tag should really be fixed to use GFX scrollbars that can
  * be create with BuildScrollFrame.
  */
 nsresult
 nsCSSFrameConstructor::InitializeSelectFrame(nsFrameConstructorState& aState,
-                                             nsIFrame*                scrollFrame,
-                                             nsIFrame*                scrolledFrame,
+                                             nsContainerFrame*        scrollFrame,
+                                             nsContainerFrame*        scrolledFrame,
                                              nsIContent*              aContent,
-                                             nsIFrame*                aParentFrame,
+                                             nsContainerFrame*        aParentFrame,
                                              nsStyleContext*          aStyleContext,
                                              bool                     aBuildCombobox,
                                              PendingBinding*          aPendingBinding,
                                              nsFrameItems&            aFrameItems)
 {
-  const nsStyleDisplay* display = aStyleContext->StyleDisplay();
-
   // Initialize it
-  nsIFrame* geometricParent = aState.GetGeometricParent(display, aParentFrame);
+  nsContainerFrame* geometricParent =
+    aState.GetGeometricParent(aStyleContext->StyleDisplay(), aParentFrame);
 
   // We don't call InitAndRestoreFrame for scrollFrame because we can only
   // restore the frame state after its parts have been created (in particular,
   // the scrollable view). So we have to split Init and Restore.
 
-  // Initialize the frame
   scrollFrame->Init(aContent, geometricParent, nullptr);
 
   if (!aBuildCombobox) {
     aState.AddChild(scrollFrame, aFrameItems, aContent,
                     aStyleContext, aParentFrame);
   }
 
   if (aBuildCombobox) {
@@ -3114,48 +3120,48 @@ nsCSSFrameConstructor::InitializeSelectF
   // Set the scrolled frame's initial child lists
   scrolledFrame->SetInitialChildList(kPrincipalList, childItems);
   return NS_OK;
 }
 
 nsIFrame*
 nsCSSFrameConstructor::ConstructFieldSetFrame(nsFrameConstructorState& aState,
                                               FrameConstructionItem&   aItem,
-                                              nsIFrame*                aParentFrame,
+                                              nsContainerFrame*        aParentFrame,
                                               const nsStyleDisplay*    aStyleDisplay,
                                               nsFrameItems&            aFrameItems)
 {
   nsIContent* const content = aItem.mContent;
   nsStyleContext* const styleContext = aItem.mStyleContext;
 
-  nsIFrame* fieldsetFrame = NS_NewFieldSetFrame(mPresShell, styleContext);
+  nsContainerFrame* fieldsetFrame = NS_NewFieldSetFrame(mPresShell, styleContext);
 
   // Initialize it
   InitAndRestoreFrame(aState, content,
                       aState.GetGeometricParent(aStyleDisplay, aParentFrame),
                       fieldsetFrame);
 
   // Resolve style and initialize the frame
   nsRefPtr<nsStyleContext> fieldsetContentStyle;
   fieldsetContentStyle = mPresShell->StyleSet()->
     ResolveAnonymousBoxStyle(nsCSSAnonBoxes::fieldsetContent, styleContext);
 
   const nsStyleDisplay* fieldsetContentDisplay = fieldsetContentStyle->StyleDisplay();
   bool isScrollable = fieldsetContentDisplay->IsScrollableOverflow();
-  nsIFrame* scrollFrame = nullptr;
+  nsContainerFrame* scrollFrame = nullptr;
   if (isScrollable) {
     fieldsetContentStyle =
       BeginBuildingScrollFrame(aState, content, fieldsetContentStyle,
                                fieldsetFrame, nsCSSAnonBoxes::scrolledContent,
                                false, scrollFrame);
   }
 
-  nsIFrame* blockFrame = NS_NewBlockFrame(mPresShell, fieldsetContentStyle,
-                                          NS_BLOCK_FLOAT_MGR |
-                                          NS_BLOCK_MARGIN_ROOT);
+  nsContainerFrame* blockFrame =
+    NS_NewBlockFrame(mPresShell, fieldsetContentStyle,
+                     NS_BLOCK_FLOAT_MGR | NS_BLOCK_MARGIN_ROOT);
   InitAndRestoreFrame(aState, content,
     scrollFrame ? scrollFrame : fieldsetFrame, blockFrame);
 
   aState.AddChild(fieldsetFrame, aFrameItems, content, styleContext, aParentFrame);
 
   // Process children
   nsFrameConstructorSaveState absoluteSaveState;
   nsFrameItems                childItems;
@@ -3247,17 +3253,17 @@ nsCSSFrameConstructor::FindTextData(nsIF
     FCDATA_DECL(FCDATA_IS_LINE_PARTICIPANT, NS_NewTextFrame);
   return &sTextData;
 }
 
 void
 nsCSSFrameConstructor::ConstructTextFrame(const FrameConstructionData* aData,
                                           nsFrameConstructorState& aState,
                                           nsIContent*              aContent,
-                                          nsIFrame*                aParentFrame,
+                                          nsContainerFrame*        aParentFrame,
                                           nsStyleContext*          aStyleContext,
                                           nsFrameItems&            aFrameItems)
 {
   NS_PRECONDITION(aData, "Must have frame construction data");
 
   nsIFrame* newFrame = (*aData->mFunc.mCreationFunc)(mPresShell, aStyleContext);
 
   InitAndRestoreFrame(aState, aContent, aParentFrame, newFrame);
@@ -3567,17 +3573,17 @@ nsCSSFrameConstructor::FindCanvasData(El
     FCDATA_WITH_WRAPPING_BLOCK(0, NS_NewHTMLCanvasFrame,
                                nsCSSAnonBoxes::htmlCanvasContent);
   return &sCanvasData;
 }
 
 void
 nsCSSFrameConstructor::ConstructFrameFromItemInternal(FrameConstructionItem& aItem,
                                                       nsFrameConstructorState& aState,
-                                                      nsIFrame* aParentFrame,
+                                                      nsContainerFrame* aParentFrame,
                                                       nsFrameItems& aFrameItems)
 {
   const FrameConstructionData* data = aItem.mFCData;
   NS_ASSERTION(data, "Must have frame construction data");
 
   uint32_t bits = data->mBits;
 
   NS_ASSERTION(!(bits & FCDATA_FUNC_IS_DATA_GETTER),
@@ -3664,27 +3670,29 @@ nsCSSFrameConstructor::ConstructFrameFro
     bool allowOutOfFlow = !(bits & FCDATA_DISALLOW_OUT_OF_FLOW);
     bool isPopup = aItem.mIsPopup;
     NS_ASSERTION(!isPopup ||
                  (aState.mPopupItems.containingBlock &&
                   aState.mPopupItems.containingBlock->GetType() ==
                     nsGkAtoms::popupSetFrame),
                  "Should have a containing block here!");
 
-    nsIFrame* geometricParent =
+    nsContainerFrame* geometricParent =
       isPopup ? aState.mPopupItems.containingBlock :
       (allowOutOfFlow ? aState.GetGeometricParent(display, aParentFrame)
                       : aParentFrame);
 
     // Must init frameToAddToList to null, since it's inout
     nsIFrame* frameToAddToList = nullptr;
     if ((bits & FCDATA_MAY_NEED_SCROLLFRAME) &&
         display->IsScrollableOverflow()) {
+      nsContainerFrame* scrollframe = nullptr;
       BuildScrollFrame(aState, content, styleContext, newFrame,
-                       geometricParent, frameToAddToList);
+                       geometricParent, scrollframe);
+      frameToAddToList = scrollframe;
     } else {
       InitAndRestoreFrame(aState, content, geometricParent, newFrame);
       // See whether we need to create a view
       nsContainerFrame::CreateViewForFrame(newFrame, false);
       frameToAddToList = newFrame;
     }
 
     // Use frameToAddToList as the primary frame.  In the non-scrollframe case
@@ -3701,19 +3709,20 @@ nsCSSFrameConstructor::ConstructFrameFro
     if (bits & FCDATA_CREATE_BLOCK_WRAPPER_FOR_ALL_KIDS) {
       nsRefPtr<nsStyleContext> blockContext;
       blockContext =
         mPresShell->StyleSet()->ResolveAnonymousBoxStyle(*data->mAnonBoxPseudo,
                                                          styleContext);
       nsIFrame* blockFrame =
         NS_NewBlockFormattingContext(mPresShell, blockContext);
 
-      InitAndRestoreFrame(aState, content, newFrame, blockFrame);
-
-      SetInitialSingleChild(newFrame, blockFrame);
+      nsContainerFrame* container = static_cast<nsContainerFrame*>(newFrame);
+      InitAndRestoreFrame(aState, content, container, blockFrame);
+
+      SetInitialSingleChild(container, blockFrame);
 
       // Now figure out whether newFrame or blockFrame should be the
       // absolute container.  It should be the latter if it's
       // positioned, otherwise the former.
       const nsStyleDisplay* blockDisplay = blockContext->StyleDisplay();
       if (blockDisplay->IsPositioned(blockFrame)) {
         maybeAbsoluteContainingBlockDisplay = blockDisplay;
         maybeAbsoluteContainingBlock = blockFrame;
@@ -3721,128 +3730,132 @@ nsCSSFrameConstructor::ConstructFrameFro
 
       // Our kids should go into the blockFrame
       newFrame = blockFrame;
     }
 
     aState.AddChild(frameToAddToList, aFrameItems, content, styleContext,
                     aParentFrame, allowOutOfFlow, allowOutOfFlow, isPopup);
 
+    nsContainerFrame* newFrameAsContainer = do_QueryFrame(newFrame);
+    if (newFrameAsContainer) {
 #ifdef MOZ_XUL
-    // Icky XUL stuff, sadly
-
-    if (aItem.mIsRootPopupgroup) {
-      NS_ASSERTION(nsIRootBox::GetRootBox(mPresShell) &&
-                   nsIRootBox::GetRootBox(mPresShell)->GetPopupSetFrame() ==
+      // Icky XUL stuff, sadly
+
+      if (aItem.mIsRootPopupgroup) {
+        NS_ASSERTION(nsIRootBox::GetRootBox(mPresShell) &&
+                     nsIRootBox::GetRootBox(mPresShell)->GetPopupSetFrame() ==
                      newFrame,
-                   "Unexpected PopupSetFrame");
-      aState.mPopupItems.containingBlock = newFrame;
-      aState.mHavePendingPopupgroup = false;
-    }
+                     "Unexpected PopupSetFrame");
+        aState.mPopupItems.containingBlock = newFrameAsContainer;
+        aState.mHavePendingPopupgroup = false;
+      }
 #endif /* MOZ_XUL */
 
-    // Process the child content if requested
-    nsFrameItems childItems;
-    nsFrameConstructorSaveState absoluteSaveState;
-
-    if (bits & FCDATA_FORCE_NULL_ABSPOS_CONTAINER) {
-      aState.PushAbsoluteContainingBlock(nullptr, nullptr, absoluteSaveState);
-    } else if (!(bits & FCDATA_SKIP_ABSPOS_PUSH)) {
-      nsIFrame* cb = maybeAbsoluteContainingBlock;
-      cb->AddStateBits(NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN);
-      // This check is identical to nsStyleDisplay::IsPositioned except without
-      // the assertion that the style display and frame match. When constructing
-      // scroll frames we intentionally use the style display for the outer, but
-      // make the inner the containing block.
-      if ((maybeAbsoluteContainingBlockDisplay->IsAbsolutelyPositionedStyle() ||
-           maybeAbsoluteContainingBlockDisplay->IsRelativelyPositionedStyle() ||
-           (maybeAbsoluteContainingBlockDisplay->HasTransformStyle() &&
-            cb->IsFrameOfType(nsIFrame::eSupportsCSSTransforms)) ||
-           maybeAbsoluteContainingBlockDisplay->HasPerspectiveStyle()) &&
-          !cb->IsSVGText()) {
-        aState.PushAbsoluteContainingBlock(cb, cb, absoluteSaveState);
+      // Process the child content if requested
+      nsFrameItems childItems;
+      nsFrameConstructorSaveState absoluteSaveState;
+
+      if (bits & FCDATA_FORCE_NULL_ABSPOS_CONTAINER) {
+        aState.PushAbsoluteContainingBlock(nullptr, nullptr, absoluteSaveState);
+      } else if (!(bits & FCDATA_SKIP_ABSPOS_PUSH)) {
+        nsIFrame* cb = maybeAbsoluteContainingBlock;
+        cb->AddStateBits(NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN);
+        // This check is identical to nsStyleDisplay::IsPositioned except without
+        // the assertion that the style display and frame match. When constructing
+        // scroll frames we intentionally use the style display for the outer, but
+        // make the inner the containing block.
+        if ((maybeAbsoluteContainingBlockDisplay->IsAbsolutelyPositionedStyle() ||
+             maybeAbsoluteContainingBlockDisplay->IsRelativelyPositionedStyle() ||
+             (maybeAbsoluteContainingBlockDisplay->HasTransformStyle() &&
+              cb->IsFrameOfType(nsIFrame::eSupportsCSSTransforms)) ||
+             maybeAbsoluteContainingBlockDisplay->HasPerspectiveStyle()) &&
+            !cb->IsSVGText()) {
+          nsContainerFrame* cf = static_cast<nsContainerFrame*>(cb);
+          aState.PushAbsoluteContainingBlock(cf, cf, absoluteSaveState);
+        }
+      }
+
+      if (!aItem.mAnonChildren.IsEmpty()) {
+        NS_ASSERTION(!(bits & FCDATA_USE_CHILD_ITEMS),
+                     "We should not have both anonymous and non-anonymous "
+                     "children in a given FrameConstructorItem");
+        AddFCItemsForAnonymousContent(aState, newFrameAsContainer, aItem.mAnonChildren,
+                                      aItem.mChildItems);
+        bits |= FCDATA_USE_CHILD_ITEMS;
       }
-    }
-
-    if (!aItem.mAnonChildren.IsEmpty()) {
-      NS_ASSERTION(!(bits & FCDATA_USE_CHILD_ITEMS),
-                   "We should not have both anonymous and non-anonymous "
-                   "children in a given FrameConstructorItem");
-      AddFCItemsForAnonymousContent(aState, newFrame, aItem.mAnonChildren,
-                                    aItem.mChildItems);
-      bits |= FCDATA_USE_CHILD_ITEMS;
-    }
-
-    if (bits & FCDATA_USE_CHILD_ITEMS) {
-      nsFrameConstructorSaveState floatSaveState;
-
-      if (ShouldSuppressFloatingOfDescendants(newFrame)) {
-        aState.PushFloatContainingBlock(nullptr, floatSaveState);
-      } else if (newFrame->IsFloatContainingBlock()) {
-        aState.PushFloatContainingBlock(newFrame, floatSaveState);
+
+      if (bits & FCDATA_USE_CHILD_ITEMS) {
+        nsFrameConstructorSaveState floatSaveState;
+
+        if (ShouldSuppressFloatingOfDescendants(newFrame)) {
+          aState.PushFloatContainingBlock(nullptr, floatSaveState);
+        } else if (newFrame->IsFloatContainingBlock()) {
+          aState.PushFloatContainingBlock(newFrameAsContainer, floatSaveState);
+        }
+        ConstructFramesFromItemList(aState, aItem.mChildItems, newFrameAsContainer,
+                                    childItems);
+      } else {
+        // Process the child frames.
+        ProcessChildren(aState, content, styleContext, newFrameAsContainer,
+                        !(bits & FCDATA_DISALLOW_GENERATED_CONTENT),
+                        childItems,
+                        (bits & FCDATA_ALLOW_BLOCK_STYLES) != 0,
+                        aItem.mPendingBinding, possiblyLeafFrame);
       }
-      ConstructFramesFromItemList(aState, aItem.mChildItems, newFrame,
-                                  childItems);
-    } else {
-      // Process the child frames.
-      ProcessChildren(aState, content, styleContext, newFrame,
-                      !(bits & FCDATA_DISALLOW_GENERATED_CONTENT),
-                      childItems,
-                      (bits & FCDATA_ALLOW_BLOCK_STYLES) != 0,
-                      aItem.mPendingBinding, possiblyLeafFrame);
-    }
+
+      if (bits & FCDATA_WRAP_KIDS_IN_BLOCKS) {
+        nsFrameItems newItems;
+        nsFrameItems currentBlockItems;
+        nsIFrame* f;
+        while ((f = childItems.FirstChild()) != nullptr) {
+          bool wrapFrame = IsInlineFrame(f) || IsFramePartOfIBSplit(f);
+          if (!wrapFrame) {
+            FlushAccumulatedBlock(aState, content, newFrameAsContainer,
+                                  currentBlockItems, newItems);
+          }
+
+          childItems.RemoveFrame(f);
+          if (wrapFrame) {
+            currentBlockItems.AddChild(f);
+          } else {
+            newItems.AddChild(f);
+          }
+        }
+        FlushAccumulatedBlock(aState, content, newFrameAsContainer,
+                              currentBlockItems, newItems);
+
+        if (childItems.NotEmpty()) {
+          // an error must have occurred, delete unprocessed frames
+          childItems.DestroyFrames();
+        }
+
+        childItems = newItems;
+      }
+
+      // Set the frame's initial child list
+      // Note that MathML depends on this being called even if
+      // childItems is empty!
+      newFrameAsContainer->SetInitialChildList(kPrincipalList, childItems);
+    }
+  }
 
 #ifdef MOZ_XUL
-    // More icky XUL stuff
-    if (aItem.mNameSpaceID == kNameSpaceID_XUL &&
-        (aItem.mTag == nsGkAtoms::treechildren || // trees always need titletips
-         content->HasAttr(kNameSpaceID_None, nsGkAtoms::tooltiptext) ||
-         content->HasAttr(kNameSpaceID_None, nsGkAtoms::tooltip))) {
-      nsIRootBox* rootBox = nsIRootBox::GetRootBox(mPresShell);
-      if (rootBox) {
-        rootBox->AddTooltipSupport(content);
-      }
-    }
+  // More icky XUL stuff
+  if (aItem.mNameSpaceID == kNameSpaceID_XUL &&
+      (aItem.mTag == nsGkAtoms::treechildren || // trees always need titletips
+       content->HasAttr(kNameSpaceID_None, nsGkAtoms::tooltiptext) ||
+       content->HasAttr(kNameSpaceID_None, nsGkAtoms::tooltip))) {
+    nsIRootBox* rootBox = nsIRootBox::GetRootBox(mPresShell);
+    if (rootBox) {
+      rootBox->AddTooltipSupport(content);
+    }
+  }
 #endif
 
-    if (bits & FCDATA_WRAP_KIDS_IN_BLOCKS) {
-      nsFrameItems newItems;
-      nsFrameItems currentBlockItems;
-      nsIFrame* f;
-      while ((f = childItems.FirstChild()) != nullptr) {
-        bool wrapFrame = IsInlineFrame(f) || IsFramePartOfIBSplit(f);
-        if (!wrapFrame) {
-          FlushAccumulatedBlock(aState, content, newFrame,
-                                currentBlockItems, newItems);
-        }
-
-        childItems.RemoveFrame(f);
-        if (wrapFrame) {
-          currentBlockItems.AddChild(f);
-        } else {
-          newItems.AddChild(f);
-        }
-      }
-      FlushAccumulatedBlock(aState, content, newFrame,
-                            currentBlockItems, newItems);
-
-      if (childItems.NotEmpty()) {
-        // an error must have occurred, delete unprocessed frames
-        childItems.DestroyFrames();
-      }
-
-      childItems = newItems;
-    }
-
-    // Set the frame's initial child list
-    // Note that MathML depends on this being called even if
-    // childItems is empty!
-    newFrame->SetInitialChildList(kPrincipalList, childItems);
-  }
-
   NS_ASSERTION(newFrame->IsFrameOfType(nsIFrame::eLineParticipant) ==
                ((bits & FCDATA_IS_LINE_PARTICIPANT) != 0),
                "Incorrectly set FCDATA_IS_LINE_PARTICIPANT bits");
 
   if (aItem.mIsAnonymousContentCreatorContent) {
     primaryFrame->AddStateBits(NS_FRAME_ANONYMOUSCONTENTCREATOR_CONTENT);
   }
 
@@ -3859,17 +3872,17 @@ nsCSSFrameConstructor::ConstructFrameFro
   }
 }
 
 // after the node has been constructed and initialized create any
 // anonymous content a node needs.
 nsresult
 nsCSSFrameConstructor::CreateAnonymousFrames(nsFrameConstructorState& aState,
                                              nsIContent*              aParent,
-                                             nsIFrame*                aParentFrame,
+                                             nsContainerFrame*        aParentFrame,
                                              PendingBinding*          aPendingBinding,
                                              nsFrameItems&            aChildItems)
 {
   nsAutoTArray<nsIAnonymousContentCreator::ContentInfo, 4> newAnonymousItems;
   nsresult rv = GetAnonymousContent(aParent, aParentFrame, newAnonymousItems);
   NS_ENSURE_SUCCESS(rv, rv);
 
   uint32_t count = newAnonymousItems.Length();
@@ -4274,22 +4287,22 @@ nsCSSFrameConstructor::FindXULDisplayDat
   return FindDataByInt(aDisplay->mDisplay, aElement, aStyleContext,
                        sXULDisplayData, ArrayLength(sXULDisplayData));
 }
 
 already_AddRefed<nsStyleContext>
 nsCSSFrameConstructor::BeginBuildingScrollFrame(nsFrameConstructorState& aState,
                                                 nsIContent*              aContent,
                                                 nsStyleContext*          aContentStyle,
-                                                nsIFrame*                aParentFrame,
+                                                nsContainerFrame*        aParentFrame,
                                                 nsIAtom*                 aScrolledPseudo,
                                                 bool                     aIsRoot,
-                                                nsIFrame*&               aNewFrame)
-{
-  nsIFrame* gfxScrollFrame = aNewFrame;
+                                                nsContainerFrame*&       aNewFrame)
+{
+  nsContainerFrame* gfxScrollFrame = aNewFrame;
 
   nsFrameItems anonymousItems;
 
   nsRefPtr<nsStyleContext> contentStyle = aContentStyle;
 
   if (!gfxScrollFrame) {
     // Build a XULScrollFrame when the child is a box, otherwise an
     // HTMLScrollFrame
@@ -4325,24 +4338,23 @@ nsCSSFrameConstructor::BeginBuildingScro
   if (gfxScrollFrame) {
      gfxScrollFrame->SetInitialChildList(kPrincipalList, anonymousItems);
   }
 
   return scrolledChildStyle.forget();
 }
 
 void
-nsCSSFrameConstructor::FinishBuildingScrollFrame(nsIFrame* aScrollFrame,
+nsCSSFrameConstructor::FinishBuildingScrollFrame(nsContainerFrame* aScrollFrame,
                                                  nsIFrame* aScrolledFrame)
 {
   nsFrameList scrolled(aScrolledFrame, aScrolledFrame);
   aScrollFrame->AppendFrames(kPrincipalList, scrolled);
 }
 
-
 /**
  * Called to wrap a gfx scrollframe around a frame. The hierarchy will look like this
  *
  * ------- for gfx scrollbars ------
  *
  *
  *            ScrollFrame
  *                 ^
@@ -4369,18 +4381,18 @@ nsCSSFrameConstructor::FinishBuildingScr
  *                  If this is not null, we'll just use it
  * @param aScrolledContentStyle the style that was resolved for the scrolled frame. (returned)
  */
 nsresult
 nsCSSFrameConstructor::BuildScrollFrame(nsFrameConstructorState& aState,
                                         nsIContent*              aContent,
                                         nsStyleContext*          aContentStyle,
                                         nsIFrame*                aScrolledFrame,
-                                        nsIFrame*                aParentFrame,
-                                        nsIFrame*&               aNewFrame)
+                                        nsContainerFrame*        aParentFrame,
+                                        nsContainerFrame*&       aNewFrame)
 {
     nsRefPtr<nsStyleContext> scrolledContentStyle =
       BeginBuildingScrollFrame(aState, aContent, aContentStyle, aParentFrame,
                                nsCSSAnonBoxes::scrolledContent,
                                false, aNewFrame);
 
     aScrolledFrame->SetStyleContextWithoutNotification(scrolledContentStyle);
     InitAndRestoreFrame(aState, aContent, aNewFrame, aScrolledFrame);
@@ -4514,33 +4526,33 @@ nsCSSFrameConstructor::FindDisplayData(c
   return FindDataByInt(aDisplay->mDisplay,
                        aElement, aStyleContext, sDisplayData,
                        ArrayLength(sDisplayData));
 }
 
 nsIFrame*
 nsCSSFrameConstructor::ConstructScrollableBlock(nsFrameConstructorState& aState,
                                                 FrameConstructionItem&   aItem,
-                                                nsIFrame*                aParentFrame,
+                                                nsContainerFrame*        aParentFrame,
                                                 const nsStyleDisplay*    aDisplay,
                                                 nsFrameItems&            aFrameItems)
 {
   nsIContent* const content = aItem.mContent;
   nsStyleContext* const styleContext = aItem.mStyleContext;
 
-  nsIFrame* newFrame = nullptr;
+  nsContainerFrame* newFrame = nullptr;
   nsRefPtr<nsStyleContext> scrolledContentStyle
     = BeginBuildingScrollFrame(aState, content, styleContext,
                                aState.GetGeometricParent(aDisplay, aParentFrame),
                                nsCSSAnonBoxes::scrolledContent,
                                false, newFrame);
 
   // Create our block frame
   // pass a temporary stylecontext, the correct one will be set later
-  nsIFrame* scrolledFrame =
+  nsContainerFrame* scrolledFrame =
     NS_NewBlockFormattingContext(mPresShell, styleContext);
 
   // Make sure to AddChild before we call ConstructBlock so that we
   // end up before our descendants in fixed-pos lists as needed.
   aState.AddChild(newFrame, aFrameItems, content, styleContext, aParentFrame);
 
   nsFrameItems blockItem;
   ConstructBlock(aState, scrolledContentStyle->StyleDisplay(), content,
@@ -4554,29 +4566,29 @@ nsCSSFrameConstructor::ConstructScrollab
   FinishBuildingScrollFrame(newFrame, scrolledFrame);
 
   return newFrame;
 }
 
 nsIFrame*
 nsCSSFrameConstructor::ConstructNonScrollableBlock(nsFrameConstructorState& aState,
                                                    FrameConstructionItem&   aItem,
-                                                   nsIFrame*                aParentFrame,
+                                                   nsContainerFrame*        aParentFrame,
                                                    const nsStyleDisplay*    aDisplay,
                                                    nsFrameItems&            aFrameItems)
 {
   nsStyleContext* const styleContext = aItem.mStyleContext;
 
   // We want a block formatting context root in paginated contexts for
   // every block that would be scrollable in a non-paginated context.
   // We mark our blocks with a bit here if this condition is true, so
   // we can check it later in nsFrame::ApplyPaginatedOverflowClipping.
   bool clipPaginatedOverflow =
     (aItem.mFCData->mBits & FCDATA_FORCED_NON_SCROLLABLE_BLOCK) != 0;
-  nsIFrame* newFrame;
+  nsContainerFrame* newFrame;
   if ((aDisplay->IsAbsolutelyPositionedStyle() ||
        aDisplay->IsFloatingStyle() ||
        NS_STYLE_DISPLAY_INLINE_BLOCK == aDisplay->mDisplay ||
        clipPaginatedOverflow) &&
       !aParentFrame->IsSVGText()) {
     newFrame = NS_NewBlockFormattingContext(mPresShell, styleContext);
     if (clipPaginatedOverflow) {
       newFrame->AddStateBits(NS_BLOCK_CLIP_PAGINATED_OVERFLOW);
@@ -4593,17 +4605,17 @@ nsCSSFrameConstructor::ConstructNonScrol
                  aItem.mPendingBinding);
   return newFrame;
 }
 
 
 void
 nsCSSFrameConstructor::InitAndRestoreFrame(const nsFrameConstructorState& aState,
                                            nsIContent*              aContent,
-                                           nsIFrame*                aParentFrame,
+                                           nsContainerFrame*        aParentFrame,
                                            nsIFrame*                aNewFrame,
                                            bool                     aAllowCounters)
 {
   NS_PRECONDITION(mUpdateCount != 0,
                   "Should be in an update while creating frames");
 
   MOZ_ASSERT(aNewFrame, "Null frame cannot be initialized");
 
@@ -4671,17 +4683,17 @@ nsCSSFrameConstructor::ResolveStyleConte
 
   return styleSet->ResolveStyleForNonElement(aParentStyleContext);
 }
 
 // MathML Mod - RBS
 void
 nsCSSFrameConstructor::FlushAccumulatedBlock(nsFrameConstructorState& aState,
                                              nsIContent* aContent,
-                                             nsIFrame* aParentFrame,
+                                             nsContainerFrame* aParentFrame,
                                              nsFrameItems& aBlockItems,
                                              nsFrameItems& aNewItems)
 {
   if (aBlockItems.IsEmpty()) {
     // Nothing to do
     return;
   }
 
@@ -4786,48 +4798,48 @@ nsCSSFrameConstructor::FindMathMLData(El
     SIMPLE_MATHML_CREATE(semantics_, NS_NewMathMLsemanticsFrame)
   };
 
   return FindDataByTag(aTag, aElement, aStyleContext, sMathMLData,
                        ArrayLength(sMathMLData));
 }
 
 
-nsIFrame*
+nsContainerFrame*
 nsCSSFrameConstructor::ConstructFrameWithAnonymousChild(
                                    nsFrameConstructorState& aState,
                                    FrameConstructionItem&   aItem,
-                                   nsIFrame*                aParentFrame,
+                                   nsContainerFrame*        aParentFrame,
                                    const nsStyleDisplay*    aDisplay,
                                    nsFrameItems&            aFrameItems,
-                                   FrameCreationFunc        aConstructor,
-                                   FrameCreationFunc        aInnerConstructor,
+                                   ContainerFrameCreationFunc aConstructor,
+                                   ContainerFrameCreationFunc aInnerConstructor,
                                    nsICSSAnonBoxPseudo*     aInnerPseudo,
                                    bool                     aCandidateRootFrame)
 {
   nsIContent* const content = aItem.mContent;
   nsStyleContext* const styleContext = aItem.mStyleContext;
 
   // Create the outer frame:
-  nsIFrame* newFrame = aConstructor(mPresShell, styleContext);
+  nsContainerFrame* newFrame = aConstructor(mPresShell, styleContext);
 
   InitAndRestoreFrame(aState, content,
                       aCandidateRootFrame ?
                         aState.GetGeometricParent(styleContext->StyleDisplay(),
                                                   aParentFrame) :
                         aParentFrame,
                       newFrame);
 
   // Create the pseudo SC for the anonymous wrapper child as a child of the SC:
   nsRefPtr<nsStyleContext> scForAnon;
   scForAnon = mPresShell->StyleSet()->
     ResolveAnonymousBoxStyle(aInnerPseudo, styleContext);
 
   // Create the anonymous inner wrapper frame
-  nsIFrame* innerFrame = aInnerConstructor(mPresShell, scForAnon);
+  nsContainerFrame* innerFrame = aInnerConstructor(mPresShell, scForAnon);
 
   InitAndRestoreFrame(aState, content, newFrame, innerFrame);
 
   // Put the newly created frames into the right child list
   SetInitialSingleChild(newFrame, innerFrame);
 
   aState.AddChild(newFrame, aFrameItems, content, styleContext, aParentFrame,
                   aCandidateRootFrame, aCandidateRootFrame);
@@ -4857,30 +4869,30 @@ nsCSSFrameConstructor::ConstructFrameWit
   innerFrame->SetInitialChildList(kPrincipalList, childItems);
 
   return newFrame;
 }
 
 nsIFrame*
 nsCSSFrameConstructor::ConstructOuterSVG(nsFrameConstructorState& aState,
                                          FrameConstructionItem&   aItem,
-                                         nsIFrame*                aParentFrame,
+                                         nsContainerFrame*        aParentFrame,
                                          const nsStyleDisplay*    aDisplay,
                                          nsFrameItems&            aFrameItems)
 {
   return ConstructFrameWithAnonymousChild(
       aState, aItem, aParentFrame, aDisplay, aFrameItems,
       NS_NewSVGOuterSVGFrame, NS_NewSVGOuterSVGAnonChildFrame,
       nsCSSAnonBoxes::mozSVGOuterSVGAnonChild, true);
 }
 
 nsIFrame*
 nsCSSFrameConstructor::ConstructMarker(nsFrameConstructorState& aState,
                                        FrameConstructionItem&   aItem,
-                                       nsIFrame*                aParentFrame,
+                                       nsContainerFrame*        aParentFrame,
                                        const nsStyleDisplay*    aDisplay,
                                        nsFrameItems&            aFrameItems)
 {
   return ConstructFrameWithAnonymousChild(
       aState, aItem, aParentFrame, aDisplay, aFrameItems,
       NS_NewSVGMarkerFrame, NS_NewSVGMarkerAnonChildFrame,
       nsCSSAnonBoxes::mozSVGMarkerAnonChild, false);
 }
@@ -5146,17 +5158,17 @@ nsCSSFrameConstructor::AddPageBreakItem(
                     kNameSpaceID_None, nullptr, pseudoStyle.forget(),
                     true, nullptr);
 }
 
 void
 nsCSSFrameConstructor::AddFrameConstructionItems(nsFrameConstructorState& aState,
                                                  nsIContent* aContent,
                                                  bool aSuppressWhiteSpaceOptimizations,
-                                                 nsIFrame* aParentFrame,
+                                                 nsContainerFrame* aParentFrame,
                                                  FrameConstructionItemList& aItems)
 {
   aContent->UnsetFlags(NODE_DESCENDANTS_NEED_FRAMES | NODE_NEEDS_FRAME);
   if (aContent->IsElement()) {
     // We can't just remove our pending restyle flags, since we may
     // have restyle-later-siblings set on us.  But we _can_ remove the
     // "is possible restyle root" flags, and need to.  Otherwise we can
     // end up with stale such flags (e.g. if we used to have a
@@ -5221,17 +5233,17 @@ nsCSSFrameConstructor::SetAsUndisplayedC
 
   NS_ASSERTION(!aIsGeneratedContent, "Should have had pseudo type");
   aList.AppendUndisplayedItem(aContent, aStyleContext);
 }
 
 void
 nsCSSFrameConstructor::AddFrameConstructionItemsInternal(nsFrameConstructorState& aState,
                                                          nsIContent* aContent,
-                                                         nsIFrame* aParentFrame,
+                                                         nsContainerFrame* aParentFrame,
                                                          nsIAtom* aTag,
                                                          int32_t aNameSpaceID,
                                                          bool aSuppressWhiteSpaceOptimizations,
                                                          nsStyleContext* aStyleContext,
                                                          uint32_t aFlags,
                                                          nsTArray<nsIAnonymousContentCreator::ContentInfo>* aAnonChildren,
                                                          FrameConstructionItemList& aItems)
 {
@@ -5577,23 +5589,23 @@ nsCSSFrameConstructor::AtLineBoundary(FC
   }
 
   return false;
 }
 
 void
 nsCSSFrameConstructor::ConstructFramesFromItem(nsFrameConstructorState& aState,
                                                FCItemIterator& aIter,
-                                               nsIFrame* aParentFrame,
+                                               nsContainerFrame* aParentFrame,
                                                nsFrameItems& aFrameItems)
 {
-  nsIFrame* adjParentFrame = aParentFrame;
+  nsContainerFrame* adjParentFrame = aParentFrame;
   FrameConstructionItem& item = aIter.item();
   nsStyleContext* styleContext = item.mStyleContext;
-  AdjustParentFrame(adjParentFrame, item.mFCData, styleContext);
+  AdjustParentFrame(&adjParentFrame, item.mFCData, styleContext);
 
   if (item.mIsText) {
     // If this is collapsible whitespace next to a line boundary,
     // don't create a frame. item.IsWhitespace() also sets the
     // NS_CREATE_FRAME_IF_NON_WHITESPACE flag in the text node. (If we
     // end up creating a frame, nsTextFrame::Init will clear the flag.)
     // We don't do this for generated content, because some generated
     // text content is empty text nodes that are about to be initialized.
@@ -5663,17 +5675,17 @@ nsCSSFrameConstructor::ReconstructDocEle
   Element* rootElement = mDocument->GetRootElement();
   if (!rootElement) {
     /* nothing to do */
     return NS_OK;
   }
   return RecreateFramesForContent(rootElement, false);
 }
 
-nsIFrame*
+nsContainerFrame*
 nsCSSFrameConstructor::GetAbsoluteContainingBlock(nsIFrame* aFrame,
                                                   ContainingBlockType aType)
 {
   NS_PRECONDITION(nullptr != mRootElementFrame, "no root element frame");
 
   // Starting with aFrame, look for a frame that is absolutely positioned or
   // relatively positioned (and transformed, if aType is FIXED)
   for (nsIFrame* frame = aFrame; frame; frame = frame->GetParent()) {
@@ -5722,41 +5734,45 @@ nsCSSFrameConstructor::GetAbsoluteContai
       continue;
     }
 
     // For tables, skip the inner frame and consider the outer table frame.
     if (type == nsGkAtoms::tableFrame) {
       continue;
     }
     // For outer table frames, we can just return absPosCBCandidate.
-    return absPosCBCandidate;
+    MOZ_ASSERT((nsContainerFrame*)do_QueryFrame(absPosCBCandidate),
+               "abs.pos. containing block must be nsContainerFrame sub-class");
+    return static_cast<nsContainerFrame*>(absPosCBCandidate);
   }
 
   // It is possible for the search for the containing block to fail, because
   // no absolute container can be found in the parent chain.  In those cases,
   // we fall back to the document element's containing block.
   if (aType == FIXED_POS) {
     return mFixedContainingBlock;
   }
   return mHasRootAbsPosContainingBlock ? mDocElementContainingBlock : nullptr;
 }
 
-nsIFrame*
+nsContainerFrame*
 nsCSSFrameConstructor::GetFloatContainingBlock(nsIFrame* aFrame)
 {
   // Starting with aFrame, look for a frame that is a float containing block.
   // IF we hit a mathml frame, bail out; we don't allow floating out of mathml
   // frames, because they don't seem to be able to deal.
   // The logic here needs to match the logic in ProcessChildren()
   for (nsIFrame* containingBlock = aFrame;
        containingBlock &&
          !ShouldSuppressFloatingOfDescendants(containingBlock);
        containingBlock = containingBlock->GetParent()) {
     if (containingBlock->IsFloatContainingBlock()) {
-      return containingBlock;
+      MOZ_ASSERT((nsContainerFrame*)do_QueryFrame(containingBlock),
+                 "float containing block must be nsContainerFrame sub-class");
+      return static_cast<nsContainerFrame*>(containingBlock);
     }
   }
 
   // If we didn't find a containing block, then there just isn't
   // one.... return null
   return nullptr;
 }
 
@@ -5851,17 +5867,17 @@ GetInsertNextSibling(nsIFrame* aParentFr
 
 /**
  * This function is called by ContentAppended() and ContentInserted() when
  * appending flowed frames to a parent's principal child list. It handles the
  * case where the parent is the trailing inline of an {ib} split.
  */
 nsresult
 nsCSSFrameConstructor::AppendFramesToParent(nsFrameConstructorState&       aState,
-                                            nsIFrame*                      aParentFrame,
+                                            nsContainerFrame*              aParentFrame,
                                             nsFrameItems&                  aFrameList,
                                             nsIFrame*                      aPrevSibling,
                                             bool                           aIsRecursiveCall)
 {
   NS_PRECONDITION(!IsFramePartOfIBSplit(aParentFrame) ||
                   !GetIBSplitSibling(aParentFrame) ||
                   !GetIBSplitSibling(aParentFrame)->GetFirstPrincipalChild(),
                   "aParentFrame has a ib-split sibling with kids?");
@@ -5900,18 +5916,18 @@ nsCSSFrameConstructor::AppendFramesToPar
       if (firstContinuation->PrincipalChildList().IsEmpty()) {
         // Our trailing inline is empty.  Collect our starting blocks from
         // aFrameList, get the right parent frame for them, and put them in.
         nsFrameList::FrameLinkEnumerator firstNonBlockEnumerator =
           FindFirstNonBlock(aFrameList);
         nsFrameList blockKids = aFrameList.ExtractHead(firstNonBlockEnumerator);
         NS_ASSERTION(blockKids.NotEmpty(), "No blocks?");
 
-        nsIFrame* prevBlock =
-          GetIBSplitPrevSibling(firstContinuation)->LastContinuation();
+        nsContainerFrame* prevBlock = GetIBSplitPrevSibling(firstContinuation);
+        prevBlock = static_cast<nsContainerFrame*>(prevBlock->LastContinuation());
         NS_ASSERTION(prevBlock, "Should have previous block here");
 
         MoveChildrenTo(aState.mPresContext, aParentFrame, prevBlock, blockKids);
       }
     }
 
     // We want to put some of the frames into this inline frame.
     nsFrameList::FrameLinkEnumerator firstBlockEnumerator(aFrameList);
@@ -6272,17 +6288,17 @@ MaybeGetListBoxBodyFrame(nsIContent* aCo
   }
 
   return nullptr;
 }
 #endif
 
 void
 nsCSSFrameConstructor::AddTextItemIfNeeded(nsFrameConstructorState& aState,
-                                           nsIFrame* aParentFrame,
+                                           nsContainerFrame* aParentFrame,
                                            nsIContent* aPossibleTextContent,
                                            FrameConstructionItemList& aItems)
 {
   NS_PRECONDITION(aPossibleTextContent, "Must have node");
   if (!aPossibleTextContent->IsNodeOfType(nsINode::eTEXT) ||
       !aPossibleTextContent->HasFlag(NS_CREATE_FRAME_IF_NON_WHITESPACE)) {
     // Not text, or not suppressed due to being all-whitespace (if it
     // were being suppressed, it would have the
@@ -6731,17 +6747,17 @@ nsCSSFrameConstructor::ContentAppended(n
   nsFrameConstructorState state(mPresShell,
                                 GetAbsoluteContainingBlock(parentFrame, FIXED_POS),
                                 GetAbsoluteContainingBlock(parentFrame, ABS_POS),
                                 GetFloatContainingBlock(parentFrame));
   state.mTreeMatchContext.InitAncestors(aContainer->AsElement());
 
   // See if the containing block has :first-letter style applied.
   bool haveFirstLetterStyle = false, haveFirstLineStyle = false;
-  nsIFrame* containingBlock = state.mFloatedItems.containingBlock;
+  nsContainerFrame* containingBlock = state.mFloatedItems.containingBlock;
   if (containingBlock) {
     haveFirstLetterStyle = HasFirstLetterStyle(containingBlock);
     haveFirstLineStyle =
       ShouldHaveFirstLineStyle(containingBlock->GetContent(),
                                containingBlock->StyleContext());
   }
 
   if (haveFirstLetterStyle) {
@@ -6842,17 +6858,17 @@ nsCSSFrameConstructor::ContentAppended(n
                           containingBlock, frameItems);
   }
 
   // Notify the parent frame passing it the list of new frames
   // Append the flowed frames to the principal child list; captions
   // need special treatment
   if (captionItems.NotEmpty()) { // append the caption to the outer table
     NS_ASSERTION(nsGkAtoms::tableFrame == frameType, "how did that happen?");
-    nsIFrame* outerTable = parentFrame->GetParent();
+    nsContainerFrame* outerTable = parentFrame->GetParent();
     AppendFrames(outerTable, nsIFrame::kCaptionList, captionItems);
   }
 
   if (frameItems.NotEmpty()) { // append the in-flow kids
     AppendFramesToParent(state, parentFrame, frameItems, prevSibling);
   }
 
   // Recover first-letter frames
@@ -7183,17 +7199,17 @@ nsCSSFrameConstructor::ContentRangeInser
                                           aContainer->AsElement() :
                                           nullptr);
 
   // Recover state for the containing block - we need to know if
   // it has :first-letter or :first-line style applied to it. The
   // reason we care is that the internal structure in these cases
   // is not the normal structure and requires custom updating
   // logic.
-  nsIFrame* containingBlock = state.mFloatedItems.containingBlock;
+  nsContainerFrame* containingBlock = state.mFloatedItems.containingBlock;
   bool haveFirstLetterStyle = false;
   bool haveFirstLineStyle = false;
 
   // In order to shave off some cycles, we only dig up the
   // containing block haveFirst* flags if the parent frame where
   // the insertion/append is occurring is an inline or block
   // container. For other types of containers this isn't relevant.
   uint8_t parentDisplay = parentFrame->GetDisplay();
@@ -7429,17 +7445,17 @@ nsCSSFrameConstructor::ContentRangeInser
       // [aStartChild,aEndChild) when looking for a
       // prevsibling.
       captionPrevSibling =
         GetInsertionPrevSibling(captionParent, aContainer, firstCaption,
                                 &captionIsAppend, &ignored,
                                 aStartChild, aEndChild);
     }
 
-    nsIFrame* outerTable = nullptr;
+    nsContainerFrame* outerTable = nullptr;
     if (GetCaptionAdjustedParent(captionParent, captionItems.FirstChild(),
                                  &outerTable)) {
       // If the parent is not an outer table frame we will try to add frames
       // to a named child list that the parent does not honour and the frames
       // will get lost
       NS_ASSERTION(nsGkAtoms::tableOuterFrame == outerTable->GetType(),
                    "Pseudo frame construction failure; "
                    "a caption can be only a child of an outer table frame");
@@ -7640,17 +7656,17 @@ nsCSSFrameConstructor::ContentRemoved(ns
 
     // Examine the containing-block for the removed content and see if
     // :first-letter style applies.
     nsIFrame* inflowChild = childFrame;
     if (childFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) {
       inflowChild = GetPlaceholderFrameFor(childFrame);
       NS_ASSERTION(inflowChild, "No placeholder for out-of-flow?");
     }
-    nsIFrame* containingBlock =
+    nsContainerFrame* containingBlock =
       GetFloatContainingBlock(inflowChild->GetParent());
     bool haveFLS = containingBlock && HasFirstLetterStyle(containingBlock);
     if (haveFLS) {
       // Trap out to special routine that handles adjusting a blocks
       // frame tree when first-letter style is present.
 #ifdef NOISY_FIRST_LETTER
       printf("ContentRemoved: containingBlock=");
       nsFrame::ListTag(stdout, containingBlock);
@@ -7708,17 +7724,17 @@ nsCSSFrameConstructor::ContentRemoved(ns
 
     if (isRoot) {
       mRootElementFrame = nullptr;
       mRootElementStyleFrame = nullptr;
       mDocElementContainingBlock = nullptr;
       mPageSequenceFrame = nullptr;
       mGfxScrollFrame = nullptr;
       mHasRootAbsPosContainingBlock = false;
-      mFixedContainingBlock = GetRootFrame();
+      mFixedContainingBlock = static_cast<nsContainerFrame*>(GetRootFrame());
     }
 
     if (haveFLS && mRootElementFrame) {
       RecoverLetterFrames(containingBlock);
     }
 
     // If we're just reconstructing frames for the element, then the
     // following ContentInserted notification on the element will
@@ -7870,17 +7886,17 @@ nsCSSFrameConstructor::CharacterDataChan
     // this happens, we should remove the letter frame, do whatever we're
     // planning to do with this notification, then put the letter frame back.
     // Note that this is basically what RecreateFramesForContent ends up doing;
     // the reason we dont' want to call that here is that our text content
     // could be native anonymous, in which case RecreateFramesForContent would
     // completely barf on it.  And recreating the non-anonymous ancestor would
     // just lead us to come back into this notification (e.g. if quotes or
     // counters are involved), leading to a loop.
-    nsIFrame* block = GetFloatContainingBlock(frame);
+    nsContainerFrame* block = GetFloatContainingBlock(frame);
     bool haveFirstLetterStyle = false;
     if (block) {
       // See if the block has first-letter style applied to it.
       haveFirstLetterStyle = HasFirstLetterStyle(block);
       if (haveFirstLetterStyle) {
         RemoveLetterFrames(mPresShell->GetPresContext(), mPresShell,
                            block);
         // Reget |frame|, since we might have killed it.
@@ -7989,24 +8005,24 @@ void nsCSSFrameConstructor::GetAlternate
     if (!aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::value, aAltText)) {
       nsContentUtils::GetLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
                                          "Submit", aAltText);
     }
   }
 }
 
 nsIFrame*
-nsCSSFrameConstructor::CreateContinuingOuterTableFrame(nsIPresShell*    aPresShell,
-                                                       nsPresContext*  aPresContext,
-                                                       nsIFrame*        aFrame,
-                                                       nsIFrame*        aParentFrame,
-                                                       nsIContent*      aContent,
-                                                       nsStyleContext*  aStyleContext)
-{
-  nsIFrame* newFrame = NS_NewTableOuterFrame(aPresShell, aStyleContext);
+nsCSSFrameConstructor::CreateContinuingOuterTableFrame(nsIPresShell*     aPresShell,
+                                                       nsPresContext*    aPresContext,
+                                                       nsIFrame*         aFrame,
+                                                       nsContainerFrame* aParentFrame,
+                                                       nsIContent*       aContent,
+                                                       nsStyleContext*   aStyleContext)
+{
+  nsTableOuterFrame* newFrame = NS_NewTableOuterFrame(aPresShell, aStyleContext);
 
   newFrame->Init(aContent, aParentFrame, aFrame);
 
   // Create a continuing inner table frame, and if there's a caption then
   // replicate the caption
   nsFrameItems  newChildFrames;
 
   nsIFrame* childFrame = aFrame->GetFirstPrincipalChild();
@@ -8020,24 +8036,24 @@ nsCSSFrameConstructor::CreateContinuingO
 
   // Set the outer table's initial child list
   newFrame->SetInitialChildList(kPrincipalList, newChildFrames);
 
   return newFrame;
 }
 
 nsIFrame*
-nsCSSFrameConstructor::CreateContinuingTableFrame(nsIPresShell* aPresShell,
-                                                  nsPresContext*  aPresContext,
-                                                  nsIFrame*        aFrame,
-                                                  nsIFrame*        aParentFrame,
-                                                  nsIContent*      aContent,
-                                                  nsStyleContext*  aStyleContext)
-{
-  nsIFrame* newFrame = NS_NewTableFrame(aPresShell, aStyleContext);
+nsCSSFrameConstructor::CreateContinuingTableFrame(nsIPresShell*     aPresShell,
+                                                  nsPresContext*    aPresContext,
+                                                  nsIFrame*         aFrame,
+                                                  nsContainerFrame* aParentFrame,
+                                                  nsIContent*       aContent,
+                                                  nsStyleContext*   aStyleContext)
+{
+  nsTableFrame* newFrame = NS_NewTableFrame(aPresShell, aStyleContext);
 
   newFrame->Init(aContent, aParentFrame, aFrame);
 
   // Replicate any header/footer frames
   nsFrameItems  childFrames;
   nsIFrame* childFrame = aFrame->GetFirstPrincipalChild();
   for ( ; childFrame; childFrame = childFrame->GetNextSibling()) {
     // See if it's a header/footer, possibly wrapped in a scroll frame.
@@ -8087,20 +8103,20 @@ nsCSSFrameConstructor::CreateContinuingT
 
   // Set the table frame's initial child list
   newFrame->SetInitialChildList(kPrincipalList, childFrames);
 
   return newFrame;
 }
 
 nsIFrame*
-nsCSSFrameConstructor::CreateContinuingFrame(nsPresContext* aPresContext,
-                                             nsIFrame*       aFrame,
-                                             nsIFrame*       aParentFrame,
-                                             bool            aIsFluid)
+nsCSSFrameConstructor::CreateContinuingFrame(nsPresContext*    aPresContext,
+                                             nsIFrame*         aFrame,
+                                             nsContainerFrame* aParentFrame,
+                                             bool              aIsFluid)
 {
   nsIPresShell*              shell = aPresContext->PresShell();
   nsStyleContext*            styleContext = aFrame->StyleContext();
   nsIFrame*                  newFrame = nullptr;
   nsIFrame*                  nextContinuation = aFrame->GetNextContinuation();
   nsIFrame*                  nextInFlow = aFrame->GetNextInFlow();
 
   // Use the frame type to determine what type of frame to create
@@ -8123,17 +8139,17 @@ nsCSSFrameConstructor::CreateContinuingF
   } else if (nsGkAtoms::XULLabelFrame == frameType) {
     newFrame = NS_NewXULLabelFrame(shell, styleContext);
     newFrame->Init(content, aParentFrame, aFrame);
 #endif
   } else if (nsGkAtoms::columnSetFrame == frameType) {
     newFrame = NS_NewColumnSetFrame(shell, styleContext, nsFrameState(0));
     newFrame->Init(content, aParentFrame, aFrame);
   } else if (nsGkAtoms::pageFrame == frameType) {
-    nsIFrame* canvasFrame;
+    nsContainerFrame* canvasFrame;
     newFrame = ConstructPageFrame(shell, aPresContext, aParentFrame, aFrame,
                                   canvasFrame);
   } else if (nsGkAtoms::tableOuterFrame == frameType) {
     newFrame =
       CreateContinuingOuterTableFrame(shell, aPresContext, aFrame, aParentFrame,
                                       content, styleContext);
 
   } else if (nsGkAtoms::tableFrame == frameType) {
@@ -8157,17 +8173,18 @@ nsCSSFrameConstructor::CreateContinuingF
 
     // Create a continuing frame for each table cell frame
     nsFrameItems  newChildList;
     nsIFrame* cellFrame = aFrame->GetFirstPrincipalChild();
     while (cellFrame) {
       // See if it's a table cell frame
       if (IS_TABLE_CELL(cellFrame->GetType())) {
         nsIFrame* continuingCellFrame =
-          CreateContinuingFrame(aPresContext, cellFrame, newFrame);
+          CreateContinuingFrame(aPresContext, cellFrame,
+                                static_cast<nsContainerFrame*>(newFrame));
         newChildList.AddChild(continuingCellFrame);
       }
       cellFrame = cellFrame->GetNextSibling();
     }
 
     // Set the table cell's initial child list
     newFrame->SetInitialChildList(kPrincipalList, newChildList);
 
@@ -8180,17 +8197,18 @@ nsCSSFrameConstructor::CreateContinuingF
     newFrame->Init(content, aParentFrame, aFrame);
     if (newFrame->GetStateBits() & NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN) {
       nsTableFrame::RegisterPositionedTablePart(newFrame);
     }
 
     // Create a continuing area frame
     nsIFrame* blockFrame = aFrame->GetFirstPrincipalChild();
     nsIFrame* continuingBlockFrame =
-      CreateContinuingFrame(aPresContext, blockFrame, newFrame);
+      CreateContinuingFrame(aPresContext, blockFrame,
+                            static_cast<nsContainerFrame*>(newFrame));
 
     // Set the table cell's initial child list
     SetInitialSingleChild(newFrame, continuingBlockFrame);
   } else if (nsGkAtoms::lineFrame == frameType) {
     newFrame = NS_NewFirstLineFrame(shell, styleContext);
     newFrame->Init(content, aParentFrame, aFrame);
   } else if (nsGkAtoms::letterFrame == frameType) {
     newFrame = NS_NewFirstLetterFrame(shell, styleContext);
@@ -8215,17 +8233,18 @@ nsCSSFrameConstructor::CreateContinuingF
 
     newFrame->Init(content, aParentFrame, aFrame);
 
     // Create a continuing area frame
     // XXXbz we really shouldn't have to do this by hand!
     nsIFrame* blockFrame = GetFieldSetBlockFrame(aFrame);
     if (blockFrame) {
       nsIFrame* continuingBlockFrame =
-        CreateContinuingFrame(aPresContext, blockFrame, newFrame);
+        CreateContinuingFrame(aPresContext, blockFrame,
+                              static_cast<nsContainerFrame*>(newFrame));
       // Set the fieldset's initial child list
       SetInitialSingleChild(newFrame, continuingBlockFrame);
     } else {
       MOZ_ASSERT(aFrame->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER,
                  "FieldSet block may only be null for overflow containers");
     }
   } else if (nsGkAtoms::legendFrame == frameType) {
     newFrame = NS_NewLegendFrame(shell, styleContext);
@@ -8278,17 +8297,18 @@ nsCSSFrameConstructor::ReplicateFixedFra
   // Now deal with fixed-pos things....  They should appear on all pages,
   // so we want to move over the placeholders when processing the child
   // of the pageContentFrame.
 
   nsIFrame* prevPageContentFrame = aParentFrame->GetPrevInFlow();
   if (!prevPageContentFrame) {
     return NS_OK;
   }
-  nsIFrame* canvasFrame = aParentFrame->GetFirstPrincipalChild();
+  nsContainerFrame* canvasFrame =
+    do_QueryFrame(aParentFrame->GetFirstPrincipalChild());
   nsIFrame* prevCanvasFrame = prevPageContentFrame->GetFirstPrincipalChild();
   if (!canvasFrame || !prevCanvasFrame) {
     // document's root element frame missing
     return NS_ERROR_UNEXPECTED;
   }
 
   nsFrameItems fixedPlaceholders;
   nsIFrame* firstFixed = prevPageContentFrame->GetFirstChild(nsIFrame::kFixedList);
@@ -9230,17 +9250,17 @@ nsCSSFrameConstructor::CreateNeededTable
     // loop and see whether we need to skip it or wrap it in something
     // different.
   } while (!iter.IsDone());
 }
 
 inline void
 nsCSSFrameConstructor::ConstructFramesFromItemList(nsFrameConstructorState& aState,
                                                    FrameConstructionItemList& aItems,
-                                                   nsIFrame* aParentFrame,
+                                                   nsContainerFrame* aParentFrame,
                                                    nsFrameItems& aFrameItems)
 {
   CreateNeededTablePseudos(aState, aItems, aParentFrame);
   CreateNeededAnonFlexOrGridItems(aState, aItems, aParentFrame);
 
   aItems.SetTriedConstructingFrames();
   for (FCItemIterator iter(aItems); !iter.IsDone(); iter.Next()) {
     NS_ASSERTION(iter.item().DesiredParentType() == GetParentType(aParentFrame),
@@ -9250,17 +9270,17 @@ nsCSSFrameConstructor::ConstructFramesFr
 
   NS_ASSERTION(!aState.mHavePendingPopupgroup,
                "Should have proccessed it by now");
 }
 
 void
 nsCSSFrameConstructor::AddFCItemsForAnonymousContent(
             nsFrameConstructorState& aState,
-            nsIFrame* aFrame,
+            nsContainerFrame* aFrame,
             nsTArray<nsIAnonymousContentCreator::ContentInfo>& aAnonymousItems,
             FrameConstructionItemList& aItemsToConstruct,
             uint32_t aExtraFlags)
 {
   for (uint32_t i = 0; i < aAnonymousItems.Length(); ++i) {
     nsIContent* content = aAnonymousItems[i].mContent;
 #ifdef DEBUG
     nsIAnonymousContentCreator* creator = do_QueryFrame(aFrame);
@@ -9305,26 +9325,25 @@ nsCSSFrameConstructor::AddFCItemsForAnon
                                       anonChildren, aItemsToConstruct);
   }
 }
 
 void
 nsCSSFrameConstructor::ProcessChildren(nsFrameConstructorState& aState,
                                        nsIContent*              aContent,
                                        nsStyleContext*          aStyleContext,
-                                       nsIFrame*                aFrame,
+                                       nsContainerFrame*        aFrame,
                                        const bool               aCanHaveGeneratedContent,
                                        nsFrameItems&            aFrameItems,
                                        const bool               aAllowBlockStyles,
                                        PendingBinding*          aPendingBinding,
                                        nsIFrame*                aPossiblyLeafFrame)
 {
   NS_PRECONDITION(aFrame, "Must have parent frame here");
-  NS_PRECONDITION(!aFrame->GetContentInsertionFrame() ||
-                  aFrame->GetContentInsertionFrame() == aFrame,
+  NS_PRECONDITION(aFrame->GetContentInsertionFrame() == aFrame,
                   "Parent frame in ProcessChildren should be its own "
                   "content insertion frame");
   const uint32_t kMaxDepth = 2 * MAX_REFLOW_DEPTH;
   static_assert(kMaxDepth <= UINT16_MAX, "mCurrentDepth type is too narrow");
   AutoRestore<uint16_t> savedDepth(mCurrentDepth);
   if (mCurrentDepth != UINT16_MAX) {
     ++mCurrentDepth;
   }
@@ -9342,17 +9361,18 @@ nsCSSFrameConstructor::ProcessChildren(n
                                 &haveFirstLineStyle);
   }
 
   // The logic here needs to match the logic in GetFloatContainingBlock()
   nsFrameConstructorSaveState floatSaveState;
   if (ShouldSuppressFloatingOfDescendants(aFrame)) {
     aState.PushFloatContainingBlock(nullptr, floatSaveState);
   } else if (aFrame->IsFloatContainingBlock()) {
-    aState.PushFloatContainingBlock(aFrame, floatSaveState);
+    aState.PushFloatContainingBlock(static_cast<nsContainerFrame*>(aFrame),
+                                    floatSaveState);
   }
 
   nsFrameConstructorState::PendingBindingAutoPusher pusher(aState,
                                                            aPendingBinding);
 
   FrameConstructionItemList itemsToConstruct;
 
   // If we have first-letter or first-line style then frames can get
@@ -9522,17 +9542,17 @@ nsCSSFrameConstructor::ProcessChildren(n
 // ContentAppended is inserting content, which may be some
 // non-first-in-flow continuation of the block to which the first-line
 // belongs. So this function needs to be careful about how it uses
 // aState.
 void
 nsCSSFrameConstructor::WrapFramesInFirstLineFrame(
   nsFrameConstructorState& aState,
   nsIContent*              aBlockContent,
-  nsIFrame*                aBlockFrame,
+  nsContainerFrame*        aBlockFrame,
   nsFirstLineFrame*        aLineFrame,
   nsFrameItems&            aFrameItems)
 {
   // Find the part of aFrameItems that we want to put in the first-line
   nsFrameList::FrameLinkEnumerator link(aFrameItems);
   while (!link.AtEnd() && link.NextFrame()->IsInlineOutside()) {
     link.Next();
   }
@@ -9579,17 +9599,17 @@ nsCSSFrameConstructor::WrapFramesInFirst
 
 // Special routine to handle appending a new frame to a block frame's
 // child list. Takes care of placing the new frame into the right
 // place when first-line style is present.
 void
 nsCSSFrameConstructor::AppendFirstLineFrames(
   nsFrameConstructorState& aState,
   nsIContent*              aBlockContent,
-  nsIFrame*                aBlockFrame,
+  nsContainerFrame*        aBlockFrame,
   nsFrameItems&            aFrameItems)
 {
   // It's possible that aBlockFrame needs to have a first-line frame
   // created because it doesn't currently have any children.
   const nsFrameList& blockKids = aBlockFrame->PrincipalChildList();
   if (blockKids.IsEmpty()) {
     WrapFramesInFirstLineFrame(aState, aBlockContent,
                                aBlockFrame, nullptr, aFrameItems);
@@ -9615,17 +9635,17 @@ nsCSSFrameConstructor::AppendFirstLineFr
 // Special routine to handle inserting a new frame into a block
 // frame's child list. Takes care of placing the new frame into the
 // right place when first-line style is present.
 nsresult
 nsCSSFrameConstructor::InsertFirstLineFrames(
   nsFrameConstructorState& aState,
   nsIContent*              aContent,
   nsIFrame*                aBlockFrame,
-  nsContainerFrame**               aParentFrame,
+  nsContainerFrame**       aParentFrame,
   nsIFrame*                aPrevSibling,
   nsFrameItems&            aFrameItems)
 {
   nsresult rv = NS_OK;
   // XXXbz If you make this method actually do something, check to
   // make sure that the caller is passing what you expect.  In
   // particular, which content is aContent?  And audit the rest of
   // this code too; it makes bogus assumptions and may not build.
@@ -9823,42 +9843,39 @@ static bool IsFirstLetterContent(nsICont
 }
 
 /**
  * Create a letter frame, only make it a floating frame.
  */
 void
 nsCSSFrameConstructor::CreateFloatingLetterFrame(
   nsFrameConstructorState& aState,
-  nsIFrame* aBlockFrame,
+  nsContainerFrame* aBlockFrame,
   nsIContent* aTextContent,
   nsIFrame* aTextFrame,
-  nsIContent* aBlockContent,
-  nsIFrame* aParentFrame,
+  nsContainerFrame* aParentFrame,
   nsStyleContext* aStyleContext,
   nsFrameItems& aResult)
 {
-  // Create the first-letter-frame
-  nsIFrame* letterFrame;
-  nsStyleSet *styleSet = mPresShell->StyleSet();
-
-  letterFrame = NS_NewFirstLetterFrame(mPresShell, aStyleContext);
+  nsFirstLetterFrame* letterFrame =
+    NS_NewFirstLetterFrame(mPresShell, aStyleContext);
   // We don't want to use a text content for a non-text frame (because we want
   // its primary frame to be a text frame).  So use its parent for the
   // first-letter.
   nsIContent* letterContent = aTextContent->GetParent();
-  nsIFrame* containingBlock = aState.GetGeometricParent(
+  nsContainerFrame* containingBlock = aState.GetGeometricParent(
     aStyleContext->StyleDisplay(), aParentFrame);
   InitAndRestoreFrame(aState, letterContent, containingBlock, letterFrame);
 
   // Init the text frame to refer to the letter frame. Make sure we
   // get a proper style context for it (the one passed in is for the
   // letter frame and will have the float property set on it; the text
   // frame shouldn't have that set).
   nsRefPtr<nsStyleContext> textSC;
+  nsStyleSet* styleSet = mPresShell->StyleSet();
   textSC = styleSet->ResolveStyleForNonElement(aStyleContext);
   aTextFrame->SetStyleContextWithoutNotification(textSC);
   InitAndRestoreFrame(aState, aTextContent, letterFrame, aTextFrame);
 
   // And then give the text frame to the letter frame
   SetInitialSingleChild(letterFrame, aTextFrame);
 
   // See if we will need to continue the text frame (does it contain
@@ -9896,20 +9913,20 @@ nsCSSFrameConstructor::CreateFloatingLet
   }
 }
 
 /**
  * Create a new letter frame for aTextFrame. The letter frame will be
  * a child of aParentFrame.
  */
 void
-nsCSSFrameConstructor::CreateLetterFrame(nsIFrame* aBlockFrame,
-                                         nsIFrame* aBlockContinuation,
+nsCSSFrameConstructor::CreateLetterFrame(nsContainerFrame* aBlockFrame,
+                                         nsContainerFrame* aBlockContinuation,
                                          nsIContent* aTextContent,
-                                         nsIFrame* aParentFrame,
+                                         nsContainerFrame* aParentFrame,
                                          nsFrameItems& aResult)
 {
   NS_PRECONDITION(aTextContent->IsNodeOfType(nsINode::eTEXT),
                   "aTextContent isn't text");
   NS_ASSERTION(nsLayoutUtils::GetAsBlock(aBlockFrame),
                  "Not a block frame?");
 
   // Get style context for the first-letter-frame
@@ -9946,21 +9963,21 @@ nsCSSFrameConstructor::CreateLetterFrame
                                   GetAbsoluteContainingBlock(aParentFrame, ABS_POS),
                                   aBlockContinuation);
 
     // Create the right type of first-letter frame
     const nsStyleDisplay* display = sc->StyleDisplay();
     if (display->IsFloatingStyle() && !aParentFrame->IsSVGText()) {
       // Make a floating first-letter frame
       CreateFloatingLetterFrame(state, aBlockFrame, aTextContent, textFrame,
-                                blockContent, aParentFrame, sc, aResult);
+                                aParentFrame, sc, aResult);
     }
     else {
       // Make an inflow first-letter frame
-      nsIFrame* letterFrame = NS_NewFirstLetterFrame(mPresShell, sc);
+      nsFirstLetterFrame* letterFrame = NS_NewFirstLetterFrame(mPresShell, sc);
 
       // Initialize the first-letter-frame.  We don't want to use a text
       // content for a non-text frame (because we want its primary frame to
       // be a text frame).  So use its parent for the first-letter.
       nsIContent* letterContent = aTextContent->GetParent();
       letterFrame->Init(letterContent, aParentFrame, nullptr);
 
       InitAndRestoreFrame(state, aTextContent, letterFrame, textFrame);
@@ -9974,22 +9991,22 @@ nsCSSFrameConstructor::CreateLetterFrame
     }
     aTextContent->SetPrimaryFrame(textFrame);
   }
 }
 
 void
 nsCSSFrameConstructor::WrapFramesInFirstLetterFrame(
   nsIContent*              aBlockContent,
-  nsIFrame*                aBlockFrame,
+  nsContainerFrame*        aBlockFrame,
   nsFrameItems&            aBlockFrames)
 {
   aBlockFrame->AddStateBits(NS_BLOCK_HAS_FIRST_LETTER_STYLE);
 
-  nsIFrame* parentFrame = nullptr;
+  nsContainerFrame* parentFrame = nullptr;
   nsIFrame* textFrame = nullptr;
   nsIFrame* prevFrame = nullptr;
   nsFrameItems letterFrames;
   bool stopLooking = false;
   WrapFramesInFirstLetterFrame(aBlockFrame, aBlockFrame, aBlockFrame,
                                aBlockFrames.FirstChild(),
                                &parentFrame, &textFrame, &prevFrame,
                                letterFrames, &stopLooking);
@@ -10007,25 +10024,25 @@ nsCSSFrameConstructor::WrapFramesInFirst
       // Insert in the letter frame(s)
       parentFrame->InsertFrames(kPrincipalList, prevFrame, letterFrames);
     }
   }
 }
 
 void
 nsCSSFrameConstructor::WrapFramesInFirstLetterFrame(
-  nsIFrame*                aBlockFrame,
-  nsIFrame*                aBlockContinuation,
-  nsIFrame*                aParentFrame,
+  nsContainerFrame*        aBlockFrame,
+  nsContainerFrame*        aBlockContinuation,
+  nsContainerFrame*        aParentFrame,
   nsIFrame*                aParentFrameList,
-  nsIFrame**               aModifiedParent,
+  nsContainerFrame**       aModifiedParent,
   nsIFrame**               aTextFrame,
   nsIFrame**               aPrevFrame,
   nsFrameItems&            aLetterFrames,
-  bool*                  aStopLooking)
+  bool*                    aStopLooking)
 {
   nsIFrame* prevFrame = nullptr;
   nsIFrame* frame = aParentFrameList;
 
   while (frame) {
     nsIFrame* nextFrame = frame->GetNextSibling();
 
     nsIAtom* frameType = frame->GetType();
@@ -10042,17 +10059,18 @@ nsCSSFrameConstructor::WrapFramesInFirst
         *aTextFrame = frame;
         *aPrevFrame = prevFrame;
         *aStopLooking = true;
         return;
       }
     }
     else if (IsInlineFrame(frame) && frameType != nsGkAtoms::brFrame) {
       nsIFrame* kids = frame->GetFirstPrincipalChild();
-      WrapFramesInFirstLetterFrame(aBlockFrame, aBlockContinuation, frame,
+      WrapFramesInFirstLetterFrame(aBlockFrame, aBlockContinuation,
+                                   static_cast<nsContainerFrame*>(frame),
                                    kids, aModifiedParent, aTextFrame,
                                    aPrevFrame, aLetterFrames, aStopLooking);
       if (*aStopLooking) {
         return;
       }
     }
     else {
       // This will stop us looking to create more letter frames. For
@@ -10103,24 +10121,22 @@ nsCSSFrameConstructor::RemoveFloatingFir
   // Take the text frame away from the letter frame (so it isn't
   // destroyed when we destroy the letter frame).
   nsIFrame* textFrame = floatFrame->GetFirstPrincipalChild();
   if (!textFrame) {
     return NS_OK;
   }
 
   // Discover the placeholder frame for the letter frame
-  nsIFrame* parentFrame;
   nsPlaceholderFrame* placeholderFrame = GetPlaceholderFrameFor(floatFrame);
-
   if (!placeholderFrame) {
     // Somethings really wrong
     return NS_OK;
   }
-  parentFrame = placeholderFrame->GetParent();
+  nsContainerFrame* parentFrame = placeholderFrame->GetParent();
   if (!parentFrame) {
     // Somethings really wrong
     return NS_OK;
   }
 
   // Create a new text frame with the right style context that maps
   // all of the content that was previously part of the letter frame
   // (and probably continued elsewhere).
@@ -10174,18 +10190,18 @@ nsCSSFrameConstructor::RemoveFloatingFir
   }
 
   return NS_OK;
 }
 
 nsresult
 nsCSSFrameConstructor::RemoveFirstLetterFrames(nsPresContext* aPresContext,
                                                nsIPresShell* aPresShell,
-                                               nsIFrame* aFrame,
-                                               nsIFrame* aBlockFrame,
+                                               nsContainerFrame* aFrame,
+                                               nsContainerFrame* aBlockFrame,
                                                bool* aStopLooking)
 {
   nsIFrame* prevSibling = nullptr;
   nsIFrame* kid = aFrame->GetFirstPrincipalChild();
 
   while (kid) {
     if (nsGkAtoms::letterFrame == kid->GetType()) {
       // Bingo. Found it. First steal away the text frame.
@@ -10234,99 +10250,104 @@ nsCSSFrameConstructor::RemoveFirstLetter
       NS_ASSERTION(!aBlockFrame->GetPrevContinuation(),
                    "should have the first continuation here");
       aBlockFrame->RemoveStateBits(NS_BLOCK_HAS_FIRST_LETTER_CHILD);
       break;
     }
     else if (IsInlineFrame(kid)) {
       // Look inside child inline frame for the letter frame
       RemoveFirstLetterFrames(aPresContext, aPresShell,
-                              kid, aBlockFrame, aStopLooking);
+                              static_cast<nsContainerFrame*>(kid),
+                              aBlockFrame, aStopLooking);
       if (*aStopLooking) {
         break;
       }
     }
     prevSibling = kid;
     kid = kid->GetNextSibling();
   }
 
   return NS_OK;
 }
 
 nsresult
 nsCSSFrameConstructor::RemoveLetterFrames(nsPresContext* aPresContext,
                                           nsIPresShell* aPresShell,
-                                          nsIFrame* aBlockFrame)
-{
-  aBlockFrame = aBlockFrame->FirstContinuation();
-  nsIFrame* continuation = aBlockFrame;
+                                          nsContainerFrame* aBlockFrame)
+{
+  aBlockFrame =
+    static_cast<nsContainerFrame*>(aBlockFrame->FirstContinuation());
+  nsContainerFrame* continuation = aBlockFrame;
 
   bool stopLooking = false;
   nsresult rv;
   do {
     rv = RemoveFloatingFirstLetterFrames(aPresContext, aPresShell,
                                          continuation, &stopLooking);
     if (NS_SUCCEEDED(rv) && !stopLooking) {
       rv = RemoveFirstLetterFrames(aPresContext, aPresShell,
                                    continuation, aBlockFrame, &stopLooking);
     }
     if (stopLooking) {
       break;
     }
-    continuation = continuation->GetNextContinuation();
+    continuation =
+      static_cast<nsContainerFrame*>(continuation->GetNextContinuation());
   }  while (continuation);
   return rv;
 }
 
 // Fixup the letter frame situation for the given block
 void
-nsCSSFrameConstructor::RecoverLetterFrames(nsIFrame* aBlockFrame)
-{
-  aBlockFrame = aBlockFrame->FirstContinuation();
-  nsIFrame* continuation = aBlockFrame;
-
-  nsIFrame* parentFrame = nullptr;
+nsCSSFrameConstructor::RecoverLetterFrames(nsContainerFrame* aBlockFrame)
+{
+  aBlockFrame =
+    static_cast<nsContainerFrame*>(aBlockFrame->FirstContinuation());
+  nsContainerFrame* continuation = aBlockFrame;
+
+  nsContainerFrame* parentFrame = nullptr;
   nsIFrame* textFrame = nullptr;
   nsIFrame* prevFrame = nullptr;
   nsFrameItems letterFrames;
   bool stopLooking = false;
   do {
     // XXX shouldn't this bit be set already (bug 408493), assert instead?
     continuation->AddStateBits(NS_BLOCK_HAS_FIRST_LETTER_STYLE);
     WrapFramesInFirstLetterFrame(aBlockFrame, continuation, continuation,
                                  continuation->GetFirstPrincipalChild(),
                                  &parentFrame, &textFrame, &prevFrame,
                                  letterFrames, &stopLooking);
     if (stopLooking) {
       break;
     }
-    continuation = continuation->GetNextContinuation();
+    continuation =
+      static_cast<nsContainerFrame*>(continuation->GetNextContinuation());
   } while (continuation);
 
   if (parentFrame) {
     // Take the old textFrame out of the parents child list
     RemoveFrame(kPrincipalList, textFrame);
 
     // Insert in the letter frame(s)
     parentFrame->InsertFrames(kPrincipalList, prevFrame, letterFrames);
   }
 }
 
 //----------------------------------------------------------------------
 
 // listbox Widget Routines
 
 nsresult
-nsCSSFrameConstructor::CreateListBoxContent(nsPresContext* aPresContext,
-                                            nsIFrame*       aParentFrame,
-                                            nsIFrame*       aPrevFrame,
-                                            nsIContent*     aChild,
-                                            nsIFrame**      aNewFrame,
-                                            bool            aIsAppend,
-                                            bool            aIsScrollbar,
+nsCSSFrameConstructor::CreateListBoxContent(nsPresContext*         aPresContext,
+                                            nsContainerFrame*      aParentFrame,
+                                            nsIFrame*              aPrevFrame,
+                                            nsIContent*            aChild,
+                                            nsIFrame**             aNewFrame,
+                                            bool                   aIsAppend,
+                                            bool                   aIsScrollbar,
                                             nsILayoutHistoryState* aFrameState)
 {
 #ifdef MOZ_XUL
   nsresult rv = NS_OK;
 
   // Construct a new frame
   if (nullptr != aParentFrame) {
     nsFrameItems            frameItems;
@@ -10390,35 +10411,34 @@ nsCSSFrameConstructor::CreateListBoxCont
 }
 
 //----------------------------------------
 
 void
 nsCSSFrameConstructor::ConstructBlock(nsFrameConstructorState& aState,
                                       const nsStyleDisplay*    aDisplay,
                                       nsIContent*              aContent,
-                                      nsIFrame*                aParentFrame,
-                                      nsIFrame*                aContentParentFrame,
+                                      nsContainerFrame*        aParentFrame,
+                                      nsContainerFrame*        aContentParentFrame,
                                       nsStyleContext*          aStyleContext,
-                                      nsIFrame**               aNewFrame,
+                                      nsContainerFrame**       aNewFrame,
                                       nsFrameItems&            aFrameItems,
                                       nsIFrame*                aPositionedFrameForAbsPosContainer,
                                       PendingBinding*          aPendingBinding)
 {
   // Create column wrapper if necessary
-  nsIFrame* blockFrame = *aNewFrame;
+  nsContainerFrame* blockFrame = *aNewFrame;
   NS_ASSERTION(blockFrame->GetType() == nsGkAtoms::blockFrame, "not a block frame?");
-  nsIFrame* parent = aParentFrame;
+  nsContainerFrame* parent = aParentFrame;
   nsRefPtr<nsStyleContext> blockStyle = aStyleContext;
   const nsStyleColumn* columns = aStyleContext->StyleColumn();
 
   if (columns->mColumnCount != NS_STYLE_COLUMN_COUNT_AUTO
       || columns->mColumnWidth.GetUnit() != eStyleUnit_Auto) {
-    nsIFrame* columnSetFrame = nullptr;
-    columnSetFrame =
+    nsContainerFrame* columnSetFrame =
       NS_NewColumnSetFrame(mPresShell, aStyleContext, nsFrameState(0));
 
     InitAndRestoreFrame(aState, aContent, aParentFrame, columnSetFrame);
     blockStyle = mPresShell->StyleSet()->
       ResolveAnonymousBoxStyle(nsCSSAnonBoxes::columnContent, aStyleContext);
     parent = columnSetFrame;
     *aNewFrame = columnSetFrame;
 
@@ -10458,17 +10478,17 @@ nsCSSFrameConstructor::ConstructBlock(ns
 
   // Set the frame's initial child list
   blockFrame->SetInitialChildList(kPrincipalList, childItems);
 }
 
 nsIFrame*
 nsCSSFrameConstructor::ConstructInline(nsFrameConstructorState& aState,
                                        FrameConstructionItem&   aItem,
-                                       nsIFrame*                aParentFrame,
+                                       nsContainerFrame*        aParentFrame,
                                        const nsStyleDisplay*    aDisplay,
                                        nsFrameItems&            aFrameItems)
 {
   // If an inline frame has non-inline kids, then we chop up the child list
   // into runs of blocks and runs of inlines, create anonymous block frames to
   // contain the runs of blocks, inline frames with our style context for the
   // runs of inlines, and put all these frames, in order, into aFrameItems.  We
   // return the the first one.  The whole setup is called an {ib}
@@ -10527,17 +10547,17 @@ nsCSSFrameConstructor::ConstructInline(n
   nsIContent* const content = aItem.mContent;
   nsStyleContext* const styleContext = aItem.mStyleContext;
 
   bool positioned =
     NS_STYLE_DISPLAY_INLINE == aDisplay->mDisplay &&
     aDisplay->IsRelativelyPositionedStyle() &&
     !aParentFrame->IsSVGText();
 
-  nsIFrame* newFrame = NS_NewInlineFrame(mPresShell, styleContext);
+  nsInlineFrame* newFrame = NS_NewInlineFrame(mPresShell, styleContext);
 
   // Initialize the frame
   InitAndRestoreFrame(aState, content, aParentFrame, newFrame);
 
   // Inline frames can always have generated content
   newFrame->AddStateBits(NS_FRAME_MAY_HAVE_GENERATED_CONTENT);
 
   nsFrameConstructorSaveState absoluteSaveState;  // definition cannot be inside next block
@@ -10583,71 +10603,68 @@ nsCSSFrameConstructor::ConstructInline(n
 
   CreateIBSiblings(aState, newFrame, positioned, childItems, aFrameItems);
 
   return newFrame;
 }
 
 void
 nsCSSFrameConstructor::CreateIBSiblings(nsFrameConstructorState& aState,
-                                        nsIFrame* aInitialInline,
+                                        nsContainerFrame* aInitialInline,
                                         bool aIsPositioned,
                                         nsFrameItems& aChildItems,
                                         nsFrameItems& aSiblings)
 {
   nsIContent* content = aInitialInline->GetContent();
   nsStyleContext* styleContext = aInitialInline->StyleContext();
-  nsIFrame* parentFrame = aInitialInline->GetParent();
+  nsContainerFrame* parentFrame = aInitialInline->GetParent();
 
   // Resolve the right style context for our anonymous blocks.
   // The distinction in styles is needed because of CSS 2.1, section
   // 9.2.1.1, which says:
   //   When such an inline box is affected by relative positioning, any
   //   resulting translation also affects the block-level box contained
   //   in the inline box.
   nsRefPtr<nsStyleContext> blockSC =
     mPresShell->StyleSet()->
       ResolveAnonymousBoxStyle(aIsPositioned ?
                                  nsCSSAnonBoxes::mozAnonymousPositionedBlock :
                                  nsCSSAnonBoxes::mozAnonymousBlock,
                                styleContext);
 
-  nsIFrame* lastNewInline = aInitialInline->FirstContinuation();
+  nsContainerFrame* lastNewInline =
+    static_cast<nsContainerFrame*>(aInitialInline->FirstContinuation());
   do {
     // On entry to this loop aChildItems is not empty and the first frame in it
     // is block-level.
     NS_PRECONDITION(aChildItems.NotEmpty(), "Should have child items");
     NS_PRECONDITION(!aChildItems.FirstChild()->IsInlineOutside(),
                     "Must have list starting with block");
 
     // The initial run of blocks belongs to an anonymous block that we create
     // right now. The anonymous block will be the parent of these block
     // children of the inline.
-    nsIFrame* blockFrame;
-    blockFrame = NS_NewBlockFrame(mPresShell, blockSC);
-
+    nsBlockFrame* blockFrame = NS_NewBlockFrame(mPresShell, blockSC);
     InitAndRestoreFrame(aState, content, parentFrame, blockFrame, false);
 
     // Find the first non-block child which defines the end of our block kids
     // and the start of our next inline's kids
     nsFrameList::FrameLinkEnumerator firstNonBlock =
       FindFirstNonBlock(aChildItems);
     nsFrameList blockKids = aChildItems.ExtractHead(firstNonBlock);
 
     MoveChildrenTo(aState.mPresContext, aInitialInline, blockFrame, blockKids);
 
     SetFrameIsIBSplit(lastNewInline, blockFrame);
     aSiblings.AddChild(blockFrame);
 
     // Now grab the initial inlines in aChildItems and put them into an inline
-    // frame
-    nsIFrame* inlineFrame = NS_NewInlineFrame(mPresShell, styleContext);
-
+    // frame.
+    nsInlineFrame* inlineFrame = NS_NewInlineFrame(mPresShell, styleContext);
     InitAndRestoreFrame(aState, content, parentFrame, inlineFrame, false);
-
     inlineFrame->AddStateBits(NS_FRAME_MAY_HAVE_GENERATED_CONTENT |
                               NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN);
     if (aIsPositioned) {
       inlineFrame->MarkAsAbsoluteContainingBlock();
     }
 
     if (aChildItems.NotEmpty()) {
       nsFrameList::FrameLinkEnumerator firstBlock(aChildItems);
@@ -11173,17 +11190,17 @@ nsCSSFrameConstructor::ReframeContaining
   }
 
   // If we get here, we're screwed!
   return RecreateFramesForContent(mPresShell->GetDocument()->GetRootElement(),
 				  true);
 }
 
 nsresult
-nsCSSFrameConstructor::GenerateChildFrames(nsIFrame* aFrame)
+nsCSSFrameConstructor::GenerateChildFrames(nsContainerFrame* aFrame)
 {
   {
     nsAutoScriptBlocker scriptBlocker;
     BeginUpdate();
 
     nsFrameItems childItems;
     nsFrameConstructorState state(mPresShell, nullptr, nullptr, nullptr);
     // We don't have a parent frame with a pending binding constructor here,
--- a/layout/base/nsCSSFrameConstructor.h
+++ b/layout/base/nsCSSFrameConstructor.h
@@ -205,79 +205,79 @@ public:
   // If aContent is a text node that has been optimized away due to being
   // whitespace next to a block boundary (or for some other reason), stop
   // doing that and create a frame for it if it should have one. This recreates
   // frames so be careful (although this should not change actual layout).
   // Returns the frame for aContent if there is one.
   nsIFrame* EnsureFrameForTextNode(nsGenericDOMDataNode* aContent);
 
   // generate the child frames and process bindings
-  nsresult GenerateChildFrames(nsIFrame* aFrame);
+  nsresult GenerateChildFrames(nsContainerFrame* aFrame);
 
   // Should be called when a frame is going to be destroyed and
   // WillDestroyFrameTree hasn't been called yet.
   void NotifyDestroyingFrame(nsIFrame* aFrame);
 
   void BeginUpdate();
   void EndUpdate();
   void RecalcQuotesAndCounters();
 
   // Gets called when the presshell is destroying itself and also
   // when we tear down our frame tree to reconstruct it
   void WillDestroyFrameTree();
 
   // Request to create a continuing frame.  This method never returns null.
-  nsIFrame* CreateContinuingFrame(nsPresContext* aPresContext,
-                                  nsIFrame*       aFrame,
-                                  nsIFrame*       aParentFrame,
-                                  bool            aIsFluid = true);
+  nsIFrame* CreateContinuingFrame(nsPresContext*    aPresContext,
+                                  nsIFrame*         aFrame,
+                                  nsContainerFrame* aParentFrame,
+                                  bool              aIsFluid = true);
 
   // Copy over fixed frames from aParentFrame's prev-in-flow
   nsresult ReplicateFixedFrames(nsPageContentFrame* aParentFrame);
 
   // Get the XBL insertion point for a child
   nsContainerFrame* GetInsertionPoint(nsIContent* aContainer,
                                       nsIContent* aChildContent,
                                       bool*       aMultiple = nullptr);
 
-  nsresult CreateListBoxContent(nsPresContext* aPresContext,
-                                nsIFrame*       aParentFrame,
-                                nsIFrame*       aPrevFrame,
-                                nsIContent*     aChild,
-                                nsIFrame**      aResult,
-                                bool            aIsAppend,
-                                bool            aIsScrollbar,
+  nsresult CreateListBoxContent(nsPresContext*    aPresContext,
+                                nsContainerFrame* aParentFrame,
+                                nsIFrame*         aPrevFrame,
+                                nsIContent*       aChild,
+                                nsIFrame**        aResult,
+                                bool              aIsAppend,
+                                bool              aIsScrollbar,
                                 nsILayoutHistoryState* aFrameState);
 
   // GetInitialContainingBlock() is deprecated in favor of GetRootElementFrame();
   // nsIFrame* GetInitialContainingBlock() { return mRootElementFrame; }
   // This returns the outermost frame for the root element
-  nsIFrame* GetRootElementFrame() { return mRootElementFrame; }
+  nsContainerFrame* GetRootElementFrame() { return mRootElementFrame; }
   // This returns the frame for the root element that does not
   // have a psuedo-element style
   nsIFrame* GetRootElementStyleFrame() { return mRootElementStyleFrame; }
   nsIFrame* GetPageSequenceFrame() { return mPageSequenceFrame; }
 
   // Get the frame that is the parent of the root element.
-  nsIFrame* GetDocElementContainingBlock()
+  nsContainerFrame* GetDocElementContainingBlock()
     { return mDocElementContainingBlock; }
 
 private:
   struct FrameConstructionItem;
   class FrameConstructionItemList;
 
-  nsIFrame* ConstructPageFrame(nsIPresShell*  aPresShell,
-                               nsPresContext* aPresContext,
-                               nsIFrame*      aParentFrame,
-                               nsIFrame*      aPrevPageFrame,
-                               nsIFrame*&     aCanvasFrame);
+  nsContainerFrame* ConstructPageFrame(nsIPresShell*      aPresShell,
+                                       nsPresContext*     aPresContext,
+                                       nsContainerFrame*  aParentFrame,
+                                       nsIFrame*          aPrevPageFrame,
+                                       nsContainerFrame*& aCanvasFrame);
 
   void InitAndRestoreFrame (const nsFrameConstructorState& aState,
                             nsIContent*                    aContent,
-                            nsIFrame*                      aParentFrame,
+                            nsContainerFrame*              aParentFrame,
                             nsIFrame*                      aNewFrame,
                             bool                           aAllowCounters = true);
 
   // aState can be null if not available; it's used as an optimization.
   // XXXbz IsValidSibling is the only caller that doesn't pass a state here!
   already_AddRefed<nsStyleContext>
   ResolveStyleContext(nsIFrame*         aParentFrame,
                       nsIContent*       aContent,
@@ -290,17 +290,17 @@ private:
   // Add the frame construction items for the given aContent and aParentFrame
   // to the list.  This might add more than one item in some rare cases.
   // If aSuppressWhiteSpaceOptimizations is true, optimizations that
   // may suppress the construction of white-space-only text frames
   // must be skipped for these items and items around them.
   void AddFrameConstructionItems(nsFrameConstructorState& aState,
                                  nsIContent*              aContent,
                                  bool                     aSuppressWhiteSpaceOptimizations,
-                                 nsIFrame*                aParentFrame,
+                                 nsContainerFrame*        aParentFrame,
                                  FrameConstructionItemList& aItems);
 
   // Construct the frames for the document element.  This can return null if the
   // document element is display:none, or if the document element has a
   // not-yet-loaded XBL binding, or if it's an SVG element that's not <svg>.
   nsIFrame* ConstructDocElementFrame(Element*                 aDocElement,
                                      nsILayoutHistoryState*   aFrameState);
 
@@ -351,68 +351,68 @@ private:
    */
   already_AddRefed<nsIContent> CreateGeneratedContent(nsFrameConstructorState& aState,
                                                       nsIContent*     aParentContent,
                                                       nsStyleContext* aStyleContext,
                                                       uint32_t        aContentIndex);
 
   // aFrame may be null; this method doesn't use it directly in any case.
   void CreateGeneratedContentItem(nsFrameConstructorState&   aState,
-                                  nsIFrame*                  aFrame,
+                                  nsContainerFrame*          aFrame,
                                   nsIContent*                aContent,
                                   nsStyleContext*            aStyleContext,
                                   nsCSSPseudoElements::Type  aPseudoElement,
                                   FrameConstructionItemList& aItems);
 
   // This method can change aFrameList: it can chop off the beginning and put
   // it in aParentFrame while putting the remainder into a ib-split sibling of
   // aParentFrame.  aPrevSibling must be the frame after which aFrameList is to
   // be placed on aParentFrame's principal child list.  It may be null if
   // aFrameList is being added at the beginning of the child list.
   nsresult AppendFramesToParent(nsFrameConstructorState&       aState,
-                                nsIFrame*                      aParentFrame,
+                                nsContainerFrame*              aParentFrame,
                                 nsFrameItems&                  aFrameList,
                                 nsIFrame*                      aPrevSibling,
                                 bool                           aIsRecursiveCall = false);
 
   // BEGIN TABLE SECTION
   /**
    * Construct an outer table frame.  This is the FrameConstructionData
    * callback used for the job.
    */
   nsIFrame* ConstructTable(nsFrameConstructorState& aState,
                            FrameConstructionItem&   aItem,
-                           nsIFrame*                aParentFrame,
+                           nsContainerFrame*        aParentFrame,
                            const nsStyleDisplay*    aDisplay,
                            nsFrameItems&            aFrameItems);
 
   /**
    * FrameConstructionData callback for constructing table rows and row groups.
    */
   nsIFrame* ConstructTableRowOrRowGroup(nsFrameConstructorState& aState,
                                         FrameConstructionItem&   aItem,
-                                        nsIFrame*                aParentFrame,
+                                        nsContainerFrame*        aParentFrame,
                                         const nsStyleDisplay*    aStyleDisplay,
                                         nsFrameItems&            aFrameItems);
 
   /**
    * FrameConstructionData callback used for constructing table columns.
    */
   nsIFrame* ConstructTableCol(nsFrameConstructorState& aState,
                               FrameConstructionItem&   aItem,
-                              nsIFrame*                aParentFrame,
+                              nsContainerFrame*        aParentFrame,
                               const nsStyleDisplay*    aStyleDisplay,
                               nsFrameItems&            aFrameItems);
 
   /**
    * FrameConstructionData callback used for constructing table cells.
    */
   nsIFrame* ConstructTableCell(nsFrameConstructorState& aState,
                                FrameConstructionItem&   aItem,
-                               nsIFrame*                aParentFrame,
+                               nsContainerFrame*        aParentFrame,
                                const nsStyleDisplay*    aStyleDisplay,
                                nsFrameItems&            aFrameItems);
 
 private:
   /* An enum of possible parent types for anonymous table object construction */
   enum ParentType {
     eTypeBlock = 0, /* This includes all non-table-related frames */
     eTypeRow,
@@ -443,16 +443,17 @@ private:
   /* A constructor function that just creates an nsIFrame object.  The caller
      is responsible for initializing the object, adding it to frame lists,
      constructing frames for the children, etc.
 
      @param nsIPresShell the presshell whose arena should be used to allocate
                          the frame.
      @param nsStyleContext the style context to use for the frame. */
   typedef nsIFrame* (* FrameCreationFunc)(nsIPresShell*, nsStyleContext*);
+  typedef nsContainerFrame* (* ContainerFrameCreationFunc)(nsIPresShell*, nsStyleContext*);
 
   /* A function that can be used to get a FrameConstructionData.  Such
      a function is allowed to return null.
 
      @param nsIContent the node for which the frame is being constructed.
      @param nsStyleContext the style context to be used for the frame.
   */
   struct FrameConstructionData;
@@ -477,17 +478,17 @@ private:
      @param aFrameItems the frame list to add the new frame (or its
                         placeholder) to.
      @return the frame that was constructed.  This frame is what the caller
              will set as the frame on the content.  Guaranteed non-null.
   */
   typedef nsIFrame*
     (nsCSSFrameConstructor::* FrameFullConstructor)(nsFrameConstructorState& aState,
                                                     FrameConstructionItem& aItem,
-                                                    nsIFrame* aParentFrame,
+                                                    nsContainerFrame* aParentFrame,
                                                     const nsStyleDisplay* aStyleDisplay,
                                                     nsFrameItems& aFrameItems);
 
   /* Bits that modify the way a FrameConstructionData is handled */
 
   /* If the FCDATA_SKIP_FRAMESET bit is set, then the frame created should not
      be set as the primary frame on the content node.  This should only be used
      in very rare cases when we create more than one frame for a given content
@@ -1048,63 +1049,63 @@ private:
    * @param aFCData the FrameConstructionData that would be used for frame
    *        construction.
    * @param aStyleContext the style context for aChildContent
    */
   // XXXbz this function should really go away once we rework pseudo-frame
   // handling to be better. This should simply be part of the job of
   // GetGeometricParent, and stuff like the frameitems and parent frame should
   // be kept track of in the state...
-  void AdjustParentFrame(nsIFrame* &                  aParentFrame,
+  void AdjustParentFrame(nsContainerFrame**           aParentFrame,
                          const FrameConstructionData* aFCData,
                          nsStyleContext*              aStyleContext);
 
   // END TABLE SECTION
 
 protected:
-  static nsIFrame* CreatePlaceholderFrameFor(nsIPresShell*    aPresShell,
-                                             nsIContent*      aContent,
-                                             nsIFrame*        aFrame,
-                                             nsStyleContext*  aStyleContext,
-                                             nsIFrame*        aParentFrame,
-                                             nsIFrame*        aPrevInFlow,
-                                             nsFrameState     aTypeBit);
+  static nsIFrame* CreatePlaceholderFrameFor(nsIPresShell*     aPresShell,
+                                             nsIContent*       aContent,
+                                             nsIFrame*         aFrame,
+                                             nsStyleContext*   aStyleContext,
+                                             nsContainerFrame* aParentFrame,
+                                             nsIFrame*         aPrevInFlow,
+                                             nsFrameState      aTypeBit);
 
 private:
   // ConstructSelectFrame puts the new frame in aFrameItems and
   // handles the kids of the select.
   nsIFrame* ConstructSelectFrame(nsFrameConstructorState& aState,
                                  FrameConstructionItem&   aItem,
-                                 nsIFrame*                aParentFrame,
+                                 nsContainerFrame*        aParentFrame,
                                  const nsStyleDisplay*    aStyleDisplay,
                                  nsFrameItems&            aFrameItems);
 
   // ConstructFieldSetFrame puts the new frame in aFrameItems and
   // handles the kids of the fieldset
   nsIFrame* ConstructFieldSetFrame(nsFrameConstructorState& aState,
                                    FrameConstructionItem&   aItem,
-                                   nsIFrame*                aParentFrame,
+                                   nsContainerFrame*        aParentFrame,
                                    const nsStyleDisplay*    aStyleDisplay,
                                    nsFrameItems&            aFrameItems);
 
   // aParentFrame might be null.  If it is, that means it was an
   // inline frame.
   static const FrameConstructionData* FindTextData(nsIFrame* aParentFrame);
 
   void ConstructTextFrame(const FrameConstructionData* aData,
                           nsFrameConstructorState& aState,
                           nsIContent*              aContent,
-                          nsIFrame*                aParentFrame,
+                          nsContainerFrame*        aParentFrame,
                           nsStyleContext*          aStyleContext,
                           nsFrameItems&            aFrameItems);
 
   // If aPossibleTextContent is a text node and doesn't have a frame, append a
   // frame construction item for it to aItems.
   void AddTextItemIfNeeded(nsFrameConstructorState& aState,
-                           nsIFrame* aParentFrame,
+                           nsContainerFrame* aParentFrame,
                            nsIContent* aPossibleTextContent,
                            FrameConstructionItemList& aItems);
 
   // If aParentContent's child aContent is a text node and
   // doesn't have a frame, try to create a frame for it.
   void ReframeTextIfNeeded(nsIContent* aParentContent,
                            nsIContent* aContent);
 
@@ -1141,17 +1142,17 @@ private:
      @param aState the frame construction state to use.
      @param aParentFrame the frame to set as the parent of the
                          newly-constructed frame.
      @param aFrameItems the frame list to add the new frame (or its
                         placeholder) to.
   */
   void ConstructFrameFromItemInternal(FrameConstructionItem& aItem,
                                       nsFrameConstructorState& aState,
-                                      nsIFrame* aParentFrame,
+                                      nsContainerFrame* aParentFrame,
                                       nsFrameItems& aFrameItems);
 
   // possible flags for AddFrameConstructionItemInternal's aFlags argument
   /* Allow xbl:base to affect the tag/namespace used. */
 #define ITEM_ALLOW_XBL_BASE 0x1
   /* Allow page-break before and after items to be created if the
      style asks for them. */
 #define ITEM_ALLOW_PAGE_BREAK 0x2
@@ -1163,58 +1164,58 @@ private:
 #define ITEM_ALLOWS_TEXT_PATH_CHILD 0x10
   /* The item is content created by an nsIAnonymousContentCreator frame */
 #define ITEM_IS_ANONYMOUSCONTENTCREATOR_CONTENT 0x20
   // The guts of AddFrameConstructionItems
   // aParentFrame might be null.  If it is, that means it was an
   // inline frame.
   void AddFrameConstructionItemsInternal(nsFrameConstructorState& aState,
                                          nsIContent*              aContent,
-                                         nsIFrame*                aParentFrame,
+                                         nsContainerFrame*        aParentFrame,
                                          nsIAtom*                 aTag,
                                          int32_t                  aNameSpaceID,
                                          bool                     aSuppressWhiteSpaceOptimizations,
                                          nsStyleContext*          aStyleContext,
                                          uint32_t                 aFlags,
                                          nsTArray<nsIAnonymousContentCreator::ContentInfo>* aAnonChildren,
                                          FrameConstructionItemList& aItems);
 
   /**
    * Construct frames for the given item list and parent frame, and put the
    * resulting frames in aFrameItems.
    */
   void ConstructFramesFromItemList(nsFrameConstructorState& aState,
                                    FrameConstructionItemList& aItems,
-                                   nsIFrame* aParentFrame,
+                                   nsContainerFrame* aParentFrame,
                                    nsFrameItems& aFrameItems);
   void ConstructFramesFromItem(nsFrameConstructorState& aState,
                                FCItemIterator& aItem,
-                               nsIFrame* aParentFrame,
+                               nsContainerFrame* aParentFrame,
                                nsFrameItems& aFrameItems);
   static bool AtLineBoundary(FCItemIterator& aIter);
 
   nsresult CreateAnonymousFrames(nsFrameConstructorState& aState,
                                  nsIContent*              aParent,
-                                 nsIFrame*                aParentFrame,
-                                 PendingBinding  *        aPendingBinding,
+                                 nsContainerFrame*        aParentFrame,
+                                 PendingBinding*          aPendingBinding,
                                  nsFrameItems&            aChildItems);
 
   nsresult GetAnonymousContent(nsIContent* aParent,
                                nsIFrame* aParentFrame,
                                nsTArray<nsIAnonymousContentCreator::ContentInfo>& aAnonContent);
 
 //MathML Mod - RBS
   /**
    * Takes the frames in aBlockItems and wraps them in a new anonymous block
    * frame whose content is aContent and whose parent will be aParentFrame.
    * The anonymous block is added to aNewItems and aBlockItems is cleared.
    */
   void FlushAccumulatedBlock(nsFrameConstructorState& aState,
                              nsIContent* aContent,
-                             nsIFrame* aParentFrame,
+                             nsContainerFrame* aParentFrame,
                              nsFrameItems& aBlockItems,
                              nsFrameItems& aNewItems);
 
   // Function to find FrameConstructionData for aContent.  Will return
   // null if aContent is not MathML.
   static const FrameConstructionData* FindMathMLData(Element* aElement,
                                                      nsIAtom* aTag,
                                                      int32_t aNameSpaceID,
@@ -1257,42 +1258,42 @@ private:
                        nsStyleContext* aStyleContext);
 
   /**
    * Constructs an outer frame, an anonymous child that wraps its real
    * children, and its descendant frames.  This is used by both ConstructOuterSVG
    * and ConstructMarker, which both want an anonymous block child for their
    * children to go in to.
    */
-  nsIFrame* ConstructFrameWithAnonymousChild(
+  nsContainerFrame* ConstructFrameWithAnonymousChild(
                                   nsFrameConstructorState& aState,
                                   FrameConstructionItem&   aItem,
-                                  nsIFrame*                aParentFrame,
+                                  nsContainerFrame*        aParentFrame,
                                   const nsStyleDisplay*    aDisplay,
                                   nsFrameItems&            aFrameItems,
-                                  FrameCreationFunc        aConstructor,
-                                  FrameCreationFunc        aInnerConstructor,
+                                  ContainerFrameCreationFunc aConstructor,
+                                  ContainerFrameCreationFunc aInnerConstructor,
                                   nsICSSAnonBoxPseudo*     aInnerPseudo,
                                   bool                     aCandidateRootFrame);
 
   /**
    * Construct an nsSVGOuterSVGFrame.
    */
   nsIFrame* ConstructOuterSVG(nsFrameConstructorState& aState,
                               FrameConstructionItem&   aItem,
-                              nsIFrame*                aParentFrame,
+                              nsContainerFrame*        aParentFrame,
                               const nsStyleDisplay*    aDisplay,
                               nsFrameItems&            aFrameItems);
 
   /**
    * Construct an nsSVGMarkerFrame.
    */
   nsIFrame* ConstructMarker(nsFrameConstructorState& aState,
                             FrameConstructionItem&   aItem,
-                            nsIFrame*                aParentFrame,
+                            nsContainerFrame*        aParentFrame,
                             const nsStyleDisplay*    aDisplay,
                             nsFrameItems&            aFrameItems);
 
   static const FrameConstructionData* FindSVGData(Element* aElement,
                                                   nsIAtom* aTag,
                                                   int32_t aNameSpaceID,
                                                   nsIFrame* aParentFrame,
                                                   bool aIsWithinSVGText,
@@ -1305,37 +1306,37 @@ private:
     FindDisplayData(const nsStyleDisplay* aDisplay, Element* aElement,
                     nsIFrame* aParentFrame, nsStyleContext* aStyleContext);
 
   /**
    * Construct a scrollable block frame
    */
   nsIFrame* ConstructScrollableBlock(nsFrameConstructorState& aState,
                                      FrameConstructionItem&   aItem,
-                                     nsIFrame*                aParentFrame,
+                                     nsContainerFrame*        aParentFrame,
                                      const nsStyleDisplay*    aDisplay,
                                      nsFrameItems&            aFrameItems);
 
   /**
    * Construct a non-scrollable block frame
    */
   nsIFrame* ConstructNonScrollableBlock(nsFrameConstructorState& aState,
                                         FrameConstructionItem&   aItem,
-                                        nsIFrame*                aParentFrame,
+                                        nsContainerFrame*        aParentFrame,
                                         const nsStyleDisplay*    aDisplay,
                                         nsFrameItems&            aFrameItems);
 
   /**
    * This adds FrameConstructionItem objects to aItemsToConstruct for the
    * anonymous content returned by an nsIAnonymousContentCreator::
    * CreateAnonymousContent implementation.
    */
   void AddFCItemsForAnonymousContent(
             nsFrameConstructorState& aState,
-            nsIFrame* aFrame,
+            nsContainerFrame* aFrame,
             nsTArray<nsIAnonymousContentCreator::ContentInfo>& aAnonymousItems,
             FrameConstructionItemList& aItemsToConstruct,
             uint32_t aExtraFlags = 0);
 
   /**
    * Construct the frames for the children of aContent.  "children" is defined
    * as "whatever FlattenedChildIterator returns for aContent".  This means we're
    * basically operating on children in the "flattened tree" per sXBL/XBL2.
@@ -1344,17 +1345,17 @@ private:
    *
    * If the parent is a float containing block, this method will handle pushing
    * it as the float containing block in aState (so there's no need for callers
    * to push it themselves).
    *
    * @param aState the frame construction state
    * @param aContent the content node whose children need frames
    * @param aStyleContext the style context for aContent
-   * @param aFrame the frame to use as the parent frame for the new in-flow
+   * @param aParentFrame the frame to use as the parent frame for the new in-flow
    *        kids. Note that this must be its own content insertion frame, but
    *        need not be be the primary frame for aContent.  This frame will be
    *        pushed as the float containing block, as needed.  aFrame is also
    *        used to find the parent style context for the kids' style contexts
    *        (not necessary aFrame's style context).
    * @param aCanHaveGeneratedContent Whether to allow :before and
    *        :after styles on the parent.
    * @param aFrameItems the list in which we should place the in-flow children
@@ -1364,17 +1365,17 @@ private:
    *        child item construction.
    * @param aPossiblyLeafFrame if non-null, this should be used for the isLeaf
    *        test and the anonymous content creation.  If null, aFrame will be
    *        used.
    */
   void ProcessChildren(nsFrameConstructorState& aState,
                        nsIContent*              aContent,
                        nsStyleContext*          aStyleContext,
-                       nsIFrame*                aFrame,
+                       nsContainerFrame*        aParentFrame,
                        const bool               aCanHaveGeneratedContent,
                        nsFrameItems&            aFrameItems,
                        const bool               aAllowBlockStyles,
                        PendingBinding*          aPendingBinding,
                        nsIFrame*                aPossiblyLeafFrame = nullptr);
 
   /**
    * These two functions are used when we start frame creation from a non-root
@@ -1384,59 +1385,60 @@ private:
    * PushAbsoluteContainingBlock during frame construction should get
    * corresponding logic in these functions.
    */
 public:
   enum ContainingBlockType {
     ABS_POS,
     FIXED_POS
   };
-  nsIFrame* GetAbsoluteContainingBlock(nsIFrame* aFrame, ContainingBlockType aType);
-  nsIFrame* GetFloatContainingBlock(nsIFrame* aFrame);
+  nsContainerFrame* GetAbsoluteContainingBlock(nsIFrame* aFrame,
+                                               ContainingBlockType aType);
+  nsContainerFrame* GetFloatContainingBlock(nsIFrame* aFrame);
 
 private:
   nsIContent* PropagateScrollToViewport();
 
   // Build a scroll frame:
   //  Calls BeginBuildingScrollFrame, InitAndRestoreFrame, and then FinishBuildingScrollFrame.
   // @param aNewFrame the created scrollframe --- output only
   // @param aParentFrame the geometric parent that the scrollframe will have.
   nsresult
   BuildScrollFrame(nsFrameConstructorState& aState,
                    nsIContent*              aContent,
                    nsStyleContext*          aContentStyle,
                    nsIFrame*                aScrolledFrame,
-                   nsIFrame*                aParentFrame,
-                   nsIFrame*&               aNewFrame);
+                   nsContainerFrame*        aParentFrame,
+                   nsContainerFrame*&       aNewFrame);
 
   // Builds the initial ScrollFrame
   already_AddRefed<nsStyleContext>
   BeginBuildingScrollFrame(nsFrameConstructorState& aState,
                            nsIContent*              aContent,
                            nsStyleContext*          aContentStyle,
-                           nsIFrame*                aParentFrame,
+                           nsContainerFrame*        aParentFrame,
                            nsIAtom*                 aScrolledPseudo,
                            bool                     aIsRoot,
-                           nsIFrame*&               aNewFrame);
+                           nsContainerFrame*&       aNewFrame);
 
   // Completes the building of the scrollframe:
   // Creates a view for the scrolledframe and makes it the child of the scrollframe.
   void
-  FinishBuildingScrollFrame(nsIFrame* aScrollFrame,
+  FinishBuildingScrollFrame(nsContainerFrame* aScrollFrame,
                             nsIFrame* aScrolledFrame);
 
   // InitializeSelectFrame puts scrollFrame in aFrameItems if aBuildCombobox is false
   // aBuildCombobox indicates if we are building a combobox that has a dropdown
   // popup widget or not.
   nsresult
   InitializeSelectFrame(nsFrameConstructorState& aState,
-                        nsIFrame*                scrollFrame,
-                        nsIFrame*                scrolledFrame,
+                        nsContainerFrame*        aScrollFrame,
+                        nsContainerFrame*        aScrolledFrame,
                         nsIContent*              aContent,
-                        nsIFrame*                aParentFrame,
+                        nsContainerFrame*        aParentFrame,
                         nsStyleContext*          aStyleContext,
                         bool                     aBuildCombobox,
                         PendingBinding*          aPendingBinding,
                         nsFrameItems&            aFrameItems);
 
   nsresult MaybeRecreateFramesForElement(Element* aElement);
 
   // If aAsyncInsert is true then a restyle event will be posted to handle the
@@ -1450,29 +1452,29 @@ private:
   // the return value of ReframeContainingBlock or RecreateFramesForContent.  If
   // this method returns false, the value of *aResult is not affected.  aFrame
   // and aResult must not be null.  aFrame must be the result of a
   // GetPrimaryFrame() call on a content node (which means its parent is also
   // not null).
   bool MaybeRecreateContainerForFrameRemoval(nsIFrame* aFrame,
                                                nsresult* aResult);
 
-  nsIFrame* CreateContinuingOuterTableFrame(nsIPresShell*    aPresShell,
-                                            nsPresContext*  aPresContext,
-                                            nsIFrame*        aFrame,
-                                            nsIFrame*        aParentFrame,
-                                            nsIContent*      aContent,
-                                            nsStyleContext*  aStyleContext);
+  nsIFrame* CreateContinuingOuterTableFrame(nsIPresShell*     aPresShell,
+                                            nsPresContext*    aPresContext,
+                                            nsIFrame*         aFrame,
+                                            nsContainerFrame* aParentFrame,
+                                            nsIContent*       aContent,
+                                            nsStyleContext*   aStyleContext);
 
-  nsIFrame* CreateContinuingTableFrame(nsIPresShell*    aPresShell,
-                                       nsPresContext*  aPresContext,
-                                       nsIFrame*        aFrame,
-                                       nsIFrame*        aParentFrame,
-                                       nsIContent*      aContent,
-                                       nsStyleContext*  aStyleContext);
+  nsIFrame* CreateContinuingTableFrame(nsIPresShell*     aPresShell,
+                                       nsPresContext*    aPresContext,
+                                       nsIFrame*         aFrame,
+                                       nsContainerFrame* aParentFrame,
+                                       nsIContent*       aContent,
+                                       nsStyleContext*   aStyleContext);
 
   //----------------------------------------
 
   // Methods support creating block frames and their children
 
   already_AddRefed<nsStyleContext>
   GetFirstLetterStyle(nsIContent*      aContent,
                       nsStyleContext*  aStyleContext);
@@ -1510,27 +1512,27 @@ private:
   // @param aPositionedFrameForAbsPosContainer if non-null, then the new
   // block should be an abs-pos container and aPositionedFrameForAbsPosContainer
   // is the frame whose style is making this block an abs-pos container.
   // @param aPendingBinding the pending binding  from this block's frame
   // construction item.
   void ConstructBlock(nsFrameConstructorState& aState,
                       const nsStyleDisplay*    aDisplay,
                       nsIContent*              aContent,
-                      nsIFrame*                aParentFrame,
-                      nsIFrame*                aContentParentFrame,
+                      nsContainerFrame*        aParentFrame,
+                      nsContainerFrame*        aContentParentFrame,
                       nsStyleContext*          aStyleContext,
-                      nsIFrame**               aNewFrame,
+                      nsContainerFrame**       aNewFrame,
                       nsFrameItems&            aFrameItems,
                       nsIFrame*                aPositionedFrameForAbsPosContainer,
                       PendingBinding*          aPendingBinding);
 
   nsIFrame* ConstructInline(nsFrameConstructorState& aState,
                             FrameConstructionItem&   aItem,
-                            nsIFrame*                aParentFrame,
+                            nsContainerFrame*        aParentFrame,
                             const nsStyleDisplay*    aDisplay,
                             nsFrameItems&            aFrameItems);
 
   /**
    * Create any additional {ib} siblings needed to contain aChildItems and put
    * them in aSiblings.
    *
    * @param aState the frame constructor state
@@ -1543,17 +1545,17 @@ private:
    *                    children it wants.  When the method returns aChildItems
    *                    will be empty.
    * @param aSiblings the nsFrameItems to put the newly-created siblings into.
    *
    * This method is responsible for making any SetFrameIsIBSplit calls that are
    * needed.
    */
   void CreateIBSiblings(nsFrameConstructorState& aState,
-                        nsIFrame* aInitialInline,
+                        nsContainerFrame* aInitialInline,
                         bool aIsPositioned,
                         nsFrameItems& aChildItems,
                         nsFrameItems& aSiblings);
 
   /**
    * For an inline aParentItem, construct its list of child
    * FrameConstructionItems and set its mIsAllInline flag appropriately.
    */
@@ -1563,17 +1565,17 @@ private:
                              bool aItemAllowsTextPathChild);
 
   // Determine whether we need to wipe out what we just did and start over
   // because we're doing something like adding block kids to an inline frame
   // (and therefore need an {ib} split).  aPrevSibling must be correct, even in
   // aIsAppend cases.  Passing aIsAppend false even when an append is happening
   // is ok in terms of correctness, but can lead to unnecessary reframing.  If
   // aIsAppend is true, then the caller MUST call
-  // nsCSSFrameConstructor::AppendFrames (as opposed to
+  // nsCSSFrameConstructor::AppendFramesToParent (as opposed to
   // nsFrameManager::InsertFrames directly) to add the new frames.
   // @return true if we reconstructed the containing block, false
   // otherwise
   bool WipeContainingBlock(nsFrameConstructorState& aState,
                              nsIFrame*                aContainingBlock,
                              nsIFrame*                aFrame,
                              FrameConstructionItemList& aItems,
                              bool                     aIsAppend,
@@ -1581,33 +1583,32 @@ private:
 
   nsresult ReframeContainingBlock(nsIFrame* aFrame);
 
   //----------------------------------------
 
   // Methods support :first-letter style
 
   void CreateFloatingLetterFrame(nsFrameConstructorState& aState,
-                                 nsIFrame*                aBlockFrame,
+                                 nsContainerFrame*        aBlockFrame,
                                  nsIContent*              aTextContent,
                                  nsIFrame*                aTextFrame,
-                                 nsIContent*              aBlockContent,
-                                 nsIFrame*                aParentFrame,
+                                 nsContainerFrame*        aParentFrame,
                                  nsStyleContext*          aStyleContext,
                                  nsFrameItems&            aResult);
 
-  void CreateLetterFrame(nsIFrame*                aBlockFrame,
-                         nsIFrame*                aBlockContinuation,
+  void CreateLetterFrame(nsContainerFrame*        aBlockFrame,
+                         nsContainerFrame*        aBlockContinuation,
                          nsIContent*              aTextContent,
-                         nsIFrame*                aParentFrame,
+                         nsContainerFrame*        aParentFrame,
                          nsFrameItems&            aResult);
 
-  void WrapFramesInFirstLetterFrame(nsIContent*   aBlockContent,
-                                    nsIFrame*     aBlockFrame,
-                                    nsFrameItems& aBlockFrames);
+  void WrapFramesInFirstLetterFrame(nsIContent*       aBlockContent,
+                                    nsContainerFrame* aBlockFrame,
+                                    nsFrameItems&     aBlockFrames);
 
   /**
    * Looks in the block aBlockFrame for a text frame that contains the
    * first-letter of the block and creates the necessary first-letter frames
    * and returns them in aLetterFrames.
    *
    * @param aBlockFrame the (first-continuation of) the block we are creating a
    *                    first-letter frame for
@@ -1621,39 +1622,39 @@ private:
    *                        the first-letter
    * @param aTextFrame returns the textframe that had the first-letter
    * @param aPrevFrame returns the previous sibling of aTextFrame
    * @param aLetterFrames returns the frames that were created
    * @param aStopLooking returns whether we should stop looking for a
    *                     first-letter either because it was found or won't be
    *                     found
    */
-  void WrapFramesInFirstLetterFrame(nsIFrame*     aBlockFrame,
-                                    nsIFrame*     aBlockContinuation,
-                                    nsIFrame*     aParentFrame,
-                                    nsIFrame*     aParentFrameList,
-                                    nsIFrame**    aModifiedParent,
-                                    nsIFrame**    aTextFrame,
-                                    nsIFrame**    aPrevFrame,
-                                    nsFrameItems& aLetterFrames,
-                                    bool*       aStopLooking);
+  void WrapFramesInFirstLetterFrame(nsContainerFrame*  aBlockFrame,
+                                    nsContainerFrame*  aBlockContinuation,
+                                    nsContainerFrame*  aParentFrame,
+                                    nsIFrame*          aParentFrameList,
+                                    nsContainerFrame** aModifiedParent,
+                                    nsIFrame**         aTextFrame,
+                                    nsIFrame**         aPrevFrame,
+                                    nsFrameItems&      aLetterFrames,
+                                    bool*              aStopLooking);
 
-  void RecoverLetterFrames(nsIFrame* aBlockFrame);
+  void RecoverLetterFrames(nsContainerFrame* aBlockFrame);
 
   //
-  nsresult RemoveLetterFrames(nsPresContext*  aPresContext,
-                              nsIPresShell*    aPresShell,
-                              nsIFrame*        aBlockFrame);
+  nsresult RemoveLetterFrames(nsPresContext*    aPresContext,
+                              nsIPresShell*     aPresShell,
+                              nsContainerFrame* aBlockFrame);
 
   // Recursive helper for RemoveLetterFrames
-  nsresult RemoveFirstLetterFrames(nsPresContext*  aPresContext,
-                                   nsIPresShell*    aPresShell,
-                                   nsIFrame*        aFrame,
-                                   nsIFrame*        aBlockFrame,
-                                   bool*          aStopLooking);
+  nsresult RemoveFirstLetterFrames(nsPresContext*    aPresContext,
+                                   nsIPresShell*     aPresShell,
+                                   nsContainerFrame* aFrame,
+                                   nsContainerFrame* aBlockFrame,
+                                   bool*             aStopLooking);
 
   // Special remove method for those pesky floating first-letter frames
   nsresult RemoveFloatingFirstLetterFrames(nsPresContext*  aPresContext,
                                            nsIPresShell*    aPresShell,
                                            nsIFrame*        aBlockFrame,
                                            bool*          aStopLooking);
 
   // Capture state for the frame tree rooted at the frame associated with the
@@ -1669,25 +1670,25 @@ private:
   // If aLineFrame is non-null, it appends them to that frame.  Otherwise, it
   // creates a new line frame, sets the inline frames as its initial child
   // list, and inserts that line frame at the front of what's left of
   // aFrameItems.  In both cases, the kids are reparented to the line frame.
   // After this call, aFrameItems holds the frames that need to become kids of
   // the block (possibly including line frames).
   void WrapFramesInFirstLineFrame(nsFrameConstructorState& aState,
                                   nsIContent*              aBlockContent,
-                                  nsIFrame*                aBlockFrame,
+                                  nsContainerFrame*        aBlockFrame,
                                   nsFirstLineFrame*        aLineFrame,
                                   nsFrameItems&            aFrameItems);
 
   // Handle the case when a block with first-line style is appended to (by
   // possibly calling WrapFramesInFirstLineFrame as needed).
   void AppendFirstLineFrames(nsFrameConstructorState& aState,
                              nsIContent*              aContent,
-                             nsIFrame*                aBlockFrame,
+                             nsContainerFrame*        aBlockFrame,
                              nsFrameItems&            aFrameItems);
 
   nsresult InsertFirstLineFrames(nsFrameConstructorState& aState,
                                  nsIContent*              aContent,
                                  nsIFrame*                aBlockFrame,
                                  nsContainerFrame**       aParentFrame,
                                  nsIFrame*                aPrevSibling,
                                  nsFrameItems&            aFrameItems);
@@ -1776,25 +1777,25 @@ public:
 private:
 
   nsIDocument*        mDocument;  // Weak ref
 
   // See the comment at the start of ConstructRootFrame for more details
   // about the following frames.
 
   // This is just the outermost frame for the root element.
-  nsIFrame*           mRootElementFrame;
+  nsContainerFrame*   mRootElementFrame;
   // This is the frame for the root element that has no pseudo-element style.
   nsIFrame*           mRootElementStyleFrame;
   // This is the containing block for fixed-pos frames --- the
   // viewport or page frame
-  nsIFrame*           mFixedContainingBlock;
+  nsContainerFrame*   mFixedContainingBlock;
   // This is the containing block that contains the root element ---
   // the real "initial containing block" according to CSS 2.1.
-  nsIFrame*           mDocElementContainingBlock;
+  nsContainerFrame*   mDocElementContainingBlock;
   nsIFrame*           mGfxScrollFrame;
   nsIFrame*           mPageSequenceFrame;
   nsQuoteList         mQuoteList;
   nsCounterManager    mCounterManager;
   // Current ProcessChildren depth.
   uint16_t            mCurrentDepth;
   uint16_t            mUpdateCount;
   bool                mQuotesDirty : 1;
--- a/layout/forms/nsComboboxControlFrame.cpp
+++ b/layout/forms/nsComboboxControlFrame.cpp
@@ -95,17 +95,17 @@ public:
 };
 
 NS_IMPL_ISUPPORTS(nsComboButtonListener,
                   nsIDOMEventListener)
 
 // static class data member for Bug 32920
 nsComboboxControlFrame* nsComboboxControlFrame::sFocused = nullptr;
 
-nsIFrame*
+nsContainerFrame*
 NS_NewComboboxControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, nsFrameState aStateFlags)
 {
   nsComboboxControlFrame* it = new (aPresShell) nsComboboxControlFrame(aContext);
 
   if (it) {
     // set the state flags (if any are provided)
     it->AddStateBits(aStateFlags);
   }
--- a/layout/forms/nsComboboxControlFrame.h
+++ b/layout/forms/nsComboboxControlFrame.h
@@ -41,17 +41,19 @@ class nsComboboxControlFrame : public ns
                                public nsIFormControlFrame,
                                public nsIComboboxControlFrame,
                                public nsIAnonymousContentCreator,
                                public nsISelectControlFrame,
                                public nsIRollupListener,
                                public nsIStatefulFrame
 {
 public:
-  friend nsIFrame* NS_NewComboboxControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, nsFrameState aFlags);
+  friend nsContainerFrame* NS_NewComboboxControlFrame(nsIPresShell* aPresShell,
+                                                      nsStyleContext* aContext,
+                                                      nsFrameState aFlags);
   friend class nsComboboxDisplayFrame;
 
   nsComboboxControlFrame(nsStyleContext* aContext);
   ~nsComboboxControlFrame();
 
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS
 
--- a/layout/forms/nsFieldSetFrame.cpp
+++ b/layout/forms/nsFieldSetFrame.cpp
@@ -18,17 +18,17 @@
 #include "nsRenderingContext.h"
 #include "nsIScrollableFrame.h"
 #include "mozilla/Likely.h"
 #include "mozilla/Maybe.h"
 
 using namespace mozilla;
 using namespace mozilla::layout;
 
-nsIFrame*
+nsContainerFrame*
 NS_NewFieldSetFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsFieldSetFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsFieldSetFrame)
 
 nsFieldSetFrame::nsFieldSetFrame(nsStyleContext* aContext)
--- a/layout/forms/nsGfxButtonControlFrame.cpp
+++ b/layout/forms/nsGfxButtonControlFrame.cpp
@@ -17,17 +17,17 @@
 
 using namespace mozilla;
 
 nsGfxButtonControlFrame::nsGfxButtonControlFrame(nsStyleContext* aContext):
   nsHTMLButtonControlFrame(aContext)
 {
 }
 
-nsIFrame*
+nsContainerFrame*
 NS_NewGfxButtonControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsGfxButtonControlFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsGfxButtonControlFrame)
 
 void nsGfxButtonControlFrame::DestroyFrom(nsIFrame* aDestructRoot)
--- a/layout/forms/nsHTMLButtonControlFrame.cpp
+++ b/layout/forms/nsHTMLButtonControlFrame.cpp
@@ -14,17 +14,17 @@
 #include "nsFormControlFrame.h"
 #include "nsNameSpaceManager.h"
 #include "nsStyleSet.h"
 #include "nsDisplayList.h"
 #include <algorithm>
 
 using namespace mozilla;
 
-nsIFrame*
+nsContainerFrame*
 NS_NewHTMLButtonControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsHTMLButtonControlFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsHTMLButtonControlFrame)
 
 nsHTMLButtonControlFrame::nsHTMLButtonControlFrame(nsStyleContext* aContext)
--- a/layout/forms/nsListControlFrame.cpp
+++ b/layout/forms/nsListControlFrame.cpp
@@ -70,17 +70,17 @@ public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIDOMEVENTLISTENER
 
 private:
   nsListControlFrame  *mFrame;
 };
 
 //---------------------------------------------------------
-nsIFrame*
+nsContainerFrame*
 NS_NewListControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   nsListControlFrame* it =
     new (aPresShell) nsListControlFrame(aPresShell, aPresShell->GetDocument(), aContext);
 
   it->AddStateBits(NS_FRAME_INDEPENDENT_SELECTION);
 
   return it;
--- a/layout/forms/nsListControlFrame.h
+++ b/layout/forms/nsListControlFrame.h
@@ -47,17 +47,18 @@ class HTMLOptionsCollection;
  */
 
 class nsListControlFrame : public nsHTMLScrollFrame,
                            public nsIFormControlFrame, 
                            public nsIListControlFrame,
                            public nsISelectControlFrame
 {
 public:
-  friend nsIFrame* NS_NewListControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
+  friend nsContainerFrame* NS_NewListControlFrame(nsIPresShell* aPresShell,
+                                                  nsStyleContext* aContext);
 
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS
 
     // nsIFrame
   virtual nsresult HandleEvent(nsPresContext* aPresContext,
                                mozilla::WidgetGUIEvent* aEvent,
                                nsEventStatus* aEventStatus) MOZ_OVERRIDE;
--- a/layout/forms/nsSelectsAreaFrame.cpp
+++ b/layout/forms/nsSelectsAreaFrame.cpp
@@ -2,17 +2,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #include "nsSelectsAreaFrame.h"
 #include "nsIContent.h"
 #include "nsListControlFrame.h"
 #include "nsDisplayList.h"
 
-nsIFrame*
+nsContainerFrame*
 NS_NewSelectsAreaFrame(nsIPresShell* aShell, nsStyleContext* aContext, nsFrameState aFlags)
 {
   nsSelectsAreaFrame* it = new (aShell) nsSelectsAreaFrame(aContext);
 
   // We need NS_BLOCK_FLOAT_MGR to ensure that the options inside the select
   // aren't expanded by right floats outside the select.
   it->SetFlags(aFlags | NS_BLOCK_FLOAT_MGR);
 
--- a/layout/forms/nsSelectsAreaFrame.h
+++ b/layout/forms/nsSelectsAreaFrame.h
@@ -8,17 +8,19 @@
 #include "mozilla/Attributes.h"
 #include "nsBlockFrame.h"
 
 class nsSelectsAreaFrame : public nsBlockFrame
 {
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
-  friend nsIFrame* NS_NewSelectsAreaFrame(nsIPresShell* aShell, nsStyleContext* aContext, nsFrameState aFlags);
+  friend nsContainerFrame* NS_NewSelectsAreaFrame(nsIPresShell* aShell,
+                                                  nsStyleContext* aContext,
+                                                  nsFrameState aFlags);
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
 
   void BuildDisplayListInternal(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists);
--- a/layout/generic/nsCanvasFrame.cpp
+++ b/layout/generic/nsCanvasFrame.cpp
@@ -25,17 +25,17 @@
 #endif
 
 //#define DEBUG_CANVAS_FOCUS
 
 using namespace mozilla;
 using namespace mozilla::layout;
 using namespace mozilla::gfx;
 
-nsIFrame*
+nsCanvasFrame*
 NS_NewCanvasFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsCanvasFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsCanvasFrame)
 
 NS_QUERYFRAME_HEAD(nsCanvasFrame)
--- a/layout/generic/nsColumnSetFrame.cpp
+++ b/layout/generic/nsColumnSetFrame.cpp
@@ -15,17 +15,17 @@ using namespace mozilla::layout;
 /**
  * Tracking issues:
  *
  * XXX cursor movement around the top and bottom of colums seems to make the editor
  * lose the caret.
  *
  * XXX should we support CSS columns applied to table elements?
  */
-nsIFrame*
+nsContainerFrame*
 NS_NewColumnSetFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, nsFrameState aStateFlags)
 {
   nsColumnSetFrame* it = new (aPresShell) nsColumnSetFrame(aContext);
   it->AddStateBits(aStateFlags | NS_BLOCK_MARGIN_ROOT);
   return it;
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsColumnSetFrame)
--- a/layout/generic/nsFirstLetterFrame.cpp
+++ b/layout/generic/nsFirstLetterFrame.cpp
@@ -16,17 +16,17 @@
 #include "nsFrameManager.h"
 #include "RestyleManager.h"
 #include "nsPlaceholderFrame.h"
 #include "nsCSSFrameConstructor.h"
 
 using namespace mozilla;
 using namespace mozilla::layout;
 
-nsIFrame*
+nsFirstLetterFrame*
 NS_NewFirstLetterFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsFirstLetterFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsFirstLetterFrame)
 
 NS_QUERYFRAME_HEAD(nsFirstLetterFrame)
@@ -298,17 +298,17 @@ nsFirstLetterFrame::CreateContinuationFo
   NS_PRECONDITION(aContinuation, "bad args");
 
   *aContinuation = nullptr;
   nsresult rv = NS_OK;
 
   nsIPresShell* presShell = aPresContext->PresShell();
   nsPlaceholderFrame* placeholderFrame =
     presShell->FrameManager()->GetPlaceholderFrameFor(this);
-  nsIFrame* parent = placeholderFrame->GetParent();
+  nsContainerFrame* parent = placeholderFrame->GetParent();
 
   nsIFrame* continuation = presShell->FrameConstructor()->
     CreateContinuingFrame(aPresContext, aChild, parent, aIsFluid);
 
   // The continuation will have gotten the first letter style from its
   // prev continuation, so we need to repair the style context so it
   // doesn't have the first letter styling.
   nsStyleContext* parentSC = this->StyleContext()->GetParent();
--- a/layout/generic/nsFlexContainerFrame.cpp
+++ b/layout/generic/nsFlexContainerFrame.cpp
@@ -1459,17 +1459,17 @@ public:
 // =======================
 
 NS_QUERYFRAME_HEAD(nsFlexContainerFrame)
   NS_QUERYFRAME_ENTRY(nsFlexContainerFrame)
 NS_QUERYFRAME_TAIL_INHERITING(nsFlexContainerFrameSuper)
 
 NS_IMPL_FRAMEARENA_HELPERS(nsFlexContainerFrame)
 
-nsIFrame*
+nsContainerFrame*
 NS_NewFlexContainerFrame(nsIPresShell* aPresShell,
                          nsStyleContext* aContext)
 {
   return new (aPresShell) nsFlexContainerFrame(aContext);
 }
 
 //----------------------------------------------------------------------
 
--- a/layout/generic/nsFlexContainerFrame.h
+++ b/layout/generic/nsFlexContainerFrame.h
@@ -11,30 +11,30 @@
 #define nsFlexContainerFrame_h___
 
 #include "nsContainerFrame.h"
 
 namespace mozilla {
 template <class T> class LinkedList;
 }
 
-nsIFrame* NS_NewFlexContainerFrame(nsIPresShell* aPresShell,
-                                   nsStyleContext* aContext);
+nsContainerFrame* NS_NewFlexContainerFrame(nsIPresShell* aPresShell,
+                                           nsStyleContext* aContext);
 
 typedef nsContainerFrame nsFlexContainerFrameSuper;
 
 class nsFlexContainerFrame : public nsFlexContainerFrameSuper {
 public:
   NS_DECL_FRAMEARENA_HELPERS
   NS_DECL_QUERYFRAME_TARGET(nsFlexContainerFrame)
   NS_DECL_QUERYFRAME
 
   // Factory method:
-  friend nsIFrame* NS_NewFlexContainerFrame(nsIPresShell* aPresShell,
-                                            nsStyleContext* aContext);
+  friend nsContainerFrame* NS_NewFlexContainerFrame(nsIPresShell* aPresShell,
+                                                    nsStyleContext* aContext);
 
   // Forward-decls of helper classes
   class FlexItem;
   class FlexLine;
   class FlexboxAxisTracker;
   class StrutInfo;
 
   // nsIFrame overrides
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -60,17 +60,17 @@
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::layout;
 
 //----------------------------------------------------------------------
 
 //----------nsHTMLScrollFrame-------------------------------------------
 
-nsIFrame*
+nsHTMLScrollFrame*
 NS_NewHTMLScrollFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, bool aIsRoot)
 {
   return new (aPresShell) nsHTMLScrollFrame(aPresShell, aContext, aIsRoot);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsHTMLScrollFrame)
 
 nsHTMLScrollFrame::nsHTMLScrollFrame(nsIPresShell* aShell, nsStyleContext* aContext, bool aIsRoot)
@@ -894,17 +894,17 @@ NS_QUERYFRAME_HEAD(nsHTMLScrollFrame)
   NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
   NS_QUERYFRAME_ENTRY(nsIScrollbarOwner)
   NS_QUERYFRAME_ENTRY(nsIScrollableFrame)
   NS_QUERYFRAME_ENTRY(nsIStatefulFrame)
 NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
 
 //----------nsXULScrollFrame-------------------------------------------
 
-nsIFrame*
+nsXULScrollFrame*
 NS_NewXULScrollFrame(nsIPresShell* aPresShell, nsStyleContext* aContext,
                      bool aIsRoot, bool aClipAllDescendants)
 {
   return new (aPresShell) nsXULScrollFrame(aPresShell, aContext, aIsRoot,
                                            aClipAllDescendants);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsXULScrollFrame)
--- a/layout/generic/nsGfxScrollFrame.h
+++ b/layout/generic/nsGfxScrollFrame.h
@@ -445,17 +445,19 @@ protected:
  */
 class nsHTMLScrollFrame : public nsContainerFrame,
                           public nsIScrollableFrame,
                           public nsIAnonymousContentCreator,
                           public nsIStatefulFrame {
 public:
   typedef mozilla::ScrollFrameHelper ScrollFrameHelper;
   typedef mozilla::CSSIntPoint CSSIntPoint;
-  friend nsIFrame* NS_NewHTMLScrollFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, bool aIsRoot);
+  friend nsHTMLScrollFrame* NS_NewHTMLScrollFrame(nsIPresShell* aPresShell,
+                                                  nsStyleContext* aContext,
+                                                  bool aIsRoot);
 
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS
 
   // Called to set the child frames. We typically have three: the scroll area,
   // the vertical scrollbar, and the horizontal scrollbar.
   virtual nsresult SetInitialChildList(ChildListID     aListID,
                                        nsFrameList&    aChildList) MOZ_OVERRIDE;
@@ -757,18 +759,20 @@ class nsXULScrollFrame : public nsBoxFra
                          public nsIStatefulFrame {
 public:
   typedef mozilla::ScrollFrameHelper ScrollFrameHelper;
   typedef mozilla::CSSIntPoint CSSIntPoint;
 
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS
 
-  friend nsIFrame* NS_NewXULScrollFrame(nsIPresShell* aPresShell, nsStyleContext* aContext,
-                                        bool aIsRoot, bool aClipAllDescendants);
+  friend nsXULScrollFrame* NS_NewXULScrollFrame(nsIPresShell* aPresShell,
+                                                nsStyleContext* aContext,
+                                                bool aIsRoot,
+                                                bool aClipAllDescendants);
 
   // Called to set the child frames. We typically have three: the scroll area,
   // the vertical scrollbar, and the horizontal scrollbar.
   virtual nsresult SetInitialChildList(ChildListID     aListID,
                                        nsFrameList&    aChildList) MOZ_OVERRIDE;
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
--- a/layout/generic/nsGridContainerFrame.cpp
+++ b/layout/generic/nsGridContainerFrame.cpp
@@ -18,17 +18,17 @@
 // =======================
 
 NS_QUERYFRAME_HEAD(nsGridContainerFrame)
   NS_QUERYFRAME_ENTRY(nsGridContainerFrame)
 NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
 
 NS_IMPL_FRAMEARENA_HELPERS(nsGridContainerFrame)
 
-nsIFrame*
+nsContainerFrame*
 NS_NewGridContainerFrame(nsIPresShell* aPresShell,
                          nsStyleContext* aContext)
 {
   return new (aPresShell) nsGridContainerFrame(aContext);
 }
 
 
 //----------------------------------------------------------------------
--- a/layout/generic/nsGridContainerFrame.h
+++ b/layout/generic/nsGridContainerFrame.h
@@ -10,18 +10,18 @@
 #define nsGridContainerFrame_h___
 
 #include "nsContainerFrame.h"
 
 /**
  * Factory function.
  * @return a newly allocated nsGridContainerFrame (infallible)
  */
-nsIFrame* NS_NewGridContainerFrame(nsIPresShell* aPresShell,
-                                   nsStyleContext* aContext);
+nsContainerFrame* NS_NewGridContainerFrame(nsIPresShell* aPresShell,
+                                           nsStyleContext* aContext);
 
 class nsGridContainerFrame MOZ_FINAL : public nsContainerFrame
 {
 public:
   NS_DECL_FRAMEARENA_HELPERS
   NS_DECL_QUERYFRAME_TARGET(nsGridContainerFrame)
   NS_DECL_QUERYFRAME
 
@@ -32,18 +32,18 @@ public:
               nsReflowStatus&          aStatus) MOZ_OVERRIDE;
   virtual nsIAtom* GetType() const MOZ_OVERRIDE;
 
 #ifdef DEBUG_FRAME_DUMP
   virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
 #endif
 
 protected:
-  friend nsIFrame* NS_NewGridContainerFrame(nsIPresShell* aPresShell,
-                                            nsStyleContext* aContext);
+  friend nsContainerFrame* NS_NewGridContainerFrame(nsIPresShell* aPresShell,
+                                                    nsStyleContext* aContext);
   nsGridContainerFrame(nsStyleContext* aContext) : nsContainerFrame(aContext) {}
 
 #ifdef DEBUG
   void SanityCheckAnonymousGridItems() const;
 #endif // DEBUG
 };
 
 #endif /* nsGridContainerFrame_h___ */
--- a/layout/generic/nsHTMLParts.h
+++ b/layout/generic/nsHTMLParts.h
@@ -58,17 +58,17 @@ nsresult
 NS_NewAttributeContent(nsNodeInfoManager *aNodeInfoManager,
                        int32_t aNameSpaceID, nsIAtom* aAttrName,
                        nsIContent** aResult);
 
 // Create a basic area frame but the GetFrameForPoint is overridden to always
 // return the option frame 
 // By default, area frames will extend
 // their height to cover any children that "stick out".
-nsIFrame*
+nsContainerFrame*
 NS_NewSelectsAreaFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, nsFrameState aFlags);
 
 // Create a block formatting context blockframe
 inline nsBlockFrame* NS_NewBlockFormattingContext(nsIPresShell* aPresShell,
                                                   nsStyleContext* aStyleContext)
 {
   return NS_NewBlockFrame(aPresShell, aStyleContext,
                           NS_BLOCK_FLOAT_MGR | NS_BLOCK_MARGIN_ROOT);
@@ -82,68 +82,75 @@ NS_NewCommentFrame(nsIPresShell* aPresSh
 
 // <frame> and <iframe> 
 nsIFrame*
 NS_NewSubDocumentFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 // <frameset>
 nsIFrame*
 NS_NewHTMLFramesetFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
-nsIFrame*
+class ViewportFrame;
+ViewportFrame*
 NS_NewViewportFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
-nsIFrame*
+class nsCanvasFrame;
+nsCanvasFrame*
 NS_NewCanvasFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewImageFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
-nsIFrame*
+class nsInlineFrame;
+nsInlineFrame*
 NS_NewInlineFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewObjectFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewTextFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewContinuingTextFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewEmptyFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 inline nsIFrame*
 NS_NewWBRFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) {
   return NS_NewEmptyFrame(aPresShell, aContext);
 }
 
-nsIFrame*
+nsContainerFrame*
 NS_NewColumnSetFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, nsFrameState aStateFlags);
 
-nsIFrame*
+class nsSimplePageSequenceFrame;
+nsSimplePageSequenceFrame*
 NS_NewSimplePageSequenceFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
-nsIFrame*
+class nsPageFrame;
+nsPageFrame*
 NS_NewPageFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
-nsIFrame*
+class nsPageContentFrame;
+nsPageContentFrame*
 NS_NewPageContentFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewPageBreakFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
-nsIFrame*
+class nsFirstLetterFrame;
+nsFirstLetterFrame*
 NS_NewFirstLetterFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 class nsFirstLineFrame;
 nsFirstLineFrame*
 NS_NewFirstLineFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
 // forms
-nsIFrame*
+nsContainerFrame*
 NS_NewGfxButtonControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewNativeButtonControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewImageControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
-nsIFrame*
+nsContainerFrame*
 NS_NewHTMLButtonControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewGfxCheckboxControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewNativeCheckboxControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
-nsIFrame*
+nsContainerFrame*
 NS_NewFieldSetFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewFileControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewColorControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewLegendFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
@@ -153,45 +160,52 @@ NS_NewTextControlFrame(nsIPresShell* aPr
 nsIFrame*
 NS_NewGfxAutoTextControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewGfxRadioControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewNativeRadioControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewNativeSelectControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
-nsIFrame*
+nsContainerFrame*
 NS_NewListControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
-nsIFrame*
+nsContainerFrame*
 NS_NewComboboxControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, nsFrameState aFlags);
 nsIFrame*
 NS_NewProgressFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewMeterFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewRangeFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewNumberControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
 // Table frame factories
-nsIFrame*
+class nsTableOuterFrame;
+nsTableOuterFrame*
 NS_NewTableOuterFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
-nsIFrame*
+class nsTableFrame;
+nsTableFrame*
 NS_NewTableFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
-nsIFrame*
+class nsTableCaptionFrame;
+nsTableCaptionFrame*
 NS_NewTableCaptionFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsTableColFrame*
 NS_NewTableColFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
-nsIFrame*
+class nsTableColGroupFrame;
+nsTableColGroupFrame*
 NS_NewTableColGroupFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
-nsIFrame*
+class nsTableRowFrame;
+nsTableRowFrame*
 NS_NewTableRowFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
-nsIFrame*
+class nsTableRowGroupFrame;
+nsTableRowGroupFrame*
 NS_NewTableRowGroupFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
-nsIFrame*
+class nsTableCellFrame;
+nsTableCellFrame*
 NS_NewTableCellFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, bool aIsBorderCollapse);
 
 nsresult
 NS_NewHTMLContentSink(nsIHTMLContentSink** aInstancePtrResult,
                       nsIDocument* aDoc, nsIURI* aURL,
                       nsISupports* aContainer, // e.g. docshell
                       nsIChannel* aChannel);
 nsresult
--- a/layout/generic/nsInlineFrame.cpp
+++ b/layout/generic/nsInlineFrame.cpp
@@ -26,17 +26,17 @@
 using namespace mozilla;
 using namespace mozilla::layout;
 
 
 //////////////////////////////////////////////////////////////////////
 
 // Basic nsInlineFrame methods
 
-nsIFrame*
+nsInlineFrame*
 NS_NewInlineFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsInlineFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsInlineFrame)
 
 NS_QUERYFRAME_HEAD(nsInlineFrame)
--- a/layout/generic/nsInlineFrame.h
+++ b/layout/generic/nsInlineFrame.h
@@ -23,17 +23,18 @@ typedef nsContainerFrame nsInlineFrameBa
  */
 class nsInlineFrame : public nsInlineFrameBase
 {
 public:
   NS_DECL_QUERYFRAME_TARGET(nsInlineFrame)
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS
 
-  friend nsIFrame* NS_NewInlineFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
+  friend nsInlineFrame* NS_NewInlineFrame(nsIPresShell* aPresShell,
+                                          nsStyleContext* aContext);
 
   // nsIFrame overrides
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
 
 #ifdef ACCESSIBILITY
   virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE;
--- a/layout/generic/nsPageContentFrame.cpp
+++ b/layout/generic/nsPageContentFrame.cpp
@@ -4,17 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #include "nsPageContentFrame.h"
 #include "nsCSSFrameConstructor.h"
 #include "nsPresContext.h"
 #include "nsGkAtoms.h"
 #include "nsIPresShell.h"
 #include "nsSimplePageSequenceFrame.h"
 
-nsIFrame*
+nsPageContentFrame*
 NS_NewPageContentFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsPageContentFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsPageContentFrame)
 
 void
--- a/layout/generic/nsPageContentFrame.h
+++ b/layout/generic/nsPageContentFrame.h
@@ -11,17 +11,18 @@ class nsPageFrame;
 class nsSharedPageData;
 
 // Page frame class used by the simple page sequence frame
 class nsPageContentFrame : public ViewportFrame {
 
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
-  friend nsIFrame* NS_NewPageContentFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
+  friend nsPageContentFrame* NS_NewPageContentFrame(nsIPresShell* aPresShell,
+                                                    nsStyleContext* aContext);
   friend class nsPageFrame;
 
   // nsIFrame
   virtual void Reflow(nsPresContext*      aPresContext,
                       nsHTMLReflowMetrics& aDesiredSize,
                       const nsHTMLReflowState& aMaxSize,
                       nsReflowStatus&      aStatus) MOZ_OVERRIDE;
 
--- a/layout/generic/nsPageFrame.cpp
+++ b/layout/generic/nsPageFrame.cpp
@@ -21,17 +21,17 @@
 extern PRLogModuleInfo *GetLayoutPrintingLog();
 #define PR_PL(_p1)  PR_LOG(GetLayoutPrintingLog(), PR_LOG_DEBUG, _p1)
 #else
 #define PR_PL(_p1)
 #endif
 
 using namespace mozilla;
 
-nsIFrame*
+nsPageFrame*
 NS_NewPageFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsPageFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsPageFrame)
 
 nsPageFrame::nsPageFrame(nsStyleContext* aContext)
--- a/layout/generic/nsPageFrame.h
+++ b/layout/generic/nsPageFrame.h
@@ -12,17 +12,18 @@
 class nsSharedPageData;
 
 // Page frame class used by the simple page sequence frame
 class nsPageFrame : public nsContainerFrame {
 
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
-  friend nsIFrame* NS_NewPageFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
+  friend nsPageFrame* NS_NewPageFrame(nsIPresShell* aPresShell,
+                                      nsStyleContext* aContext);
 
   virtual void Reflow(nsPresContext*      aPresContext,
                       nsHTMLReflowMetrics& aDesiredSize,
                       const nsHTMLReflowState& aMaxSize,
                       nsReflowStatus&      aStatus) MOZ_OVERRIDE;
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
--- a/layout/generic/nsSimplePageSequenceFrame.cpp
+++ b/layout/generic/nsSimplePageSequenceFrame.cpp
@@ -50,17 +50,17 @@ GetLayoutPrintingLog()
     sLog = PR_NewLogModule("printing-layout");
   return sLog;
 }
 #define PR_PL(_p1)  PR_LOG(GetLayoutPrintingLog(), PR_LOG_DEBUG, _p1)
 #else
 #define PR_PL(_p1)
 #endif
 
-nsIFrame*
+nsSimplePageSequenceFrame*
 NS_NewSimplePageSequenceFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsSimplePageSequenceFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsSimplePageSequenceFrame)
 
 nsSimplePageSequenceFrame::nsSimplePageSequenceFrame(nsStyleContext* aContext) :
--- a/layout/generic/nsSimplePageSequenceFrame.h
+++ b/layout/generic/nsSimplePageSequenceFrame.h
@@ -53,17 +53,18 @@ public:
   // that overflowed.  It's 1.0 if none overflowed horizontally.
   float mShrinkToFitRatio;
 };
 
 // Simple page sequence frame class. Used when we're in paginated mode
 class nsSimplePageSequenceFrame : public nsContainerFrame,
                                   public nsIPageSequenceFrame {
 public:
-  friend nsIFrame* NS_NewSimplePageSequenceFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
+  friend nsSimplePageSequenceFrame* NS_NewSimplePageSequenceFrame(nsIPresShell* aPresShell,
+                                                                  nsStyleContext* aContext);
 
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS
 
   // nsIFrame
   virtual void Reflow(nsPresContext*      aPresContext,
                       nsHTMLReflowMetrics& aDesiredSize,
                       const nsHTMLReflowState& aMaxSize,
--- a/layout/generic/nsViewportFrame.cpp
+++ b/layout/generic/nsViewportFrame.cpp
@@ -12,17 +12,17 @@
 #include "nsGkAtoms.h"
 #include "nsIScrollableFrame.h"
 #include "nsSubDocumentFrame.h"
 #include "nsAbsoluteContainingBlock.h"
 #include "GeckoProfiler.h"
 
 using namespace mozilla;
 
-nsIFrame*
+ViewportFrame*
 NS_NewViewportFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) ViewportFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(ViewportFrame)
 NS_QUERYFRAME_HEAD(ViewportFrame)
   NS_QUERYFRAME_ENTRY(ViewportFrame)
--- a/layout/mathml/nsMathMLParts.h
+++ b/layout/mathml/nsMathMLParts.h
@@ -19,21 +19,21 @@ nsIFrame* NS_NewMathMLmspaceFrame(nsIPre
 nsIFrame* NS_NewMathMLmsFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame* NS_NewMathMLmfencedFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame* NS_NewMathMLmfracFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame* NS_NewMathMLmsubFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame* NS_NewMathMLmsupFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame* NS_NewMathMLmsubsupFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame* NS_NewMathMLmunderoverFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame* NS_NewMathMLmmultiscriptsFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
-nsIFrame* NS_NewMathMLmtableOuterFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
-nsIFrame* NS_NewMathMLmtableFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
-nsIFrame* NS_NewMathMLmtrFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
-nsIFrame* NS_NewMathMLmtdFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
-nsIFrame* NS_NewMathMLmtdInnerFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
+nsContainerFrame* NS_NewMathMLmtableOuterFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
+nsContainerFrame* NS_NewMathMLmtableFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
+nsContainerFrame* NS_NewMathMLmtrFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
+nsContainerFrame* NS_NewMathMLmtdFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
+nsContainerFrame* NS_NewMathMLmtdInnerFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame* NS_NewMathMLmsqrtFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame* NS_NewMathMLmrootFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame* NS_NewMathMLmactionFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame* NS_NewMathMLmencloseFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame* NS_NewMathMLsemanticsFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
 nsContainerFrame* NS_NewMathMLmathBlockFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, nsFrameState aFlags);
 nsContainerFrame* NS_NewMathMLmathInlineFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
--- a/layout/mathml/nsMathMLmtableFrame.cpp
+++ b/layout/mathml/nsMathMLmtableFrame.cpp
@@ -417,17 +417,17 @@ ListMathMLTree(nsIFrame* atLeast)
 
 // --------
 // implementation of nsMathMLmtableOuterFrame
 
 NS_QUERYFRAME_HEAD(nsMathMLmtableOuterFrame)
   NS_QUERYFRAME_ENTRY(nsIMathMLFrame)
 NS_QUERYFRAME_TAIL_INHERITING(nsTableOuterFrame)
 
-nsIFrame*
+nsContainerFrame*
 NS_NewMathMLmtableOuterFrame (nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsMathMLmtableOuterFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsMathMLmtableOuterFrame)
  
 nsMathMLmtableOuterFrame::~nsMathMLmtableOuterFrame()
@@ -642,17 +642,17 @@ nsMathMLmtableOuterFrame::Reflow(nsPresC
   mBoundingMetrics.width = aDesiredSize.Width();
   mBoundingMetrics.leftBearing = 0;
   mBoundingMetrics.rightBearing = aDesiredSize.Width();
 
   aDesiredSize.mBoundingMetrics = mBoundingMetrics;
   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
 }
 
-nsIFrame*
+nsContainerFrame*
 NS_NewMathMLmtableFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsMathMLmtableFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsMathMLmtableFrame)
 
 nsMathMLmtableFrame::~nsMathMLmtableFrame()
@@ -679,17 +679,17 @@ nsMathMLmtableFrame::RestyleTable()
   PresContext()->RestyleManager()->
     PostRestyleEvent(mContent->AsElement(), eRestyle_Subtree,
                      nsChangeHint_AllReflowHints);
 }
 
 // --------
 // implementation of nsMathMLmtrFrame
 
-nsIFrame*
+nsContainerFrame*
 NS_NewMathMLmtrFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsMathMLmtrFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsMathMLmtrFrame)
 
 nsMathMLmtrFrame::~nsMathMLmtrFrame()
@@ -725,17 +725,17 @@ nsMathMLmtrFrame::AttributeChanged(int32
       FrameNeedsReflow(this, nsIPresShell::eStyleChange, NS_FRAME_IS_DIRTY);
 
   return NS_OK;
 }
 
 // --------
 // implementation of nsMathMLmtdFrame
 
-nsIFrame*
+nsContainerFrame*
 NS_NewMathMLmtdFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsMathMLmtdFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsMathMLmtdFrame)
 
 nsMathMLmtdFrame::~nsMathMLmtdFrame()
@@ -859,17 +859,17 @@ nsMathMLmtdFrame::GetBorderWidth(nsMargi
 
 // --------
 // implementation of nsMathMLmtdInnerFrame
 
 NS_QUERYFRAME_HEAD(nsMathMLmtdInnerFrame)
   NS_QUERYFRAME_ENTRY(nsIMathMLFrame)
 NS_QUERYFRAME_TAIL_INHERITING(nsBlockFrame)
 
-nsIFrame*
+nsContainerFrame*
 NS_NewMathMLmtdInnerFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsMathMLmtdInnerFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsMathMLmtdInnerFrame)
 
 nsMathMLmtdInnerFrame::nsMathMLmtdInnerFrame(nsStyleContext* aContext)
--- a/layout/mathml/nsMathMLmtableFrame.h
+++ b/layout/mathml/nsMathMLmtableFrame.h
@@ -16,17 +16,18 @@
 //
 // <mtable> -- table or matrix
 //
 
 class nsMathMLmtableOuterFrame : public nsTableOuterFrame,
                                  public nsMathMLFrame
 {
 public:
-  friend nsIFrame* NS_NewMathMLmtableOuterFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
+  friend nsContainerFrame* NS_NewMathMLmtableOuterFrame(nsIPresShell* aPresShell,
+                                                        nsStyleContext* aContext);
 
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS
 
   // overloaded nsTableOuterFrame methods
 
   virtual void
   Reflow(nsPresContext*          aPresContext,
@@ -58,17 +59,18 @@ protected:
 
 // --------------
 
 class nsMathMLmtableFrame : public nsTableFrame
 {
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
-  friend nsIFrame* NS_NewMathMLmtableFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
+  friend nsContainerFrame* NS_NewMathMLmtableFrame(nsIPresShell* aPresShell,
+                                                   nsStyleContext* aContext);
 
   // Overloaded nsTableFrame methods
 
   virtual nsresult
   SetInitialChildList(ChildListID  aListID,
                       nsFrameList& aChildList) MOZ_OVERRIDE;
 
   virtual nsresult
@@ -116,17 +118,18 @@ protected:
 
 // --------------
 
 class nsMathMLmtrFrame : public nsTableRowFrame
 {
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
-  friend nsIFrame* NS_NewMathMLmtrFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
+  friend nsContainerFrame* NS_NewMathMLmtrFrame(nsIPresShell* aPresShell,
+                                                nsStyleContext* aContext);
 
   // overloaded nsTableRowFrame methods
 
   virtual nsresult
   AttributeChanged(int32_t  aNameSpaceID,
                    nsIAtom* aAttribute,
                    int32_t  aModType) MOZ_OVERRIDE;
 
@@ -180,17 +183,18 @@ protected:
 
 // --------------
 
 class nsMathMLmtdFrame : public nsTableCellFrame
 {
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
-  friend nsIFrame* NS_NewMathMLmtdFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
+  friend nsContainerFrame* NS_NewMathMLmtdFrame(nsIPresShell* aPresShell,
+                                                nsStyleContext* aContext);
 
   // overloaded nsTableCellFrame methods
 
   virtual nsresult
   AttributeChanged(int32_t  aNameSpaceID,
                    nsIAtom* aAttribute,
                    int32_t  aModType) MOZ_OVERRIDE;
 
@@ -213,17 +217,17 @@ protected:
   virtual ~nsMathMLmtdFrame();
 }; // class nsMathMLmtdFrame
 
 // --------------
 
 class nsMathMLmtdInnerFrame : public nsBlockFrame,
                               public nsMathMLFrame {
 public:
-  friend nsIFrame* NS_NewMathMLmtdInnerFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
+  friend nsContainerFrame* NS_NewMathMLmtdInnerFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS
 
   // Overloaded nsIMathMLFrame methods
 
   NS_IMETHOD
   UpdatePresentationDataFromChildAt(int32_t         aFirstIndex,
--- a/layout/svg/nsSVGForeignObjectFrame.cpp
+++ b/layout/svg/nsSVGForeignObjectFrame.cpp
@@ -22,17 +22,17 @@
 #include "mozilla/AutoRestore.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 //----------------------------------------------------------------------
 // Implementation
 
-nsIFrame*
+nsContainerFrame*
 NS_NewSVGForeignObjectFrame(nsIPresShell   *aPresShell,
                             nsStyleContext *aContext)
 {
   return new (aPresShell) nsSVGForeignObjectFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsSVGForeignObjectFrame)
 
--- a/layout/svg/nsSVGForeignObjectFrame.h
+++ b/layout/svg/nsSVGForeignObjectFrame.h
@@ -16,17 +16,17 @@
 class nsRenderingContext;
 class nsSVGOuterSVGFrame;
 
 typedef nsContainerFrame nsSVGForeignObjectFrameBase;
 
 class nsSVGForeignObjectFrame : public nsSVGForeignObjectFrameBase,
                                 public nsISVGChildFrame
 {
-  friend nsIFrame*
+  friend nsContainerFrame*
   NS_NewSVGForeignObjectFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 protected:
   nsSVGForeignObjectFrame(nsStyleContext* aContext);
 
 public:
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS
 
--- a/layout/svg/nsSVGMarkerFrame.cpp
+++ b/layout/svg/nsSVGMarkerFrame.cpp
@@ -12,17 +12,17 @@
 #include "nsSVGEffects.h"
 #include "mozilla/dom/SVGMarkerElement.h"
 #include "nsSVGPathGeometryElement.h"
 #include "nsSVGPathGeometryFrame.h"
 
 using namespace mozilla::dom;
 using namespace mozilla::gfx;
 
-nsIFrame*
+nsContainerFrame*
 NS_NewSVGMarkerFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsSVGMarkerFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsSVGMarkerFrame)
 
 //----------------------------------------------------------------------
@@ -239,17 +239,17 @@ nsSVGMarkerFrame::AutoMarkerReferencer::
 
   mFrame->mMarkedFrame = nullptr;
   mFrame->mInUse = false;
 }
 
 //----------------------------------------------------------------------
 // Implementation of nsSVGMarkerAnonChildFrame
 
-nsIFrame*
+nsContainerFrame*
 NS_NewSVGMarkerAnonChildFrame(nsIPresShell* aPresShell,
                               nsStyleContext* aContext)
 {
   return new (aPresShell) nsSVGMarkerAnonChildFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsSVGMarkerAnonChildFrame)
 
--- a/layout/svg/nsSVGMarkerFrame.h
+++ b/layout/svg/nsSVGMarkerFrame.h
@@ -10,38 +10,33 @@
 #include "gfxMatrix.h"
 #include "gfxRect.h"
 #include "nsFrame.h"
 #include "nsLiteralString.h"
 #include "nsQueryFrame.h"
 #include "nsSVGContainerFrame.h"
 #include "nsSVGUtils.h"
 
-class nsIAtom;
-class nsIContent;
-class nsIFrame;
-class nsIPresShell;
 class nsRenderingContext;
-class nsStyleContext;
 class nsSVGPathGeometryFrame;
 
 namespace mozilla {
 namespace dom {
 class SVGSVGElement;
 }
 }
 
 struct nsSVGMark;
 
 typedef nsSVGContainerFrame nsSVGMarkerFrameBase;
 
 class nsSVGMarkerFrame : public nsSVGMarkerFrameBase
 {
   friend class nsSVGMarkerAnonChildFrame;
-  friend nsIFrame*
+  friend nsContainerFrame*
   NS_NewSVGMarkerFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 protected:
   nsSVGMarkerFrame(nsStyleContext* aContext)
     : nsSVGMarkerFrameBase(aContext)
     , mMarkedFrame(nullptr)
     , mInUse(false)
     , mInUse2(false)
   {
@@ -142,17 +137,17 @@ private:
 
 typedef nsSVGDisplayContainerFrame nsSVGMarkerAnonChildFrameBase;
 
 /**
  */
 class nsSVGMarkerAnonChildFrame
   : public nsSVGMarkerAnonChildFrameBase
 {
-  friend nsIFrame*
+  friend nsContainerFrame*
   NS_NewSVGMarkerAnonChildFrame(nsIPresShell* aPresShell,
                                 nsStyleContext* aContext);
 
   nsSVGMarkerAnonChildFrame(nsStyleContext* aContext)
     : nsSVGMarkerAnonChildFrameBase(aContext)
   {}
 
 public:
--- a/layout/svg/nsSVGOuterSVGFrame.cpp
+++ b/layout/svg/nsSVGOuterSVGFrame.cpp
@@ -50,17 +50,17 @@ nsSVGOuterSVGFrame::UnregisterForeignObj
   NS_ASSERTION(mForeignObjectHash && mForeignObjectHash->GetEntry(aFrame),
                "nsSVGForeignObjectFrame not in registry!");
   return mForeignObjectHash->RemoveEntry(aFrame);
 }
 
 //----------------------------------------------------------------------
 // Implementation
 
-nsIFrame*
+nsContainerFrame*
 NS_NewSVGOuterSVGFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {  
   return new (aPresShell) nsSVGOuterSVGFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsSVGOuterSVGFrame)
 
 nsSVGOuterSVGFrame::nsSVGOuterSVGFrame(nsStyleContext* aContext)
@@ -896,17 +896,17 @@ nsSVGOuterSVGFrame::VerticalScrollbarNot
                            mLengthAttributes[SVGSVGElement::ATTR_HEIGHT];
   return height.IsPercentage() && height.GetBaseValInSpecifiedUnits() <= 100;
 }
 
 
 //----------------------------------------------------------------------
 // Implementation of nsSVGOuterSVGAnonChildFrame
 
-nsIFrame*
+nsContainerFrame*
 NS_NewSVGOuterSVGAnonChildFrame(nsIPresShell* aPresShell,
                                 nsStyleContext* aContext)
 {
   return new (aPresShell) nsSVGOuterSVGAnonChildFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsSVGOuterSVGAnonChildFrame)
 
--- a/layout/svg/nsSVGOuterSVGFrame.h
+++ b/layout/svg/nsSVGOuterSVGFrame.h
@@ -16,17 +16,17 @@ class nsSVGForeignObjectFrame;
 ////////////////////////////////////////////////////////////////////////
 // nsSVGOuterSVGFrame class
 
 typedef nsSVGDisplayContainerFrame nsSVGOuterSVGFrameBase;
 
 class nsSVGOuterSVGFrame : public nsSVGOuterSVGFrameBase,
                            public nsISVGSVGFrame
 {
-  friend nsIFrame*
+  friend nsContainerFrame*
   NS_NewSVGOuterSVGFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 protected:
   nsSVGOuterSVGFrame(nsStyleContext* aContext);
 
 public:
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS
 
@@ -228,17 +228,17 @@ typedef nsSVGDisplayContainerFrame nsSVG
  * than simply from nsContainerFrame is so that we can avoid having special
  * handling for these inner wrappers in multiple parts of the SVG code. For
  * example, the implementations of IsSVGTransformed and GetCanvasTM assume
  * nsSVGContainerFrame instances all the way up to the nsSVGOuterSVGFrame.
  */
 class nsSVGOuterSVGAnonChildFrame
   : public nsSVGOuterSVGAnonChildFrameBase
 {
-  friend nsIFrame*
+  friend nsContainerFrame*
   NS_NewSVGOuterSVGAnonChildFrame(nsIPresShell* aPresShell,
                                   nsStyleContext* aContext);
 
   nsSVGOuterSVGAnonChildFrame(nsStyleContext* aContext)
     : nsSVGOuterSVGAnonChildFrameBase(aContext)
   {}
 
 public:
--- a/layout/tables/nsTableCellFrame.cpp
+++ b/layout/tables/nsTableCellFrame.cpp
@@ -1042,17 +1042,17 @@ nsTableCellFrame::GetCellIndexes(int32_t
   {
     aColIndex = 0;
     return res;
   }
   aColIndex = mColIndex;
   return  NS_OK;
 }
 
-nsIFrame*
+nsTableCellFrame*
 NS_NewTableCellFrame(nsIPresShell*   aPresShell,
                      nsStyleContext* aContext,
                      bool            aIsBorderCollapse)
 {
   if (aIsBorderCollapse)
     return new (aPresShell) nsBCTableCellFrame(aContext);
   else
     return new (aPresShell) nsTableCellFrame(aContext);
--- a/layout/tables/nsTableColGroupFrame.cpp
+++ b/layout/tables/nsTableColGroupFrame.cpp
@@ -452,17 +452,17 @@ void nsTableColGroupFrame::GetContinuous
   aBorder.top = BC_BORDER_BOTTOM_HALF_COORD(aPixelsToTwips,
                                             mTopContBorderWidth);
   aBorder.bottom = BC_BORDER_TOP_HALF_COORD(aPixelsToTwips,
                                             mBottomContBorderWidth);
 }
 
 /* ----- global methods ----- */
 
-nsIFrame*
+nsTableColGroupFrame*
 NS_NewTableColGroupFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsTableColGroupFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsTableColGroupFrame)
 
 nsIAtom*
--- a/layout/tables/nsTableColGroupFrame.h
+++ b/layout/tables/nsTableColGroupFrame.h
@@ -32,17 +32,18 @@ public:
 
   // default constructor supplied by the compiler
 
   /** instantiate a new instance of nsTableRowFrame.
     * @param aPresShell the pres shell for this frame
     *
     * @return           the frame that was created
     */
-  friend nsIFrame* NS_NewTableColGroupFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
+  friend nsTableColGroupFrame* NS_NewTableColGroupFrame(nsIPresShell* aPresShell,
+                                                        nsStyleContext* aContext);
 
   /** Initialize the colgroup frame with a set of children.
     * @see nsIFrame::SetInitialChildList
     */
   virtual nsresult SetInitialChildList(ChildListID     aListID,
                                        nsFrameList&    aChildList) MOZ_OVERRIDE;
 
   /**
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -3556,17 +3556,17 @@ nsTableFrame::GetBaseline() const
     }
   }
   if (!firstRow)
     ascent = GetRect().height;
   return ascent;
 }
 /* ----- global methods ----- */
 
-nsIFrame*
+nsTableFrame*
 NS_NewTableFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsTableFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsTableFrame)
 
 nsTableFrame*
--- a/layout/tables/nsTableFrame.h
+++ b/layout/tables/nsTableFrame.h
@@ -117,17 +117,18 @@ public:
   /** nsTableOuterFrame has intimate knowledge of the inner table frame */
   friend class nsTableOuterFrame;
 
   /** instantiate a new instance of nsTableRowFrame.
     * @param aPresShell the pres shell for this frame
     *
     * @return           the frame that was created
     */
-  friend nsIFrame* NS_NewTableFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
+  friend nsTableFrame* NS_NewTableFrame(nsIPresShell* aPresShell,
+                                        nsStyleContext* aContext);
 
   /** sets defaults for table-specific style.
     * @see nsIFrame::Init 
     */
   virtual void Init(nsIContent*      aContent,
                     nsIFrame*        aParent,
                     nsIFrame*        aPrevInFlow) MOZ_OVERRIDE;
 
--- a/layout/tables/nsTableOuterFrame.cpp
+++ b/layout/tables/nsTableOuterFrame.cpp
@@ -127,17 +127,17 @@ nsTableCaptionFrame::AccessibleType()
 #ifdef DEBUG_FRAME_DUMP
 nsresult
 nsTableCaptionFrame::GetFrameName(nsAString& aResult) const
 {
   return MakeFrameName(NS_LITERAL_STRING("Caption"), aResult);
 }
 #endif
 
-nsIFrame* 
+nsTableCaptionFrame* 
 NS_NewTableCaptionFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsTableCaptionFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsTableCaptionFrame)
 
 /* ----------- nsTableOuterFrame ---------- */
@@ -1087,17 +1087,17 @@ nsTableOuterFrame::GetCellAt(uint32_t aR
   if (!cell) {
     return nullptr;
   }
 
   return cell->GetContent();
 }
 
 
-nsIFrame*
+nsTableOuterFrame*
 NS_NewTableOuterFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsTableOuterFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsTableOuterFrame)
 
 #ifdef DEBUG_FRAME_DUMP
--- a/layout/tables/nsTableOuterFrame.h
+++ b/layout/tables/nsTableOuterFrame.h
@@ -12,19 +12,20 @@
 #include "nsBlockFrame.h"
 #include "nsTableFrame.h"
 
 class nsTableCaptionFrame : public nsBlockFrame
 {
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
-  // nsISupports
+  friend nsTableCaptionFrame* NS_NewTableCaptionFrame(nsIPresShell* aPresShell,
+                                                      nsStyleContext*  aContext);
+  // nsIFrame
   virtual nsIAtom* GetType() const MOZ_OVERRIDE;
-  friend nsIFrame* NS_NewTableCaptionFrame(nsIPresShell* aPresShell, nsStyleContext*  aContext);
 
   virtual nsSize ComputeAutoSize(nsRenderingContext *aRenderingContext,
                                  nsSize aCBSize, nscoord aAvailableWidth,
                                  nsSize aMargin, nsSize aBorder,
                                  nsSize aPadding, bool aShrinkWrap) MOZ_OVERRIDE;
 
   virtual nsIFrame* GetParentStyleContextFrame() const MOZ_OVERRIDE;
 
@@ -59,17 +60,18 @@ public:
 
   NS_DECL_QUERYFRAME_TARGET(nsTableOuterFrame)
 
   /** instantiate a new instance of nsTableRowFrame.
     * @param aPresShell the pres shell for this frame
     *
     * @return           the frame that was created
     */
-  friend nsIFrame* NS_NewTableOuterFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
+  friend nsTableOuterFrame* NS_NewTableOuterFrame(nsIPresShell* aPresShell,
+                                                  nsStyleContext* aContext);
   
   // nsIFrame overrides - see there for a description
 
   virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
 
   virtual nsresult SetInitialChildList(ChildListID     aListID,
                                        nsFrameList&    aChildList) MOZ_OVERRIDE;
  
--- a/layout/tables/nsTableRowFrame.cpp
+++ b/layout/tables/nsTableRowFrame.cpp
@@ -1430,17 +1430,17 @@ nsTableRowFrame::InvalidateFrameWithRect
   // If we have filters applied that would affects our bounds, then
   // we get an inactive layer created and this is computed
   // within FrameLayerBuilder
   GetParent()->InvalidateFrameWithRect(aRect + GetPosition(), aDisplayItemKey);
 }
 
 /* ----- global methods ----- */
 
-nsIFrame* 
+nsTableRowFrame* 
 NS_NewTableRowFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsTableRowFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsTableRowFrame)
 
 #ifdef DEBUG_FRAME_DUMP
--- a/layout/tables/nsTableRowFrame.h
+++ b/layout/tables/nsTableRowFrame.h
@@ -50,17 +50,18 @@ public:
   virtual nsresult RemoveFrame(ChildListID     aListID,
                                nsIFrame*       aOldFrame) MOZ_OVERRIDE;
 
   /** instantiate a new instance of nsTableRowFrame.
     * @param aPresShell the pres shell for this frame
     *
     * @return           the frame that was created
     */
-  friend nsIFrame* NS_NewTableRowFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
+  friend nsTableRowFrame* NS_NewTableRowFrame(nsIPresShell* aPresShell,
+                                              nsStyleContext* aContext);
 
   virtual nsMargin GetUsedMargin() const MOZ_OVERRIDE;
   virtual nsMargin GetUsedBorder() const MOZ_OVERRIDE;
   virtual nsMargin GetUsedPadding() const MOZ_OVERRIDE;
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
--- a/layout/tables/nsTableRowGroupFrame.cpp
+++ b/layout/tables/nsTableRowGroupFrame.cpp
@@ -1579,17 +1579,17 @@ nsTableRowGroupFrame::HasInternalBreakAf
 {
   nsIFrame* lastChild = mFrames.LastChild(); 
   if (!lastChild)
     return false;
   return lastChild->StyleDisplay()->mBreakAfter;
 }
 /* ----- global methods ----- */
 
-nsIFrame*
+nsTableRowGroupFrame*
 NS_NewTableRowGroupFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsTableRowGroupFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsTableRowGroupFrame)
 
 #ifdef DEBUG_FRAME_DUMP
--- a/layout/tables/nsTableRowGroupFrame.h
+++ b/layout/tables/nsTableRowGroupFrame.h
@@ -60,17 +60,18 @@ public:
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS
 
   /** instantiate a new instance of nsTableRowFrame.
     * @param aPresShell the pres shell for this frame
     *
     * @return           the frame that was created
     */
-  friend nsIFrame* NS_NewTableRowGroupFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
+  friend nsTableRowGroupFrame* NS_NewTableRowGroupFrame(nsIPresShell* aPresShell,
+                                                        nsStyleContext* aContext);
   virtual ~nsTableRowGroupFrame();
 
   virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
 
   /** @see nsIFrame::DidSetStyleContext */
   virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE;
   
   virtual nsresult AppendFrames(ChildListID     aListID,
--- a/layout/xul/nsDocElementBoxFrame.cpp
+++ b/layout/xul/nsDocElementBoxFrame.cpp
@@ -59,17 +59,17 @@ public:
 #endif
 private:
   nsCOMPtr<Element> mPopupgroupContent;
   nsCOMPtr<Element> mTooltipContent;
 };
 
 //----------------------------------------------------------------------
 
-nsIFrame*
+nsContainerFrame*
 NS_NewDocElementBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsDocElementBoxFrame (aPresShell, aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsDocElementBoxFrame)
 
 void
--- a/layout/xul/nsRootBoxFrame.cpp
+++ b/layout/xul/nsRootBoxFrame.cpp
@@ -100,17 +100,17 @@ public:
   nsPopupSetFrame* mPopupSetFrame;
 
 protected:
   nsIContent* mDefaultTooltip;
 };
 
 //----------------------------------------------------------------------
 
-nsIFrame*
+nsContainerFrame*
 NS_NewRootBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsRootBoxFrame (aPresShell, aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsRootBoxFrame)
 
 nsRootBoxFrame::nsRootBoxFrame(nsIPresShell* aShell, nsStyleContext* aContext):