Bug 921876 - Stop #including nsIFrame.h in nsLayoutUtils.h; r=roc
authorEhsan Akhgari <ehsan@mozilla.com>
Mon, 30 Sep 2013 17:26:04 -0400
changeset 149384 e8453cdce0057180b18cd1ba8514e279f24b0cf5
parent 149383 cb856e6d57c1eeb387e3b57a5e4f95afc16f80cb
child 149385 b17120deb5b40081ab60402044439752b0ec5c64
push id25386
push useremorley@mozilla.com
push dateTue, 01 Oct 2013 09:29:22 +0000
treeherdermozilla-central@6856c45f3688 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs921876
milestone27.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 921876 - Stop #including nsIFrame.h in nsLayoutUtils.h; r=roc This patch does the following: * Move nsIFrame::IntrinsicSize to mozilla::IntrinsicSize so that it can be forward-declared. * Move a number of templated inline nsLayoutUtils methods to nsIFrame. * Use mozilla::layout::FrameChildListID instead of the nsIFrame::ChildListID typedef in nsLayoutUtils.h. * Move nsReflowFrameRunnable to its only user, nsProgressMeterFrame.cpp. * Make a number of functions requiring nsIFrame.h out-of-line. * Remove the nsIFrame.h #include from nsLayoutUtils.h and add it to the places which require it implicitly.
content/canvas/src/DocumentRendererChild.cpp
content/canvas/src/WebGLContext.h
content/events/src/Touch.cpp
content/events/src/nsDOMUIEvent.h
content/events/src/nsEventDispatcher.cpp
dom/base/nsFocusManager.cpp
dom/base/nsScreen.cpp
image/src/VectorImage.cpp
layout/base/PositionedEventTargeting.cpp
layout/base/RestyleManager.cpp
layout/base/nsBidiPresUtils.cpp
layout/base/nsCSSRendering.h
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
layout/generic/nsFlexContainerFrame.cpp
layout/generic/nsFontInflationData.cpp
layout/generic/nsFrame.cpp
layout/generic/nsFrame.h
layout/generic/nsFrameList.h
layout/generic/nsIFrame.h
layout/generic/nsImageFrame.cpp
layout/generic/nsImageFrame.h
layout/generic/nsInlineFrame.cpp
layout/generic/nsLineLayout.cpp
layout/generic/nsSubDocumentFrame.cpp
layout/generic/nsSubDocumentFrame.h
layout/mathml/nsMathMLFrame.h
layout/style/nsAnimationManager.cpp
layout/svg/nsSVGOuterSVGFrame.cpp
layout/svg/nsSVGOuterSVGFrame.h
layout/svg/nsSVGTextFrame2.cpp
layout/xul/base/src/nsBoxFrame.cpp
layout/xul/base/src/nsProgressMeterFrame.cpp
--- a/content/canvas/src/DocumentRendererChild.cpp
+++ b/content/canvas/src/DocumentRendererChild.cpp
@@ -15,16 +15,18 @@
 #include "nsComponentManagerUtils.h"
 #include "nsCSSParser.h"
 #include "nsPresContext.h"
 #include "nsCOMPtr.h"
 #include "nsColor.h"
 #include "gfxContext.h"
 #include "nsLayoutUtils.h"
 #include "nsContentUtils.h"
+#include "nsCSSValue.h"
+#include "nsRuleNode.h"
 
 using namespace mozilla::ipc;
 
 DocumentRendererChild::DocumentRendererChild()
 {}
 
 DocumentRendererChild::~DocumentRendererChild()
 {}
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -17,16 +17,17 @@
 
 #include "nsIDOMWebGLRenderingContext.h"
 #include "nsICanvasRenderingContextInternal.h"
 #include "mozilla/dom/HTMLCanvasElement.h"
 #include "nsWrapperCache.h"
 #include "nsIObserver.h"
 
 #include "GLContextProvider.h"
+#include "gfxImageSurface.h"
 
 #include "mozilla/LinkedList.h"
 #include "mozilla/CheckedInt.h"
 
 #ifdef XP_MACOSX
 #include "ForceDiscreteGPUHelperCGL.h"
 #endif
 
--- a/content/events/src/Touch.cpp
+++ b/content/events/src/Touch.cpp
@@ -4,16 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/Touch.h"
 
 #include "mozilla/dom/EventTarget.h"
 #include "mozilla/dom/TouchBinding.h"
 #include "nsContentUtils.h"
 #include "nsDOMTouchEvent.h"
+#include "nsIContent.h"
 
 namespace mozilla {
 namespace dom {
 
 Touch::Touch(mozilla::dom::EventTarget* aTarget,
              int32_t aIdentifier,
              int32_t aPageX,
              int32_t aPageY,
--- a/content/events/src/nsDOMUIEvent.h
+++ b/content/events/src/nsDOMUIEvent.h
@@ -9,16 +9,18 @@
 #include "mozilla/Attributes.h"
 #include "nsIDOMUIEvent.h"
 #include "nsDOMEvent.h"
 #include "nsLayoutUtils.h"
 #include "mozilla/dom/UIEventBinding.h"
 #include "nsPresContext.h"
 #include "nsDeviceContext.h"
 
+class nsINode;
+
 class nsDOMUIEvent : public nsDOMEvent,
                      public nsIDOMUIEvent
 {
   typedef mozilla::CSSIntPoint CSSIntPoint;
 public:
   nsDOMUIEvent(mozilla::dom::EventTarget* aOwner,
                nsPresContext* aPresContext, nsGUIEvent* aEvent);
 
--- a/content/events/src/nsEventDispatcher.cpp
+++ b/content/events/src/nsEventDispatcher.cpp
@@ -6,16 +6,18 @@
 
 #include "nsEventDispatcher.h"
 #include "nsPresContext.h"
 #include "nsEventListenerManager.h"
 #include "nsContentUtils.h"
 #include "nsCxPusher.h"
 #include "nsError.h"
 #include <new>
+#include "nsIContent.h"
+#include "nsIDocument.h"
 #include "nsINode.h"
 #include "nsPIDOMWindow.h"
 #include "nsDOMTouchEvent.h"
 #include "GeckoProfiler.h"
 #include "GeneratedEvents.h"
 #include "mozilla/ContentEvents.h"
 #include "mozilla/dom/EventTarget.h"
 #include "mozilla/MiscEvents.h"
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -32,16 +32,17 @@
 #include "nsFrameSelection.h"
 #include "mozilla/Selection.h"
 #include "nsXULPopupManager.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsIPrincipal.h"
 #include "nsIObserverService.h"
 #include "nsIObjectFrame.h"
 #include "nsBindingManager.h"
+#include "nsStyleCoord.h"
 
 #include "mozilla/ContentEvents.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/LookAndFeel.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
 #include <algorithm>
 
--- a/dom/base/nsScreen.cpp
+++ b/dom/base/nsScreen.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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 "mozilla/Hal.h"
 #include "nsScreen.h"
 #include "nsIDocShell.h"
+#include "nsIDocument.h"
 #include "nsPresContext.h"
 #include "nsCOMPtr.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsLayoutUtils.h"
 #include "nsDOMEvent.h"
 #include "nsJSUtils.h"
 #include "mozilla/dom/ScreenBinding.h"
 #include "nsDeviceContext.h"
--- a/image/src/VectorImage.cpp
+++ b/image/src/VectorImage.cpp
@@ -521,17 +521,17 @@ VectorImage::GetIntrinsicSize(nsSize* aS
   if (mError || !mIsFullyLoaded)
     return NS_ERROR_FAILURE;
 
   nsIFrame* rootFrame = mSVGDocumentWrapper->GetRootLayoutFrame();
   if (!rootFrame)
     return NS_ERROR_FAILURE;
 
   *aSize = nsSize(-1, -1);
-  nsIFrame::IntrinsicSize rfSize = rootFrame->GetIntrinsicSize();
+  IntrinsicSize rfSize = rootFrame->GetIntrinsicSize();
   if (rfSize.width.GetUnit() == eStyleUnit_Coord)
     aSize->width = rfSize.width.GetCoordValue();
   if (rfSize.height.GetUnit() == eStyleUnit_Coord)
     aSize->height = rfSize.height.GetCoordValue();
 
   return NS_OK;
 }
 
--- a/layout/base/PositionedEventTargeting.cpp
+++ b/layout/base/PositionedEventTargeting.cpp
@@ -8,16 +8,17 @@
 #include "mozilla/Preferences.h"
 #include "nsLayoutUtils.h"
 #include "nsGkAtoms.h"
 #include "nsEventListenerManager.h"
 #include "nsPrintfCString.h"
 #include "mozilla/dom/Element.h"
 #include "nsRegion.h"
 #include "nsDeviceContext.h"
+#include "nsIFrame.h"
 #include <algorithm>
 
 namespace mozilla {
 
 /*
  * The basic goal of FindFrameTargetedByInputEvent() is to find a good
  * target element that can respond to mouse events. Both mouse events and touch
  * events are targeted at this element. Note that even for touch events, we
--- a/layout/base/RestyleManager.cpp
+++ b/layout/base/RestyleManager.cpp
@@ -2633,17 +2633,17 @@ void
 ElementRestyler::InitializeAccessibilityNotifications()
 {
 #ifdef ACCESSIBILITY
   // Notify a11y for primary frame only if it's a root frame of visibility
   // changes or its parent frame was hidden while it stays visible and
   // it is not inside a {ib} split or is the first frame of {ib} split.
   if (nsIPresShell::IsAccessibilityActive() &&
       !mFrame->GetPrevContinuation() &&
-      !nsLayoutUtils::FrameIsNonFirstInIBSplit(mFrame)) {
+      !mFrame->FrameIsNonFirstInIBSplit()) {
     if (mDesiredA11yNotifications == eSendAllNotifications) {
       bool isFrameVisible = mFrame->StyleVisibility()->IsVisible();
       if (isFrameVisible != mWasFrameVisible) {
         if (isFrameVisible) {
           // Notify a11y the element (perhaps with its children) was shown.
           // We don't fall into this case if this element gets or stays shown
           // while its parent becomes hidden.
           mKidsDesiredA11yNotifications = eSkipNotifications;
--- a/layout/base/nsBidiPresUtils.cpp
+++ b/layout/base/nsBidiPresUtils.cpp
@@ -1305,25 +1305,25 @@ nsBidiPresUtils::IsLeftOrRightMost(nsIFr
                         : !firstFrameState->mHasContOnPrevLines);
 
   if ((aIsLeftMost || aIsRightMost) &&
       (aFrame->GetStateBits() & NS_FRAME_IS_SPECIAL)) {
     // For ib splits, don't treat anything except the last part as
     // endmost or anything except the first part as startmost.
     // As an optimization, only get the first continuation once.
     nsIFrame* firstContinuation = aFrame->FirstContinuation();
-    if (nsLayoutUtils::FrameIsNonLastInIBSplit(firstContinuation)) {
+    if (firstContinuation->FrameIsNonLastInIBSplit()) {
       // We are not endmost
       if (isLTR) {
         aIsRightMost = false;
       } else {
         aIsLeftMost = false;
       }
     }
-    if (nsLayoutUtils::FrameIsNonFirstInIBSplit(firstContinuation)) {
+    if (firstContinuation->FrameIsNonFirstInIBSplit()) {
       // We are not startmost
       if (isLTR) {
         aIsLeftMost = false;
       } else {
         aIsRightMost = false;
       }
     }
   }
@@ -1447,17 +1447,17 @@ nsBidiPresUtils::RepositionInlineFrames(
   bool isLTR = (NS_STYLE_DIRECTION_LTR == vis->mDirection);
   nscoord leftSpace = 0;
 
   // This method is called from nsBlockFrame::PlaceLine via the call to
   // bidiUtils->ReorderFrames, so this is guaranteed to be after the inlines
   // have been reflowed, which is required for GetUsedMargin/Border/Padding
   nsMargin margin = aFirstChild->GetUsedMargin();
   if (!aFirstChild->GetPrevContinuation() &&
-      !nsLayoutUtils::FrameIsNonFirstInIBSplit(aFirstChild))
+      !aFirstChild->FrameIsNonFirstInIBSplit())
     leftSpace = isLTR ? margin.left : margin.right;
 
   nscoord left = aFirstChild->GetPosition().x - leftSpace;
   nsIFrame* frame;
   int32_t count = aBld->mVisualFrames.Length();
   int32_t index;
   nsContinuationStates continuationStates;
 
--- a/layout/base/nsCSSRendering.h
+++ b/layout/base/nsCSSRendering.h
@@ -6,16 +6,18 @@
 /* utility functions for drawing borders and backgrounds */
 
 #ifndef nsCSSRendering_h___
 #define nsCSSRendering_h___
 
 #include "gfxBlur.h"
 #include "gfxContext.h"
 #include "nsLayoutUtils.h"
+#include "nsStyleStruct.h"
+#include "nsIFrame.h"
 
 class nsStyleContext;
 class nsPresContext;
 class nsRenderingContext;
 
 namespace mozilla {
 
 // A CSSSizeOrRatio represents a (possibly partially specified) size for use
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -625,17 +625,17 @@ GetLastChildFrame(nsIFrame*       aFrame
 
     return lastChildFrame;
   }
 
   return nullptr;
 }
 
 //static
-nsIFrame::ChildListID
+FrameChildListID
 nsLayoutUtils::GetChildListNameFor(nsIFrame* aChildFrame)
 {
   nsIFrame::ChildListID id = nsIFrame::kPrincipalList;
 
   if (aChildFrame->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER) {
     nsIFrame* pif = aChildFrame->GetPrevInFlow();
     if (pif->GetParent() == aChildFrame->GetParent()) {
       id = nsIFrame::kExcessOverflowContainersList;
@@ -3128,17 +3128,17 @@ nsLayoutUtils::ComputeHeightDependentVal
   return 0;
 }
 
 #define MULDIV(a,b,c) (nscoord(int64_t(a) * int64_t(b) / int64_t(c)))
 
 /* static */ nsSize
 nsLayoutUtils::ComputeSizeWithIntrinsicDimensions(
                    nsRenderingContext* aRenderingContext, nsIFrame* aFrame,
-                   const nsIFrame::IntrinsicSize& aIntrinsicSize,
+                   const IntrinsicSize& aIntrinsicSize,
                    nsSize aIntrinsicRatio, nsSize aCBSize,
                    nsSize aMargin, nsSize aBorder, nsSize aPadding)
 {
   const nsStylePosition* stylePos = aFrame->StylePosition();
 
   // If we're a flex item, we'll compute our size a bit differently.
   const nsStyleCoord* widthStyleCoord = &(stylePos->mWidth);
   const nsStyleCoord* heightStyleCoord = &(stylePos->mHeight);
@@ -3453,31 +3453,31 @@ nsLayoutUtils::ComputeAutoSizeWithIntrin
 
   return nsSize(width, height);
 }
 
 /* static */ nscoord
 nsLayoutUtils::MinWidthFromInline(nsIFrame* aFrame,
                                   nsRenderingContext* aRenderingContext)
 {
-  NS_ASSERTION(!nsLayoutUtils::IsContainerForFontSizeInflation(aFrame),
+  NS_ASSERTION(!aFrame->IsContainerForFontSizeInflation(),
                "should not be container for font size inflation");
 
   nsIFrame::InlineMinWidthData data;
   DISPLAY_MIN_WIDTH(aFrame, data.prevLines);
   aFrame->AddInlineMinWidth(aRenderingContext, &data);
   data.ForceBreak(aRenderingContext);
   return data.prevLines;
 }
 
 /* static */ nscoord
 nsLayoutUtils::PrefWidthFromInline(nsIFrame* aFrame,
                                    nsRenderingContext* aRenderingContext)
 {
-  NS_ASSERTION(!nsLayoutUtils::IsContainerForFontSizeInflation(aFrame),
+  NS_ASSERTION(!aFrame->IsContainerForFontSizeInflation(),
                "should not be container for font size inflation");
 
   nsIFrame::InlinePrefWidthData data;
   DISPLAY_PREF_WIDTH(aFrame, data.prevLines);
   aFrame->AddInlinePrefWidth(aRenderingContext, &data);
   data.ForceBreak(aRenderingContext);
   return data.prevLines;
 }
@@ -5216,35 +5216,16 @@ nsUnsetAttrRunnable::nsUnsetAttrRunnable
 }
 
 NS_IMETHODIMP
 nsUnsetAttrRunnable::Run()
 {
   return mContent->UnsetAttr(kNameSpaceID_None, mAttrName, true);
 }
 
-nsReflowFrameRunnable::nsReflowFrameRunnable(nsIFrame* aFrame,
-                          nsIPresShell::IntrinsicDirty aIntrinsicDirty,
-                          nsFrameState aBitToAdd)
-  : mWeakFrame(aFrame),
-    mIntrinsicDirty(aIntrinsicDirty),
-    mBitToAdd(aBitToAdd)
-{
-}
-
-NS_IMETHODIMP
-nsReflowFrameRunnable::Run()
-{
-  if (mWeakFrame.IsAlive()) {
-    mWeakFrame->PresContext()->PresShell()->
-      FrameNeedsReflow(mWeakFrame, mIntrinsicDirty, mBitToAdd);
-  }
-  return NS_OK;
-}
-
 /**
  * Compute the minimum font size inside of a container with the given
  * width, such that **when the user zooms the container to fill the full
  * width of the device**, the fonts satisfy our minima.
  */
 static nscoord
 MinimumFontSizeFor(nsPresContext* aPresContext, nscoord aContainerWidth)
 {
@@ -5293,17 +5274,17 @@ nsLayoutUtils::FontSizeInflationInner(co
     // No need to scale.
     return 1.0;
   }
 
   // If between this current frame and its font inflation container there is a
   // non-inline element with fixed width or height, then we should not inflate
   // fonts for this frame.
   for (const nsIFrame* f = aFrame;
-       f && !IsContainerForFontSizeInflation(f);
+       f && !f->IsContainerForFontSizeInflation();
        f = f->GetParent()) {
     nsIContent* content = f->GetContent();
     nsIAtom* fType = f->GetType();
     // Also, if there is more than one frame corresponding to a single
     // content node, we want the outermost one.
     if (!(f->GetParent() && f->GetParent()->GetContent() == content) &&
         // ignore width/height on inlines since they don't apply
         fType != nsGkAtoms::inlineFrame &&
@@ -5386,17 +5367,17 @@ nsLayoutUtils::InflationMinFontSizeFor(c
 {
   nsPresContext *presContext = aFrame->PresContext();
   if (!FontSizeInflationEnabled(presContext) ||
       presContext->mInflationDisabledForShrinkWrap) {
     return 0;
   }
 
   for (const nsIFrame *f = aFrame; f; f = f->GetParent()) {
-    if (IsContainerForFontSizeInflation(f)) {
+    if (f->IsContainerForFontSizeInflation()) {
       if (!ShouldInflateFontsForContainer(f)) {
         return 0;
       }
 
       nsFontInflationData *data =
         nsFontInflationData::FindFontInflationDataFor(aFrame);
       // FIXME: The need to null-check here is sort of a bug, and might
       // lead to incorrect results.
@@ -5539,8 +5520,51 @@ nsLayoutUtils::UpdateImageVisibilityForF
   }
 
   if (visible) {
     presShell->EnsureImageInVisibleList(content);
   } else {
     presShell->RemoveImageFromVisibleList(content);
   }
 }
+
+nsLayoutUtils::SurfaceFromElementResult::SurfaceFromElementResult()
+  // Use safe default values here
+  : mIsWriteOnly(true), mIsStillLoading(false), mCORSUsed(false)
+{
+}
+
+bool
+nsLayoutUtils::IsNonWrapperBlock(nsIFrame* aFrame)
+{
+  return GetAsBlock(aFrame) && !aFrame->IsBlockWrapper();
+}
+
+bool
+nsLayoutUtils::NeedsPrintPreviewBackground(nsPresContext* aPresContext)
+{
+  return aPresContext->IsRootPaginatedDocument() &&
+    (aPresContext->Type() == nsPresContext::eContext_PrintPreview ||
+     aPresContext->Type() == nsPresContext::eContext_PageLayout);
+}
+
+AutoMaybeDisableFontInflation::AutoMaybeDisableFontInflation(nsIFrame *aFrame)
+{
+  // FIXME: Now that inflation calculations are based on the flow
+  // root's NCA's (nearest common ancestor of its inflatable
+  // descendants) width, we could probably disable inflation in
+  // fewer cases than we currently do.
+  if (aFrame->IsContainerForFontSizeInflation()) {
+    mPresContext = aFrame->PresContext();
+    mOldValue = mPresContext->mInflationDisabledForShrinkWrap;
+    mPresContext->mInflationDisabledForShrinkWrap = true;
+  } else {
+    // indicate we have nothing to restore
+    mPresContext = nullptr;
+  }
+}
+
+AutoMaybeDisableFontInflation::~AutoMaybeDisableFontInflation()
+{
+  if (mPresContext) {
+    mPresContext->mInflationDisabledForShrinkWrap = mOldValue;
+  }
+}
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -19,35 +19,50 @@ class nsFontMetrics;
 class nsClientRectList;
 class nsFontFaceList;
 class nsIImageLoadingContent;
 class nsStyleContext;
 class nsBlockFrame;
 class gfxDrawable;
 class nsView;
 class imgIContainer;
+class nsIFrame;
+class nsStyleCoord;
+class nsStyleCorners;
+class gfxContext;
+class nsPIDOMWindow;
+class imgIRequest;
+class nsIDocument;
+struct nsStyleFont;
+struct nsStyleImageOrientation;
+struct nsOverflowAreas;
 
 #include "mozilla/MemoryReporting.h"
 #include "nsChangeHint.h"
 #include "nsAutoPtr.h"
-#include "nsIFrame.h"
+#include "nsFrameList.h"
 #include "nsThreadUtils.h"
-#include "nsIPresShell.h"
 #include "nsIPrincipal.h"
 #include "gfxPattern.h"
 #include "nsCSSPseudoElements.h"
 #include "FrameMetrics.h"
 #include "gfx3DMatrix.h"
 #include "nsIWidget.h"
+#include "nsCSSProperty.h"
+#include "nsStyleCoord.h"
+#include "nsStyleConsts.h"
+#include "nsGkAtoms.h"
+#include "nsRuleNode.h"
 
 #include <limits>
 #include <algorithm>
 
 namespace mozilla {
 class SVGImageContext;
+struct IntrinsicSize;
 namespace dom {
 class Element;
 class HTMLImageElement;
 class HTMLCanvasElement;
 class HTMLVideoElement;
 } // namespace dom
 } // namespace mozilla
 
@@ -96,17 +111,17 @@ public:
    * Get the critical display port for the given element.
    */
   static bool GetCriticalDisplayPort(nsIContent* aContent, nsRect* aResult);
 
   /**
    * Use heuristics to figure out the child list that
    * aChildFrame is currently in.
    */
-  static nsIFrame::ChildListID GetChildListNameFor(nsIFrame* aChildFrame);
+  static mozilla::layout::FrameChildListID GetChildListNameFor(nsIFrame* aChildFrame);
 
   /**
    * GetBeforeFrame returns the outermost :before frame of the given frame, if
    * one exists.  This is typically O(1).  The frame passed in must be
    * the first-in-flow.
    *
    * @param aFrame the frame whose :before is wanted
    * @return the :before frame or nullptr if there isn't one
@@ -254,33 +269,16 @@ public:
    */
   static int32_t DoCompareTreePosition(nsIFrame* aFrame1,
                                        nsIFrame* aFrame2,
                                        int32_t aIf1Ancestor,
                                        int32_t aIf2Ancestor,
                                        nsIFrame* aCommonAncestor = nullptr);
 
   /**
-   * Sorts the given nsFrameList, so that for every two adjacent frames in the
-   * list, the former is less than or equal to the latter, according to the
-   * templated IsLessThanOrEqual method.
-   *
-   * Note: this method uses a stable merge-sort algorithm.
-   */
-  template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
-  static void SortFrameList(nsFrameList& aFrameList);
-
-  /**
-   * Returns true if the given frame list is already sorted, according to the
-   * templated IsLessThanOrEqual function.
-   */
-  template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
-  static bool IsFrameListSorted(nsFrameList& aFrameList);
-
-  /**
    * LastContinuationWithChild gets the last continuation in aFrame's chain
    * that has a child, or the first continuation if the frame has no children.
    */
   static nsIFrame* LastContinuationWithChild(nsIFrame* aFrame);
 
   /**
    * GetLastSibling simply finds the last sibling of aFrame, or returns nullptr if
    * aFrame is null.
@@ -910,19 +908,17 @@ public:
    * Cast aFrame to an nsBlockFrame* or return null if it's not
    * an nsBlockFrame.
    */
   static nsBlockFrame* GetAsBlock(nsIFrame* aFrame);
 
   /*
    * Whether the frame is an nsBlockFrame which is not a wrapper block.
    */
-  static bool IsNonWrapperBlock(nsIFrame* aFrame) {
-    return GetAsBlock(aFrame) && !aFrame->IsBlockWrapper();
-  }
+  static bool IsNonWrapperBlock(nsIFrame* aFrame);
 
   /**
    * If aFrame is an out of flow frame, return its placeholder, otherwise
    * return its parent.
    */
   static nsIFrame* GetParentOrPlaceholderFor(nsIFrame* aFrame);
 
   /**
@@ -1015,32 +1011,32 @@ public:
 
   /*
    * Likewise, but for 'height', 'min-height', or 'max-height'.
    */
   static nscoord ComputeHeightValue(nscoord aContainingBlockHeight,
                                     nscoord aContentEdgeToBoxSizingBoxEdge,
                                     const nsStyleCoord& aCoord)
   {
-    MOZ_ASSERT(aContainingBlockHeight != NS_AUTOHEIGHT || !aCoord.HasPercent(),
+    MOZ_ASSERT(aContainingBlockHeight != nscoord_MAX || !aCoord.HasPercent(),
                "caller must deal with %% of unconstrained height");
     MOZ_ASSERT(aCoord.IsCoordPercentCalcUnit());
 
     nscoord result =
       nsRuleNode::ComputeCoordPercentCalc(aCoord, aContainingBlockHeight);
     // Clamp calc(), and the subtraction for box-sizing.
     return std::max(0, result - aContentEdgeToBoxSizingBoxEdge);
   }
 
   static bool IsAutoHeight(const nsStyleCoord &aCoord, nscoord aCBHeight)
   {
     nsStyleUnit unit = aCoord.GetUnit();
     return unit == eStyleUnit_Auto ||  // only for 'height'
            unit == eStyleUnit_None ||  // only for 'max-height'
-           (aCBHeight == NS_AUTOHEIGHT && aCoord.HasPercent());
+           (aCBHeight == nscoord_MAX && aCoord.HasPercent());
   }
 
   static bool IsPaddingZero(const nsStyleCoord &aCoord)
   {
     return (aCoord.GetUnit() == eStyleUnit_Coord &&
             aCoord.GetCoordValue() == 0) ||
            (aCoord.GetUnit() == eStyleUnit_Percent &&
             aCoord.GetPercentValue() == 0.0f) ||
@@ -1063,17 +1059,17 @@ public:
 
   /*
    * Calculate the used values for 'width' and 'height' for a replaced element.
    *
    *   http://www.w3.org/TR/CSS21/visudet.html#min-max-widths
    */
   static nsSize ComputeSizeWithIntrinsicDimensions(
                     nsRenderingContext* aRenderingContext, nsIFrame* aFrame,
-                    const nsIFrame::IntrinsicSize& aIntrinsicSize,
+                    const mozilla::IntrinsicSize& aIntrinsicSize,
                     nsSize aIntrinsicRatio, nsSize aCBSize,
                     nsSize aMargin, nsSize aBorder, nsSize aPadding);
 
   /*
    * Calculate the used values for 'width' and 'height' when width
    * and height are 'auto'. The tentWidth and tentHeight arguments should be
    * the result of applying the rules for computing intrinsic sizes and ratios.
    * as specified by CSS 2.1 sections 10.3.2 and 10.6.2
@@ -1464,36 +1460,16 @@ public:
    * Some frames with 'position: fixed' (nsStylePosition::mDisplay ==
    * NS_STYLE_POSITION_FIXED) are not really fixed positioned, since
    * they're inside an element with -moz-transform.  This function says
    * whether such an element is a real fixed-pos element.
    */
   static bool IsReallyFixedPos(nsIFrame* aFrame);
 
   /**
-   * Return true if aFrame is in an {ib} split and is NOT one of the
-   * continuations of the first inline in it.
-   */
-  static bool FrameIsNonFirstInIBSplit(const nsIFrame* aFrame) {
-    return (aFrame->GetStateBits() & NS_FRAME_IS_SPECIAL) &&
-      aFrame->FirstContinuation()->
-        Properties().Get(nsIFrame::IBSplitSpecialPrevSibling());
-  }
-
-  /**
-   * Return true if aFrame is in an {ib} split and is NOT one of the
-   * continuations of the last inline in it.
-   */
-  static bool FrameIsNonLastInIBSplit(const nsIFrame* aFrame) {
-    return (aFrame->GetStateBits() & NS_FRAME_IS_SPECIAL) &&
-      aFrame->FirstContinuation()->
-        Properties().Get(nsIFrame::IBSplitSpecialSibling());
-  }
-
-  /**
    * Obtain a gfxASurface from the given DOM element, if possible.
    * This obtains the most natural surface from the element; that
    * is, the one that can be obtained with the fewest conversions.
    *
    * The flags below can modify the behaviour of this function.  The
    * result is returned as a SurfaceFromElementResult struct, also
    * defined below.
    *
@@ -1518,19 +1494,17 @@ public:
     SFE_NO_COLORSPACE_CONVERSION = 1 << 3,
     /* Whether we should skip premultiplication -- the resulting
        image will always be an image surface, and must not be given to
        Thebes for compositing! */
     SFE_NO_PREMULTIPLY_ALPHA = 1 << 4
   };
 
   struct SurfaceFromElementResult {
-    SurfaceFromElementResult() :
-      // Use safe default values here
-      mIsWriteOnly(true), mIsStillLoading(false), mCORSUsed(false) {}
+    SurfaceFromElementResult();
 
     /* mSurface will contain the resulting surface, or will be NULL on error */
     nsRefPtr<gfxASurface> mSurface;
     /* The size of the surface */
     gfxIntSize mSize;
     /* The principal associated with the element whose surface was returned.
        If there is a surface, this will never be null. */
     nsCOMPtr<nsIPrincipal> mPrincipal;
@@ -1581,21 +1555,17 @@ public:
    */
   static nsIContent*
     GetEditableRootContentByContentEditable(nsIDocument* aDocument);
 
   /**
    * Returns true if the passed in prescontext needs the dark grey background
    * that goes behind the page of a print preview presentation.
    */
-  static bool NeedsPrintPreviewBackground(nsPresContext* aPresContext) {
-    return aPresContext->IsRootPaginatedDocument() &&
-      (aPresContext->Type() == nsPresContext::eContext_PrintPreview ||
-       aPresContext->Type() == nsPresContext::eContext_PageLayout);
-  }
+  static bool NeedsPrintPreviewBackground(nsPresContext* aPresContext);
 
   /**
    * Adds all font faces used in the frame tree starting from aFrame
    * to the list aFontFaceList.
    */
   static nsresult GetFontFacesForFrames(nsIFrame* aFrame,
                                         nsFontFaceList* aFontFaceList);
 
@@ -1675,25 +1645,16 @@ public:
   /**
    * Unions the overflow areas of all non-popup children of aFrame with
    * aOverflowAreas.
    */
   static void UnionChildOverflow(nsIFrame* aFrame,
                                  nsOverflowAreas& aOverflowAreas);
 
   /**
-   * Return whether this is a frame whose width is used when computing
-   * the font size inflation of its descendants.
-   */
-  static bool IsContainerForFontSizeInflation(const nsIFrame *aFrame)
-  {
-    return aFrame->GetStateBits() & NS_FRAME_FONT_INFLATION_CONTAINER;
-  }
-
-  /**
    * Return the font size inflation *ratio* for a given frame.  This is
    * the factor by which font sizes should be inflated; it is never
    * smaller than 1.
    */
   static float FontSizeInflationFor(const nsIFrame *aFrame);
 
   /**
    * Perform the first half of the computation of FontSizeInflationFor
@@ -1895,165 +1856,26 @@ public:
    * Determine if aImageFrame (which is an nsImageFrame, nsImageControlFrame, or
    * nsSVGImageFrame) is visible or close to being visible via scrolling and
    * update the presshell with this knowledge.
    */
   static void
   UpdateImageVisibilityForFrame(nsIFrame* aImageFrame);
 
 private:
-  // Helper-functions for SortFrameList():
-  template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
-  static nsIFrame* SortedMerge(nsIFrame *aLeft, nsIFrame *aRight);
-
-  template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
-  static nsIFrame* MergeSort(nsIFrame *aSource);
-
   static uint32_t sFontSizeInflationEmPerLine;
   static uint32_t sFontSizeInflationMinTwips;
   static uint32_t sFontSizeInflationLineThreshold;
   static int32_t  sFontSizeInflationMappingIntercept;
   static uint32_t sFontSizeInflationMaxRatio;
   static bool sFontSizeInflationForceEnabled;
   static bool sFontSizeInflationDisabledInMasterProcess;
   static bool sInvalidationDebuggingIsEnabled;
 };
 
-// Helper-functions for nsLayoutUtils::SortFrameList()
-// ---------------------------------------------------
-
-template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
-/* static */ nsIFrame*
-nsLayoutUtils::SortedMerge(nsIFrame *aLeft, nsIFrame *aRight)
-{
-  NS_PRECONDITION(aLeft && aRight, "SortedMerge must have non-empty lists");
-
-  nsIFrame *result;
-  // Unroll first iteration to avoid null-check 'result' inside the loop.
-  if (IsLessThanOrEqual(aLeft, aRight)) {
-    result = aLeft;
-    aLeft = aLeft->GetNextSibling();
-    if (!aLeft) {
-      result->SetNextSibling(aRight);
-      return result;
-    }
-  }
-  else {
-    result = aRight;
-    aRight = aRight->GetNextSibling();
-    if (!aRight) {
-      result->SetNextSibling(aLeft);
-      return result;
-    }
-  }
-
-  nsIFrame *last = result;
-  for (;;) {
-    if (IsLessThanOrEqual(aLeft, aRight)) {
-      last->SetNextSibling(aLeft);
-      last = aLeft;
-      aLeft = aLeft->GetNextSibling();
-      if (!aLeft) {
-        last->SetNextSibling(aRight);
-        return result;
-      }
-    }
-    else {
-      last->SetNextSibling(aRight);
-      last = aRight;
-      aRight = aRight->GetNextSibling();
-      if (!aRight) {
-        last->SetNextSibling(aLeft);
-        return result;
-      }
-    }
-  }
-}
-
-template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
-/* static */ nsIFrame*
-nsLayoutUtils::MergeSort(nsIFrame *aSource)
-{
-  NS_PRECONDITION(aSource, "MergeSort null arg");
-
-  nsIFrame *sorted[32] = { nullptr };
-  nsIFrame **fill = &sorted[0];
-  nsIFrame **left;
-  nsIFrame *rest = aSource;
-
-  do {
-    nsIFrame *current = rest;
-    rest = rest->GetNextSibling();
-    current->SetNextSibling(nullptr);
-
-    // Merge it with sorted[0] if present; then merge the result with sorted[1] etc.
-    // sorted[0] is a list of length 1 (or nullptr).
-    // sorted[1] is a list of length 2 (or nullptr).
-    // sorted[2] is a list of length 4 (or nullptr). etc.
-    for (left = &sorted[0]; left != fill && *left; ++left) {
-      current = SortedMerge<IsLessThanOrEqual>(*left, current);
-      *left = nullptr;
-    }
-
-    // Fill the empty slot that we couldn't merge with the last result.
-    *left = current;
-
-    if (left == fill)
-      ++fill;
-  } while (rest);
-
-  // Collect and merge the results.
-  nsIFrame *result = nullptr;
-  for (left = &sorted[0]; left != fill; ++left) {
-    if (*left) {
-      result = result ? SortedMerge<IsLessThanOrEqual>(*left, result) : *left;
-    }
-  }
-  return result;
-}
-
-template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
-/* static */ void
-nsLayoutUtils::SortFrameList(nsFrameList& aFrameList)
-{
-  nsIFrame* head = MergeSort<IsLessThanOrEqual>(aFrameList.FirstChild());
-  aFrameList = nsFrameList(head, GetLastSibling(head));
-  MOZ_ASSERT(IsFrameListSorted<IsLessThanOrEqual>(aFrameList),
-             "After we sort a frame list, it should be in sorted order...");
-}
-
-template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
-/* static */ bool
-nsLayoutUtils::IsFrameListSorted(nsFrameList& aFrameList)
-{
-  if (aFrameList.IsEmpty()) {
-    // empty lists are trivially sorted.
-    return true;
-  }
-
-  // We'll walk through the list with two iterators, one trailing behind the
-  // other. The list is sorted IFF trailingIter <= iter, across the whole list.
-  nsFrameList::Enumerator trailingIter(aFrameList);
-  nsFrameList::Enumerator iter(aFrameList);
-  iter.Next(); // Skip |iter| past first frame. (List is nonempty, so we can.)
-
-  // Now, advance the iterators in parallel, comparing each adjacent pair.
-  while (!iter.AtEnd()) {
-    MOZ_ASSERT(!trailingIter.AtEnd(), "trailing iter shouldn't finish first");
-    if (!IsLessThanOrEqual(trailingIter.get(), iter.get())) {
-      return false;
-    }
-    trailingIter.Next();
-    iter.Next();
-  }
-
-  // We made it to the end without returning early, so the list is sorted.
-  return true;
-}
-
 template<typename PointType, typename RectType, typename CoordType>
 /* static */ bool
 nsLayoutUtils::PointIsCloserToRect(PointType aPoint, const RectType& aRect,
                                    CoordType& aClosestXDistance,
                                    CoordType& aClosestYDistance)
 {
   CoordType fromLeft = aPoint.x - aRect.x;
   CoordType fromRight = aPoint.x - aRect.XMost();
@@ -2096,38 +1918,19 @@ namespace mozilla {
     /**
      * An RAII class which will, for the duration of its lifetime,
      * **if** the frame given is a container for font size inflation,
      * set the current inflation container on the pres context to null
      * (and then, in its destructor, restore the old value).
      */
     class AutoMaybeDisableFontInflation {
     public:
-      AutoMaybeDisableFontInflation(nsIFrame *aFrame)
-      {
-        // FIXME: Now that inflation calculations are based on the flow
-        // root's NCA's (nearest common ancestor of its inflatable
-        // descendants) width, we could probably disable inflation in
-        // fewer cases than we currently do.
-        if (nsLayoutUtils::IsContainerForFontSizeInflation(aFrame)) {
-          mPresContext = aFrame->PresContext();
-          mOldValue = mPresContext->mInflationDisabledForShrinkWrap;
-          mPresContext->mInflationDisabledForShrinkWrap = true;
-        } else {
-          // indicate we have nothing to restore
-          mPresContext = nullptr;
-        }
-      }
+      AutoMaybeDisableFontInflation(nsIFrame *aFrame);
 
-      ~AutoMaybeDisableFontInflation()
-      {
-        if (mPresContext) {
-          mPresContext->mInflationDisabledForShrinkWrap = mOldValue;
-        }
-      }
+      ~AutoMaybeDisableFontInflation();
     private:
       nsPresContext *mPresContext;
       bool mOldValue;
     };
 
   }
 }
 
@@ -2152,23 +1955,9 @@ public:
   nsUnsetAttrRunnable(nsIContent* aContent, nsIAtom* aAttrName);
 
   NS_DECL_NSIRUNNABLE
 
   nsCOMPtr<nsIContent> mContent;
   nsCOMPtr<nsIAtom> mAttrName;
 };
 
-class nsReflowFrameRunnable : public nsRunnable
-{
-public:
-  nsReflowFrameRunnable(nsIFrame* aFrame,
-                        nsIPresShell::IntrinsicDirty aIntrinsicDirty,
-                        nsFrameState aBitToAdd);
-
-  NS_DECL_NSIRUNNABLE
-
-  nsWeakFrame mWeakFrame;
-  nsIPresShell::IntrinsicDirty mIntrinsicDirty;
-  nsFrameState mBitToAdd;
-};
-
 #endif // nsLayoutUtils_h__
--- a/layout/generic/nsFlexContainerFrame.cpp
+++ b/layout/generic/nsFlexContainerFrame.cpp
@@ -1111,21 +1111,21 @@ NS_NewFlexContainerFrame(nsIPresShell* a
 nsFlexContainerFrame::~nsFlexContainerFrame()
 {
 }
 
 template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
 /* static */ bool
 nsFlexContainerFrame::SortChildrenIfNeeded()
 {
-  if (nsLayoutUtils::IsFrameListSorted<IsLessThanOrEqual>(mFrames)) {
+  if (nsIFrame::IsFrameListSorted<IsLessThanOrEqual>(mFrames)) {
     return false;
   }
 
-  nsLayoutUtils::SortFrameList<IsLessThanOrEqual>(mFrames);
+  nsIFrame::SortFrameList<IsLessThanOrEqual>(mFrames);
   return true;
 }
 
 /* virtual */
 nsIAtom*
 nsFlexContainerFrame::GetType() const
 {
   return nsGkAtoms::flexContainerFrame;
@@ -1158,17 +1158,17 @@ GetDisplayFlagsForFlexItem(nsIFrame* aFr
 }
 
 void
 nsFlexContainerFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                        const nsRect&           aDirtyRect,
                                        const nsDisplayListSet& aLists)
 {
   NS_ASSERTION(
-    nsLayoutUtils::IsFrameListSorted<IsOrderLEQWithDOMFallback>(mFrames),
+    nsIFrame::IsFrameListSorted<IsOrderLEQWithDOMFallback>(mFrames),
     "Child frames aren't sorted correctly");
 
   DisplayBorderBackgroundOutline(aBuilder, aLists);
 
   // Our children are all block-level, so their borders/backgrounds all go on
   // the BlockBorderBackgrounds list.
   nsDisplayListSet childLists(aLists, aLists.BlockBorderBackgrounds());
   for (nsFrameList::Enumerator e(mFrames); !e.AtEnd(); e.Next()) {
--- a/layout/generic/nsFontInflationData.cpp
+++ b/layout/generic/nsFontInflationData.cpp
@@ -197,17 +197,17 @@ nsFontInflationData::UpdateWidth(const n
                     "null-ness should match; NearestCommonAncestorFirstInFlow"
                     " will crash when passed null");
 
   // Particularly when we're computing for the root BFC, the width of
   // nca might differ significantly for the width of bfc.
   nsIFrame *nca = NearestCommonAncestorFirstInFlow(firstInflatableDescendant,
                                                    lastInflatableDescendant,
                                                    bfc);
-  while (!nsLayoutUtils::IsContainerForFontSizeInflation(nca)) {
+  while (!nca->IsContainerForFontSizeInflation()) {
     nca = nca->GetParent()->FirstInFlow();
   }
 
   nscoord newNCAWidth = ComputeDescendantWidth(aReflowState, nca);
 
   // See comment above "font.size.inflation.lineThreshold" in
   // modules/libpref/src/init/all.js .
   nsIPresShell* presShell = bfc->PresContext()->PresShell();
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -3873,17 +3873,17 @@ nsFrame::IntrinsicWidthOffsets(nsRenderi
       result.hPadding = presContext->DevPixelsToAppUnits(padding.LeftRight());
       result.hPctPadding = 0;
     }
   }
 
   return result;
 }
 
-/* virtual */ nsIFrame::IntrinsicSize
+/* virtual */ IntrinsicSize
 nsFrame::GetIntrinsicSize()
 {
   return IntrinsicSize(); // default is width/height set to eStyleUnit_None
 }
 
 /* virtual */ nsSize
 nsFrame::GetIntrinsicRatio()
 {
--- a/layout/generic/nsFrame.h
+++ b/layout/generic/nsFrame.h
@@ -252,17 +252,17 @@ public:
   virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
   virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
   virtual void AddInlineMinWidth(nsRenderingContext *aRenderingContext,
                                  InlineMinWidthData *aData) MOZ_OVERRIDE;
   virtual void AddInlinePrefWidth(nsRenderingContext *aRenderingContext,
                                   InlinePrefWidthData *aData) MOZ_OVERRIDE;
   virtual IntrinsicWidthOffsetData
     IntrinsicWidthOffsets(nsRenderingContext* aRenderingContext) MOZ_OVERRIDE;
-  virtual IntrinsicSize GetIntrinsicSize() MOZ_OVERRIDE;
+  virtual mozilla::IntrinsicSize GetIntrinsicSize() MOZ_OVERRIDE;
   virtual nsSize GetIntrinsicRatio() MOZ_OVERRIDE;
 
   virtual nsSize ComputeSize(nsRenderingContext *aRenderingContext,
                              nsSize aCBSize, nscoord aAvailableWidth,
                              nsSize aMargin, nsSize aBorder, nsSize aPadding,
                              uint32_t aFlags) MOZ_OVERRIDE;
 
   // Compute tight bounds assuming this frame honours its border, background
--- a/layout/generic/nsFrameList.h
+++ b/layout/generic/nsFrameList.h
@@ -426,20 +426,17 @@ public:
     inline FrameLinkEnumerator(const nsFrameList& aList, nsIFrame* aPrevFrame);
 
     void operator=(const FrameLinkEnumerator& aOther) {
       NS_PRECONDITION(&List() == &aOther.List(), "Different lists?");
       mFrame = aOther.mFrame;
       mPrev = aOther.mPrev;
     }
 
-    void Next() {
-      mPrev = mFrame;
-      Enumerator::Next();
-    }
+    inline void Next();
 
     bool AtEnd() const { return Enumerator::AtEnd(); }
 
     nsIFrame* PrevFrame() const { return mPrev; }
     nsIFrame* NextFrame() const { return mFrame; }
 
   protected:
     nsIFrame* mPrev;
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -28,16 +28,17 @@
 #include "nsFrameList.h"
 #include "mozilla/layout/FrameChildList.h"
 #include "FramePropertyTable.h"
 #include "mozilla/TypedEnum.h"
 #include "nsDirection.h"
 #include <algorithm>
 #include "nsITheme.h"
 #include "gfx3DMatrix.h"
+#include "nsLayoutUtils.h"
 
 #ifdef ACCESSIBILITY
 #include "mozilla/a11y/AccTypes.h"
 #endif
 
 /**
  * New rules of reflow:
  * 1. you get a WillReflow() followed by a Reflow() followed by a DidReflow() in order
@@ -538,16 +539,45 @@ MOZ_END_ENUM_CLASS(nsDidReflowStatus)
 
 #define NS_FRAME_OVERFLOW_NONE    0x00000000 // there are no overflow rects;
                                              // code relies on this being
                                              // the all-zero value
 
 #define NS_FRAME_OVERFLOW_LARGE   0x000000ff // overflow is stored as a
                                              // separate rect property
 
+namespace mozilla {
+/*
+ * For replaced elements only. Gets the intrinsic dimensions of this element.
+ * The dimensions may only be one of the following two types:
+ *
+ *   eStyleUnit_Coord   - a length in app units
+ *   eStyleUnit_None    - the element has no intrinsic size in this dimension
+ */
+struct IntrinsicSize {
+  nsStyleCoord width, height;
+
+  IntrinsicSize()
+    : width(eStyleUnit_None), height(eStyleUnit_None)
+  {}
+  IntrinsicSize(const IntrinsicSize& rhs)
+    : width(rhs.width), height(rhs.height)
+  {}
+  IntrinsicSize& operator=(const IntrinsicSize& rhs) {
+    width = rhs.width; height = rhs.height; return *this;
+  }
+  bool operator==(const IntrinsicSize& rhs) {
+    return width == rhs.width && height == rhs.height;
+  }
+  bool operator!=(const IntrinsicSize& rhs) {
+    return !(*this == rhs);
+  }
+};
+}
+
 //----------------------------------------------------------------------
 
 /**
  * A frame in the layout model. This interface is supported by all frame
  * objects.
  *
  * Frames can have multiple child lists: the default child list
  * (referred to as the <i>principal</i> child list, and additional named
@@ -1704,43 +1734,17 @@ public:
     IntrinsicWidthOffsetData()
       : hPadding(0), hBorder(0), hMargin(0)
       , hPctPadding(0.0f), hPctMargin(0.0f)
     {}
   };
   virtual IntrinsicWidthOffsetData
     IntrinsicWidthOffsets(nsRenderingContext* aRenderingContext) = 0;
 
-  /*
-   * For replaced elements only. Gets the intrinsic dimensions of this element.
-   * The dimensions may only be one of the following two types:
-   *
-   *   eStyleUnit_Coord   - a length in app units
-   *   eStyleUnit_None    - the element has no intrinsic size in this dimension
-   */
-  struct IntrinsicSize {
-    nsStyleCoord width, height;
-
-    IntrinsicSize()
-      : width(eStyleUnit_None), height(eStyleUnit_None)
-    {}
-    IntrinsicSize(const IntrinsicSize& rhs)
-      : width(rhs.width), height(rhs.height)
-    {}
-    IntrinsicSize& operator=(const IntrinsicSize& rhs) {
-      width = rhs.width; height = rhs.height; return *this;
-    }
-    bool operator==(const IntrinsicSize& rhs) {
-      return width == rhs.width && height == rhs.height;
-    }
-    bool operator!=(const IntrinsicSize& rhs) {
-      return !(*this == rhs);
-    }
-  };
-  virtual IntrinsicSize GetIntrinsicSize() = 0;
+  virtual mozilla::IntrinsicSize GetIntrinsicSize() = 0;
 
   /*
    * Get the intrinsic ratio of this element, or nsSize(0,0) if it has
    * no intrinsic ratio.  The intrinsic ratio is the ratio of the
    * height/width of a box with an intrinsic size or the intrinsic
    * aspect ratio of a scalable vector image without an intrinsic size.
    *
    * Either one of the sides may be zero, indicating a zero or infinite
@@ -2958,16 +2962,59 @@ NS_PTR_TO_INT32(frame->Properties().Get(
   static void AddInPopupStateBitToDescendants(nsIFrame* aFrame);
   /**
    * Removes the NS_FRAME_IN_POPUP state bit from aFrame and
    * all descendant frames (including cross-doc ones), unless
    * the frame is a popup itself.
    */
   static void RemoveInPopupStateBitFromDescendants(nsIFrame* aFrame);
 
+  /**
+   * Sorts the given nsFrameList, so that for every two adjacent frames in the
+   * list, the former is less than or equal to the latter, according to the
+   * templated IsLessThanOrEqual method.
+   *
+   * Note: this method uses a stable merge-sort algorithm.
+   */
+  template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
+  static void SortFrameList(nsFrameList& aFrameList);
+
+  /**
+   * Returns true if the given frame list is already sorted, according to the
+   * templated IsLessThanOrEqual function.
+   */
+  template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
+  static bool IsFrameListSorted(nsFrameList& aFrameList);
+
+  /**
+   * Return true if aFrame is in an {ib} split and is NOT one of the
+   * continuations of the first inline in it.
+   */
+  bool FrameIsNonFirstInIBSplit() const {
+    return (GetStateBits() & NS_FRAME_IS_SPECIAL) &&
+      FirstContinuation()->Properties().Get(nsIFrame::IBSplitSpecialPrevSibling());
+  }
+
+  /**
+   * Return true if aFrame is in an {ib} split and is NOT one of the
+   * continuations of the last inline in it.
+   */
+  bool FrameIsNonLastInIBSplit() const {
+    return (GetStateBits() & NS_FRAME_IS_SPECIAL) &&
+      FirstContinuation()->Properties().Get(nsIFrame::IBSplitSpecialSibling());
+  }
+
+  /**
+   * Return whether this is a frame whose width is used when computing
+   * the font size inflation of its descendants.
+   */
+  bool IsContainerForFontSizeInflation() const {
+    return GetStateBits() & NS_FRAME_FONT_INFLATION_CONTAINER;
+  }
+
 protected:
   // Members
   nsRect           mRect;
   nsIContent*      mContent;
   nsStyleContext*  mStyleContext;
   nsIFrame*        mParent;
 private:
   nsIFrame*        mNextSibling;  // doubly-linked list of frames
@@ -3138,16 +3185,23 @@ private:
                                  mOverflow.mVisualDeltas.mTop);
   }
   /**
    * Returns true if any overflow changed.
    */
   bool SetOverflowAreas(const nsOverflowAreas& aOverflowAreas);
   nsPoint GetOffsetToCrossDoc(const nsIFrame* aOther, const int32_t aAPD) const;
 
+  // Helper-functions for SortFrameList():
+  template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
+  static nsIFrame* SortedMerge(nsIFrame *aLeft, nsIFrame *aRight);
+
+  template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
+  static nsIFrame* MergeSort(nsIFrame *aSource);
+
 #ifdef DEBUG
 public:
   static void IndentBy(FILE* out, int32_t aIndent) {
     while (--aIndent >= 0) fputs("  ", out);
   }
   void ListTag(FILE* out) const {
     ListTag(out, this);
   }
@@ -3302,16 +3356,155 @@ inline
 nsFrameList::FrameLinkEnumerator::
 FrameLinkEnumerator(const nsFrameList& aList, nsIFrame* aPrevFrame)
   : Enumerator(aList)
 {
   mPrev = aPrevFrame;
   mFrame = aPrevFrame ? aPrevFrame->GetNextSibling() : aList.FirstChild();
 }
 
+inline void
+nsFrameList::FrameLinkEnumerator::Next()
+{
+  mPrev = mFrame;
+  Enumerator::Next();
+}
+
+// Helper-functions for nsIFrame::SortFrameList()
+// ---------------------------------------------------
+
+template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
+/* static */ nsIFrame*
+nsIFrame::SortedMerge(nsIFrame *aLeft, nsIFrame *aRight)
+{
+  NS_PRECONDITION(aLeft && aRight, "SortedMerge must have non-empty lists");
+
+  nsIFrame *result;
+  // Unroll first iteration to avoid null-check 'result' inside the loop.
+  if (IsLessThanOrEqual(aLeft, aRight)) {
+    result = aLeft;
+    aLeft = aLeft->GetNextSibling();
+    if (!aLeft) {
+      result->SetNextSibling(aRight);
+      return result;
+    }
+  }
+  else {
+    result = aRight;
+    aRight = aRight->GetNextSibling();
+    if (!aRight) {
+      result->SetNextSibling(aLeft);
+      return result;
+    }
+  }
+
+  nsIFrame *last = result;
+  for (;;) {
+    if (IsLessThanOrEqual(aLeft, aRight)) {
+      last->SetNextSibling(aLeft);
+      last = aLeft;
+      aLeft = aLeft->GetNextSibling();
+      if (!aLeft) {
+        last->SetNextSibling(aRight);
+        return result;
+      }
+    }
+    else {
+      last->SetNextSibling(aRight);
+      last = aRight;
+      aRight = aRight->GetNextSibling();
+      if (!aRight) {
+        last->SetNextSibling(aLeft);
+        return result;
+      }
+    }
+  }
+}
+
+template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
+/* static */ nsIFrame*
+nsIFrame::MergeSort(nsIFrame *aSource)
+{
+  NS_PRECONDITION(aSource, "MergeSort null arg");
+
+  nsIFrame *sorted[32] = { nullptr };
+  nsIFrame **fill = &sorted[0];
+  nsIFrame **left;
+  nsIFrame *rest = aSource;
+
+  do {
+    nsIFrame *current = rest;
+    rest = rest->GetNextSibling();
+    current->SetNextSibling(nullptr);
+
+    // Merge it with sorted[0] if present; then merge the result with sorted[1] etc.
+    // sorted[0] is a list of length 1 (or nullptr).
+    // sorted[1] is a list of length 2 (or nullptr).
+    // sorted[2] is a list of length 4 (or nullptr). etc.
+    for (left = &sorted[0]; left != fill && *left; ++left) {
+      current = SortedMerge<IsLessThanOrEqual>(*left, current);
+      *left = nullptr;
+    }
+
+    // Fill the empty slot that we couldn't merge with the last result.
+    *left = current;
+
+    if (left == fill)
+      ++fill;
+  } while (rest);
+
+  // Collect and merge the results.
+  nsIFrame *result = nullptr;
+  for (left = &sorted[0]; left != fill; ++left) {
+    if (*left) {
+      result = result ? SortedMerge<IsLessThanOrEqual>(*left, result) : *left;
+    }
+  }
+  return result;
+}
+
+template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
+/* static */ void
+nsIFrame::SortFrameList(nsFrameList& aFrameList)
+{
+  nsIFrame* head = MergeSort<IsLessThanOrEqual>(aFrameList.FirstChild());
+  aFrameList = nsFrameList(head, nsLayoutUtils::GetLastSibling(head));
+  MOZ_ASSERT(IsFrameListSorted<IsLessThanOrEqual>(aFrameList),
+             "After we sort a frame list, it should be in sorted order...");
+}
+
+template<bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)>
+/* static */ bool
+nsIFrame::IsFrameListSorted(nsFrameList& aFrameList)
+{
+  if (aFrameList.IsEmpty()) {
+    // empty lists are trivially sorted.
+    return true;
+  }
+
+  // We'll walk through the list with two iterators, one trailing behind the
+  // other. The list is sorted IFF trailingIter <= iter, across the whole list.
+  nsFrameList::Enumerator trailingIter(aFrameList);
+  nsFrameList::Enumerator iter(aFrameList);
+  iter.Next(); // Skip |iter| past first frame. (List is nonempty, so we can.)
+
+  // Now, advance the iterators in parallel, comparing each adjacent pair.
+  while (!iter.AtEnd()) {
+    MOZ_ASSERT(!trailingIter.AtEnd(), "trailing iter shouldn't finish first");
+    if (!IsLessThanOrEqual(trailingIter.get(), iter.get())) {
+      return false;
+    }
+    trailingIter.Next();
+    iter.Next();
+  }
+
+  // We made it to the end without returning early, so the list is sorted.
+  return true;
+}
+
 #include "nsStyleStructInlines.h"
 
 bool
 nsIFrame::IsFloating() const
 {
   return StyleDisplay()->IsFloating(this);
 }
 
--- a/layout/generic/nsImageFrame.cpp
+++ b/layout/generic/nsImageFrame.cpp
@@ -260,18 +260,18 @@ nsImageFrame::Init(nsIContent*      aCon
 
 bool
 nsImageFrame::UpdateIntrinsicSize(imgIContainer* aImage)
 {
   NS_PRECONDITION(aImage, "null image");
   if (!aImage)
     return false;
 
-  nsIFrame::IntrinsicSize oldIntrinsicSize = mIntrinsicSize;
-  mIntrinsicSize = nsIFrame::IntrinsicSize();
+  IntrinsicSize oldIntrinsicSize = mIntrinsicSize;
+  mIntrinsicSize = IntrinsicSize();
 
   // Set intrinsic size to match aImage's reported intrinsic width & height.
   nsSize intrinsicSize;
   if (NS_SUCCEEDED(aImage->GetIntrinsicSize(&intrinsicSize))) {
     // If the image has no intrinsic width, intrinsicSize.width will be -1, and
     // we can leave mIntrinsicSize.width at its default value of eStyleUnit_None.
     // Otherwise we use intrinsicSize.width. Height works the same way.
     if (intrinsicSize.width != -1)
@@ -788,17 +788,17 @@ nsImageFrame::GetPrefWidth(nsRenderingCo
   DISPLAY_PREF_WIDTH(this, result);
   nsPresContext *presContext = PresContext();
   EnsureIntrinsicSizeAndRatio(presContext);
   // convert from normal twips to scaled twips (printing...)
   return mIntrinsicSize.width.GetUnit() == eStyleUnit_Coord ?
     mIntrinsicSize.width.GetCoordValue() : 0;
 }
 
-/* virtual */ nsIFrame::IntrinsicSize
+/* virtual */ IntrinsicSize
 nsImageFrame::GetIntrinsicSize()
 {
   return mIntrinsicSize;
 }
 
 /* virtual */ nsSize
 nsImageFrame::GetIntrinsicRatio()
 {
--- a/layout/generic/nsImageFrame.h
+++ b/layout/generic/nsImageFrame.h
@@ -76,17 +76,17 @@ public:
   virtual void Init(nsIContent*      aContent,
                     nsIFrame*        aParent,
                     nsIFrame*        aPrevInFlow) MOZ_OVERRIDE;
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
   virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext);
   virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext);
-  virtual IntrinsicSize GetIntrinsicSize();
+  virtual mozilla::IntrinsicSize GetIntrinsicSize();
   virtual nsSize GetIntrinsicRatio();
   NS_IMETHOD Reflow(nsPresContext*          aPresContext,
                     nsHTMLReflowMetrics&     aDesiredSize,
                     const nsHTMLReflowState& aReflowState,
                     nsReflowStatus&          aStatus);
   
   NS_IMETHOD  GetContentForEvent(nsEvent* aEvent,
                                  nsIContent** aContent);
@@ -281,17 +281,17 @@ private:
   nsRect SourceRectToDest(const nsIntRect & aRect);
 
   nsImageMap*         mImageMap;
 
   nsCOMPtr<imgINotificationObserver> mListener;
 
   nsCOMPtr<imgIContainer> mImage;
   nsSize mComputedSize;
-  nsIFrame::IntrinsicSize mIntrinsicSize;
+  mozilla::IntrinsicSize mIntrinsicSize;
   nsSize mIntrinsicRatio;
 
   bool mDisplayingIcon;
   bool mFirstFrameComplete;
   bool mReflowCallbackPosted;
 
   static nsIIOService* sIOService;
   
--- a/layout/generic/nsInlineFrame.cpp
+++ b/layout/generic/nsInlineFrame.cpp
@@ -127,18 +127,18 @@ nsInlineFrame::IsSelfEmpty()
       // For special frames, ignore things we know we'll skip in GetSkipSides.
       // XXXbz should we be doing this for non-special frames too, in a more
       // general way?
 
       // Get the first continuation eagerly, as a performance optimization, to
       // avoid having to get it twice..
       nsIFrame* firstCont = FirstContinuation();
       return
-        (!haveStart || nsLayoutUtils::FrameIsNonFirstInIBSplit(firstCont)) &&
-        (!haveEnd || nsLayoutUtils::FrameIsNonLastInIBSplit(firstCont));
+        (!haveStart || firstCont->FrameIsNonFirstInIBSplit()) &&
+        (!haveEnd || firstCont->FrameIsNonLastInIBSplit());
     }
     return false;
   }
   return true;
 }
 
 bool
 nsInlineFrame::IsEmpty()
@@ -458,18 +458,17 @@ nsInlineFrame::ReflowFrames(nsPresContex
 
   nsLineLayout* lineLayout = aReflowState.mLineLayout;
   bool inFirstLine = aReflowState.mLineLayout->GetInFirstLine();
   RestyleManager* restyleManager = aPresContext->RestyleManager();
   bool ltr = (NS_STYLE_DIRECTION_LTR == aReflowState.mStyleVisibility->mDirection);
   nscoord leftEdge = 0;
   // Don't offset by our start borderpadding if we have a prev continuation or
   // if we're in a part of an {ib} split other than the first one.
-  if (!GetPrevContinuation() &&
-      !nsLayoutUtils::FrameIsNonFirstInIBSplit(this)) {
+  if (!GetPrevContinuation() && !FrameIsNonFirstInIBSplit()) {
     leftEdge = ltr ? aReflowState.mComputedBorderPadding.left
                    : aReflowState.mComputedBorderPadding.right;
   }
   nscoord availableWidth = aReflowState.availableWidth;
   NS_ASSERTION(availableWidth != NS_UNCONSTRAINEDSIZE,
                "should no longer use available widths");
   // Subtract off left and right border+padding from availableWidth
   availableWidth -= leftEdge;
@@ -621,32 +620,31 @@ nsInlineFrame::ReflowFrames(nsPresContex
   // whitespace in an inline element don't affect the line-height.
   aMetrics.width = lineLayout->EndSpan(this);
 
   // Compute final width.
 
   // Make sure to not include our start border and padding if we have a prev
   // continuation or if we're in a part of an {ib} split other than the first
   // one.
-  if (!GetPrevContinuation() &&
-      !nsLayoutUtils::FrameIsNonFirstInIBSplit(this)) {
+  if (!GetPrevContinuation() && !FrameIsNonFirstInIBSplit()) {
     aMetrics.width += ltr ? aReflowState.mComputedBorderPadding.left
                           : aReflowState.mComputedBorderPadding.right;
   }
 
   /*
    * We want to only apply the end border and padding if we're the last
    * continuation and either not in an {ib} split or the last part of it.  To
    * be the last continuation we have to be complete (so that we won't get a
    * next-in-flow) and have no non-fluid continuations on our continuation
    * chain.
    */
   if (NS_FRAME_IS_COMPLETE(aStatus) &&
       !LastInFlow()->GetNextContinuation() &&
-      !nsLayoutUtils::FrameIsNonLastInIBSplit(this)) {
+      !FrameIsNonLastInIBSplit()) {
     aMetrics.width += ltr ? aReflowState.mComputedBorderPadding.right
                           : aReflowState.mComputedBorderPadding.left;
   }
 
   nsRefPtr<nsFontMetrics> fm;
   float inflation = nsLayoutUtils::FontSizeInflationFor(this);
   nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fm), inflation);
   aReflowState.rendContext->SetFont(fm);
@@ -882,20 +880,20 @@ nsInlineFrame::GetSkipSides(const nsHTML
     // expensive.  So don't bother if we already have the relevant bits set.
     bool ltr = (NS_STYLE_DIRECTION_LTR == StyleVisibility()->mDirection);
     int startBit = (1 << (ltr ? NS_SIDE_LEFT : NS_SIDE_RIGHT));
     int endBit = (1 << (ltr ? NS_SIDE_RIGHT : NS_SIDE_LEFT));
     if (((startBit | endBit) & skip) != (startBit | endBit)) {
       // We're missing one of the skip bits, so check whether we need to set it.
       // Only get the first continuation once, as an optimization.
       nsIFrame* firstContinuation = FirstContinuation();
-      if (nsLayoutUtils::FrameIsNonLastInIBSplit(firstContinuation)) {
+      if (firstContinuation->FrameIsNonLastInIBSplit()) {
         skip |= endBit;
       }
-      if (nsLayoutUtils::FrameIsNonFirstInIBSplit(firstContinuation)) {
+      if (firstContinuation->FrameIsNonFirstInIBSplit()) {
         skip |= startBit;
       }
     }
   }
 
   return skip;
 }
 
--- a/layout/generic/nsLineLayout.cpp
+++ b/layout/generic/nsLineLayout.cpp
@@ -680,17 +680,17 @@ IsPercentageAware(const nsIFrame* aFrame
     //   width and the containing block's width does not itself depend
     //   on the replaced element's width, then the used value of 'width'
     //   is calculated from the constraint equation used for
     //   block-level, non-replaced elements in normal flow. 
     nsIFrame *f = const_cast<nsIFrame*>(aFrame);
     if (f->GetIntrinsicRatio() != nsSize(0, 0) &&
         // Some percents are treated like 'auto', so check != coord
         pos->mHeight.GetUnit() != eStyleUnit_Coord) {
-      const nsIFrame::IntrinsicSize &intrinsicSize = f->GetIntrinsicSize();
+      const IntrinsicSize &intrinsicSize = f->GetIntrinsicSize();
       if (intrinsicSize.width.GetUnit() == eStyleUnit_None &&
           intrinsicSize.height.GetUnit() == eStyleUnit_None) {
         return true;
       }
     }
   }
 
   return false;
@@ -1061,17 +1061,17 @@ nsLineLayout::ApplyStartMargin(PerFrameD
   bool ltr = (NS_STYLE_DIRECTION_LTR == aReflowState.mStyleVisibility->mDirection);
 
   // Only apply start-margin on the first-in flow for inline frames,
   // and make sure to not apply it to any inline other than the first
   // in an ib split.  Note that the ib special sibling annotations
   // only live on the first continuation, but we don't want to apply
   // the start margin for later continuations anyway.
   if (pfd->mFrame->GetPrevContinuation() ||
-      nsLayoutUtils::FrameIsNonFirstInIBSplit(pfd->mFrame)) {
+      pfd->mFrame->FrameIsNonFirstInIBSplit()) {
     // Zero this out so that when we compute the max-element-width of
     // the frame we will properly avoid adding in the starting margin.
     if (ltr)
       pfd->mMargin.left = 0;
     else
       pfd->mMargin.right = 0;
   }
   else {
@@ -1141,17 +1141,17 @@ nsLineLayout::CanPlaceFrame(PerFrameData
      *    continuation will get destroyed later, so we don't want to drop the
      *    end-margin in that case.
      * 3) The frame is in an {ib} split and is not the last part.
      *
      * However, none of that applies if this is a letter frame (XXXbz why?)
      */
     if ((NS_FRAME_IS_NOT_COMPLETE(aStatus) ||
          pfd->mFrame->LastInFlow()->GetNextContinuation() ||
-         nsLayoutUtils::FrameIsNonLastInIBSplit(pfd->mFrame))
+         pfd->mFrame->FrameIsNonLastInIBSplit())
         && !pfd->GetFlag(PFD_ISLETTERFRAME)) {
       if (ltr)
         pfd->mMargin.right = 0;
       else
         pfd->mMargin.left = 0;
     }
   }
   else {
--- a/layout/generic/nsSubDocumentFrame.cpp
+++ b/layout/generic/nsSubDocumentFrame.cpp
@@ -541,17 +541,17 @@ nsSubDocumentFrame::GetPrefWidth(nsRende
     result = subDocRoot->GetPrefWidth(aRenderingContext);
   } else {
     result = GetIntrinsicWidth();
   }
 
   return result;
 }
 
-/* virtual */ nsIFrame::IntrinsicSize
+/* virtual */ IntrinsicSize
 nsSubDocumentFrame::GetIntrinsicSize()
 {
   nsIFrame* subDocRoot = ObtainIntrinsicSizeFrame();
   if (subDocRoot) {
     return subDocRoot->GetIntrinsicSize();
   }
   return nsLeafFrame::GetIntrinsicSize();
 }
--- a/layout/generic/nsSubDocumentFrame.h
+++ b/layout/generic/nsSubDocumentFrame.h
@@ -43,17 +43,17 @@ public:
                     nsIFrame*        aParent,
                     nsIFrame*        aPrevInFlow) MOZ_OVERRIDE;
 
   virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
 
   virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
   virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
 
-  virtual IntrinsicSize GetIntrinsicSize() MOZ_OVERRIDE;
+  virtual mozilla::IntrinsicSize GetIntrinsicSize() MOZ_OVERRIDE;
   virtual nsSize  GetIntrinsicRatio() MOZ_OVERRIDE;
 
   virtual nsSize ComputeAutoSize(nsRenderingContext *aRenderingContext,
                                  nsSize aCBSize, nscoord aAvailableWidth,
                                  nsSize aMargin, nsSize aBorder,
                                  nsSize aPadding, bool aShrinkWrap) MOZ_OVERRIDE;
 
   virtual nsSize ComputeSize(nsRenderingContext *aRenderingContext,
--- a/layout/mathml/nsMathMLFrame.h
+++ b/layout/mathml/nsMathMLFrame.h
@@ -6,18 +6,22 @@
 #ifndef nsMathMLFrame_h___
 #define nsMathMLFrame_h___
 
 #include "mozilla/Attributes.h"
 #include "nsFontMetrics.h"
 #include "nsMathMLOperators.h"
 #include "nsIMathMLFrame.h"
 #include "nsLayoutUtils.h"
+#include "nsBoundingMetrics.h"
+#include "nsIFrame.h"
 
 class nsMathMLChar;
+class nsCSSValue;
+class nsDisplayListSet;
 
 // Concrete base class with default methods that derived MathML frames can override
 class nsMathMLFrame : public nsIMathMLFrame {
 public:
 
   // nsIMathMLFrame ---
 
   virtual bool
--- a/layout/style/nsAnimationManager.cpp
+++ b/layout/style/nsAnimationManager.cpp
@@ -9,16 +9,17 @@
 
 #include "nsPresContext.h"
 #include "nsRuleProcessorData.h"
 #include "nsStyleSet.h"
 #include "nsCSSRules.h"
 #include "nsStyleAnimation.h"
 #include "nsEventDispatcher.h"
 #include "nsLayoutUtils.h"
+#include "nsIFrame.h"
 #include <math.h>
 
 using namespace mozilla;
 using namespace mozilla::css;
 
 ElementAnimations::ElementAnimations(mozilla::dom::Element *aElement, nsIAtom *aElementProperty,
                                      nsAnimationManager *aAnimationManager)
   : CommonElementAnimationData(aElement, aElementProperty,
--- a/layout/svg/nsSVGOuterSVGFrame.cpp
+++ b/layout/svg/nsSVGOuterSVGFrame.cpp
@@ -226,17 +226,17 @@ nsSVGOuterSVGFrame::GetPrefWidth(nsRende
     if (result < 0) {
       result = nscoord(0);
     }
   }
 
   return result;
 }
 
-/* virtual */ nsIFrame::IntrinsicSize
+/* virtual */ IntrinsicSize
 nsSVGOuterSVGFrame::GetIntrinsicSize()
 {
   // XXXjwatt Note that here we want to return the CSS width/height if they're
   // specified and we're embedded inside an nsIObjectLoadingContent.
 
   IntrinsicSize intrinsicSize;
 
   SVGSVGElement *content = static_cast<SVGSVGElement*>(mContent);
--- a/layout/svg/nsSVGOuterSVGFrame.h
+++ b/layout/svg/nsSVGOuterSVGFrame.h
@@ -37,17 +37,17 @@ public:
                  "foreignObject(s) still registered!");
   }
 #endif
 
   // nsIFrame:
   virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
   virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
 
-  virtual IntrinsicSize GetIntrinsicSize() MOZ_OVERRIDE;
+  virtual mozilla::IntrinsicSize GetIntrinsicSize() MOZ_OVERRIDE;
   virtual nsSize  GetIntrinsicRatio() MOZ_OVERRIDE;
 
   virtual nsSize ComputeSize(nsRenderingContext *aRenderingContext,
                              nsSize aCBSize, nscoord aAvailableWidth,
                              nsSize aMargin, nsSize aBorder, nsSize aPadding,
                              uint32_t aFlags) MOZ_OVERRIDE;
 
   NS_IMETHOD Reflow(nsPresContext*          aPresContext,
--- a/layout/svg/nsSVGTextFrame2.cpp
+++ b/layout/svg/nsSVGTextFrame2.cpp
@@ -35,16 +35,17 @@
 #include "nsTextFrame.h"
 #include "nsTextNode.h"
 #include "SVGAnimatedNumberList.h"
 #include "SVGContentUtils.h"
 #include "SVGLengthList.h"
 #include "SVGNumberList.h"
 #include "SVGPathElement.h"
 #include "SVGTextPathElement.h"
+#include "nsLayoutUtils.h"
 #include <algorithm>
 #include <cmath>
 #include <limits>
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 // ============================================================================
--- a/layout/xul/base/src/nsBoxFrame.cpp
+++ b/layout/xul/base/src/nsBoxFrame.cpp
@@ -57,16 +57,17 @@
 #include "nsITheme.h"
 #include "nsTransform2D.h"
 #include "nsEventStateManager.h"
 #include "nsEventDispatcher.h"
 #include "nsIDOMEvent.h"
 #include "nsDisplayList.h"
 #include "mozilla/Preferences.h"
 #include "nsThemeConstants.h"
+#include "nsLayoutUtils.h"
 #include <algorithm>
 
 // Needed for Print Preview
 #include "nsIURI.h"
 
 #include "mozilla/TouchEvents.h"
 
 using namespace mozilla;
@@ -1905,18 +1906,18 @@ IsBoxOrdinalLEQ(nsIFrame* aFrame1,
   nsIFrame* aRealFrame2 = nsPlaceholderFrame::GetRealFrameFor(aFrame2);
   return aRealFrame1->GetOrdinal() <= aRealFrame2->GetOrdinal();
 }
 
 void 
 nsBoxFrame::CheckBoxOrder()
 {
   if (SupportsOrdinalsInChildren() &&
-      !nsLayoutUtils::IsFrameListSorted<IsBoxOrdinalLEQ>(mFrames)) {
-    nsLayoutUtils::SortFrameList<IsBoxOrdinalLEQ>(mFrames);
+      !nsIFrame::IsFrameListSorted<IsBoxOrdinalLEQ>(mFrames)) {
+    nsIFrame::SortFrameList<IsBoxOrdinalLEQ>(mFrames);
   }
 }
 
 nsresult
 nsBoxFrame::LayoutChildAt(nsBoxLayoutState& aState, nsIFrame* aBox, const nsRect& aRect)
 {
   // get the current rect
   nsRect oldRect(aBox->GetRect());
--- a/layout/xul/base/src/nsProgressMeterFrame.cpp
+++ b/layout/xul/base/src/nsProgressMeterFrame.cpp
@@ -16,16 +16,50 @@
 #include "nsPresContext.h"
 #include "nsGkAtoms.h"
 #include "nsINameSpaceManager.h"
 #include "nsCOMPtr.h"
 #include "nsBoxLayoutState.h"
 #include "nsIReflowCallback.h"
 #include "nsContentUtils.h"
 #include "mozilla/Attributes.h"
+
+class nsReflowFrameRunnable : public nsRunnable
+{
+public:
+  nsReflowFrameRunnable(nsIFrame* aFrame,
+                        nsIPresShell::IntrinsicDirty aIntrinsicDirty,
+                        nsFrameState aBitToAdd);
+
+  NS_DECL_NSIRUNNABLE
+
+  nsWeakFrame mWeakFrame;
+  nsIPresShell::IntrinsicDirty mIntrinsicDirty;
+  nsFrameState mBitToAdd;
+};
+
+nsReflowFrameRunnable::nsReflowFrameRunnable(nsIFrame* aFrame,
+                          nsIPresShell::IntrinsicDirty aIntrinsicDirty,
+                          nsFrameState aBitToAdd)
+  : mWeakFrame(aFrame),
+    mIntrinsicDirty(aIntrinsicDirty),
+    mBitToAdd(aBitToAdd)
+{
+}
+
+NS_IMETHODIMP
+nsReflowFrameRunnable::Run()
+{
+  if (mWeakFrame.IsAlive()) {
+    mWeakFrame->PresContext()->PresShell()->
+      FrameNeedsReflow(mWeakFrame, mIntrinsicDirty, mBitToAdd);
+  }
+  return NS_OK;
+}
+
 //
 // NS_NewToolbarFrame
 //
 // Creates a new Toolbar frame and returns it
 //
 nsIFrame*
 NS_NewProgressMeterFrame (nsIPresShell* aPresShell, nsStyleContext* aContext)
 {