Bug 1304598 Part 6 - Rename nsViewportFrame.h/cpp to ViewportFrame.h/cpp, and move exported header to mozilla/ subdir. draft
authorTing-Yu Lin <tlin@mozilla.com>
Fri, 25 Nov 2016 11:53:31 +0800
changeset 444606 e0f4f0c354c9b44e6ee8551e87535695bec31224
parent 444605 d8c143cfc5d62ede900f9cf17fbeba3aa59a0bcd
child 444607 41157be46533d2e24affde4010ce737c87eb6154
push id37303
push userbmo:tlin@mozilla.com
push dateMon, 28 Nov 2016 09:54:16 +0000
bugs1304598
milestone53.0a1
Bug 1304598 Part 6 - Rename nsViewportFrame.h/cpp to ViewportFrame.h/cpp, and move exported header to mozilla/ subdir. The class ViewportFrame doesn't have ns-prefix, so it's better to drop the ns-prefix in the file names to avoid confusion. MozReview-Commit-ID: 8Jrmfzb3tVR
layout/base/RestyleManager.cpp
layout/generic/ViewportFrame.cpp
layout/generic/ViewportFrame.h
layout/generic/moz.build
layout/generic/nsBRFrame.cpp
layout/generic/nsPageContentFrame.h
layout/generic/nsViewportFrame.cpp
layout/generic/nsViewportFrame.h
layout/ipc/RenderFrameParent.cpp
layout/painting/nsDisplayList.cpp
--- a/layout/base/RestyleManager.cpp
+++ b/layout/base/RestyleManager.cpp
@@ -8,16 +8,17 @@
  * changes need to happen, scheduling them, and doing them.
  */
 
 #include "mozilla/RestyleManager.h"
 
 #include <algorithm> // For std::max
 #include "mozilla/EffectSet.h"
 #include "mozilla/EventStates.h"
+#include "mozilla/ViewportFrame.h"
 #include "nsLayoutUtils.h"
 #include "AnimationCommon.h" // For GetLayerAnimationInfo
 #include "FrameLayerBuilder.h"
 #include "GeckoProfiler.h"
 #include "LayerAnimationInfo.h" // For LayerAnimationInfo::sRecords
 #include "nsAutoPtr.h"
 #include "nsStyleChangeList.h"
 #include "nsRuleProcessorData.h"
@@ -31,17 +32,16 @@
 #include "nsTransitionManager.h"
 #include "nsViewManager.h"
 #include "nsRenderingContext.h"
 #include "nsSVGIntegrationUtils.h"
 #include "nsCSSAnonBoxes.h"
 #include "nsContainerFrame.h"
 #include "nsPlaceholderFrame.h"
 #include "nsBlockFrame.h"
-#include "nsViewportFrame.h"
 #include "SVGTextFrame.h"
 #include "StickyScrollContainer.h"
 #include "nsIRootBox.h"
 #include "nsIDOMMutationEvent.h"
 #include "nsContentUtils.h"
 #include "nsIFrameInlines.h"
 #include "ActiveLayerTracker.h"
 #include "nsDisplayList.h"
new file mode 100644
--- /dev/null
+++ b/layout/generic/ViewportFrame.cpp
@@ -0,0 +1,417 @@
+/* -*- 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/. */
+
+/*
+ * rendering object that is the root of the frame tree, which contains
+ * the document's scrollbars and contains fixed-positioned elements
+ */
+
+#include "mozilla/ViewportFrame.h"
+
+#include "nsGkAtoms.h"
+#include "nsIScrollableFrame.h"
+#include "nsSubDocumentFrame.h"
+#include "nsCanvasFrame.h"
+#include "nsAbsoluteContainingBlock.h"
+#include "GeckoProfiler.h"
+#include "nsIMozBrowserFrame.h"
+
+using namespace mozilla;
+typedef nsAbsoluteContainingBlock::AbsPosReflowFlags AbsPosReflowFlags;
+
+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)
+NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
+
+void
+ViewportFrame::Init(nsIContent*       aContent,
+                    nsContainerFrame* aParent,
+                    nsIFrame*         aPrevInFlow)
+{
+  nsContainerFrame::Init(aContent, aParent, aPrevInFlow);
+
+  nsIFrame* parent = nsLayoutUtils::GetCrossDocParentFrame(this);
+  if (parent) {
+    nsFrameState state = parent->GetStateBits();
+
+    mState |= state & (NS_FRAME_IN_POPUP);
+  }
+}
+
+void
+ViewportFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
+                                const nsRect&           aDirtyRect,
+                                const nsDisplayListSet& aLists)
+{
+  PROFILER_LABEL("ViewportFrame", "BuildDisplayList",
+    js::ProfileEntry::Category::GRAPHICS);
+
+  if (nsIFrame* kid = mFrames.FirstChild()) {
+    // make the kid's BorderBackground our own. This ensures that the canvas
+    // frame's background becomes our own background and therefore appears
+    // below negative z-index elements.
+    BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists);
+  }
+
+  nsDisplayList topLayerList;
+  BuildDisplayListForTopLayer(aBuilder, &topLayerList);
+  if (!topLayerList.IsEmpty()) {
+    // Wrap the whole top layer in a single item with maximum z-index,
+    // and append it at the very end, so that it stays at the topmost.
+    nsDisplayWrapList* wrapList =
+      new (aBuilder) nsDisplayWrapList(aBuilder, this, &topLayerList);
+    wrapList->SetOverrideZIndex(
+      std::numeric_limits<decltype(wrapList->ZIndex())>::max());
+    aLists.PositionedDescendants()->AppendNewToTop(wrapList);
+  }
+}
+
+#ifdef DEBUG
+/**
+ * Returns whether we are going to put an element in the top layer for
+ * fullscreen. This function should matches the CSS rule in ua.css.
+ */
+static bool
+ShouldInTopLayerForFullscreen(Element* aElement)
+{
+  if (!aElement->GetParent()) {
+    return false;
+  }
+  nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(aElement);
+  if (browserFrame && browserFrame->GetReallyIsBrowser()) {
+    return false;
+  }
+  return true;
+}
+#endif // DEBUG
+
+static void
+BuildDisplayListForTopLayerFrame(nsDisplayListBuilder* aBuilder,
+                                 nsIFrame* aFrame,
+                                 nsDisplayList* aList)
+{
+  nsRect dirty;
+  DisplayListClipState::AutoClipMultiple clipState(aBuilder);
+  nsDisplayListBuilder::OutOfFlowDisplayData*
+    savedOutOfFlowData = nsDisplayListBuilder::GetOutOfFlowData(aFrame);
+  if (savedOutOfFlowData) {
+    dirty = savedOutOfFlowData->mDirtyRect;
+    clipState.SetClipForContainingBlockDescendants(
+      &savedOutOfFlowData->mContainingBlockClip);
+    clipState.SetScrollClipForContainingBlockDescendants(
+      aBuilder, savedOutOfFlowData->mContainingBlockScrollClip);
+  }
+  nsDisplayList list;
+  aFrame->BuildDisplayListForStackingContext(aBuilder, dirty, &list);
+  aList->AppendToTop(&list);
+}
+
+void
+ViewportFrame::BuildDisplayListForTopLayer(nsDisplayListBuilder* aBuilder,
+                                           nsDisplayList* aList)
+{
+  nsIDocument* doc = PresContext()->Document();
+  nsTArray<Element*> fullscreenStack = doc->GetFullscreenStack();
+  for (Element* elem : fullscreenStack) {
+    if (nsIFrame* frame = elem->GetPrimaryFrame()) {
+      // There are two cases where an element in fullscreen is not in
+      // the top layer:
+      // 1. When building display list for purpose other than painting,
+      //    it is possible that there is inconsistency between the style
+      //    info and the content tree.
+      // 2. This is an element which we are not going to put in the top
+      //    layer for fullscreen. See ShouldInTopLayerForFullscreen().
+      // In both cases, we want to skip the frame here and paint it in
+      // the normal path.
+      if (frame->StyleDisplay()->mTopLayer == NS_STYLE_TOP_LAYER_NONE) {
+        MOZ_ASSERT(!aBuilder->IsForPainting() ||
+                   !ShouldInTopLayerForFullscreen(elem));
+        continue;
+      }
+      MOZ_ASSERT(ShouldInTopLayerForFullscreen(elem));
+      // Inner SVG, MathML elements, as well as children of some XUL
+      // elements are not allowed to be out-of-flow. They should not
+      // be handled as top layer element here.
+      if (!(frame->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) {
+        MOZ_ASSERT(!elem->GetParent()->IsHTMLElement(), "HTML element "
+                   "should always be out-of-flow if in the top layer");
+        continue;
+      }
+      if (nsIFrame* backdropPh =
+          frame->GetChildList(kBackdropList).FirstChild()) {
+        MOZ_ASSERT(backdropPh->GetType() == nsGkAtoms::placeholderFrame);
+        nsIFrame* backdropFrame =
+          static_cast<nsPlaceholderFrame*>(backdropPh)->GetOutOfFlowFrame();
+        MOZ_ASSERT(backdropFrame);
+        BuildDisplayListForTopLayerFrame(aBuilder, backdropFrame, aList);
+      }
+      BuildDisplayListForTopLayerFrame(aBuilder, frame, aList);
+    }
+  }
+
+  nsIPresShell* shell = PresContext()->PresShell();
+  if (nsCanvasFrame* canvasFrame = shell->GetCanvasFrame()) {
+    if (Element* container = canvasFrame->GetCustomContentContainer()) {
+      if (nsIFrame* frame = container->GetPrimaryFrame()) {
+        BuildDisplayListForTopLayerFrame(aBuilder, frame, aList);
+      }
+    }
+  }
+}
+
+#ifdef DEBUG
+void
+ViewportFrame::AppendFrames(ChildListID     aListID,
+                            nsFrameList&    aFrameList)
+{
+  NS_ASSERTION(aListID == kPrincipalList, "unexpected child list");
+  NS_ASSERTION(GetChildList(aListID).IsEmpty(), "Shouldn't have any kids!");
+  nsContainerFrame::AppendFrames(aListID, aFrameList);
+}
+
+void
+ViewportFrame::InsertFrames(ChildListID     aListID,
+                            nsIFrame*       aPrevFrame,
+                            nsFrameList&    aFrameList)
+{
+  NS_ASSERTION(aListID == kPrincipalList, "unexpected child list");
+  NS_ASSERTION(GetChildList(aListID).IsEmpty(), "Shouldn't have any kids!");
+  nsContainerFrame::InsertFrames(aListID, aPrevFrame, aFrameList);
+}
+
+void
+ViewportFrame::RemoveFrame(ChildListID     aListID,
+                           nsIFrame*       aOldFrame)
+{
+  NS_ASSERTION(aListID == kPrincipalList, "unexpected child list");
+  nsContainerFrame::RemoveFrame(aListID, aOldFrame);
+}
+#endif
+
+/* virtual */ nscoord
+ViewportFrame::GetMinISize(nsRenderingContext *aRenderingContext)
+{
+  nscoord result;
+  DISPLAY_MIN_WIDTH(this, result);
+  if (mFrames.IsEmpty())
+    result = 0;
+  else
+    result = mFrames.FirstChild()->GetMinISize(aRenderingContext);
+
+  return result;
+}
+
+/* virtual */ nscoord
+ViewportFrame::GetPrefISize(nsRenderingContext *aRenderingContext)
+{
+  nscoord result;
+  DISPLAY_PREF_WIDTH(this, result);
+  if (mFrames.IsEmpty())
+    result = 0;
+  else
+    result = mFrames.FirstChild()->GetPrefISize(aRenderingContext);
+
+  return result;
+}
+
+nsPoint
+ViewportFrame::AdjustReflowInputForScrollbars(ReflowInput* aReflowInput) const
+{
+  // Get our prinicpal child frame and see if we're scrollable
+  nsIFrame* kidFrame = mFrames.FirstChild();
+  nsIScrollableFrame* scrollingFrame = do_QueryFrame(kidFrame);
+
+  if (scrollingFrame) {
+    WritingMode wm = aReflowInput->GetWritingMode();
+    LogicalMargin scrollbars(wm, scrollingFrame->GetActualScrollbarSizes());
+    aReflowInput->SetComputedISize(aReflowInput->ComputedISize() -
+                                   scrollbars.IStartEnd(wm));
+    aReflowInput->AvailableISize() -= scrollbars.IStartEnd(wm);
+    aReflowInput->SetComputedBSizeWithoutResettingResizeFlags(
+      aReflowInput->ComputedBSize() - scrollbars.BStartEnd(wm));
+    return nsPoint(scrollbars.Left(wm), scrollbars.Top(wm));
+  }
+  return nsPoint(0, 0);
+}
+
+nsRect
+ViewportFrame::AdjustReflowInputAsContainingBlock(ReflowInput* aReflowInput) const
+{
+#ifdef DEBUG
+  nsPoint offset =
+#endif
+    AdjustReflowInputForScrollbars(aReflowInput);
+
+  NS_ASSERTION(GetAbsoluteContainingBlock()->GetChildList().IsEmpty() ||
+               (offset.x == 0 && offset.y == 0),
+               "We don't handle correct positioning of fixed frames with "
+               "scrollbars in odd positions");
+
+  // If a scroll position clamping scroll-port size has been set, layout
+  // fixed position elements to this size instead of the computed size.
+  nsRect rect(0, 0, aReflowInput->ComputedWidth(), aReflowInput->ComputedHeight());
+  nsIPresShell* ps = PresContext()->PresShell();
+  if (ps->IsScrollPositionClampingScrollPortSizeSet()) {
+    rect.SizeTo(ps->GetScrollPositionClampingScrollPortSize());
+  }
+
+  return rect;
+}
+
+void
+ViewportFrame::Reflow(nsPresContext*           aPresContext,
+                      ReflowOutput&     aDesiredSize,
+                      const ReflowInput& aReflowInput,
+                      nsReflowStatus&          aStatus)
+{
+  MarkInReflow();
+  DO_GLOBAL_REFLOW_COUNT("ViewportFrame");
+  DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus);
+  NS_FRAME_TRACE_REFLOW_IN("ViewportFrame::Reflow");
+
+  // Initialize OUT parameters
+  aStatus = NS_FRAME_COMPLETE;
+
+  // Because |Reflow| sets ComputedBSize() on the child to our
+  // ComputedBSize().
+  AddStateBits(NS_FRAME_CONTAINS_RELATIVE_BSIZE);
+
+  // Set our size up front, since some parts of reflow depend on it
+  // being already set.  Note that the computed height may be
+  // unconstrained; that's ok.  Consumers should watch out for that.
+  SetSize(nsSize(aReflowInput.ComputedWidth(), aReflowInput.ComputedHeight()));
+
+  // Reflow the main content first so that the placeholders of the
+  // fixed-position frames will be in the right places on an initial
+  // reflow.
+  nscoord kidBSize = 0;
+  WritingMode wm = aReflowInput.GetWritingMode();
+
+  if (mFrames.NotEmpty()) {
+    // Deal with a non-incremental reflow or an incremental reflow
+    // targeted at our one-and-only principal child frame.
+    if (aReflowInput.ShouldReflowAllKids() ||
+        aReflowInput.IsBResize() ||
+        NS_SUBTREE_DIRTY(mFrames.FirstChild())) {
+      // Reflow our one-and-only principal child frame
+      nsIFrame*           kidFrame = mFrames.FirstChild();
+      ReflowOutput kidDesiredSize(aReflowInput);
+      WritingMode         wm = kidFrame->GetWritingMode();
+      LogicalSize         availableSpace = aReflowInput.AvailableSize(wm);
+      ReflowInput   kidReflowInput(aPresContext, aReflowInput,
+                                         kidFrame, availableSpace);
+
+      // Reflow the frame
+      kidReflowInput.SetComputedBSize(aReflowInput.ComputedBSize());
+      ReflowChild(kidFrame, aPresContext, kidDesiredSize, kidReflowInput,
+                  0, 0, 0, aStatus);
+      kidBSize = kidDesiredSize.BSize(wm);
+
+      FinishReflowChild(kidFrame, aPresContext, kidDesiredSize, nullptr, 0, 0, 0);
+    } else {
+      kidBSize = LogicalSize(wm, mFrames.FirstChild()->GetSize()).BSize(wm);
+    }
+  }
+
+  NS_ASSERTION(aReflowInput.AvailableISize() != NS_UNCONSTRAINEDSIZE,
+               "shouldn't happen anymore");
+
+  // Return the max size as our desired size
+  LogicalSize maxSize(wm, aReflowInput.AvailableISize(),
+                      // Being flowed initially at an unconstrained block size
+                      // means we should return our child's intrinsic size.
+                      aReflowInput.ComputedBSize() != NS_UNCONSTRAINEDSIZE
+                        ? aReflowInput.ComputedBSize()
+                        : kidBSize);
+  aDesiredSize.SetSize(wm, maxSize);
+  aDesiredSize.SetOverflowAreasToDesiredBounds();
+
+  if (HasAbsolutelyPositionedChildren()) {
+    // Make a copy of the reflow state and change the computed width and height
+    // to reflect the available space for the fixed items
+    ReflowInput reflowInput(aReflowInput);
+
+    if (reflowInput.AvailableBSize() == NS_UNCONSTRAINEDSIZE) {
+      // We have an intrinsic-height document with abs-pos/fixed-pos children.
+      // Set the available height and mComputedHeight to our chosen height.
+      reflowInput.AvailableBSize() = maxSize.BSize(wm);
+      // Not having border/padding simplifies things
+      NS_ASSERTION(reflowInput.ComputedPhysicalBorderPadding() == nsMargin(0,0,0,0),
+                   "Viewports can't have border/padding");
+      reflowInput.SetComputedBSize(maxSize.BSize(wm));
+    }
+
+    nsRect rect = AdjustReflowInputAsContainingBlock(&reflowInput);
+    nsOverflowAreas* overflowAreas = &aDesiredSize.mOverflowAreas;
+    nsIScrollableFrame* rootScrollFrame =
+                    aPresContext->PresShell()->GetRootScrollFrameAsScrollable();
+    if (rootScrollFrame && !rootScrollFrame->IsIgnoringViewportClipping()) {
+      overflowAreas = nullptr;
+    }
+    AbsPosReflowFlags flags =
+      AbsPosReflowFlags::eCBWidthAndHeightChanged; // XXX could be optimized
+    GetAbsoluteContainingBlock()->Reflow(this, aPresContext, reflowInput, aStatus,
+                                         rect, flags, overflowAreas);
+  }
+
+  if (mFrames.NotEmpty()) {
+    ConsiderChildOverflow(aDesiredSize.mOverflowAreas, mFrames.FirstChild());
+  }
+
+  // If we were dirty then do a repaint
+  if (GetStateBits() & NS_FRAME_IS_DIRTY) {
+    InvalidateFrame();
+  }
+
+  // Clipping is handled by the document container (e.g., nsSubDocumentFrame),
+  // so we don't need to change our overflow areas.
+  bool overflowChanged = FinishAndStoreOverflow(&aDesiredSize);
+  if (overflowChanged) {
+    // We may need to alert our container to get it to pick up the
+    // overflow change.
+    nsSubDocumentFrame* container = static_cast<nsSubDocumentFrame*>
+      (nsLayoutUtils::GetCrossDocParentFrame(this));
+    if (container && !container->ShouldClipSubdocument()) {
+      container->PresContext()->PresShell()->
+        FrameNeedsReflow(container, nsIPresShell::eResize, NS_FRAME_IS_DIRTY);
+    }
+  }
+
+  NS_FRAME_TRACE_REFLOW_OUT("ViewportFrame::Reflow", aStatus);
+  NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize);
+}
+
+bool
+ViewportFrame::ComputeCustomOverflow(nsOverflowAreas& aOverflowAreas)
+{
+  nsIScrollableFrame* rootScrollFrame =
+    PresContext()->PresShell()->GetRootScrollFrameAsScrollable();
+  if (rootScrollFrame && !rootScrollFrame->IsIgnoringViewportClipping()) {
+    return false;
+  }
+
+  return nsContainerFrame::ComputeCustomOverflow(aOverflowAreas);
+}
+
+nsIAtom*
+ViewportFrame::GetType() const
+{
+  return nsGkAtoms::viewportFrame;
+}
+
+#ifdef DEBUG_FRAME_DUMP
+nsresult
+ViewportFrame::GetFrameName(nsAString& aResult) const
+{
+  return MakeFrameName(NS_LITERAL_STRING("Viewport"), aResult);
+}
+#endif
new file mode 100644
--- /dev/null
+++ b/layout/generic/ViewportFrame.h
@@ -0,0 +1,111 @@
+/* -*- 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/. */
+
+/*
+ * rendering object that is the root of the frame tree, which contains
+ * the document's scrollbars and contains fixed-positioned elements
+ */
+
+#ifndef mozilla_ViewportFrame_h
+#define mozilla_ViewportFrame_h
+
+#include "mozilla/Attributes.h"
+#include "nsContainerFrame.h"
+
+class nsPresContext;
+
+namespace mozilla {
+
+/**
+  * ViewportFrame is the parent of a single child - the doc root frame or a scroll frame
+  * containing the doc root frame. ViewportFrame stores this child in its primary child
+  * list.
+  */
+class ViewportFrame : public nsContainerFrame {
+public:
+  NS_DECL_QUERYFRAME_TARGET(ViewportFrame)
+  NS_DECL_QUERYFRAME
+  NS_DECL_FRAMEARENA_HELPERS
+
+  explicit ViewportFrame(nsStyleContext* aContext)
+    : nsContainerFrame(aContext)
+  {}
+  virtual ~ViewportFrame() { } // useful for debugging
+
+  virtual void Init(nsIContent*       aContent,
+                    nsContainerFrame* aParent,
+                    nsIFrame*         aPrevInFlow) override;
+
+  virtual mozilla::WritingMode GetWritingMode() const override
+  {
+    nsIFrame* firstChild = mFrames.FirstChild();
+    if (firstChild) {
+      return firstChild->GetWritingMode();
+    }
+    return nsIFrame::GetWritingMode();
+  }
+
+#ifdef DEBUG
+  virtual void AppendFrames(ChildListID     aListID,
+                            nsFrameList&    aFrameList) override;
+  virtual void InsertFrames(ChildListID     aListID,
+                            nsIFrame*       aPrevFrame,
+                            nsFrameList&    aFrameList) override;
+  virtual void RemoveFrame(ChildListID     aListID,
+                           nsIFrame*       aOldFrame) override;
+#endif
+
+  virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
+                                const nsRect&           aDirtyRect,
+                                const nsDisplayListSet& aLists) override;
+
+  void BuildDisplayListForTopLayer(nsDisplayListBuilder* aBuilder,
+                                   nsDisplayList* aList);
+
+  virtual nscoord GetMinISize(nsRenderingContext *aRenderingContext) override;
+  virtual nscoord GetPrefISize(nsRenderingContext *aRenderingContext) override;
+  virtual void Reflow(nsPresContext*           aPresContext,
+                      ReflowOutput&     aDesiredSize,
+                      const ReflowInput& aReflowInput,
+                      nsReflowStatus&          aStatus) override;
+
+  /**
+   * Get the "type" of the frame
+   *
+   * @see nsGkAtoms::viewportFrame
+   */
+  virtual nsIAtom* GetType() const override;
+
+  virtual bool ComputeCustomOverflow(nsOverflowAreas& aOverflowAreas) override;
+
+  /**
+   * Adjust aReflowInput to account for scrollbars and pres shell
+   * GetScrollPositionClampingScrollPortSizeSet and
+   * GetContentDocumentFixedPositionMargins adjustments.
+   * @return the rect to use as containing block rect
+   */
+  nsRect AdjustReflowInputAsContainingBlock(ReflowInput* aReflowInput) const;
+
+#ifdef DEBUG_FRAME_DUMP
+  virtual nsresult GetFrameName(nsAString& aResult) const override;
+#endif
+
+private:
+  virtual mozilla::layout::FrameChildListID GetAbsoluteListID() const override { return kFixedList; }
+
+protected:
+  /**
+   * Calculate how much room is available for fixed frames. That means
+   * determining if the viewport is scrollable and whether the vertical and/or
+   * horizontal scrollbars are visible.  Adjust the computed width/height and
+   * available width for aReflowInput accordingly.
+   * @return the current scroll position, or 0,0 if not scrollable
+   */
+  nsPoint AdjustReflowInputForScrollbars(ReflowInput* aReflowInput) const;
+};
+
+} // namespace mozilla
+
+#endif // mozilla_ViewportFrame_h
--- a/layout/generic/moz.build
+++ b/layout/generic/moz.build
@@ -107,16 +107,17 @@ EXPORTS += [
     'ScrollSnap.h',
     'Visibility.h',
 ]
 
 EXPORTS.mozilla += [
     'CSSAlignUtils.h',
     'ReflowInput.h',
     'ReflowOutput.h',
+    'ViewportFrame.h',
     'WritingModes.h',
 ]
 
 EXPORTS.mozilla.dom += [
     'Selection.h',
 ]
 
 EXPORTS.mozilla.layout += [
@@ -169,25 +170,25 @@ UNIFIED_SOURCES += [
     'nsSelection.cpp',
     'nsSimplePageSequenceFrame.cpp',
     'nsSplittableFrame.cpp',
     'nsSubDocumentFrame.cpp',
     'nsTextFrame.cpp',
     'nsTextFrameUtils.cpp',
     'nsTextRunTransformations.cpp',
     'nsVideoFrame.cpp',
-    'nsViewportFrame.cpp',
     'ReflowInput.cpp',
     'ReflowOutput.cpp',
     'RubyUtils.cpp',
     'ScrollbarActivity.cpp',
     'ScrollSnap.cpp',
     'ScrollVelocityQueue.cpp',
     'StickyScrollContainer.cpp',
     'TextOverflow.cpp',
+    'ViewportFrame.cpp',
 ]
 
 # nsLineLayout.cpp needs to be built separately because it uses plarena.h.
 # nsPluginFrame.cpp needs to be built separately because of name clashes in the OS X headers.
 SOURCES += [
     'nsLineLayout.cpp',
     'nsPluginFrame.cpp',
 ]
--- a/layout/generic/nsBRFrame.cpp
+++ b/layout/generic/nsBRFrame.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/. */
 
 /* rendering object for HTML <br> elements */
 
 #include "nsCOMPtr.h"
+#include "nsContainerFrame.h"
 #include "nsFontMetrics.h"
 #include "nsFrame.h"
 #include "nsPresContext.h"
 #include "nsLineLayout.h"
 #include "nsStyleConsts.h"
 #include "nsGkAtoms.h"
 #include "nsRenderingContext.h"
 #include "nsLayoutUtils.h"
--- a/layout/generic/nsPageContentFrame.h
+++ b/layout/generic/nsPageContentFrame.h
@@ -1,17 +1,18 @@
 /* -*- 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/. */
 #ifndef nsPageContentFrame_h___
 #define nsPageContentFrame_h___
 
 #include "mozilla/Attributes.h"
-#include "nsViewportFrame.h"
+#include "mozilla/ViewportFrame.h"
+
 class nsPageFrame;
 class nsSharedPageData;
 
 // Page frame class used by the simple page sequence frame
 class nsPageContentFrame : public mozilla::ViewportFrame {
 
 public:
   NS_DECL_FRAMEARENA_HELPERS
deleted file mode 100644
--- a/layout/generic/nsViewportFrame.cpp
+++ /dev/null
@@ -1,416 +0,0 @@
-/* -*- 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/. */
-
-/*
- * rendering object that is the root of the frame tree, which contains
- * the document's scrollbars and contains fixed-positioned elements
- */
-
-#include "nsViewportFrame.h"
-#include "nsGkAtoms.h"
-#include "nsIScrollableFrame.h"
-#include "nsSubDocumentFrame.h"
-#include "nsCanvasFrame.h"
-#include "nsAbsoluteContainingBlock.h"
-#include "GeckoProfiler.h"
-#include "nsIMozBrowserFrame.h"
-
-using namespace mozilla;
-typedef nsAbsoluteContainingBlock::AbsPosReflowFlags AbsPosReflowFlags;
-
-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)
-NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
-
-void
-ViewportFrame::Init(nsIContent*       aContent,
-                    nsContainerFrame* aParent,
-                    nsIFrame*         aPrevInFlow)
-{
-  nsContainerFrame::Init(aContent, aParent, aPrevInFlow);
-
-  nsIFrame* parent = nsLayoutUtils::GetCrossDocParentFrame(this);
-  if (parent) {
-    nsFrameState state = parent->GetStateBits();
-
-    mState |= state & (NS_FRAME_IN_POPUP);
-  }
-}
-
-void
-ViewportFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
-                                const nsRect&           aDirtyRect,
-                                const nsDisplayListSet& aLists)
-{
-  PROFILER_LABEL("ViewportFrame", "BuildDisplayList",
-    js::ProfileEntry::Category::GRAPHICS);
-
-  if (nsIFrame* kid = mFrames.FirstChild()) {
-    // make the kid's BorderBackground our own. This ensures that the canvas
-    // frame's background becomes our own background and therefore appears
-    // below negative z-index elements.
-    BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists);
-  }
-
-  nsDisplayList topLayerList;
-  BuildDisplayListForTopLayer(aBuilder, &topLayerList);
-  if (!topLayerList.IsEmpty()) {
-    // Wrap the whole top layer in a single item with maximum z-index,
-    // and append it at the very end, so that it stays at the topmost.
-    nsDisplayWrapList* wrapList =
-      new (aBuilder) nsDisplayWrapList(aBuilder, this, &topLayerList);
-    wrapList->SetOverrideZIndex(
-      std::numeric_limits<decltype(wrapList->ZIndex())>::max());
-    aLists.PositionedDescendants()->AppendNewToTop(wrapList);
-  }
-}
-
-#ifdef DEBUG
-/**
- * Returns whether we are going to put an element in the top layer for
- * fullscreen. This function should matches the CSS rule in ua.css.
- */
-static bool
-ShouldInTopLayerForFullscreen(Element* aElement)
-{
-  if (!aElement->GetParent()) {
-    return false;
-  }
-  nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(aElement);
-  if (browserFrame && browserFrame->GetReallyIsBrowser()) {
-    return false;
-  }
-  return true;
-}
-#endif // DEBUG
-
-static void
-BuildDisplayListForTopLayerFrame(nsDisplayListBuilder* aBuilder,
-                                 nsIFrame* aFrame,
-                                 nsDisplayList* aList)
-{
-  nsRect dirty;
-  DisplayListClipState::AutoClipMultiple clipState(aBuilder);
-  nsDisplayListBuilder::OutOfFlowDisplayData*
-    savedOutOfFlowData = nsDisplayListBuilder::GetOutOfFlowData(aFrame);
-  if (savedOutOfFlowData) {
-    dirty = savedOutOfFlowData->mDirtyRect;
-    clipState.SetClipForContainingBlockDescendants(
-      &savedOutOfFlowData->mContainingBlockClip);
-    clipState.SetScrollClipForContainingBlockDescendants(
-      aBuilder, savedOutOfFlowData->mContainingBlockScrollClip);
-  }
-  nsDisplayList list;
-  aFrame->BuildDisplayListForStackingContext(aBuilder, dirty, &list);
-  aList->AppendToTop(&list);
-}
-
-void
-ViewportFrame::BuildDisplayListForTopLayer(nsDisplayListBuilder* aBuilder,
-                                           nsDisplayList* aList)
-{
-  nsIDocument* doc = PresContext()->Document();
-  nsTArray<Element*> fullscreenStack = doc->GetFullscreenStack();
-  for (Element* elem : fullscreenStack) {
-    if (nsIFrame* frame = elem->GetPrimaryFrame()) {
-      // There are two cases where an element in fullscreen is not in
-      // the top layer:
-      // 1. When building display list for purpose other than painting,
-      //    it is possible that there is inconsistency between the style
-      //    info and the content tree.
-      // 2. This is an element which we are not going to put in the top
-      //    layer for fullscreen. See ShouldInTopLayerForFullscreen().
-      // In both cases, we want to skip the frame here and paint it in
-      // the normal path.
-      if (frame->StyleDisplay()->mTopLayer == NS_STYLE_TOP_LAYER_NONE) {
-        MOZ_ASSERT(!aBuilder->IsForPainting() ||
-                   !ShouldInTopLayerForFullscreen(elem));
-        continue;
-      }
-      MOZ_ASSERT(ShouldInTopLayerForFullscreen(elem));
-      // Inner SVG, MathML elements, as well as children of some XUL
-      // elements are not allowed to be out-of-flow. They should not
-      // be handled as top layer element here.
-      if (!(frame->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) {
-        MOZ_ASSERT(!elem->GetParent()->IsHTMLElement(), "HTML element "
-                   "should always be out-of-flow if in the top layer");
-        continue;
-      }
-      if (nsIFrame* backdropPh =
-          frame->GetChildList(kBackdropList).FirstChild()) {
-        MOZ_ASSERT(backdropPh->GetType() == nsGkAtoms::placeholderFrame);
-        nsIFrame* backdropFrame =
-          static_cast<nsPlaceholderFrame*>(backdropPh)->GetOutOfFlowFrame();
-        MOZ_ASSERT(backdropFrame);
-        BuildDisplayListForTopLayerFrame(aBuilder, backdropFrame, aList);
-      }
-      BuildDisplayListForTopLayerFrame(aBuilder, frame, aList);
-    }
-  }
-
-  nsIPresShell* shell = PresContext()->PresShell();
-  if (nsCanvasFrame* canvasFrame = shell->GetCanvasFrame()) {
-    if (Element* container = canvasFrame->GetCustomContentContainer()) {
-      if (nsIFrame* frame = container->GetPrimaryFrame()) {
-        BuildDisplayListForTopLayerFrame(aBuilder, frame, aList);
-      }
-    }
-  }
-}
-
-#ifdef DEBUG
-void
-ViewportFrame::AppendFrames(ChildListID     aListID,
-                            nsFrameList&    aFrameList)
-{
-  NS_ASSERTION(aListID == kPrincipalList, "unexpected child list");
-  NS_ASSERTION(GetChildList(aListID).IsEmpty(), "Shouldn't have any kids!");
-  nsContainerFrame::AppendFrames(aListID, aFrameList);
-}
-
-void
-ViewportFrame::InsertFrames(ChildListID     aListID,
-                            nsIFrame*       aPrevFrame,
-                            nsFrameList&    aFrameList)
-{
-  NS_ASSERTION(aListID == kPrincipalList, "unexpected child list");
-  NS_ASSERTION(GetChildList(aListID).IsEmpty(), "Shouldn't have any kids!");
-  nsContainerFrame::InsertFrames(aListID, aPrevFrame, aFrameList);
-}
-
-void
-ViewportFrame::RemoveFrame(ChildListID     aListID,
-                           nsIFrame*       aOldFrame)
-{
-  NS_ASSERTION(aListID == kPrincipalList, "unexpected child list");
-  nsContainerFrame::RemoveFrame(aListID, aOldFrame);
-}
-#endif
-
-/* virtual */ nscoord
-ViewportFrame::GetMinISize(nsRenderingContext *aRenderingContext)
-{
-  nscoord result;
-  DISPLAY_MIN_WIDTH(this, result);
-  if (mFrames.IsEmpty())
-    result = 0;
-  else
-    result = mFrames.FirstChild()->GetMinISize(aRenderingContext);
-
-  return result;
-}
-
-/* virtual */ nscoord
-ViewportFrame::GetPrefISize(nsRenderingContext *aRenderingContext)
-{
-  nscoord result;
-  DISPLAY_PREF_WIDTH(this, result);
-  if (mFrames.IsEmpty())
-    result = 0;
-  else
-    result = mFrames.FirstChild()->GetPrefISize(aRenderingContext);
-
-  return result;
-}
-
-nsPoint
-ViewportFrame::AdjustReflowInputForScrollbars(ReflowInput* aReflowInput) const
-{
-  // Get our prinicpal child frame and see if we're scrollable
-  nsIFrame* kidFrame = mFrames.FirstChild();
-  nsIScrollableFrame* scrollingFrame = do_QueryFrame(kidFrame);
-
-  if (scrollingFrame) {
-    WritingMode wm = aReflowInput->GetWritingMode();
-    LogicalMargin scrollbars(wm, scrollingFrame->GetActualScrollbarSizes());
-    aReflowInput->SetComputedISize(aReflowInput->ComputedISize() -
-                                   scrollbars.IStartEnd(wm));
-    aReflowInput->AvailableISize() -= scrollbars.IStartEnd(wm);
-    aReflowInput->SetComputedBSizeWithoutResettingResizeFlags(
-      aReflowInput->ComputedBSize() - scrollbars.BStartEnd(wm));
-    return nsPoint(scrollbars.Left(wm), scrollbars.Top(wm));
-  }
-  return nsPoint(0, 0);
-}
-
-nsRect
-ViewportFrame::AdjustReflowInputAsContainingBlock(ReflowInput* aReflowInput) const
-{
-#ifdef DEBUG
-  nsPoint offset =
-#endif
-    AdjustReflowInputForScrollbars(aReflowInput);
-
-  NS_ASSERTION(GetAbsoluteContainingBlock()->GetChildList().IsEmpty() ||
-               (offset.x == 0 && offset.y == 0),
-               "We don't handle correct positioning of fixed frames with "
-               "scrollbars in odd positions");
-
-  // If a scroll position clamping scroll-port size has been set, layout
-  // fixed position elements to this size instead of the computed size.
-  nsRect rect(0, 0, aReflowInput->ComputedWidth(), aReflowInput->ComputedHeight());
-  nsIPresShell* ps = PresContext()->PresShell();
-  if (ps->IsScrollPositionClampingScrollPortSizeSet()) {
-    rect.SizeTo(ps->GetScrollPositionClampingScrollPortSize());
-  }
-
-  return rect;
-}
-
-void
-ViewportFrame::Reflow(nsPresContext*           aPresContext,
-                      ReflowOutput&     aDesiredSize,
-                      const ReflowInput& aReflowInput,
-                      nsReflowStatus&          aStatus)
-{
-  MarkInReflow();
-  DO_GLOBAL_REFLOW_COUNT("ViewportFrame");
-  DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus);
-  NS_FRAME_TRACE_REFLOW_IN("ViewportFrame::Reflow");
-
-  // Initialize OUT parameters
-  aStatus = NS_FRAME_COMPLETE;
-
-  // Because |Reflow| sets ComputedBSize() on the child to our
-  // ComputedBSize().
-  AddStateBits(NS_FRAME_CONTAINS_RELATIVE_BSIZE);
-
-  // Set our size up front, since some parts of reflow depend on it
-  // being already set.  Note that the computed height may be
-  // unconstrained; that's ok.  Consumers should watch out for that.
-  SetSize(nsSize(aReflowInput.ComputedWidth(), aReflowInput.ComputedHeight()));
-
-  // Reflow the main content first so that the placeholders of the
-  // fixed-position frames will be in the right places on an initial
-  // reflow.
-  nscoord kidBSize = 0;
-  WritingMode wm = aReflowInput.GetWritingMode();
-
-  if (mFrames.NotEmpty()) {
-    // Deal with a non-incremental reflow or an incremental reflow
-    // targeted at our one-and-only principal child frame.
-    if (aReflowInput.ShouldReflowAllKids() ||
-        aReflowInput.IsBResize() ||
-        NS_SUBTREE_DIRTY(mFrames.FirstChild())) {
-      // Reflow our one-and-only principal child frame
-      nsIFrame*           kidFrame = mFrames.FirstChild();
-      ReflowOutput kidDesiredSize(aReflowInput);
-      WritingMode         wm = kidFrame->GetWritingMode();
-      LogicalSize         availableSpace = aReflowInput.AvailableSize(wm);
-      ReflowInput   kidReflowInput(aPresContext, aReflowInput,
-                                         kidFrame, availableSpace);
-
-      // Reflow the frame
-      kidReflowInput.SetComputedBSize(aReflowInput.ComputedBSize());
-      ReflowChild(kidFrame, aPresContext, kidDesiredSize, kidReflowInput,
-                  0, 0, 0, aStatus);
-      kidBSize = kidDesiredSize.BSize(wm);
-
-      FinishReflowChild(kidFrame, aPresContext, kidDesiredSize, nullptr, 0, 0, 0);
-    } else {
-      kidBSize = LogicalSize(wm, mFrames.FirstChild()->GetSize()).BSize(wm);
-    }
-  }
-
-  NS_ASSERTION(aReflowInput.AvailableISize() != NS_UNCONSTRAINEDSIZE,
-               "shouldn't happen anymore");
-
-  // Return the max size as our desired size
-  LogicalSize maxSize(wm, aReflowInput.AvailableISize(),
-                      // Being flowed initially at an unconstrained block size
-                      // means we should return our child's intrinsic size.
-                      aReflowInput.ComputedBSize() != NS_UNCONSTRAINEDSIZE
-                        ? aReflowInput.ComputedBSize()
-                        : kidBSize);
-  aDesiredSize.SetSize(wm, maxSize);
-  aDesiredSize.SetOverflowAreasToDesiredBounds();
-
-  if (HasAbsolutelyPositionedChildren()) {
-    // Make a copy of the reflow state and change the computed width and height
-    // to reflect the available space for the fixed items
-    ReflowInput reflowInput(aReflowInput);
-
-    if (reflowInput.AvailableBSize() == NS_UNCONSTRAINEDSIZE) {
-      // We have an intrinsic-height document with abs-pos/fixed-pos children.
-      // Set the available height and mComputedHeight to our chosen height.
-      reflowInput.AvailableBSize() = maxSize.BSize(wm);
-      // Not having border/padding simplifies things
-      NS_ASSERTION(reflowInput.ComputedPhysicalBorderPadding() == nsMargin(0,0,0,0),
-                   "Viewports can't have border/padding");
-      reflowInput.SetComputedBSize(maxSize.BSize(wm));
-    }
-
-    nsRect rect = AdjustReflowInputAsContainingBlock(&reflowInput);
-    nsOverflowAreas* overflowAreas = &aDesiredSize.mOverflowAreas;
-    nsIScrollableFrame* rootScrollFrame =
-                    aPresContext->PresShell()->GetRootScrollFrameAsScrollable();
-    if (rootScrollFrame && !rootScrollFrame->IsIgnoringViewportClipping()) {
-      overflowAreas = nullptr;
-    }
-    AbsPosReflowFlags flags =
-      AbsPosReflowFlags::eCBWidthAndHeightChanged; // XXX could be optimized
-    GetAbsoluteContainingBlock()->Reflow(this, aPresContext, reflowInput, aStatus,
-                                         rect, flags, overflowAreas);
-  }
-
-  if (mFrames.NotEmpty()) {
-    ConsiderChildOverflow(aDesiredSize.mOverflowAreas, mFrames.FirstChild());
-  }
-
-  // If we were dirty then do a repaint
-  if (GetStateBits() & NS_FRAME_IS_DIRTY) {
-    InvalidateFrame();
-  }
-
-  // Clipping is handled by the document container (e.g., nsSubDocumentFrame),
-  // so we don't need to change our overflow areas.
-  bool overflowChanged = FinishAndStoreOverflow(&aDesiredSize);
-  if (overflowChanged) {
-    // We may need to alert our container to get it to pick up the
-    // overflow change.
-    nsSubDocumentFrame* container = static_cast<nsSubDocumentFrame*>
-      (nsLayoutUtils::GetCrossDocParentFrame(this));
-    if (container && !container->ShouldClipSubdocument()) {
-      container->PresContext()->PresShell()->
-        FrameNeedsReflow(container, nsIPresShell::eResize, NS_FRAME_IS_DIRTY);
-    }
-  }
-
-  NS_FRAME_TRACE_REFLOW_OUT("ViewportFrame::Reflow", aStatus);
-  NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize);
-}
-
-bool
-ViewportFrame::ComputeCustomOverflow(nsOverflowAreas& aOverflowAreas)
-{
-  nsIScrollableFrame* rootScrollFrame =
-    PresContext()->PresShell()->GetRootScrollFrameAsScrollable();
-  if (rootScrollFrame && !rootScrollFrame->IsIgnoringViewportClipping()) {
-    return false;
-  }
-
-  return nsContainerFrame::ComputeCustomOverflow(aOverflowAreas);
-}
-
-nsIAtom*
-ViewportFrame::GetType() const
-{
-  return nsGkAtoms::viewportFrame;
-}
-
-#ifdef DEBUG_FRAME_DUMP
-nsresult
-ViewportFrame::GetFrameName(nsAString& aResult) const
-{
-  return MakeFrameName(NS_LITERAL_STRING("Viewport"), aResult);
-}
-#endif
deleted file mode 100644
--- a/layout/generic/nsViewportFrame.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/* -*- 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/. */
-
-/*
- * rendering object that is the root of the frame tree, which contains
- * the document's scrollbars and contains fixed-positioned elements
- */
-
-#ifndef nsViewportFrame_h___
-#define nsViewportFrame_h___
-
-#include "mozilla/Attributes.h"
-#include "nsContainerFrame.h"
-
-class nsPresContext;
-
-namespace mozilla {
-
-/**
-  * ViewportFrame is the parent of a single child - the doc root frame or a scroll frame
-  * containing the doc root frame. ViewportFrame stores this child in its primary child
-  * list.
-  */
-class ViewportFrame : public nsContainerFrame {
-public:
-  NS_DECL_QUERYFRAME_TARGET(ViewportFrame)
-  NS_DECL_QUERYFRAME
-  NS_DECL_FRAMEARENA_HELPERS
-
-  explicit ViewportFrame(nsStyleContext* aContext)
-    : nsContainerFrame(aContext)
-  {}
-  virtual ~ViewportFrame() { } // useful for debugging
-
-  virtual void Init(nsIContent*       aContent,
-                    nsContainerFrame* aParent,
-                    nsIFrame*         aPrevInFlow) override;
-
-  virtual mozilla::WritingMode GetWritingMode() const override
-  {
-    nsIFrame* firstChild = mFrames.FirstChild();
-    if (firstChild) {
-      return firstChild->GetWritingMode();
-    }
-    return nsIFrame::GetWritingMode();
-  }
-
-#ifdef DEBUG
-  virtual void AppendFrames(ChildListID     aListID,
-                            nsFrameList&    aFrameList) override;
-  virtual void InsertFrames(ChildListID     aListID,
-                            nsIFrame*       aPrevFrame,
-                            nsFrameList&    aFrameList) override;
-  virtual void RemoveFrame(ChildListID     aListID,
-                           nsIFrame*       aOldFrame) override;
-#endif
-
-  virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
-                                const nsRect&           aDirtyRect,
-                                const nsDisplayListSet& aLists) override;
-
-  void BuildDisplayListForTopLayer(nsDisplayListBuilder* aBuilder,
-                                   nsDisplayList* aList);
-
-  virtual nscoord GetMinISize(nsRenderingContext *aRenderingContext) override;
-  virtual nscoord GetPrefISize(nsRenderingContext *aRenderingContext) override;
-  virtual void Reflow(nsPresContext*           aPresContext,
-                      ReflowOutput&     aDesiredSize,
-                      const ReflowInput& aReflowInput,
-                      nsReflowStatus&          aStatus) override;
-
-  /**
-   * Get the "type" of the frame
-   *
-   * @see nsGkAtoms::viewportFrame
-   */
-  virtual nsIAtom* GetType() const override;
-
-  virtual bool ComputeCustomOverflow(nsOverflowAreas& aOverflowAreas) override;
-
-  /**
-   * Adjust aReflowInput to account for scrollbars and pres shell
-   * GetScrollPositionClampingScrollPortSizeSet and
-   * GetContentDocumentFixedPositionMargins adjustments.
-   * @return the rect to use as containing block rect
-   */
-  nsRect AdjustReflowInputAsContainingBlock(ReflowInput* aReflowInput) const;
-
-#ifdef DEBUG_FRAME_DUMP
-  virtual nsresult GetFrameName(nsAString& aResult) const override;
-#endif
-
-private:
-  virtual mozilla::layout::FrameChildListID GetAbsoluteListID() const override { return kFixedList; }
-
-protected:
-  /**
-   * Calculate how much room is available for fixed frames. That means
-   * determining if the viewport is scrollable and whether the vertical and/or
-   * horizontal scrollbars are visible.  Adjust the computed width/height and
-   * available width for aReflowInput accordingly.
-   * @return the current scroll position, or 0,0 if not scrollable
-   */
-  nsPoint AdjustReflowInputForScrollbars(ReflowInput* aReflowInput) const;
-};
-
-} // namespace mozilla
-
-#endif // nsViewportFrame_h___
--- a/layout/ipc/RenderFrameParent.cpp
+++ b/layout/ipc/RenderFrameParent.cpp
@@ -9,32 +9,32 @@
 
 #include "BasicLayers.h"
 #include "gfxPrefs.h"
 #ifdef MOZ_ENABLE_D3D9_LAYER
 # include "LayerManagerD3D9.h"
 #endif //MOZ_ENABLE_D3D9_LAYER
 #include "mozilla/BrowserElementParent.h"
 #include "mozilla/EventForwards.h"  // for Modifiers
+#include "mozilla/ViewportFrame.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/TabChild.h"
 #include "mozilla/dom/TabParent.h"
 #include "mozilla/layers/APZCTreeManager.h"
 #include "mozilla/layers/APZThreadUtils.h"
 #include "mozilla/layers/CompositorBridgeParent.h"
 #include "mozilla/layers/LayerTransactionParent.h"
 #include "nsContentUtils.h"
 #include "nsFocusManager.h"
 #include "nsFrameLoader.h"
 #include "nsIObserver.h"
 #include "nsStyleStructInlines.h"
 #include "nsSubDocumentFrame.h"
 #include "nsView.h"
-#include "nsViewportFrame.h"
 #include "RenderFrameParent.h"
 #include "mozilla/gfx/GPUProcessManager.h"
 #include "mozilla/layers/LayerManagerComposite.h"
 #include "mozilla/layers/CompositorBridgeChild.h"
 #include "ClientLayerManager.h"
 #include "FrameLayerBuilder.h"
 
 using namespace mozilla::dom;
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -37,17 +37,16 @@
 #include "nsIFrameInlines.h"
 #include "nsThemeConstants.h"
 #include "BorderConsts.h"
 #include "LayerTreeInvalidation.h"
 
 #include "imgIContainer.h"
 #include "BasicLayers.h"
 #include "nsBoxFrame.h"
-#include "nsViewportFrame.h"
 #include "nsSubDocumentFrame.h"
 #include "nsSVGEffects.h"
 #include "nsSVGElement.h"
 #include "nsSVGClipPathFrame.h"
 #include "GeckoProfiler.h"
 #include "nsViewManager.h"
 #include "ImageLayers.h"
 #include "ImageContainer.h"
@@ -60,16 +59,17 @@
 #include "mozilla/EventStates.h"
 #include "mozilla/LookAndFeel.h"
 #include "mozilla/OperatorNewExtensions.h"
 #include "mozilla/PendingAnimationTracker.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/Unused.h"
+#include "mozilla/ViewportFrame.h"
 #include "mozilla/gfx/gfxVars.h"
 #include "ActiveLayerTracker.h"
 #include "nsContentUtils.h"
 #include "nsPrintfCString.h"
 #include "UnitTransforms.h"
 #include "LayersLogging.h"
 #include "FrameLayerBuilder.h"
 #include "mozilla/EventStateManager.h"