Bug 1540015 - part 3: Rename Document::GetShell() to Document::GetPresShell() and make it return PresShell* rather than nsIPresShell* r=smaug,emilio
☠☠ backed out by 5d97989d4f0d ☠ ☠
authorMasayuki Nakano <masayuki@d-toybox.com>
Fri, 29 Mar 2019 13:09:26 +0000
changeset 466751 7b71c9da0214e43368ab5cfb95344ca5ae13d670
parent 466750 5723ddbc5c44979b0c6dfae7d7989f4f532d8913
child 466752 253bab8dbd5a24eef1938a742e010a63016a8807
push id35780
push useropoprus@mozilla.com
push dateFri, 29 Mar 2019 21:53:01 +0000
treeherdermozilla-central@414f37afbe07 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug, emilio
bugs1540015
milestone68.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 1540015 - part 3: Rename Document::GetShell() to Document::GetPresShell() and make it return PresShell* rather than nsIPresShell* r=smaug,emilio This makes `Document::GetShell()` return `PresShell*` instead of `nsIPresShell`. Additonally, "shell" is unclear ("docshell" vs. "presshell"). Therefore, this also renames `Document::GetShell()` to `Document::GetPresShell()`. Similarly, some other method names of `Document` are also renamed from `*Shell*` to `*PresShell*`. Differential Revision: https://phabricator.services.mozilla.com/D25338
accessible/base/DocManager.cpp
accessible/base/DocManager.h
accessible/base/Logging.cpp
accessible/base/nsAccessibilityService.cpp
accessible/base/nsCoreUtils.cpp
accessible/base/nsCoreUtils.h
accessible/generic/DocAccessible.cpp
chrome/nsChromeRegistry.cpp
docshell/base/nsDocShell.cpp
dom/animation/KeyframeEffect.cpp
dom/animation/KeyframeEffect.h
dom/animation/PendingAnimationTracker.cpp
dom/base/AnonymousContent.cpp
dom/base/DOMIntersectionObserver.cpp
dom/base/Document.cpp
dom/base/Document.h
dom/base/DocumentInlines.h
dom/base/DocumentOrShadowRoot.cpp
dom/base/Element.cpp
dom/base/FragmentOrElement.cpp
dom/base/ResponsiveImageSelector.cpp
dom/base/ShadowRoot.cpp
dom/base/nsContentSink.cpp
dom/base/nsContentUtils.cpp
dom/base/nsContentUtils.h
dom/base/nsCopySupport.cpp
dom/base/nsDOMWindowUtils.cpp
dom/base/nsFocusManager.cpp
dom/base/nsFrameLoader.cpp
dom/base/nsGlobalWindowInner.cpp
dom/base/nsJSEnvironment.cpp
dom/base/nsNodeUtils.cpp
dom/base/nsObjectLoadingContent.cpp
dom/base/nsRange.cpp
dom/canvas/CanvasRenderingContext2D.h
dom/canvas/nsICanvasRenderingContextInternal.h
dom/events/ContentEventHandler.cpp
dom/events/EventListenerManager.cpp
dom/events/EventStateManager.cpp
dom/events/IMEStateManager.cpp
dom/events/PointerEventHandler.cpp
dom/html/ImageDocument.cpp
dom/html/MediaDocument.cpp
dom/html/PluginDocument.cpp
dom/html/nsHTMLDocument.cpp
dom/html/nsTextEditorState.cpp
dom/ipc/TabChild.cpp
dom/ipc/TabParent.cpp
dom/prototype/PrototypeDocumentContentSink.cpp
dom/smil/SMILAnimationController.cpp
dom/svg/SVGContentUtils.cpp
dom/svg/SVGElement.cpp
dom/svg/SVGSVGElement.cpp
dom/xbl/XBLChildrenElement.cpp
dom/xbl/nsBindingManager.cpp
dom/xbl/nsXBLPrototypeResources.cpp
dom/xbl/nsXBLResourceLoader.cpp
dom/xbl/nsXBLService.cpp
dom/xul/nsXULElement.cpp
editor/libeditor/EditorBase.h
gfx/layers/apz/src/FocusTarget.cpp
gfx/layers/apz/util/APZCCallbackHelper.cpp
gfx/layers/apz/util/ActiveElementManager.cpp
gfx/layers/apz/util/ChromeProcessController.cpp
gfx/layers/apz/util/ContentProcessController.cpp
gfx/layers/apz/util/DoubleTapToZoom.cpp
layout/base/AccessibleCaretManager.cpp
layout/base/GeometryUtils.cpp
layout/base/PresShell.cpp
layout/base/PresShell.h
layout/base/TouchManager.cpp
layout/base/nsDocumentViewer.cpp
layout/base/nsIPresShellInlines.h
layout/base/nsLayoutUtils.cpp
layout/base/nsPresContext.cpp
layout/generic/nsFrame.cpp
layout/generic/nsSubDocumentFrame.cpp
layout/inspector/InspectorUtils.cpp
layout/painting/RetainedDisplayListBuilder.cpp
layout/painting/nsDisplayList.cpp
layout/printing/nsPrintJob.cpp
layout/style/FontFaceSet.cpp
layout/style/ServoStyleSet.cpp
layout/style/StyleAnimationValue.cpp
layout/style/nsComputedDOMStyle.cpp
layout/style/nsHTMLStyleSheet.cpp
layout/xul/BoxObject.cpp
layout/xul/nsXULPopupManager.cpp
layout/xul/nsXULTooltipListener.cpp
servo/components/style/gecko/media_queries.rs
toolkit/components/find/nsWebBrowserFind.cpp
toolkit/components/sessionstore/SessionStoreUtils.cpp
toolkit/components/typeaheadfind/nsTypeAheadFind.cpp
uriloader/base/nsDocLoader.cpp
widget/android/GeckoSystemStateListener.h
widget/cocoa/nsDragService.mm
widget/gtk/nsDragService.cpp
widget/nsBaseDragService.cpp
--- a/accessible/base/DocManager.cpp
+++ b/accessible/base/DocManager.cpp
@@ -17,16 +17,17 @@
 #include "xpcAccessibleDocument.h"
 
 #ifdef A11Y_LOG
 #  include "Logging.h"
 #endif
 
 #include "mozilla/Components.h"
 #include "mozilla/EventListenerManager.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/dom/Event.h"  // for Event
 #include "nsContentUtils.h"
 #include "nsDocShellLoadTypes.h"
 #include "nsIChannel.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIWebNavigation.h"
 #include "nsServiceManagerUtils.h"
 #include "nsIWebProgress.h"
@@ -432,18 +433,20 @@ DocAccessible* DocManager::CreateDocOrRo
   }
 
   nsIWidget* widget = nsContentUtils::WidgetForDocument(aDocument);
   if (!widget || widget->WindowType() == eWindowType_invisible) {
     return nullptr;
   }
 
   // Ignore documents without presshell and not having root frame.
-  nsIPresShell* presShell = aDocument->GetShell();
-  if (!presShell || presShell->IsDestroying()) return nullptr;
+  PresShell* presShell = aDocument->GetPresShell();
+  if (!presShell || presShell->IsDestroying()) {
+    return nullptr;
+  }
 
   bool isRootDoc = nsCoreUtils::IsRootDocument(aDocument);
 
   DocAccessible* parentDocAcc = nullptr;
   if (!isRootDoc) {
     // XXXaaronl: ideally we would traverse the presshell chain. Since there's
     // no easy way to do that, we cheat and use the document hierarchy.
     parentDocAcc = GetDocAccessible(aDocument->GetParentDocument());
--- a/accessible/base/DocManager.h
+++ b/accessible/base/DocManager.h
@@ -1,16 +1,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_a11_DocManager_h_
 #define mozilla_a11_DocManager_h_
 
 #include "mozilla/ClearOnShutdown.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/dom/Document.h"
 #include "nsIDOMEventListener.h"
 #include "nsRefPtrHashtable.h"
 #include "nsIWebProgressListener.h"
 #include "nsWeakReference.h"
 #include "nsIPresShell.h"
 #include "mozilla/StaticPtr.h"
 
@@ -178,16 +179,16 @@ class DocManager : public nsIWebProgress
 };
 
 /**
  * Return the existing document accessible for the document if any.
  * Note this returns the doc accessible for the primary pres shell if there is
  * more than one.
  */
 inline DocAccessible* GetExistingDocAccessible(const dom::Document* aDocument) {
-  nsIPresShell* ps = aDocument->GetShell();
-  return ps ? ps->GetDocAccessible() : nullptr;
+  PresShell* presShell = aDocument->GetPresShell();
+  return presShell ? presShell->GetDocAccessible() : nullptr;
 }
 
 }  // namespace a11y
 }  // namespace mozilla
 
 #endif  // mozilla_a11_DocManager_h_
--- a/accessible/base/Logging.cpp
+++ b/accessible/base/Logging.cpp
@@ -17,16 +17,17 @@
 #include "nsIChannel.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsISelectionController.h"
 #include "nsTraceRefcnt.h"
 #include "nsIWebProgress.h"
 #include "prenv.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsIURI.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/HTMLBodyElement.h"
 #include "mozilla/dom/Selection.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -159,23 +160,23 @@ static void LogDocState(dom::Document* a
   dom::Element* rootEl = aDocumentNode->GetBodyElement();
   if (!rootEl) {
     rootEl = aDocumentNode->GetRootElement();
   }
   printf(", has %srole content", rootEl ? "" : "no ");
 }
 
 static void LogPresShell(dom::Document* aDocumentNode) {
-  nsIPresShell* ps = aDocumentNode->GetShell();
-  printf("presshell: %p", static_cast<void*>(ps));
+  PresShell* presShell = aDocumentNode->GetPresShell();
+  printf("presshell: %p", static_cast<void*>(presShell));
 
   nsIScrollableFrame* sf = nullptr;
-  if (ps) {
-    printf(", is %s destroying", (ps->IsDestroying() ? "" : "not"));
-    sf = ps->GetRootScrollFrameAsScrollable();
+  if (presShell) {
+    printf(", is %s destroying", (presShell->IsDestroying() ? "" : "not"));
+    sf = presShell->GetRootScrollFrameAsScrollable();
   }
   printf(", root scroll frame: %p", static_cast<void*>(sf));
 }
 
 static void LogDocLoadGroup(dom::Document* aDocumentNode) {
   nsCOMPtr<nsILoadGroup> loadGroup = aDocumentNode->GetDocumentLoadGroup();
   printf("load group: %p", static_cast<void*>(loadGroup));
 }
--- a/accessible/base/nsAccessibilityService.cpp
+++ b/accessible/base/nsAccessibilityService.cpp
@@ -67,16 +67,17 @@
 #include "nsTreeUtils.h"
 #include "nsXBLPrototypeBinding.h"
 #include "nsXBLBinding.h"
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/dom/DOMStringList.h"
 #include "mozilla/dom/EventTarget.h"
 #include "mozilla/dom/HTMLTableElement.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/Services.h"
 #include "nsDeckFrame.h"
 
 #ifdef MOZ_XUL
 #  include "XULAlertAccessible.h"
 #  include "XULComboboxAccessible.h"
 #  include "XULElementAccessibles.h"
 #  include "XULFormControlAccessible.h"
@@ -367,19 +368,19 @@ class PluginTimerCallBack final : public
  public:
   explicit PluginTimerCallBack(nsIContent* aContent) : mContent(aContent) {}
 
   NS_DECL_ISUPPORTS
 
   NS_IMETHOD Notify(nsITimer* aTimer) final {
     if (!mContent->IsInUncomposedDoc()) return NS_OK;
 
-    nsIPresShell* ps = mContent->OwnerDoc()->GetShell();
-    if (ps) {
-      DocAccessible* doc = ps->GetDocAccessible();
+    PresShell* presShell = mContent->OwnerDoc()->GetPresShell();
+    if (presShell) {
+      DocAccessible* doc = presShell->GetDocAccessible();
       if (doc) {
         // Make sure that if we created an accessible for the plugin that wasn't
         // a plugin accessible we remove it before creating the right
         // accessible.
         doc->RecreateAccessible(mContent);
         sPluginTimers->RemoveElement(aTimer);
         return NS_OK;
       }
--- a/accessible/base/nsCoreUtils.cpp
+++ b/accessible/base/nsCoreUtils.cpp
@@ -9,26 +9,26 @@
 
 #include "nsIBaseWindow.h"
 #include "nsIDocShellTreeOwner.h"
 #include "mozilla/dom/Document.h"
 #include "nsRange.h"
 #include "nsXULElement.h"
 #include "nsIDocShell.h"
 #include "nsIObserverService.h"
-#include "nsIPresShell.h"
 #include "nsPresContext.h"
 #include "nsIScrollableFrame.h"
 #include "nsISelectionController.h"
 #include "nsISimpleEnumerator.h"
 #include "mozilla/dom/TouchEvent.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/EventListenerManager.h"
 #include "mozilla/EventStateManager.h"
 #include "mozilla/MouseEvents.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/TouchEvents.h"
 #include "nsView.h"
 #include "nsGkAtoms.h"
 
 #include "nsComponentManagerUtils.h"
 
 #include "XULTreeElement.h"
 #include "nsTreeColumns.h"
@@ -65,18 +65,20 @@ void nsCoreUtils::DispatchClickEvent(XUL
                                      nsTreeColumn *aColumn,
                                      const nsAString &aPseudoElt) {
   RefPtr<dom::Element> tcElm = aTree->GetTreeBody();
   if (!tcElm) return;
 
   Document *document = tcElm->GetUncomposedDoc();
   if (!document) return;
 
-  nsCOMPtr<nsIPresShell> presShell = document->GetShell();
-  if (!presShell) return;
+  RefPtr<PresShell> presShell = document->GetPresShell();
+  if (!presShell) {
+    return;
+  }
 
   // Ensure row is visible.
   aTree->EnsureRowIsVisible(aRowIndex);
 
   // Calculate x and y coordinates.
   nsresult rv;
   nsIntRect rect =
       aTree->GetCoordsForCellItem(aRowIndex, aColumn, aPseudoElt, rv);
--- a/accessible/base/nsCoreUtils.h
+++ b/accessible/base/nsCoreUtils.h
@@ -2,21 +2,21 @@
 /* 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 nsCoreUtils_h_
 #define nsCoreUtils_h_
 
 #include "mozilla/EventForwards.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/dom/Element.h"
 #include "nsIAccessibleEvent.h"
 #include "nsIContent.h"
-#include "mozilla/dom/Document.h"  // for GetShell()
-#include "nsIPresShell.h"
+#include "mozilla/dom/Document.h"  // for GetPresShell()
 
 #include "nsPoint.h"
 #include "nsTArray.h"
 
 class nsRange;
 class nsTreeColumn;
 class nsIFrame;
 class nsIDocShell;
@@ -208,17 +208,17 @@ class nsCoreUtils {
    * Return true if the given document is an error page.
    */
   static bool IsErrorPage(Document *aDocument);
 
   /**
    * Return presShell for the document containing the given DOM node.
    */
   static nsIPresShell *GetPresShellFor(nsINode *aNode) {
-    return aNode->OwnerDoc()->GetShell();
+    return aNode->OwnerDoc()->GetPresShell();
   }
 
   /**
    * Get the ID for an element, in some types of XML this may not be the ID
    * attribute
    * @param aContent  Node to get the ID for
    * @param aID       Where to put ID string
    * @return          true if there is an ID set for this node
--- a/accessible/generic/DocAccessible.cpp
+++ b/accessible/generic/DocAccessible.cpp
@@ -25,29 +25,29 @@
 #include "nsIDocShell.h"
 #include "mozilla/dom/Document.h"
 #include "nsPIDOMWindow.h"
 #include "nsIEditingSession.h"
 #include "nsIFrame.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsImageFrame.h"
 #include "nsIPersistentProperties2.h"
-#include "nsIPresShell.h"
 #include "nsIServiceManager.h"
 #include "nsViewManager.h"
 #include "nsIScrollableFrame.h"
 #include "nsUnicharUtils.h"
 #include "nsIURI.h"
 #include "nsIWebNavigation.h"
 #include "nsFocusManager.h"
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/EventStateManager.h"
 #include "mozilla/EventStates.h"
 #include "mozilla/HTMLEditor.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/TextEditor.h"
 #include "mozilla/dom/TabChild.h"
 #include "mozilla/dom/DocumentType.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/MutationEventBinding.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
@@ -461,18 +461,20 @@ nsIFrame* DocAccessible::GetFrame() cons
 nsRect DocAccessible::RelativeBounds(nsIFrame** aRelativeFrame) const {
   *aRelativeFrame = GetFrame();
 
   dom::Document* document = mDocumentNode;
   dom::Document* parentDoc = nullptr;
 
   nsRect bounds;
   while (document) {
-    nsIPresShell* presShell = document->GetShell();
-    if (!presShell) return nsRect();
+    mozilla::PresShell* presShell = document->GetPresShell();
+    if (!presShell) {
+      return nsRect();
+    }
 
     nsRect scrollPort;
     nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
     if (sf) {
       scrollPort = sf->GetScrollPortRect();
     } else {
       nsIFrame* rootFrame = presShell->GetRootFrame();
       if (!rootFrame) return nsRect();
--- a/chrome/nsChromeRegistry.cpp
+++ b/chrome/nsChromeRegistry.cpp
@@ -16,33 +16,34 @@
 #include "nsQueryObject.h"
 
 #include "mozilla/dom/URL.h"
 #include "nsDOMWindowList.h"
 #include "nsIConsoleService.h"
 #include "mozilla/dom/Document.h"
 #include "nsIDOMWindow.h"
 #include "nsIObserverService.h"
-#include "nsIPresShell.h"
 #include "nsIScriptError.h"
 #include "nsIWindowMediator.h"
 #include "nsIPrefService.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/Printf.h"
 #include "mozilla/StyleSheet.h"
 #include "mozilla/StyleSheetInlines.h"
 #include "mozilla/dom/Location.h"
 #include "nsIURIMutator.h"
 
 #include "unicode/uloc.h"
 
 nsChromeRegistry* nsChromeRegistry::gChromeRegistry;
 
 // DO NOT use namespace mozilla; it'll break due to a naming conflict between
 // mozilla::TextRange and a TextRange in OSX headers.
+using mozilla::PresShell;
 using mozilla::StyleSheet;
 using mozilla::dom::Document;
 using mozilla::dom::IsChromeURI;
 using mozilla::dom::Location;
 
 ////////////////////////////////////////////////////////////////////////////////
 
 void nsChromeRegistry::LogMessage(const char* aMsg, ...) {
@@ -339,21 +340,21 @@ nsresult nsChromeRegistry::RefreshWindow
   }
 
   nsresult rv;
   // Get the document.
   RefPtr<Document> document = aWindow->GetDoc();
   if (!document) return NS_OK;
 
   // Deal with the agent sheets first.  Have to do all the style sets by hand.
-  nsCOMPtr<nsIPresShell> shell = document->GetShell();
-  if (shell) {
+  RefPtr<PresShell> presShell = document->GetPresShell();
+  if (presShell) {
     // Reload only the chrome URL agent style sheets.
     nsTArray<RefPtr<StyleSheet>> agentSheets;
-    rv = shell->GetAgentStyleSheets(agentSheets);
+    rv = presShell->GetAgentStyleSheets(agentSheets);
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsTArray<RefPtr<StyleSheet>> newAgentSheets;
     for (StyleSheet* sheet : agentSheets) {
       nsIURI* uri = sheet->GetSheetURI();
 
       if (IsChromeURI(uri)) {
         // Reload the sheet.
@@ -365,17 +366,17 @@ nsresult nsChromeRegistry::RefreshWindow
           return NS_OK;
         }
       } else {  // Just use the same sheet.
         rv = newAgentSheets.AppendElement(sheet) ? NS_OK : NS_ERROR_FAILURE;
         if (NS_FAILED(rv)) return rv;
       }
     }
 
-    rv = shell->SetAgentStyleSheets(newAgentSheets);
+    rv = presShell->SetAgentStyleSheets(newAgentSheets);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   size_t count = document->SheetCount();
 
   // Build an array of style sheets we need to reload.
   nsTArray<RefPtr<StyleSheet>> oldSheets(count);
   nsTArray<RefPtr<StyleSheet>> newSheets(count);
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -23,16 +23,17 @@
 #include "mozilla/Components.h"
 #include "mozilla/Encoding.h"
 #include "mozilla/EventStateManager.h"
 #include "mozilla/HTMLEditor.h"
 #include "mozilla/LoadInfo.h"
 #include "mozilla/Logging.h"
 #include "mozilla/MediaFeatureChange.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/ResultExtensions.h"
 #include "mozilla/ScrollTypes.h"
 #include "mozilla/Services.h"
 #include "mozilla/StaticPrefs.h"
 #include "mozilla/StartupTimeline.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/Unused.h"
 #include "mozilla/WidgetUtils.h"
@@ -7873,18 +7874,19 @@ nsresult nsDocShell::RestoreFromHistory(
   // Insert the new root view at the correct location in the view tree.
   if (container) {
     nsSubDocumentFrame* subDocFrame =
         do_QueryFrame(container->GetPrimaryFrame());
     rootViewParent = subDocFrame ? subDocFrame->EnsureInnerView() : nullptr;
   } else {
     rootViewParent = nullptr;
   }
-  if (sibling && sibling->GetShell() && sibling->GetShell()->GetViewManager()) {
-    rootViewSibling = sibling->GetShell()->GetViewManager()->GetRootView();
+  if (sibling && sibling->GetPresShell() &&
+      sibling->GetPresShell()->GetViewManager()) {
+    rootViewSibling = sibling->GetPresShell()->GetViewManager()->GetRootView();
   } else {
     rootViewSibling = nullptr;
   }
   if (rootViewParent && newRootView &&
       newRootView->GetParent() != rootViewParent) {
     nsViewManager* parentVM = rootViewParent->GetViewManager();
     if (parentVM) {
       // InsertChild(parent, child, sib, true) inserts the child after
--- a/dom/animation/KeyframeEffect.cpp
+++ b/dom/animation/KeyframeEffect.cpp
@@ -15,28 +15,28 @@
 #include "mozilla/AnimationUtils.h"
 #include "mozilla/AutoRestore.h"
 #include "mozilla/ComputedStyleInlines.h"
 #include "mozilla/EffectSet.h"
 #include "mozilla/FloatingPoint.h"  // For IsFinite
 #include "mozilla/LayerAnimationInfo.h"
 #include "mozilla/LookAndFeel.h"  // For LookAndFeel::GetInt
 #include "mozilla/KeyframeUtils.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/ServoBindings.h"
 #include "mozilla/StaticPrefs.h"
 #include "mozilla/TypeTraits.h"
 #include "Layers.h"              // For Layer
 #include "nsComputedDOMStyle.h"  // nsComputedDOMStyle::GetComputedStyle
 #include "nsContentUtils.h"
 #include "nsCSSPropertyIDSet.h"
 #include "nsCSSProps.h"             // For nsCSSProps::PropHasFlags
 #include "nsCSSPseudoElements.h"    // For PseudoStyleType
 #include "nsDOMMutationObserver.h"  // For nsAutoAnimationMutationBatch
 #include "nsIFrame.h"
-#include "nsIPresShell.h"
 #include "nsIScriptError.h"
 #include "nsPresContextInlines.h"
 #include "nsRefreshDriver.h"
 
 namespace mozilla {
 
 void AnimationProperty::SetPerformanceWarning(
     const AnimationPerformanceWarning& aWarning, const Element* aElement) {
@@ -1202,17 +1202,17 @@ KeyframeEffect::OverflowRegionRefreshInt
 bool KeyframeEffect::CanThrottleIfNotVisible(nsIFrame& aFrame) const {
   // Unless we are newly in-effect, we can throttle the animation if the
   // animation is paint only and the target frame is out of view or the document
   // is in background tabs.
   if (!mInEffectOnLastAnimationTimingUpdate || !CanIgnoreIfNotVisible()) {
     return false;
   }
 
-  nsIPresShell* presShell = GetPresShell();
+  PresShell* presShell = GetPresShell();
   if (presShell && !presShell->IsActive()) {
     return true;
   }
 
   const bool isVisibilityHidden =
       !aFrame.IsVisibleOrMayHaveVisibleDescendants();
   if ((!isVisibilityHidden || HasVisibilityChange()) &&
       !aFrame.IsScrolledOutOfView()) {
@@ -1404,22 +1404,22 @@ nsIFrame* KeyframeEffect::GetPrimaryFram
 
 Document* KeyframeEffect::GetRenderedDocument() const {
   if (!mTarget) {
     return nullptr;
   }
   return mTarget->mElement->GetComposedDoc();
 }
 
-nsIPresShell* KeyframeEffect::GetPresShell() const {
+PresShell* KeyframeEffect::GetPresShell() const {
   Document* doc = GetRenderedDocument();
   if (!doc) {
     return nullptr;
   }
-  return doc->GetShell();
+  return doc->GetPresShell();
 }
 
 /* static */
 bool KeyframeEffect::IsGeometricProperty(const nsCSSPropertyID aProperty) {
   MOZ_ASSERT(!nsCSSProps::IsShorthand(aProperty),
              "Property should be a longhand property");
 
   switch (aProperty) {
--- a/dom/animation/KeyframeEffect.h
+++ b/dom/animation/KeyframeEffect.h
@@ -29,27 +29,27 @@
 #include "mozilla/dom/AnimationEffect.h"
 #include "mozilla/dom/BindingDeclarations.h"
 #include "mozilla/dom/Element.h"
 
 struct JSContext;
 class JSObject;
 class nsIContent;
 class nsIFrame;
-class nsIPresShell;
 
 namespace mozilla {
 
 class AnimValuesStyleRule;
 enum class PseudoStyleType : uint8_t;
 class ErrorResult;
 struct AnimationRule;
 struct TimingParams;
 class EffectSet;
 class ComputedStyle;
+class PresShell;
 
 namespace dom {
 class ElementOrCSSPseudoElement;
 class GlobalObject;
 class OwningElementOrCSSPseudoElement;
 class UnrestrictedDoubleOrKeyframeAnimationOptions;
 class UnrestrictedDoubleOrKeyframeEffectOptions;
 enum class IterationCompositeOperation : uint8_t;
@@ -278,17 +278,17 @@ class KeyframeEffect : public AnimationE
       const nsIFrame* aFrame,
       AnimationPerformanceWarning::Type& aPerformanceWarning /* out */) const;
   bool HasGeometricProperties() const;
   bool AffectsGeometry() const override {
     return GetTarget() && HasGeometricProperties();
   }
 
   Document* GetRenderedDocument() const;
-  nsIPresShell* GetPresShell() const;
+  PresShell* GetPresShell() const;
 
   // Associates a warning with the animated property set on the specified frame
   // indicating why, for example, the property could not be animated on the
   // compositor. |aParams| and |aParamsLength| are optional parameters which
   // will be used to generate a localized message for devtools.
   void SetPerformanceWarning(const nsCSSPropertyIDSet& aPropertySet,
                              const AnimationPerformanceWarning& aWarning);
 
--- a/dom/animation/PendingAnimationTracker.cpp
+++ b/dom/animation/PendingAnimationTracker.cpp
@@ -1,20 +1,20 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 "PendingAnimationTracker.h"
 
+#include "mozilla/PresShell.h"
 #include "mozilla/dom/AnimationTimeline.h"
 #include "mozilla/dom/Nullable.h"
 #include "nsIFrame.h"
-#include "nsIPresShell.h"
 #include "nsTransitionManager.h"  // For CSSTransition
 
 using mozilla::dom::Nullable;
 
 namespace mozilla {
 
 NS_IMPL_CYCLE_COLLECTION(PendingAnimationTracker, mPlayPendingSet,
                          mPausePendingSet, mDocument)
@@ -168,17 +168,17 @@ void PendingAnimationTracker::MarkAnimat
   }
 }
 
 void PendingAnimationTracker::EnsurePaintIsScheduled() {
   if (!mDocument) {
     return;
   }
 
-  nsIPresShell* presShell = mDocument->GetShell();
+  PresShell* presShell = mDocument->GetPresShell();
   if (!presShell) {
     return;
   }
 
   nsIFrame* rootFrame = presShell->GetRootFrame();
   if (!rootFrame) {
     return;
   }
--- a/dom/base/AnonymousContent.cpp
+++ b/dom/base/AnonymousContent.cpp
@@ -1,20 +1,21 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 "AnonymousContent.h"
+#include "mozilla/PresShell.h"
+#include "mozilla/dom/Document.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/AnonymousContentBinding.h"
 #include "nsComputedDOMStyle.h"
 #include "nsCycleCollectionParticipant.h"
-#include "mozilla/dom/Document.h"
 #include "nsIFrame.h"
 #include "nsStyledElement.h"
 #include "HTMLCanvasElement.h"
 
 namespace mozilla {
 namespace dom {
 
 // Ref counting and cycle collection
@@ -180,18 +181,17 @@ void AnonymousContent::GetComputedStyleP
     const nsAString& aElementId, const nsAString& aPropertyName,
     DOMString& aResult, ErrorResult& aRv) {
   Element* element = GetElementById(aElementId);
   if (!element) {
     aRv.Throw(NS_ERROR_NOT_AVAILABLE);
     return;
   }
 
-  nsIPresShell* shell = element->OwnerDoc()->GetShell();
-  if (!shell) {
+  if (!element->OwnerDoc()->GetPresShell()) {
     aRv.Throw(NS_ERROR_NOT_AVAILABLE);
     return;
   }
 
   RefPtr<nsComputedDOMStyle> cs =
       new nsComputedDOMStyle(element, NS_LITERAL_STRING(""),
                              element->OwnerDoc(), nsComputedDOMStyle::eAll);
   aRv = cs->GetPropertyValue(aPropertyName, aResult);
--- a/dom/base/DOMIntersectionObserver.cpp
+++ b/dom/base/DOMIntersectionObserver.cpp
@@ -4,16 +4,17 @@
  * 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 "DOMIntersectionObserver.h"
 #include "nsCSSPropertyID.h"
 #include "nsIFrame.h"
 #include "nsContentUtils.h"
 #include "nsLayoutUtils.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/ServoBindings.h"
 
 namespace mozilla {
 namespace dom {
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMIntersectionObserverEntry)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
@@ -247,17 +248,17 @@ void DOMIntersectionObserver::Update(Doc
         rootRectRelativeToRootFrame = rootFrame->GetRectRelativeToSelf();
       }
       nsIFrame* containingBlock =
           nsLayoutUtils::GetContainingBlockForClientRect(rootFrame);
       rootRect = nsLayoutUtils::TransformFrameRectToAncestor(
           rootFrame, rootRectRelativeToRootFrame, containingBlock);
     }
   } else {
-    nsCOMPtr<nsIPresShell> presShell = aDocument->GetShell();
+    RefPtr<PresShell> presShell = aDocument->GetPresShell();
     if (presShell) {
       rootFrame = presShell->GetRootScrollFrame();
       if (rootFrame) {
         nsPresContext* presContext = rootFrame->PresContext();
         while (!presContext->IsRootContentDocument()) {
           presContext = presContext->GetParentPresContext();
           if (!presContext) {
             break;
--- a/dom/base/Document.cpp
+++ b/dom/base/Document.cpp
@@ -2246,35 +2246,35 @@ already_AddRefed<nsIPrincipal> Document:
 }
 
 void Document::RemoveDocStyleSheetsFromStyleSets() {
   // The stylesheets should forget us
   for (StyleSheet* sheet : Reversed(mStyleSheets)) {
     sheet->ClearAssociatedDocumentOrShadowRoot();
 
     if (sheet->IsApplicable()) {
-      nsCOMPtr<nsIPresShell> shell = GetShell();
-      if (shell) {
-        shell->StyleSet()->RemoveDocStyleSheet(sheet);
+      RefPtr<PresShell> presShell = GetPresShell();
+      if (presShell) {
+        presShell->StyleSet()->RemoveDocStyleSheet(sheet);
       }
     }
     // XXX Tell observers?
   }
 }
 
 void Document::RemoveStyleSheetsFromStyleSets(
     const nsTArray<RefPtr<StyleSheet>>& aSheets, SheetType aType) {
   // The stylesheets should forget us
   for (StyleSheet* sheet : Reversed(aSheets)) {
     sheet->ClearAssociatedDocumentOrShadowRoot();
 
     if (sheet->IsApplicable()) {
-      nsCOMPtr<nsIPresShell> shell = GetShell();
-      if (shell) {
-        shell->StyleSet()->RemoveStyleSheet(aType, sheet);
+      RefPtr<PresShell> presShell = GetPresShell();
+      if (presShell) {
+        presShell->StyleSet()->RemoveStyleSheet(aType, sheet);
       }
     }
     // XXX Tell observers?
   }
 }
 
 void Document::ResetStylesheetsToURI(nsIURI* aURI) {
   MOZ_ASSERT(aURI);
@@ -2318,20 +2318,20 @@ void Document::ResetStylesheetsToURI(nsI
     mAttrStyleSheet = new nsHTMLStyleSheet(this);
   }
 
   if (!mStyleAttrStyleSheet) {
     mStyleAttrStyleSheet = new nsHTMLCSSStyleSheet();
   }
 
   // Now set up our style sets
-  if (nsIPresShell* shell = GetShell()) {
-    FillStyleSet(shell->StyleSet());
-    if (shell->StyleSet()->StyleSheetsHaveChanged()) {
-      shell->ApplicableStylesChanged();
+  if (PresShell* presShell = GetPresShell()) {
+    FillStyleSet(presShell->StyleSet());
+    if (presShell->StyleSet()->StyleSheetsHaveChanged()) {
+      presShell->ApplicableStylesChanged();
     }
   }
 }
 
 static void AppendSheetsToStyleSet(ServoStyleSet* aStyleSet,
                                    const nsTArray<RefPtr<StyleSheet>>& aSheets,
                                    SheetType aType) {
   for (StyleSheet* sheet : Reversed(aSheets)) {
@@ -3625,65 +3625,67 @@ static inline void AssertNoStaleServoDat
           AssertNoStaleServoDataIn(*child);
         }
       }
     }
   }
 #endif
 }
 
-already_AddRefed<nsIPresShell> Document::CreateShell(
+already_AddRefed<PresShell> Document::CreatePresShell(
     nsPresContext* aContext, nsViewManager* aViewManager,
     UniquePtr<ServoStyleSet> aStyleSet) {
   NS_ASSERTION(!mPresShell, "We have a presshell already!");
 
   NS_ENSURE_FALSE(GetBFCacheEntry(), nullptr);
 
   FillStyleSet(aStyleSet.get());
   AssertNoStaleServoDataIn(*this);
 
-  RefPtr<PresShell> shell = new PresShell;
+  RefPtr<PresShell> presShell = new PresShell;
   // Note: we don't hold a ref to the shell (it holds a ref to us)
-  mPresShell = shell;
-  shell->Init(this, aContext, aViewManager, std::move(aStyleSet));
+  mPresShell = presShell;
+  presShell->Init(this, aContext, aViewManager, std::move(aStyleSet));
 
   // Make sure to never paint if we belong to an invisible DocShell.
   nsCOMPtr<nsIDocShell> docShell(mDocumentContainer);
-  if (docShell && docShell->IsInvisible()) shell->SetNeverPainting(true);
+  if (docShell && docShell->IsInvisible()) {
+    presShell->SetNeverPainting(true);
+  }
 
   MOZ_LOG(gDocumentLeakPRLog, LogLevel::Debug,
-          ("DOCUMENT %p with PressShell %p and DocShell %p", this, shell.get(),
-           docShell.get()));
+          ("DOCUMENT %p with PressShell %p and DocShell %p", this,
+           presShell.get(), docShell.get()));
 
   mExternalResourceMap.ShowViewers();
 
   UpdateFrameRequestCallbackSchedulingState();
 
   // Now that we have a shell, we might have @font-face rules (the presence of a
   // shell may change which rules apply to us). We don't need to do anything
   // like EnsureStyleFlush or such, there's nothing to update yet and when stuff
   // is ready to update we'll flush the font set.
   MarkUserFontSetDirty();
 
-  return shell.forget();
+  return presShell.forget();
 }
 
 void Document::UpdateFrameRequestCallbackSchedulingState(
-    nsIPresShell* aOldShell) {
+    PresShell* aOldPresShell) {
   // If the condition for shouldBeScheduled changes to depend on some other
   // variable, add UpdateFrameRequestCallbackSchedulingState() calls to the
   // places where that variable can change.
   bool shouldBeScheduled = mPresShell && IsEventHandlingEnabled() &&
                            !mFrameRequestCallbacks.IsEmpty();
   if (shouldBeScheduled == mFrameRequestCallbacksScheduled) {
     // nothing to do
     return;
   }
 
-  nsIPresShell* presShell = aOldShell ? aOldShell : mPresShell;
+  PresShell* presShell = aOldPresShell ? aOldPresShell : mPresShell;
   MOZ_RELEASE_ASSERT(presShell);
 
   nsRefreshDriver* rd = presShell->GetPresContext()->RefreshDriver();
   if (shouldBeScheduled) {
     rd->ScheduleFrameRequestCallbacks(this);
   } else {
     rd->RevokeFrameRequestCallbacks(this);
   }
@@ -3733,36 +3735,36 @@ bool Document::ShouldThrottleFrameReques
     // platforms and is unlikely to be human-perceivable on non-APZ platforms.
     return true;
   }
 
   // We got painted during the last paint, so run at full speed.
   return false;
 }
 
-void Document::DeleteShell() {
+void Document::DeletePresShell() {
   mExternalResourceMap.HideViewers();
   if (nsPresContext* presContext = mPresShell->GetPresContext()) {
     presContext->RefreshDriver()->CancelPendingFullscreenEvents(this);
   }
 
   // When our shell goes away, request that all our images be immediately
   // discarded, so we don't carry around decoded image data for a document we
   // no longer intend to paint.
   ImageTracker()->RequestDiscardAll();
 
   // Now that we no longer have a shell, we need to forget about any FontFace
   // objects for @font-face rules that came from the style set. There's no need
   // to call EnsureStyleFlush either, the shell is going away anyway, so there's
   // no point on it.
   MarkUserFontSetDirty();
 
-  nsIPresShell* oldShell = mPresShell;
+  PresShell* oldPresShell = mPresShell;
   mPresShell = nullptr;
-  UpdateFrameRequestCallbackSchedulingState(oldShell);
+  UpdateFrameRequestCallbackSchedulingState(oldPresShell);
   mStyleSetFilled = false;
 
   ClearStaleServoData();
   AssertNoStaleServoDataIn(*this);
 }
 
 void Document::SetBFCacheEntry(nsIBFCacheEntry* aEntry) {
   MOZ_ASSERT(IsBFCachingAllowed() || !aEntry, "You should have checked!");
@@ -3947,19 +3949,19 @@ void Document::RemoveChildNode(nsIConten
   mCachedRootElement = nullptr;
   nsINode::RemoveChildNode(aKid, aNotify);
   MOZ_ASSERT(mCachedRootElement != aKid,
              "Stale pointer in mCachedRootElement, after we tried to clear it "
              "(maybe somebody called GetRootElement() too early?)");
 }
 
 void Document::AddStyleSheetToStyleSets(StyleSheet* aSheet) {
-  if (nsIPresShell* shell = GetShell()) {
-    shell->StyleSet()->AddDocStyleSheet(aSheet, this);
-    shell->ApplicableStylesChanged();
+  if (PresShell* presShell = GetPresShell()) {
+    presShell->StyleSet()->AddDocStyleSheet(aSheet, this);
+    presShell->ApplicableStylesChanged();
   }
 }
 
 #define DO_STYLESHEET_NOTIFICATION(className, type, memberName, argName) \
   do {                                                                   \
     className##Init init;                                                \
     init.mBubbles = true;                                                \
     init.mCancelable = true;                                             \
@@ -3987,19 +3989,19 @@ void Document::NotifyStyleSheetRemoved(S
                                        bool aDocumentSheet) {
   if (StyleSheetChangeEventsEnabled()) {
     DO_STYLESHEET_NOTIFICATION(StyleSheetChangeEvent, "StyleSheetRemoved",
                                mDocumentSheet, aDocumentSheet);
   }
 }
 
 void Document::RemoveStyleSheetFromStyleSets(StyleSheet* aSheet) {
-  if (nsIPresShell* shell = GetShell()) {
-    shell->StyleSet()->RemoveDocStyleSheet(aSheet);
-    shell->ApplicableStylesChanged();
+  if (PresShell* presShell = GetPresShell()) {
+    presShell->StyleSet()->RemoveDocStyleSheet(aSheet);
+    presShell->ApplicableStylesChanged();
   }
 }
 
 void Document::RemoveStyleSheet(StyleSheet* aSheet) {
   MOZ_ASSERT(aSheet);
   RefPtr<StyleSheet> sheet = DocumentOrShadowRoot::RemoveSheet(*aSheet);
 
   if (!sheet) {
@@ -4169,20 +4171,20 @@ nsresult Document::LoadAdditionalStyleSh
 nsresult Document::AddAdditionalStyleSheet(additionalSheetType aType,
                                            StyleSheet* aSheet) {
   if (mAdditionalSheets[aType].Contains(aSheet)) return NS_ERROR_INVALID_ARG;
 
   if (!aSheet->IsApplicable()) return NS_ERROR_INVALID_ARG;
 
   mAdditionalSheets[aType].AppendElement(aSheet);
 
-  if (nsIPresShell* shell = GetShell()) {
+  if (PresShell* presShell = GetPresShell()) {
     SheetType type = ConvertAdditionalSheetType(aType);
-    shell->StyleSet()->AppendStyleSheet(type, aSheet);
-    shell->ApplicableStylesChanged();
+    presShell->StyleSet()->AppendStyleSheet(type, aSheet);
+    presShell->ApplicableStylesChanged();
   }
 
   // Passing false, so documet.styleSheets.length will not be affected by
   // these additional sheets.
   NotifyStyleSheetAdded(aSheet, false);
   return NS_OK;
 }
 
@@ -4194,20 +4196,20 @@ void Document::RemoveAdditionalStyleShee
 
   int32_t i = FindSheet(mAdditionalSheets[aType], aSheetURI);
   if (i >= 0) {
     RefPtr<StyleSheet> sheetRef = sheets[i];
     sheets.RemoveElementAt(i);
 
     if (!mIsGoingAway) {
       MOZ_ASSERT(sheetRef->IsApplicable());
-      if (nsIPresShell* shell = GetShell()) {
+      if (PresShell* presShell = GetPresShell()) {
         SheetType type = ConvertAdditionalSheetType(aType);
-        shell->StyleSet()->RemoveStyleSheet(type, sheetRef);
-        shell->ApplicableStylesChanged();
+        presShell->StyleSet()->RemoveStyleSheet(type, sheetRef);
+        presShell->ApplicableStylesChanged();
       }
     }
 
     // Passing false, so documet.styleSheets.length will not be affected by
     // these additional sheets.
     NotifyStyleSheetRemoved(sheetRef, false);
     sheetRef->ClearAssociatedDocumentOrShadowRoot();
   }
@@ -4936,18 +4938,18 @@ void Document::UnblockDOMContentLoaded()
   if (--mBlockDOMContentLoaded != 0 || mDidFireDOMContentLoaded) {
     return;
   }
 
   MOZ_LOG(gDocumentLeakPRLog, LogLevel::Debug,
           ("DOCUMENT %p UnblockDOMContentLoaded", this));
 
   mDidFireDOMContentLoaded = true;
-  if (nsIPresShell* shell = GetShell()) {
-    shell->GetRefreshDriver()->NotifyDOMContentLoaded();
+  if (PresShell* presShell = GetPresShell()) {
+    presShell->GetRefreshDriver()->NotifyDOMContentLoaded();
   }
 
   MOZ_ASSERT(mReadyState == READYSTATE_INTERACTIVE);
   if (!mSynchronousDOMContentLoaded) {
     MOZ_RELEASE_ASSERT(NS_IsMainThread());
     nsCOMPtr<nsIRunnable> ev =
         NewRunnableMethod("Document::DispatchContentLoadedEvents", this,
                           &Document::DispatchContentLoadedEvents);
@@ -4966,138 +4968,139 @@ void Document::ContentStateChanged(nsICo
 }
 
 void Document::DocumentStatesChanged(EventStates aStateMask) {
   UpdateDocumentStates(aStateMask);
   NS_DOCUMENT_NOTIFY_OBSERVERS(DocumentStatesChanged, (this, aStateMask));
 }
 
 void Document::StyleRuleChanged(StyleSheet* aSheet, css::Rule* aStyleRule) {
-  if (nsIPresShell* shell = GetShell()) {
-    shell->ApplicableStylesChanged();
+  if (PresShell* presShell = GetPresShell()) {
+    presShell->ApplicableStylesChanged();
   }
 
   if (!StyleSheetChangeEventsEnabled()) {
     return;
   }
 
   DO_STYLESHEET_NOTIFICATION(StyleRuleChangeEvent, "StyleRuleChanged", mRule,
                              aStyleRule);
 }
 
 void Document::StyleRuleAdded(StyleSheet* aSheet, css::Rule* aStyleRule) {
-  if (nsIPresShell* shell = GetShell()) {
-    shell->ApplicableStylesChanged();
+  if (PresShell* presShell = GetPresShell()) {
+    presShell->ApplicableStylesChanged();
   }
 
   if (!StyleSheetChangeEventsEnabled()) {
     return;
   }
 
   DO_STYLESHEET_NOTIFICATION(StyleRuleChangeEvent, "StyleRuleAdded", mRule,
                              aStyleRule);
 }
 
 void Document::StyleRuleRemoved(StyleSheet* aSheet, css::Rule* aStyleRule) {
-  if (nsIPresShell* shell = GetShell()) {
-    shell->ApplicableStylesChanged();
+  if (PresShell* presShell = GetPresShell()) {
+    presShell->ApplicableStylesChanged();
   }
 
   if (!StyleSheetChangeEventsEnabled()) {
     return;
   }
 
   DO_STYLESHEET_NOTIFICATION(StyleRuleChangeEvent, "StyleRuleRemoved", mRule,
                              aStyleRule);
 }
 
 #undef DO_STYLESHEET_NOTIFICATION
 
-static Element* GetCustomContentContainer(nsIPresShell* aShell) {
-  if (!aShell || !aShell->GetCanvasFrame()) {
+static Element* GetCustomContentContainer(PresShell* aPresShell) {
+  if (!aPresShell || !aPresShell->GetCanvasFrame()) {
     return nullptr;
   }
 
-  return aShell->GetCanvasFrame()->GetCustomContentContainer();
+  return aPresShell->GetCanvasFrame()->GetCustomContentContainer();
 }
 
 static void InsertAnonContentIntoCanvas(AnonymousContent& aAnonContent,
-                                        nsIPresShell* aShell) {
-  Element* container = GetCustomContentContainer(aShell);
+                                        PresShell* aPresShell) {
+  Element* container = GetCustomContentContainer(aPresShell);
   if (!container) {
     return;
   }
 
   nsresult rv = container->AppendChildTo(&aAnonContent.ContentNode(), true);
   if (NS_FAILED(rv)) {
     return;
   }
 
-  aShell->GetCanvasFrame()->ShowCustomContentContainer();
+  aPresShell->GetCanvasFrame()->ShowCustomContentContainer();
 }
 
 already_AddRefed<AnonymousContent> Document::InsertAnonymousContent(
     Element& aElement, ErrorResult& aRv) {
   nsAutoScriptBlocker scriptBlocker;
 
   // Clone the node to avoid returning a direct reference.
   nsCOMPtr<nsINode> clone = aElement.CloneNode(true, aRv);
   if (aRv.Failed()) {
     return nullptr;
   }
 
   auto anonContent =
       MakeRefPtr<AnonymousContent>(clone.forget().downcast<Element>());
   mAnonymousContents.AppendElement(anonContent);
 
-  InsertAnonContentIntoCanvas(*anonContent, GetShell());
+  InsertAnonContentIntoCanvas(*anonContent, GetPresShell());
 
   return anonContent.forget();
 }
 
 static void RemoveAnonContentFromCanvas(AnonymousContent& aAnonContent,
-                                        nsIPresShell* aShell) {
-  RefPtr<Element> container = GetCustomContentContainer(aShell);
+                                        PresShell* aPresShell) {
+  RefPtr<Element> container = GetCustomContentContainer(aPresShell);
   if (!container) {
     return;
   }
   container->RemoveChild(aAnonContent.ContentNode(), IgnoreErrors());
 }
 
 void Document::RemoveAnonymousContent(AnonymousContent& aContent,
                                       ErrorResult& aRv) {
   nsAutoScriptBlocker scriptBlocker;
 
   auto index = mAnonymousContents.IndexOf(&aContent);
   if (index == mAnonymousContents.NoIndex) {
     return;
   }
 
   mAnonymousContents.RemoveElementAt(index);
-  RemoveAnonContentFromCanvas(aContent, GetShell());
-
-  if (mAnonymousContents.IsEmpty() && GetCustomContentContainer(GetShell())) {
-    GetShell()->GetCanvasFrame()->HideCustomContentContainer();
+  RemoveAnonContentFromCanvas(aContent, GetPresShell());
+
+  if (mAnonymousContents.IsEmpty() &&
+      GetCustomContentContainer(GetPresShell())) {
+    GetPresShell()->GetCanvasFrame()->HideCustomContentContainer();
   }
 }
 
 Element* Document::GetAnonRootIfInAnonymousContentContainer(
     nsINode* aNode) const {
   if (!aNode->IsInNativeAnonymousSubtree()) {
     return nullptr;
   }
 
-  nsIPresShell* shell = GetShell();
-  if (!shell || !shell->GetCanvasFrame()) {
+  PresShell* presShell = GetPresShell();
+  if (!presShell || !presShell->GetCanvasFrame()) {
     return nullptr;
   }
 
   nsAutoScriptBlocker scriptBlocker;
   nsCOMPtr<Element> customContainer =
-      shell->GetCanvasFrame()->GetCustomContentContainer();
+      presShell->GetCanvasFrame()->GetCustomContentContainer();
   if (!customContainer) {
     return nullptr;
   }
 
   // An arbitrary number of elements can be inserted as children of the custom
   // container frame.  We want the one that was added that contains aNode, so
   // we need to keep track of the last child separately using |child| here.
   nsINode* child = aNode;
@@ -5521,19 +5524,19 @@ void Document::EnableStyleSheetsForSetIn
     sheet->GetTitle(title);
     if (!title.IsEmpty()) {
       sheet->SetEnabled(title.Equals(aSheetSet));
     }
   }
   if (aUpdateCSSLoader) {
     CSSLoader()->DocumentStyleSheetSetChanged();
   }
-  if (nsIPresShell* shell = GetShell()) {
-    if (shell->StyleSet()->StyleSheetsHaveChanged()) {
-      shell->ApplicableStylesChanged();
+  if (PresShell* presShell = GetPresShell()) {
+    if (presShell->StyleSet()->StyleSheetsHaveChanged()) {
+      presShell->ApplicableStylesChanged();
     }
   }
 }
 
 void Document::GetCharacterSet(nsAString& aCharacterSet) const {
   nsAutoCString charset;
   GetDocumentCharacterSet()->Name(charset);
   CopyASCIItoUTF16(charset, aCharacterSet);
@@ -5886,20 +5889,20 @@ void Document::NotifyPossibleTitleChange
 
 void Document::DoNotifyPossibleTitleChange() {
   mPendingTitleChangeEvent.Forget();
   mHaveFiredTitleChange = true;
 
   nsAutoString title;
   GetTitle(title);
 
-  nsCOMPtr<nsIPresShell> shell = GetShell();
-  if (shell) {
+  RefPtr<PresShell> presShell = GetPresShell();
+  if (presShell) {
     nsCOMPtr<nsISupports> container =
-        shell->GetPresContext()->GetContainerWeak();
+        presShell->GetPresContext()->GetContainerWeak();
     if (container) {
       nsCOMPtr<nsIBaseWindow> docShellWin = do_QueryInterface(container);
       if (docShellWin) {
         docShellWin->SetTitle(title);
       }
     }
   }
 
@@ -7109,18 +7112,18 @@ void Document::FlushPendingNotifications
   if (mParentDocument && IsSafeToFlush()) {
     mozilla::ChangesToFlush parentFlush = aFlush;
     if (flushType >= FlushType::Style) {
       parentFlush.mFlushType = std::max(FlushType::Layout, flushType);
     }
     mParentDocument->FlushPendingNotifications(parentFlush);
   }
 
-  if (nsIPresShell* shell = GetShell()) {
-    shell->FlushPendingNotifications(aFlush);
+  if (RefPtr<PresShell> presShell = GetPresShell()) {
+    presShell->FlushPendingNotifications(aFlush);
   }
 }
 
 static bool Copy(Document* aDocument, void* aData) {
   auto* resources = static_cast<nsTArray<nsCOMPtr<Document>>*>(aData);
   resources->AppendElement(aDocument);
   return true;
 }
@@ -7310,20 +7313,21 @@ already_AddRefed<Element> Document::Crea
 
   nsCOMPtr<Element> element;
   nsresult rv = NS_NewElement(getter_AddRefs(element), nodeInfo.forget(),
                               NOT_FROM_PARSER, aIs);
   return NS_SUCCEEDED(rv) ? element.forget() : nullptr;
 }
 
 bool Document::IsSafeToFlush() const {
-  nsIPresShell* shell = GetShell();
-  if (!shell) return true;
-
-  return shell->IsSafeToFlush();
+  PresShell* presShell = GetPresShell();
+  if (!presShell) {
+    return true;
+  }
+  return presShell->IsSafeToFlush();
 }
 
 void Document::Sanitize() {
   // Sanitize the document by resetting all (current and former) password fields
   // and any form fields with autocomplete=off to their default values.  We do
   // this now, instead of when the presentation is restored, to offer some
   // protection in case there is ever an exploit that allows a cached document
   // to be accessed from a different document.
@@ -8298,22 +8302,22 @@ static void FireOrClearDelayedEvents(nsT
   nsIFocusManager* fm = nsFocusManager::GetFocusManager();
   if (!fm) return;
 
   for (uint32_t i = 0; i < aDocuments.Length(); ++i) {
     // NB: Don't bother trying to fire delayed events on documents that were
     // closed before this event ran.
     if (!aDocuments[i]->EventHandlingSuppressed()) {
       fm->FireDelayedEvents(aDocuments[i]);
-      nsCOMPtr<nsIPresShell> shell = aDocuments[i]->GetShell();
-      if (shell) {
+      RefPtr<PresShell> presShell = aDocuments[i]->GetPresShell();
+      if (presShell) {
         // Only fire events for active documents.
         bool fire = aFireEvents && aDocuments[i]->GetInnerWindow() &&
                     aDocuments[i]->GetInnerWindow()->IsCurrentInnerWindow();
-        shell->FireOrClearDelayedEvents(fire);
+        presShell->FireOrClearDelayedEvents(fire);
       }
     }
   }
 }
 
 void Document::PreloadPictureClosed() {
   MOZ_ASSERT(mPreloadPictureDepth > 0);
   mPreloadPictureDepth--;
@@ -8785,63 +8789,64 @@ void Document::SetScrollToRef(nsIURI* aD
     ++start;  // Skip over the '#'
 
     mScrollToRef = Substring(start, end);
   }
 }
 
 void Document::ScrollToRef() {
   if (mScrolledToRefAlready) {
-    nsCOMPtr<nsIPresShell> shell = GetShell();
-    if (shell) {
-      shell->ScrollToAnchor();
+    RefPtr<PresShell> presShell = GetPresShell();
+    if (presShell) {
+      presShell->ScrollToAnchor();
     }
     return;
   }
 
   if (mScrollToRef.IsEmpty()) {
     return;
   }
 
-  nsCOMPtr<nsIPresShell> shell = GetShell();
-  if (shell) {
+  RefPtr<PresShell> presShell = GetPresShell();
+  if (presShell) {
     nsresult rv = NS_ERROR_FAILURE;
     // We assume that the bytes are in UTF-8, as it says in the spec:
     // http://www.w3.org/TR/html4/appendix/notes.html#h-B.2.1
     NS_ConvertUTF8toUTF16 ref(mScrollToRef);
     // Check an empty string which might be caused by the UTF-8 conversion
     if (!ref.IsEmpty()) {
       // Note that GoToAnchor will handle flushing layout as needed.
-      rv = shell->GoToAnchor(ref, mChangeScrollPosWhenScrollingToRef);
+      rv = presShell->GoToAnchor(ref, mChangeScrollPosWhenScrollingToRef);
     } else {
       rv = NS_ERROR_FAILURE;
     }
 
     if (NS_FAILED(rv)) {
       nsAutoCString buff;
       const bool unescaped =
           NS_UnescapeURL(mScrollToRef.BeginReading(), mScrollToRef.Length(),
                          /*aFlags =*/0, buff);
 
       // This attempt is only necessary if characters were unescaped.
       if (unescaped) {
         NS_ConvertUTF8toUTF16 utf16Str(buff);
         if (!utf16Str.IsEmpty()) {
-          rv = shell->GoToAnchor(utf16Str, mChangeScrollPosWhenScrollingToRef);
+          rv = presShell->GoToAnchor(utf16Str,
+                                     mChangeScrollPosWhenScrollingToRef);
         }
       }
 
       // If UTF-8 URI failed then try to assume the string as a
       // document's charset.
       if (NS_FAILED(rv)) {
         const Encoding* encoding = GetDocumentCharacterSet();
         rv = encoding->DecodeWithoutBOMHandling(unescaped ? buff : mScrollToRef,
                                                 ref);
         if (NS_SUCCEEDED(rv) && !ref.IsEmpty()) {
-          rv = shell->GoToAnchor(ref, mChangeScrollPosWhenScrollingToRef);
+          rv = presShell->GoToAnchor(ref, mChangeScrollPosWhenScrollingToRef);
         }
       }
     }
     if (NS_SUCCEEDED(rv)) {
       mScrolledToRefAlready = true;
     }
   }
 }
@@ -9166,18 +9171,18 @@ void Document::GetPlugins(nsTArray<nsIOb
 }
 
 void Document::ScheduleSVGUseElementShadowTreeUpdate(
     SVGUseElement& aUseElement) {
   MOZ_ASSERT(aUseElement.IsInComposedDoc());
 
   mSVGUseElementsNeedingShadowTreeUpdate.PutEntry(&aUseElement);
 
-  if (nsIPresShell* shell = GetShell()) {
-    shell->EnsureStyleFlush();
+  if (PresShell* presShell = GetPresShell()) {
+    presShell->EnsureStyleFlush();
   }
 }
 
 void Document::DoUpdateSVGUseElementShadowTrees() {
   MOZ_ASSERT(!mSVGUseElementsNeedingShadowTreeUpdate.IsEmpty());
   nsTArray<RefPtr<SVGUseElement>> useElementsToUpdate;
 
   do {
@@ -9253,39 +9258,39 @@ already_AddRefed<nsDOMCaretPosition> Doc
   using FrameForPointOption = nsLayoutUtils::FrameForPointOption;
 
   nscoord x = nsPresContext::CSSPixelsToAppUnits(aX);
   nscoord y = nsPresContext::CSSPixelsToAppUnits(aY);
   nsPoint pt(x, y);
 
   FlushPendingNotifications(FlushType::Layout);
 
-  nsIPresShell* ps = GetShell();
-  if (!ps) {
+  PresShell* presShell = GetPresShell();
+  if (!presShell) {
     return nullptr;
   }
 
-  nsIFrame* rootFrame = ps->GetRootFrame();
+  nsIFrame* rootFrame = presShell->GetRootFrame();
 
   // XUL docs, unlike HTML, have no frame tree until everything's done loading
   if (!rootFrame) {
     return nullptr;
   }
 
   nsIFrame* ptFrame = nsLayoutUtils::GetFrameForPoint(
       rootFrame, pt,
       {FrameForPointOption::IgnorePaintSuppression,
        FrameForPointOption::IgnoreCrossDoc});
   if (!ptFrame) {
     return nullptr;
   }
 
   // We require frame-relative coordinates for GetContentOffsetsFromPoint.
   nsPoint aOffset;
-  nsCOMPtr<nsIWidget> widget = nsContentUtils::GetWidget(ps, &aOffset);
+  nsCOMPtr<nsIWidget> widget = nsContentUtils::GetWidget(presShell, &aOffset);
   LayoutDeviceIntPoint refPoint = nsContentUtils::ToWidgetPoint(
       CSSPoint(aX, aY), aOffset, GetPresContext());
   nsPoint adjustedPoint =
       nsLayoutUtils::GetEventCoordinatesRelativeTo(widget, refPoint, ptFrame);
 
   nsFrame::ContentOffsets offsets =
       ptFrame->GetContentOffsetsFromPoint(adjustedPoint);
 
@@ -10217,20 +10222,20 @@ void Document::CleanupFullscreenState() 
     if (nsCOMPtr<Element> element = do_QueryReferent(weakPtr)) {
       ClearFullscreenStateOnElement(element);
     }
   }
   mFullscreenStack.Clear();
   mFullscreenRoot = nullptr;
 
   // Restore the zoom level that was in place prior to entering fullscreen.
-  if (nsIPresShell* shell = GetShell()) {
-    if (shell->GetMobileViewportManager()) {
-      shell->SetResolutionAndScaleTo(mSavedResolution,
-                                     nsIPresShell::ChangeOrigin::eMainThread);
+  if (PresShell* presShell = GetPresShell()) {
+    if (presShell->GetMobileViewportManager()) {
+      presShell->SetResolutionAndScaleTo(
+          mSavedResolution, nsIPresShell::ChangeOrigin::eMainThread);
     }
   }
 
   UpdateViewportScrollbarOverrideForFullscreen(this);
 }
 
 bool Document::FullscreenStackPush(Element* aElement) {
   NS_ASSERTION(aElement, "Must pass non-null to FullscreenStackPush()");
@@ -10611,23 +10616,24 @@ bool Document::ApplyFullscreen(UniquePtr
     child->SetFullscreenRoot(fullScreenRootDoc);
 
     // When entering fullscreen, reset the RCD's resolution to the intrinsic
     // resolution, otherwise the fullscreen content could be sized larger than
     // the screen (since fullscreen is implemented using position:fixed and
     // fixed elements are sized to the layout viewport).
     // This also ensures that things like video controls aren't zoomed in
     // when in fullscreen mode.
-    if (nsIPresShell* shell = child->GetShell()) {
+    if (PresShell* presShell = child->GetPresShell()) {
       if (RefPtr<MobileViewportManager> manager =
-              shell->GetMobileViewportManager()) {
+              presShell->GetMobileViewportManager()) {
         // Save the previous resolution so it can be restored.
-        child->mSavedResolution = shell->GetResolution();
-        shell->SetResolutionAndScaleTo(manager->ComputeIntrinsicResolution(),
-                                       nsIPresShell::ChangeOrigin::eMainThread);
+        child->mSavedResolution = presShell->GetResolution();
+        presShell->SetResolutionAndScaleTo(
+            manager->ComputeIntrinsicResolution(),
+            nsIPresShell::ChangeOrigin::eMainThread);
       }
     }
 
     NS_ASSERTION(child->GetFullscreenRoot() == fullScreenRootDoc,
                  "Fullscreen root should be set!");
     if (child == fullScreenRootDoc) {
       break;
     }
@@ -10887,41 +10893,41 @@ bool Document::SetPointerLock(Element* a
 #ifdef DEBUG
   if (!aElement) {
     nsCOMPtr<Document> pointerLockedDoc =
         do_QueryReferent(EventStateManager::sPointerLockedDoc);
     MOZ_ASSERT(pointerLockedDoc == this);
   }
 #endif
 
-  nsIPresShell* shell = GetShell();
-  if (!shell) {
+  PresShell* presShell = GetPresShell();
+  if (!presShell) {
     NS_WARNING("SetPointerLock(): No PresShell");
     if (!aElement) {
       // If we are unlocking pointer lock, but for some reason the doc
       // has already detached from the presshell, just ask the event
       // state manager to release the pointer.
       EventStateManager::SetPointerLock(nullptr, nullptr);
       return true;
     }
     return false;
   }
-  nsPresContext* presContext = shell->GetPresContext();
+  nsPresContext* presContext = presShell->GetPresContext();
   if (!presContext) {
     NS_WARNING("SetPointerLock(): Unable to get PresContext");
     return false;
   }
 
   nsCOMPtr<nsIWidget> widget;
-  nsIFrame* rootFrame = shell->GetRootFrame();
+  nsIFrame* rootFrame = presShell->GetRootFrame();
   if (!NS_WARN_IF(!rootFrame)) {
     widget = rootFrame->GetNearestWidget();
     NS_WARNING_ASSERTION(widget,
                          "SetPointerLock(): Unable to find widget in "
-                         "shell->GetRootFrame()->GetNearestWidget();");
+                         "presShell->GetRootFrame()->GetNearestWidget();");
     if (aElement && !widget) {
       return false;
     }
   }
 
   // Hide the cursor and set pointer lock for future mouse events
   RefPtr<EventStateManager> esm = presContext->EventStateManager();
   esm->SetCursor(aCursorStyle, nullptr, Nothing(), widget, true);
@@ -11691,18 +11697,18 @@ void Document::FlushUserFontSet() {
   if (!mFontFaceSetDirty) {
     return;
   }
 
   mFontFaceSetDirty = false;
 
   if (gfxPlatform::GetPlatform()->DownloadableFontsEnabled()) {
     nsTArray<nsFontFaceRuleContainer> rules;
-    nsIPresShell* shell = GetShell();
-    if (shell && !shell->StyleSet()->AppendFontFaceRules(rules)) {
+    PresShell* presShell = GetPresShell();
+    if (presShell && !presShell->StyleSet()->AppendFontFaceRules(rules)) {
       return;
     }
 
     if (!mFontFaceSet && !rules.IsEmpty()) {
       nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(GetScopeObject());
       mFontFaceSet = new FontFaceSet(window, this);
     }
 
@@ -11710,31 +11716,31 @@ void Document::FlushUserFontSet() {
     if (mFontFaceSet) {
       changed = mFontFaceSet->UpdateRules(rules);
     }
 
     // We need to enqueue a style change reflow (for later) to
     // reflect that we're modifying @font-face rules.  (However,
     // without a reflow, nothing will happen to start any downloads
     // that are needed.)
-    if (changed && shell) {
-      if (nsPresContext* presContext = shell->GetPresContext()) {
+    if (changed && presShell) {
+      if (nsPresContext* presContext = presShell->GetPresContext()) {
         presContext->UserFontSetUpdated();
       }
     }
   }
 }
 
 void Document::MarkUserFontSetDirty() {
   if (mFontFaceSetDirty) {
     return;
   }
   mFontFaceSetDirty = true;
-  if (nsIPresShell* shell = GetShell()) {
-    shell->EnsureStyleFlush();
+  if (PresShell* presShell = GetPresShell()) {
+    presShell->EnsureStyleFlush();
   }
 }
 
 FontFaceSet* Document::Fonts() {
   if (!mFontFaceSet) {
     nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(GetScopeObject());
     mFontFaceSet = new FontFaceSet(window, this);
     FlushUserFontSet();
--- a/dom/base/Document.h
+++ b/dom/base/Document.h
@@ -102,17 +102,16 @@ class nsIDocShell;
 class nsIDocShellTreeItem;
 class nsIDocumentEncoder;
 class nsIDocumentObserver;
 class nsIHTMLCollection;
 class nsILayoutHistoryState;
 class nsILoadContext;
 class nsIObjectLoadingContent;
 class nsIObserver;
-class nsIPresShell;
 class nsIPrincipal;
 class nsIRequest;
 class nsIRunnable;
 class nsISecurityConsoleMessage;
 class nsIStreamListener;
 class nsIStructuredCloneContainer;
 class nsIURI;
 class nsIVariant;
@@ -134,16 +133,17 @@ class AbstractThread;
 class CSSStyleSheet;
 class Encoding;
 class ErrorResult;
 class EventStates;
 class EventListenerManager;
 class FullscreenExit;
 class FullscreenRequest;
 class PendingAnimationTracker;
+class PresShell;
 class ServoStyleSet;
 class SMILAnimationController;
 enum class StyleCursorKind : uint8_t;
 template <typename>
 class OwningNonNull;
 struct URLExtraData;
 
 namespace css {
@@ -466,18 +466,18 @@ class Document : public nsINode,
                                                                    nsINode)
 
 #define NS_DOCUMENT_NOTIFY_OBSERVERS(func_, params_)                          \
   do {                                                                        \
     NS_OBSERVER_ARRAY_NOTIFY_XPCOM_OBSERVERS(mObservers, nsIDocumentObserver, \
                                              func_, params_);                 \
     /* FIXME(emilio): Apparently we can keep observing from the BFCache? That \
        looks bogus. */                                                        \
-    if (nsIPresShell* shell = GetObservingShell()) {                          \
-      shell->func_ params_;                                                   \
+    if (PresShell* presShell = GetObservingPresShell()) {                     \
+      presShell->func_ params_;                                               \
     }                                                                         \
   } while (0)
 
   // nsIApplicationCacheContainer
   NS_DECL_NSIAPPLICATIONCACHECONTAINER
 
   // nsIRadioGroupContainer
   NS_IMETHOD WalkRadioGroup(const nsAString& aName, nsIRadioVisitor* aVisitor,
@@ -1239,26 +1239,26 @@ class Document : public nsINode,
 
   /**
    * Create a new presentation shell that will use aContext for its
    * presentation context (presentation contexts <b>must not</b> be
    * shared among multiple presentation shells). The caller of this
    * method is responsible for calling BeginObservingDocument() on the
    * presshell if the presshell should observe document mutations.
    */
-  already_AddRefed<nsIPresShell> CreateShell(
+  already_AddRefed<PresShell> CreatePresShell(
       nsPresContext* aContext, nsViewManager* aViewManager,
       UniquePtr<ServoStyleSet> aStyleSet);
-  void DeleteShell();
-
-  nsIPresShell* GetShell() const {
+  void DeletePresShell();
+
+  PresShell* GetPresShell() const {
     return GetBFCacheEntry() ? nullptr : mPresShell;
   }
 
-  inline nsIPresShell* GetObservingShell() const;
+  inline PresShell* GetObservingPresShell() const;
 
   // Return whether the presshell for this document is safe to flush.
   bool IsSafeToFlush() const;
 
   inline nsPresContext* GetPresContext() const;
 
   bool HasShellOrBFCacheEntry() const { return mPresShell || mBFCacheEntry; }
 
@@ -2508,17 +2508,17 @@ class Document : public nsINode,
    */
   Document* GetDisplayDocument() const { return mDisplayDocument; }
 
   /**
    * Set the display document for this document.  aDisplayDocument must not be
    * null.
    */
   void SetDisplayDocument(Document* aDisplayDocument) {
-    MOZ_ASSERT(!GetShell() && !GetContainer() && !GetWindow(),
+    MOZ_ASSERT(!GetPresShell() && !GetContainer() && !GetWindow(),
                "Shouldn't set mDisplayDocument on documents that already "
                "have a presentation or a docshell or a window");
     MOZ_ASSERT(aDisplayDocument, "Must not be null");
     MOZ_ASSERT(aDisplayDocument != this, "Should be different document");
     MOZ_ASSERT(!aDisplayDocument->GetDisplayDocument(),
                "Display documents should not nest");
     mDisplayDocument = aDisplayDocument;
     mHasDisplayDocument = !!aDisplayDocument;
@@ -3847,17 +3847,17 @@ class Document : public nsINode,
   nsCString GetContentTypeInternal() const { return mContentType; }
 
   // Update our frame request callback scheduling state, if needed.  This will
   // schedule or unschedule them, if necessary, and update
   // mFrameRequestCallbacksScheduled.  aOldShell should only be passed when
   // mPresShell is becoming null; in that case it will be used to get hold of
   // the relevant refresh driver.
   void UpdateFrameRequestCallbackSchedulingState(
-      nsIPresShell* aOldShell = nullptr);
+      PresShell* aOldPresShell = nullptr);
 
   // Helper for GetScrollingElement/IsScrollingElement.
   bool IsPotentiallyScrollable(HTMLBodyElement* aBody);
 
   // Return the same type parent docuement if exists, or return null.
   Document* GetSameTypeParentDocument();
 
   void MaybeAllowStorageForOpenerAfterUserInteraction();
@@ -4327,17 +4327,17 @@ class Document : public nsINode,
   // if this document is part of a multipart document,
   // the ID can be used to distinguish it from the other parts.
   uint32_t mPartID;
 
   // Cycle collector generation in which we're certain that this document
   // won't be collected
   uint32_t mMarkedCCGeneration;
 
-  nsIPresShell* mPresShell;
+  PresShell* mPresShell;
 
   nsCOMArray<nsINode> mSubtreeModifiedTargets;
   uint32_t mSubtreeModifiedDepth;
 
   // All images in process of being preloaded.  This is a hashtable so
   // we can remove them as the real image loads start; that way we
   // make sure to not keep the image load going when no one cares
   // about it anymore.
--- a/dom/base/DocumentInlines.h
+++ b/dom/base/DocumentInlines.h
@@ -12,22 +12,22 @@
 #include "nsContentUtils.h"
 #include "nsIPresShell.h"
 #include "nsPresContext.h"
 #include "nsStyleSheetService.h"
 
 namespace mozilla {
 namespace dom {
 
-inline nsIPresShell* Document::GetObservingShell() const {
+inline PresShell* Document::GetObservingPresShell() const {
   return mPresShell && mPresShell->IsObservingDocument() ? mPresShell : nullptr;
 }
 
 inline nsPresContext* Document::GetPresContext() const {
-  nsIPresShell* presShell = GetShell();
+  PresShell* presShell = GetPresShell();
   return presShell ? presShell->GetPresContext() : nullptr;
 }
 
 inline HTMLBodyElement* Document::GetBodyElement() {
   return static_cast<HTMLBodyElement*>(GetHtmlChildElement(nsGkAtoms::body));
 }
 
 template <typename T>
--- a/dom/base/DocumentOrShadowRoot.cpp
+++ b/dom/base/DocumentOrShadowRoot.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 "DocumentOrShadowRoot.h"
 #include "mozilla/EventStateManager.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/dom/Document.h"
 #include "mozilla/dom/HTMLInputElement.h"
 #include "mozilla/dom/ShadowRoot.h"
 #include "mozilla/dom/StyleSheetList.h"
 #include "nsFocusManager.h"
 #include "nsIRadioVisitor.h"
 #include "nsIFormControl.h"
 #include "nsLayoutUtils.h"
@@ -239,22 +240,22 @@ static void QueryNodesFromRect(DocumentO
   nsCOMPtr<Document> doc = aRoot.AsNode().OwnerDoc();
 
   // Make sure the layout information we get is up-to-date, and
   // ensure we get a root frame (for everything but XUL)
   if (aShouldFlushLayout == FlushLayout::Yes) {
     doc->FlushPendingNotifications(FlushType::Layout);
   }
 
-  nsIPresShell* ps = doc->GetShell();
-  if (!ps) {
+  PresShell* presShell = doc->GetPresShell();
+  if (!presShell) {
     return;
   }
 
-  nsIFrame* rootFrame = ps->GetRootFrame();
+  nsIFrame* rootFrame = presShell->GetRootFrame();
   // XUL docs, unlike HTML, have no frame tree until everything's done loading
   if (!rootFrame) {
     return;  // return null to premature XUL callers as a reminder to wait
   }
 
   aOptions += FrameForPointOption::IgnorePaintSuppression;
   aOptions += FrameForPointOption::IgnoreCrossDoc;
 
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -29,17 +29,16 @@
 #include "mozilla/dom/DocumentTimeline.h"
 #include "nsFlexContainerFrame.h"
 #include "nsFocusManager.h"
 #include "nsILinkHandler.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIURL.h"
 #include "nsContainerFrame.h"
 #include "nsIAnonymousContentCreator.h"
-#include "nsIPresShell.h"
 #include "nsPresContext.h"
 #include "nsStyleConsts.h"
 #include "nsString.h"
 #include "nsUnicharUtils.h"
 #include "nsDOMCID.h"
 #include "nsIServiceManager.h"
 #include "nsDOMCSSAttrDeclaration.h"
 #include "nsNameSpaceManager.h"
@@ -63,16 +62,17 @@
 #include "mozilla/EffectSet.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventListenerManager.h"
 #include "mozilla/EventStateManager.h"
 #include "mozilla/EventStates.h"
 #include "mozilla/FullscreenChange.h"
 #include "mozilla/InternalMutationEvent.h"
 #include "mozilla/MouseEvents.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/RestyleManager.h"
 #include "mozilla/ScrollTypes.h"
 #include "mozilla/SizeOfState.h"
 #include "mozilla/TextEditor.h"
 #include "mozilla/TextEvents.h"
 #include "nsNodeUtils.h"
 #include "mozilla/dom/DirectionalityUtils.h"
 #include "mozilla/dom/Document.h"
@@ -443,17 +443,17 @@ Element::StyleStateLocks Element::Locked
     return *locks;
   }
   return StyleStateLocks();
 }
 
 void Element::NotifyStyleStateChange(EventStates aStates) {
   Document* doc = GetComposedDoc();
   if (doc) {
-    nsIPresShell* presShell = doc->GetShell();
+    RefPtr<PresShell> presShell = doc->GetPresShell();
     if (presShell) {
       nsAutoScriptBlocker scriptBlocker;
       presShell->ContentStateChanged(doc, this, aStates);
     }
   }
 }
 
 void Element::LockStyleStates(EventStates aStates, bool aEnabled) {
@@ -522,17 +522,17 @@ static bool IsLikelyCustomElement(const 
 }
 
 static bool MayNeedToLoadXBLBinding(const Document& aDocument,
                                     const Element& aElement) {
   // If we have a frame, the frame has already loaded the binding.
   // Otherwise, don't do anything else here unless we're dealing with
   // XUL or an HTML element that may have a plugin-related overlay
   // (i.e. object or embed).
-  if (!aDocument.GetShell() || aElement.GetPrimaryFrame()) {
+  if (!aDocument.GetPresShell() || aElement.GetPrimaryFrame()) {
     return false;
   }
 
   if (auto* xulElem = nsXULElement::FromNode(aElement)) {
     return !IsLikelyCustomElement(*xulElem);
   }
 
   return aElement.IsAnyOfHTMLElements(nsGkAtoms::object, nsGkAtoms::embed);
@@ -693,18 +693,18 @@ nsIScrollableFrame* Element::GetScrollFr
   // Now reget *aStyledFrame if the caller asked for it, because that frame
   // flush can kill it.
   if (aFrame) {
     *aFrame = GetPrimaryFrame(FlushType::None);
   }
 
   if (isScrollingElement) {
     // Our scroll info should map to the root scrollable frame if there is one.
-    if (nsIPresShell* shell = doc->GetShell()) {
-      return shell->GetRootScrollFrameAsScrollable();
+    if (PresShell* presShell = doc->GetPresShell()) {
+      return presShell->GetRootScrollFrameAsScrollable();
     }
   }
 
   return nullptr;
 }
 
 void Element::ScrollIntoView(const BooleanOrScrollIntoViewOptions& aObject) {
   if (aObject.IsScrollIntoViewOptions()) {
@@ -726,17 +726,17 @@ void Element::ScrollIntoView(const Boole
 
 void Element::ScrollIntoView(const ScrollIntoViewOptions& aOptions) {
   Document* document = GetComposedDoc();
   if (!document) {
     return;
   }
 
   // Get the presentation shell
-  nsCOMPtr<nsIPresShell> presShell = document->GetShell();
+  RefPtr<PresShell> presShell = document->GetPresShell();
   if (!presShell) {
     return;
   }
 
   int16_t vpercent = nsIPresShell::SCROLL_CENTER;
   switch (aOptions.mBlock) {
     case ScrollLogicalPosition::Start:
       vpercent = nsIPresShell::SCROLL_TOP;
@@ -985,17 +985,17 @@ nsRect Element::GetClientAreaRect() {
       LookAndFeel::GetInt(LookAndFeel::eIntID_UseOverlayScrollbars) != 0;
   bool rootContentDocument =
       presContext && presContext->IsRootContentDocument();
   if (overlayScrollbars && rootContentDocument &&
       doc->IsScrollingElement(this)) {
     // We will always have a pres shell if we have a pres context, and we will
     // only get here if we have a pres context from the root content document
     // check
-    nsIPresShell* presShell = doc->GetShell();
+    PresShell* presShell = doc->GetPresShell();
 
     // Ensure up to date dimensions, but don't reflow
     RefPtr<nsViewManager> viewManager = presShell->GetViewManager();
     if (viewManager) {
       viewManager->FlushDelayedResize(false);
     }
     return nsRect(nsPoint(), presContext->GetVisibleArea().Size());
   }
@@ -1193,18 +1193,18 @@ already_AddRefed<ShadowRoot> Element::At
   nsAutoScriptBlocker scriptBlocker;
 
   RefPtr<mozilla::dom::NodeInfo> nodeInfo =
       mNodeInfo->NodeInfoManager()->GetNodeInfo(
           nsGkAtoms::documentFragmentNodeName, nullptr, kNameSpaceID_None,
           DOCUMENT_FRAGMENT_NODE);
 
   if (Document* doc = GetComposedDoc()) {
-    if (nsIPresShell* shell = doc->GetShell()) {
-      shell->DestroyFramesForAndRestyle(this);
+    if (PresShell* presShell = doc->GetPresShell()) {
+      presShell->DestroyFramesForAndRestyle(this);
     }
   }
   MOZ_ASSERT(!GetPrimaryFrame());
 
   /**
    * 4. Let shadow be a new shadow root whose node document is
    *    context object's node document, host is context object,
    *    and mode is init's mode.
@@ -1314,18 +1314,18 @@ void Element::UnattachShadow() {
   ShadowRoot* shadowRoot = GetShadowRoot();
   if (!shadowRoot) {
     return;
   }
 
   nsAutoScriptBlocker scriptBlocker;
 
   if (Document* doc = GetComposedDoc()) {
-    if (nsIPresShell* shell = doc->GetShell()) {
-      shell->DestroyFramesForAndRestyle(this);
+    if (PresShell* presShell = doc->GetPresShell()) {
+      presShell->DestroyFramesForAndRestyle(this);
     }
   }
   MOZ_ASSERT(!GetPrimaryFrame());
 
   shadowRoot->Unattach();
   SetShadowRoot(nullptr);
 
   // Beware shadowRoot could be dead after this call.
@@ -2036,18 +2036,18 @@ nsresult Element::SetSMILOverrideStyleDe
   Element::nsExtendedDOMSlots* slots = ExtendedDOMSlots();
 
   slots->mSMILOverrideStyleDeclaration = aDeclaration;
 
   // Only need to request a restyle if we're in a document.  (We might not
   // be in a document, if we're clearing animation effects on a target node
   // that's been detached since the previous animation sample.)
   if (Document* doc = GetComposedDoc()) {
-    if (nsIPresShell* shell = doc->GetShell()) {
-      shell->RestyleForAnimation(this, StyleRestyleHint_RESTYLE_SMIL);
+    if (PresShell* presShell = doc->GetPresShell()) {
+      presShell->RestyleForAnimation(this, StyleRestyleHint_RESTYLE_SMIL);
     }
   }
 
   return NS_OK;
 }
 
 bool Element::IsLabelable() const { return false; }
 
@@ -4285,18 +4285,18 @@ static void NoteDirtyElement(Element* aE
     // order to avoid work here, because since the style system keeps style data
     // in, e.g., subtrees under a leaf frame, missing restyles and such in there
     // has observable behavior via getComputedStyle, for example.
     if (Servo_Element_IsDisplayNone(parent->AsElement())) {
       return;
     }
   }
 
-  if (nsIPresShell* shell = doc->GetShell()) {
-    shell->EnsureStyleFlush();
+  if (PresShell* presShell = doc->GetPresShell()) {
+    presShell->EnsureStyleFlush();
   }
 
   MOZ_ASSERT(parent->IsElement() || parent == doc);
 
   // The bit checks below rely on this to arrive to useful conclusions about the
   // shape of the tree.
   AssertNoBitsPropagatedFrom(existingRoot);
 
--- a/dom/base/FragmentOrElement.cpp
+++ b/dom/base/FragmentOrElement.cpp
@@ -17,16 +17,17 @@
 
 #include "mozilla/AsyncEventDispatcher.h"
 #include "mozilla/DeclarationBlock.h"
 #include "mozilla/EffectSet.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventListenerManager.h"
 #include "mozilla/EventStates.h"
 #include "mozilla/HTMLEditor.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/RestyleManager.h"
 #include "mozilla/TextEditor.h"
 #include "mozilla/TouchEvents.h"
 #include "mozilla/URLExtraData.h"
 #include "mozilla/dom/Attr.h"
 #include "nsDOMAttributeMap.h"
 #include "nsAtom.h"
 #include "mozilla/dom/NodeInfo.h"
@@ -38,17 +39,16 @@
 #include "nsIDocumentEncoder.h"
 #include "nsFocusManager.h"
 #include "nsILinkHandler.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIURL.h"
 #include "nsNetUtil.h"
 #include "nsIFrame.h"
 #include "nsIAnonymousContentCreator.h"
-#include "nsIPresShell.h"
 #include "nsPresContext.h"
 #include "nsStyleConsts.h"
 #include "nsString.h"
 #include "nsUnicharUtils.h"
 #include "nsDOMCID.h"
 #include "nsIServiceManager.h"
 #include "nsDOMCSSAttrDeclaration.h"
 #include "nsNameSpaceManager.h"
@@ -1575,17 +1575,17 @@ static bool ShouldClearPurple(nsIContent
   return aContent->HasProperties();
 }
 
 // If aNode is not optimizable, but is an element
 // with a frame in a document which has currently active presshell,
 // we can act as if it was optimizable. When the primary frame dies, aNode
 // will end up to the purple buffer because of the refcount change.
 bool NodeHasActiveFrame(Document* aCurrentDoc, nsINode* aNode) {
-  return aCurrentDoc->GetShell() && aNode->IsElement() &&
+  return aCurrentDoc->GetPresShell() && aNode->IsElement() &&
          aNode->AsElement()->GetPrimaryFrame();
 }
 
 bool OwnedByBindingManager(Document* aCurrentDoc, nsINode* aNode) {
   return aNode->IsElement() && aNode->AsElement()->GetXBLBinding();
 }
 
 // CanSkip checks if aNode is known-live, and if it is, returns true. If aNode
--- a/dom/base/ResponsiveImageSelector.cpp
+++ b/dom/base/ResponsiveImageSelector.cpp
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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/dom/ResponsiveImageSelector.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/ServoStyleSetInlines.h"
 #include "mozilla/TextUtils.h"
 #include "nsIURI.h"
 #include "mozilla/dom/Document.h"
 #include "nsContentUtils.h"
 #include "nsPresContext.h"
 
 #include "nsCSSProps.h"
@@ -396,17 +397,17 @@ int ResponsiveImageSelector::GetSelected
   SelectImage();
 
   return mSelectedCandidateIndex;
 }
 
 bool ResponsiveImageSelector::ComputeFinalWidthForCurrentViewport(
     double* aWidth) {
   dom::Document* doc = Document();
-  nsIPresShell* presShell = doc->GetShell();
+  PresShell* presShell = doc->GetPresShell();
   nsPresContext* pctx = presShell ? presShell->GetPresContext() : nullptr;
 
   if (!pctx) {
     return false;
   }
   nscoord effectiveWidth =
       presShell->StyleSet()->EvaluateSourceSizeList(mServoSourceSizeList.get());
 
--- a/dom/base/ShadowRoot.cpp
+++ b/dom/base/ShadowRoot.cpp
@@ -12,16 +12,17 @@
 #include "nsIStyleSheetLinkingElement.h"
 #include "nsWindowSizes.h"
 #include "nsXBLPrototypeBinding.h"
 #include "mozilla/dom/DirectionalityUtils.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/HTMLSlotElement.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/IdentifierMapEntry.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/ServoStyleRuleMap.h"
 #include "mozilla/StyleSheet.h"
 #include "mozilla/StyleSheetInlines.h"
 #include "mozilla/dom/StyleSheetList.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
@@ -180,22 +181,22 @@ void ShadowRoot::Unattach() {
 
 void ShadowRoot::InvalidateStyleAndLayoutOnSubtree(Element* aElement) {
   MOZ_ASSERT(aElement);
   Document* doc = GetComposedDoc();
   if (!doc) {
     return;
   }
 
-  nsIPresShell* shell = doc->GetShell();
-  if (!shell) {
+  PresShell* presShell = doc->GetPresShell();
+  if (!presShell) {
     return;
   }
 
-  shell->DestroyFramesForAndRestyle(aElement);
+  presShell->DestroyFramesForAndRestyle(aElement);
 }
 
 void ShadowRoot::AddSlot(HTMLSlotElement* aSlot) {
   MOZ_ASSERT(aSlot);
 
   // Note that if name attribute missing, the slot is a default slot.
   nsAutoString name;
   aSlot->GetName(name);
@@ -344,18 +345,18 @@ void ShadowRoot::RuleChanged(StyleSheet&
 }
 
 void ShadowRoot::ApplicableRulesChanged() {
   Document* doc = GetComposedDoc();
   if (!doc) {
     return;
   }
 
-  if (nsIPresShell* shell = doc->GetShell()) {
-    shell->RecordShadowStyleChange(*this);
+  if (PresShell* presShell = doc->GetPresShell()) {
+    presShell->RecordShadowStyleChange(*this);
   }
 }
 
 void ShadowRoot::InsertSheetAt(size_t aIndex, StyleSheet& aSheet) {
   DocumentOrShadowRoot::InsertSheetAt(aIndex, aSheet);
   if (aSheet.IsApplicable()) {
     InsertSheetIntoAuthorData(aIndex, aSheet);
   }
@@ -529,18 +530,18 @@ void ShadowRoot::MaybeReassignElement(El
   SlotAssignment assignment = SlotAssignmentFor(aElement);
 
   if (assignment.mSlot == oldSlot) {
     // Nothing to do here.
     return;
   }
 
   if (Document* doc = GetComposedDoc()) {
-    if (nsIPresShell* shell = doc->GetShell()) {
-      shell->SlotAssignmentWillChange(*aElement, oldSlot, assignment.mSlot);
+    if (RefPtr<PresShell> presShell = doc->GetPresShell()) {
+      presShell->SlotAssignmentWillChange(*aElement, oldSlot, assignment.mSlot);
     }
   }
 
   if (oldSlot) {
     oldSlot->RemoveAssignedNode(aElement);
     oldSlot->EnqueueSlotChangeEvent();
   }
 
--- a/dom/base/nsContentSink.cpp
+++ b/dom/base/nsContentSink.cpp
@@ -6,30 +6,30 @@
 
 /*
  * Base class for the XML and HTML content sinks, which construct a
  * DOM based on information from the parser.
  */
 
 #include "nsContentSink.h"
 #include "mozilla/Components.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/dom/Document.h"
 #include "mozilla/css/Loader.h"
 #include "mozilla/dom/SRILogHelper.h"
 #include "nsStyleLinkElement.h"
 #include "nsIDocShell.h"
 #include "nsILoadContext.h"
 #include "nsIPrefetchService.h"
 #include "nsIURI.h"
 #include "nsNetUtil.h"
 #include "nsIMIMEHeaderParam.h"
 #include "nsIProtocolHandler.h"
 #include "nsIHttpChannel.h"
 #include "nsIContent.h"
-#include "nsIPresShell.h"
 #include "nsPresContext.h"
 #include "nsViewManager.h"
 #include "nsAtom.h"
 #include "nsGkAtoms.h"
 #include "nsGlobalWindowInner.h"
 #include "nsNetCID.h"
 #include "nsIOfflineCacheUpdate.h"
 #include "nsIApplicationCache.h"
@@ -1185,24 +1185,24 @@ void nsContentSink::StartLayout(bool aIg
   // sure to flush tags instead of just calling UpdateChildCounts() after we
   // loop over the shells.
   FlushTags();
 
   mLayoutStarted = true;
   mLastNotificationTime = PR_Now();
 
   mDocument->SetMayStartLayout(true);
-  nsCOMPtr<nsIPresShell> shell = mDocument->GetShell();
+  RefPtr<PresShell> presShell = mDocument->GetPresShell();
   // Make sure we don't call Initialize() for a shell that has
   // already called it. This can happen when the layout frame for
   // an iframe is constructed *between* the Embed() call for the
   // docshell in the iframe, and the content sink's call to OpenBody().
   // (Bug 153815)
-  if (shell && !shell->DidInitialize()) {
-    nsresult rv = shell->Initialize();
+  if (presShell && !presShell->DidInitialize()) {
+    nsresult rv = presShell->Initialize();
     if (NS_FAILED(rv)) {
       return;
     }
   }
 
   // If the document we are loading has a reference or it is a
   // frameset document, disable the scroll bars on the views.
 
@@ -1340,30 +1340,30 @@ nsresult nsContentSink::WillResumeImpl()
 }
 
 nsresult nsContentSink::DidProcessATokenImpl() {
   if (mRunsToCompletion || !mParser) {
     return NS_OK;
   }
 
   // Get the current user event time
-  nsIPresShell* shell = mDocument->GetShell();
-  if (!shell) {
+  PresShell* presShell = mDocument->GetPresShell();
+  if (!presShell) {
     // If there's no pres shell in the document, return early since
     // we're not laying anything out here.
     return NS_OK;
   }
 
   // Increase before comparing to gEventProbeRate
   ++mDeflectedCount;
 
   // Check if there's a pending event
   if (sPendingEventMode != 0 && !mHasPendingEvent &&
       (mDeflectedCount % sEventProbeRate) == 0) {
-    nsViewManager* vm = shell->GetViewManager();
+    nsViewManager* vm = presShell->GetViewManager();
     NS_ENSURE_TRUE(vm, NS_ERROR_FAILURE);
     nsCOMPtr<nsIWidget> widget;
     vm->GetRootWidget(getter_AddRefs(widget));
     mHasPendingEvent = widget && widget->HasPendingInputEvent();
   }
 
   if (mHasPendingEvent && sPendingEventMode == 2) {
     return NS_ERROR_HTMLPARSER_INTERRUPTED;
@@ -1487,25 +1487,25 @@ bool nsContentSink::IsScriptExecutingImp
   return !!mScriptLoader->GetCurrentScript();
 }
 
 nsresult nsContentSink::WillParseImpl(void) {
   if (mRunsToCompletion || !mDocument) {
     return NS_OK;
   }
 
-  nsIPresShell* shell = mDocument->GetShell();
-  if (!shell) {
+  PresShell* presShell = mDocument->GetPresShell();
+  if (!presShell) {
     return NS_OK;
   }
 
   uint32_t currentTime = PR_IntervalToMicroseconds(PR_IntervalNow());
 
   if (sEnablePerfMode == 0) {
-    nsViewManager* vm = shell->GetViewManager();
+    nsViewManager* vm = presShell->GetViewManager();
     NS_ENSURE_TRUE(vm, NS_ERROR_FAILURE);
     uint32_t lastEventTime;
     vm->GetLastUserEventTime(lastEventTime);
 
     bool newDynLower =
         mDocument->IsInBackgroundWindow() ||
         ((currentTime - mBeginLoadTime) > uint32_t(sInitialPerfTime) &&
          (currentTime - lastEventTime) < uint32_t(sInteractiveTime));
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -86,16 +86,17 @@
 #include "mozilla/gfx/DataSurfaceHelpers.h"
 #include "mozilla/HTMLEditor.h"
 #include "mozilla/IMEStateManager.h"
 #include "mozilla/InternalMutationEvent.h"
 #include "mozilla/Likely.h"
 #include "mozilla/ManualNAC.h"
 #include "mozilla/MouseEvents.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/ResultExtensions.h"
 #include "mozilla/dom/Selection.h"
 #include "mozilla/Services.h"
 #include "mozilla/StaticPrefs.h"
 #include "mozilla/TextEditor.h"
 #include "mozilla/TextEvents.h"
 #include "nsArrayUtils.h"
 #include "nsAString.h"
@@ -3192,35 +3193,31 @@ void nsContentUtils::SplitExpatName(cons
     nameStart = aExpatName;
     nameEnd = pos;
     *aPrefix = nullptr;
   }
   *aLocalName = NS_AtomizeMainThread(Substring(nameStart, nameEnd)).take();
 }
 
 // static
-nsIPresShell* nsContentUtils::GetPresShellForContent(
-    const nsIContent* aContent) {
+PresShell* nsContentUtils::GetPresShellForContent(const nsIContent* aContent) {
   Document* doc = aContent->GetComposedDoc();
   if (!doc) {
     return nullptr;
   }
-
-  return doc->GetShell();
+  return doc->GetPresShell();
 }
 
 // static
 nsPresContext* nsContentUtils::GetContextForContent(
     const nsIContent* aContent) {
-  nsIPresShell* presShell = GetPresShellForContent(aContent);
-
+  PresShell* presShell = GetPresShellForContent(aContent);
   if (!presShell) {
     return nullptr;
   }
-
   return presShell->GetPresContext();
 }
 
 // static
 bool nsContentUtils::CanLoadImage(nsIURI* aURI, nsINode* aNode,
                                   Document* aLoadingDocument,
                                   nsIPrincipal* aLoadingPrincipal) {
   MOZ_ASSERT(aURI, "Must have a URI");
@@ -4179,17 +4176,17 @@ nsresult nsContentUtils::DispatchInputEv
     }
   } else {
     Document* document = aEventTargetElement->OwnerDoc();
     if (NS_WARN_IF(!document)) {
       return NS_ERROR_FAILURE;
     }
     // If we're running xpcshell tests, we fail to get presShell here.
     // Even in such case, we need to dispatch "input" event without widget.
-    nsIPresShell* presShell = document->GetShell();
+    PresShell* presShell = document->GetPresShell();
     if (presShell) {
       nsPresContext* presContext = presShell->GetPresContext();
       if (NS_WARN_IF(!presContext)) {
         return NS_ERROR_FAILURE;
       }
       widget = presContext->GetRootWidget();
       if (NS_WARN_IF(!widget)) {
         return NS_ERROR_FAILURE;
@@ -6293,19 +6290,19 @@ void nsContentUtils::PopulateStringFromS
 
 nsIPresShell* nsContentUtils::FindPresShellForDocument(const Document* aDoc) {
   const Document* doc = aDoc;
   Document* displayDoc = doc->GetDisplayDocument();
   if (displayDoc) {
     doc = displayDoc;
   }
 
-  nsIPresShell* shell = doc->GetShell();
-  if (shell) {
-    return shell;
+  PresShell* presShell = doc->GetPresShell();
+  if (presShell) {
+    return presShell;
   }
 
   nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem = doc->GetDocShell();
   while (docShellTreeItem) {
     // We may be in a display:none subdocument, or we may not have a presshell
     // created yet.
     // Walk the docshell tree to find the nearest container that has a
     // presshell, and return that.
@@ -9828,17 +9825,17 @@ bool nsContentUtils::AttemptLargeAllocat
 /* static */
 void nsContentUtils::AppendDocumentLevelNativeAnonymousContentTo(
     Document* aDocument, nsTArray<nsIContent*>& aElements) {
   MOZ_ASSERT(aDocument);
 #ifdef DEBUG
   size_t oldLength = aElements.Length();
 #endif
 
-  if (nsIPresShell* presShell = aDocument->GetShell()) {
+  if (PresShell* presShell = aDocument->GetPresShell()) {
     if (nsIFrame* scrollFrame = presShell->GetRootScrollFrame()) {
       nsIAnonymousContentCreator* creator = do_QueryFrame(scrollFrame);
       MOZ_ASSERT(
           creator,
           "scroll frame should always implement nsIAnonymousContentCreator");
       creator->AppendAnonymousContentTo(aElements, 0);
     }
 
@@ -10505,19 +10502,19 @@ bool nsContentUtils::StringifyJSON(JSCon
 bool nsContentUtils::
     HighPriorityEventPendingForTopLevelDocumentBeforeContentfulPaint(
         Document* aDocument) {
   if (!aDocument || aDocument->IsLoadedAsData()) {
     return false;
   }
 
   Document* topLevel = aDocument->GetTopLevelContentDocument();
-  return topLevel && topLevel->GetShell() &&
-         topLevel->GetShell()->GetPresContext() &&
-         !topLevel->GetShell()->GetPresContext()->HadContentfulPaint() &&
+  return topLevel && topLevel->GetPresShell() &&
+         topLevel->GetPresShell()->GetPresContext() &&
+         !topLevel->GetPresShell()->GetPresContext()->HadContentfulPaint() &&
          nsThreadManager::MainThreadHasPendingHighPriorityEvents();
 }
 
 /* static */
 bool nsContentUtils::IsURIInPrefList(nsIURI* aURI, const char* aPrefName) {
   MOZ_ASSERT(aPrefName);
 
   nsAutoCString blackList;
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -122,16 +122,17 @@ class nsRefPtrHashtable;
 template <class T>
 class nsReadingIterator;
 
 namespace mozilla {
 class Dispatcher;
 class ErrorResult;
 class EventListenerManager;
 class HTMLEditor;
+class PresShell;
 class TextEditor;
 
 namespace dom {
 class ContentFrameMessageManager;
 struct CustomElementDefinition;
 class DataTransfer;
 class DocumentFragment;
 class Element;
@@ -822,17 +823,17 @@ class nsContentUtils {
 
   /**
    * Method that gets the pres shell for the node.
    *
    * @param aContent The content node.
    * @return the pres shell, or nullptr if the content is not in a document
    *         (if GetComposedDoc returns nullptr)
    */
-  static nsIPresShell* GetPresShellForContent(const nsIContent* aContent);
+  static mozilla::PresShell* GetPresShellForContent(const nsIContent* aContent);
 
   /**
    * Method to do security and content policy checks on the image URI
    *
    * @param aURI uri of the image to be loaded
    * @param aNode, the context the image is loaded in (eg an element)
    * @param aLoadingDocument the document we belong to
    * @param aLoadingPrincipal the principal doing the load
--- a/dom/base/nsCopySupport.cpp
+++ b/dom/base/nsCopySupport.cpp
@@ -13,17 +13,16 @@
 #include "nsIClipboard.h"
 #include "nsIFormControl.h"
 #include "nsWidgetsCID.h"
 #include "nsXPCOM.h"
 #include "nsISupportsPrimitives.h"
 #include "nsRange.h"
 #include "imgIContainer.h"
 #include "imgIRequest.h"
-#include "nsIPresShell.h"
 #include "nsFocusManager.h"
 #include "mozilla/dom/DataTransfer.h"
 
 #include "nsIDocShell.h"
 #include "nsIContentViewerEdit.h"
 #include "nsIClipboardHelper.h"
 #include "nsISelectionController.h"
 
@@ -51,16 +50,17 @@
 #  include "nsReadableUtils.h"
 #  include "nsXULAppAPI.h"
 #endif
 
 #include "mozilla/ContentEvents.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/dom/Selection.h"
 #include "mozilla/IntegerRange.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
 static NS_DEFINE_CID(kCTransferableCID, NS_TRANSFERABLE_CID);
@@ -583,18 +583,20 @@ static nsresult AppendImagePromise(nsITr
   return aTransferable->AddDataFlavor(kFilePromiseMime);
 }
 #endif  // XP_WIN
 
 nsIContent* nsCopySupport::GetSelectionForCopy(Document* aDocument,
                                                Selection** aSelection) {
   *aSelection = nullptr;
 
-  nsIPresShell* presShell = aDocument->GetShell();
-  if (!presShell) return nullptr;
+  PresShell* presShell = aDocument->GetPresShell();
+  if (!presShell) {
+    return nullptr;
+  }
 
   nsCOMPtr<nsIContent> focusedContent;
   nsCOMPtr<nsISelectionController> selectionController =
       presShell->GetSelectionControllerForFocusedContent(
           getter_AddRefs(focusedContent));
   if (!selectionController) {
     return nullptr;
   }
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -40,25 +40,25 @@
 #include "nsCharsetSource.h"
 #include "nsJSEnvironment.h"
 #include "nsJSUtils.h"
 
 #include "mozilla/ChaosMode.h"
 #include "mozilla/EventStateManager.h"
 #include "mozilla/MiscEvents.h"
 #include "mozilla/MouseEvents.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/TextEvents.h"
 #include "mozilla/TextEventDispatcher.h"
 #include "mozilla/TouchEvents.h"
 
 #include "nsViewManager.h"
 
 #include "nsLayoutUtils.h"
 #include "nsComputedDOMStyle.h"
-#include "nsIPresShell.h"
 #include "nsCSSProps.h"
 #include "nsIDocShell.h"
 #include "nsIContentViewer.h"
 #include "mozilla/StyleAnimationValue.h"
 #include "mozilla/dom/File.h"
 #include "mozilla/dom/FileBinding.h"
 #include "mozilla/dom/DOMRect.h"
 #include <algorithm>
@@ -1035,17 +1035,17 @@ nsIWidget* nsDOMWindowUtils::GetWidget(n
 
   return nullptr;
 }
 
 nsIWidget* nsDOMWindowUtils::GetWidgetForElement(Element* aElement) {
   if (!aElement) return GetWidget();
 
   Document* doc = aElement->GetUncomposedDoc();
-  nsIPresShell* presShell = doc ? doc->GetShell() : nullptr;
+  PresShell* presShell = doc ? doc->GetPresShell() : nullptr;
 
   if (presShell) {
     nsIFrame* frame = aElement->GetPrimaryFrame();
     if (!frame) {
       frame = presShell->GetRootFrame();
     }
     if (frame) return frame->GetNearestWidget();
   }
@@ -1371,17 +1371,17 @@ static nsresult getScrollXYAppUnits(cons
   nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(aWindow);
   nsCOMPtr<Document> doc = window ? window->GetExtantDoc() : nullptr;
   NS_ENSURE_STATE(doc);
 
   if (aFlushLayout) {
     doc->FlushPendingNotifications(FlushType::Layout);
   }
 
-  nsIPresShell* presShell = doc->GetShell();
+  PresShell* presShell = doc->GetPresShell();
   if (presShell) {
     nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
     if (sf) {
       aScrollPos = sf->GetScrollPosition();
     }
   }
   return NS_OK;
 }
@@ -1457,17 +1457,17 @@ NS_IMETHODIMP
 nsDOMWindowUtils::GetVisualViewportOffsetRelativeToLayoutViewport(
     float* aOffsetX, float* aOffsetY) {
   *aOffsetX = 0;
   *aOffsetY = 0;
 
   nsCOMPtr<Document> doc = GetDocument();
   NS_ENSURE_STATE(doc);
 
-  nsIPresShell* presShell = doc->GetShell();
+  PresShell* presShell = doc->GetPresShell();
   NS_ENSURE_TRUE(presShell, NS_ERROR_NOT_AVAILABLE);
 
   nsPoint offset = presShell->GetVisualViewportOffsetRelativeToLayoutViewport();
   *aOffsetX = nsPresContext::AppUnitsToFloatCSSPixels(offset.x);
   *aOffsetY = nsPresContext::AppUnitsToFloatCSSPixels(offset.y);
 
   return NS_OK;
 }
@@ -1476,17 +1476,17 @@ NS_IMETHODIMP
 nsDOMWindowUtils::GetVisualViewportOffset(int32_t* aOffsetX,
                                           int32_t* aOffsetY) {
   *aOffsetX = 0;
   *aOffsetY = 0;
 
   nsCOMPtr<Document> doc = GetDocument();
   NS_ENSURE_STATE(doc);
 
-  nsIPresShell* presShell = doc->GetShell();
+  PresShell* presShell = doc->GetPresShell();
   NS_ENSURE_TRUE(presShell, NS_ERROR_NOT_AVAILABLE);
 
   nsPoint offset = presShell->GetVisualViewportOffset();
   *aOffsetX = nsPresContext::AppUnitsToIntCSSPixels(offset.x);
   *aOffsetY = nsPresContext::AppUnitsToIntCSSPixels(offset.y);
 
   return NS_OK;
 }
@@ -1499,17 +1499,17 @@ nsDOMWindowUtils::GetScrollbarSize(bool 
 
   nsCOMPtr<Document> doc = GetDocument();
   NS_ENSURE_STATE(doc);
 
   if (aFlushLayout) {
     doc->FlushPendingNotifications(FlushType::Layout);
   }
 
-  nsIPresShell* presShell = doc->GetShell();
+  PresShell* presShell = doc->GetPresShell();
   NS_ENSURE_TRUE(presShell, NS_ERROR_NOT_AVAILABLE);
 
   nsIScrollableFrame* scrollFrame = presShell->GetRootScrollFrameAsScrollable();
   NS_ENSURE_TRUE(scrollFrame, NS_OK);
 
   nsMargin sizes = scrollFrame->GetActualScrollbarSizes();
   *aWidth = nsPresContext::AppUnitsToIntCSSPixels(sizes.LeftRight());
   *aHeight = nsPresContext::AppUnitsToIntCSSPixels(sizes.TopBottom());
@@ -1541,17 +1541,17 @@ nsDOMWindowUtils::GetBoundsWithoutFlushi
 
 NS_IMETHODIMP
 nsDOMWindowUtils::NeedsFlush(int32_t aFlushType, bool* aResult) {
   MOZ_ASSERT(aResult);
 
   nsCOMPtr<Document> doc = GetDocument();
   NS_ENSURE_STATE(doc);
 
-  nsIPresShell* presShell = doc->GetShell();
+  PresShell* presShell = doc->GetPresShell();
   NS_ENSURE_STATE(presShell);
 
   FlushType flushType;
   switch (aFlushType) {
     case FLUSH_STYLE:
       flushType = FlushType::Style;
       break;
 
@@ -1583,17 +1583,17 @@ nsDOMWindowUtils::FlushLayoutWithoutThro
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::GetRootBounds(DOMRect** aResult) {
   Document* doc = GetDocument();
   NS_ENSURE_STATE(doc);
 
   nsRect bounds(0, 0, 0, 0);
-  nsIPresShell* presShell = doc->GetShell();
+  PresShell* presShell = doc->GetPresShell();
   if (presShell) {
     nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
     if (sf) {
       bounds = sf->GetScrollRange();
       bounds.SetWidth(bounds.Width() + sf->GetScrollPortRect().Width());
       bounds.SetHeight(bounds.Height() + sf->GetScrollPortRect().Height());
     } else if (presShell->GetRootFrame()) {
       bounds = presShell->GetRootFrame()->GetRect();
@@ -1693,23 +1693,24 @@ nsDOMWindowUtils::DispatchDOMEventViaPre
   nsCOMPtr<nsIContent> content = do_QueryInterface(aTarget);
   NS_ENSURE_STATE(content);
   nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
   if (content->OwnerDoc()->GetWindow() != window) {
     return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
   }
   nsCOMPtr<Document> targetDoc = content->GetUncomposedDoc();
   NS_ENSURE_STATE(targetDoc);
-  RefPtr<nsIPresShell> targetShell = targetDoc->GetShell();
-  NS_ENSURE_STATE(targetShell);
+  RefPtr<PresShell> targetPresShell = targetDoc->GetPresShell();
+  NS_ENSURE_STATE(targetPresShell);
 
   targetDoc->FlushPendingNotifications(FlushType::Layout);
 
   nsEventStatus status = nsEventStatus_eIgnore;
-  targetShell->HandleEventWithTarget(internalEvent, nullptr, content, &status);
+  targetPresShell->HandleEventWithTarget(internalEvent, nullptr, content,
+                                         &status);
   *aRetVal = (status != nsEventStatus_eConsumeNoDefault);
   return NS_OK;
 }
 
 static void InitEvent(WidgetGUIEvent& aEvent,
                       LayoutDeviceIntPoint* aPt = nullptr) {
   if (aPt) {
     aEvent.mRefPoint = *aPt;
@@ -4027,17 +4028,17 @@ nsDOMWindowUtils::GetDirectionFromText(c
       return NS_ERROR_FAILURE;
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::EnsureDirtyRootFrame() {
   Document* doc = GetDocument();
-  nsIPresShell* presShell = doc ? doc->GetShell() : nullptr;
+  PresShell* presShell = doc ? doc->GetPresShell() : nullptr;
 
   if (!presShell) {
     return NS_ERROR_FAILURE;
   }
 
   nsIFrame* frame = presShell->GetRootFrame();
   if (!frame) {
     return NS_ERROR_FAILURE;
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -16,17 +16,16 @@
 #include "ContentParent.h"
 #include "nsPIDOMWindow.h"
 #include "nsIDOMChromeWindow.h"
 #include "nsIHTMLDocument.h"
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeOwner.h"
 #include "nsIFormControl.h"
 #include "nsLayoutUtils.h"
-#include "nsIPresShell.h"
 #include "nsFrameTraversal.h"
 #include "nsIWebNavigation.h"
 #include "nsCaret.h"
 #include "nsIBaseWindow.h"
 #include "nsIXULWindow.h"
 #include "nsViewManager.h"
 #include "nsFrameSelection.h"
 #include "mozilla/dom/Document.h"
@@ -55,16 +54,17 @@
 #include "mozilla/dom/Text.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventStateManager.h"
 #include "mozilla/EventStates.h"
 #include "mozilla/HTMLEditor.h"
 #include "mozilla/IMEStateManager.h"
 #include "mozilla/LookAndFeel.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/Services.h"
 #include "mozilla/Unused.h"
 #include <algorithm>
 
 #ifdef MOZ_XUL
 #  include "nsIDOMXULMenuListElement.h"
 #endif
 
@@ -1477,27 +1477,29 @@ Element* nsFocusManager::CheckIfFocusabl
     return nullptr;
   }
 
   // Make sure that our frames are up to date while ensuring the presshell is
   // also initialized in case we come from a script calling focus() early.
   mEventHandlingNeedsFlush = false;
   doc->FlushPendingNotifications(FlushType::EnsurePresShellInitAndFrames);
 
-  nsIPresShell* shell = doc->GetShell();
-  if (!shell) return nullptr;
+  PresShell* presShell = doc->GetPresShell();
+  if (!presShell) {
+    return nullptr;
+  }
 
   // the root content can always be focused,
   // except in userfocusignored context.
   if (aElement == doc->GetRootElement()) {
     return nsContentUtils::IsUserFocusIgnored(aElement) ? nullptr : aElement;
   }
 
   // cannot focus content in print preview mode. Only the root can be focused.
-  nsPresContext* presContext = shell->GetPresContext();
+  nsPresContext* presContext = presShell->GetPresContext();
   if (presContext &&
       presContext->Type() == nsPresContext::eContext_PrintPreview) {
     LOGCONTENT("Cannot focus %s while in print preview", aElement)
     return nullptr;
   }
 
   nsIFrame* frame = aElement->GetPrimaryFrame();
   if (!frame) {
@@ -2524,17 +2526,17 @@ nsresult nsFocusManager::DetermineElemen
     } else {
       return NS_OK;
     }
   }
 
   Element* rootContent = doc->GetRootElement();
   NS_ENSURE_TRUE(rootContent, NS_OK);
 
-  nsIPresShell* presShell = doc->GetShell();
+  PresShell* presShell = doc->GetPresShell();
   NS_ENSURE_TRUE(presShell, NS_OK);
 
   if (aType == MOVEFOCUS_FIRST) {
     if (!aStartContent) startContent = rootContent;
     return GetNextTabbableContent(presShell, startContent, nullptr,
                                   startContent, true, 1, false, false,
                                   aNextContent);
   }
@@ -2771,17 +2773,17 @@ nsresult nsFocusManager::DetermineElemen
     // parent document and presshell. If there is no enclosing frame element,
     // then this is a top-level, embedded or remote window.
     startContent = piWindow->GetFrameElementInternal();
     if (startContent) {
       doc = startContent->GetComposedDoc();
       NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
 
       rootContent = doc->GetRootElement();
-      presShell = doc->GetShell();
+      presShell = doc->GetPresShell();
 
       // We can focus the root element now that we have moved to another
       // document.
       mayFocusRoot = true;
 
       nsIFrame* frame = startContent->GetPrimaryFrame();
       if (!frame) {
         return NS_OK;
@@ -3621,21 +3623,22 @@ bool nsFocusManager::TryToMoveFocusToSub
         *aResultContent = GetRootForFocus(subframe, subdoc, false, true);
         if (*aResultContent) {
           NS_ADDREF(*aResultContent);
           return true;
         }
       }
     }
     Element* rootElement = subdoc->GetRootElement();
-    nsIPresShell* subShell = subdoc->GetShell();
-    if (rootElement && subShell) {
+    PresShell* subPresShell = subdoc->GetPresShell();
+    if (rootElement && subPresShell) {
       nsresult rv = GetNextTabbableContent(
-          subShell, rootElement, aOriginalStartContent, rootElement, aForward,
-          (aForward ? 1 : 0), false, aForDocumentNavigation, aResultContent);
+          subPresShell, rootElement, aOriginalStartContent, rootElement,
+          aForward, (aForward ? 1 : 0), false, aForDocumentNavigation,
+          aResultContent);
       NS_ENSURE_SUCCESS(rv, false);
       if (*aResultContent) {
         return true;
       }
     }
   }
   return false;
 }
@@ -3768,17 +3771,17 @@ nsresult nsFocusManager::FocusFirst(Elem
       }
     }
 
     nsCOMPtr<nsIDocShell> docShell = doc->GetDocShell();
     if (docShell->ItemType() == nsIDocShellTreeItem::typeChrome) {
       // If the found content is in a chrome shell, navigate forward one
       // tabbable item so that the first item is focused. Note that we
       // always go forward and not back here.
-      nsIPresShell* presShell = doc->GetShell();
+      PresShell* presShell = doc->GetPresShell();
       if (presShell) {
         return GetNextTabbableContent(presShell, aRootElement, nullptr,
                                       aRootElement, true, 1, false, false,
                                       aNextContent);
       }
     }
   }
 
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -11,17 +11,16 @@
 
 #include "base/basictypes.h"
 
 #include "prenv.h"
 
 #include "nsDocShell.h"
 #include "nsIDOMMozBrowserFrame.h"
 #include "nsIDOMWindow.h"
-#include "nsIPresShell.h"
 #include "nsIContentInlines.h"
 #include "nsIContentViewer.h"
 #include "mozilla/dom/Document.h"
 #include "nsPIDOMWindow.h"
 #include "nsIWebNavigation.h"
 #include "nsIWebProgress.h"
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeOwner.h"
@@ -81,16 +80,17 @@
 #include "mozilla/Unused.h"
 #include "mozilla/dom/ChromeMessageSender.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/FrameLoaderBinding.h"
 #include "mozilla/dom/MozFrameLoaderOwnerBinding.h"
 #include "mozilla/gfx/CrossProcessPaint.h"
 #include "mozilla/jsipc/CrossProcessObjectWrappers.h"
 #include "mozilla/layout/RenderFrame.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/ServoCSSParser.h"
 #include "mozilla/ServoStyleSet.h"
 #include "nsGenericHTMLFrameElement.h"
 #include "GeckoProfiler.h"
 
 #include "jsapi.h"
 #include "mozilla/dom/HTMLIFrameElement.h"
 #include "nsSandboxFlags.h"
@@ -1000,19 +1000,19 @@ nsresult nsFrameLoader::SwapWithOtherRem
 
   Document* ourDoc = ourContent->GetComposedDoc();
   Document* otherDoc = otherContent->GetComposedDoc();
   if (!ourDoc || !otherDoc) {
     // Again, how odd, given that we had docshells
     return NS_ERROR_NOT_IMPLEMENTED;
   }
 
-  nsIPresShell* ourShell = ourDoc->GetShell();
-  nsIPresShell* otherShell = otherDoc->GetShell();
-  if (!ourShell || !otherShell) {
+  PresShell* ourPresShell = ourDoc->GetPresShell();
+  PresShell* otherPresShell = otherDoc->GetPresShell();
+  if (!ourPresShell || !otherPresShell) {
     return NS_ERROR_NOT_IMPLEMENTED;
   }
 
   // FIXME: Consider supporting FrameLoader swapping for remote sub frames.
   if (mBrowserBridgeChild) {
     return NS_ERROR_NOT_IMPLEMENTED;
   }
 
@@ -1148,18 +1148,18 @@ nsresult nsFrameLoader::SwapWithOtherRem
   // to ourselves to make sure we don't die while we overwrite our reference to
   // ourself.
   RefPtr<nsFrameLoader> kungFuDeathGrip(this);
   aThisOwner->SetFrameLoader(aOther);
   aOtherOwner->SetFrameLoader(kungFuDeathGrip);
 
   ourFrameFrame->EndSwapDocShells(otherFrame);
 
-  ourShell->BackingScaleFactorChanged();
-  otherShell->BackingScaleFactorChanged();
+  ourPresShell->BackingScaleFactorChanged();
+  otherPresShell->BackingScaleFactorChanged();
 
   // Initialize browser API if needed now that owner content has changed.
   InitializeBrowserAPI();
   aOther->InitializeBrowserAPI();
 
   mInSwap = aOther->mInSwap = false;
 
   // Send an updated tab context since owner content type may have changed.
@@ -1412,19 +1412,19 @@ nsresult nsFrameLoader::SwapWithOtherLoa
   if (!ourDoc || !otherDoc) {
     // Again, how odd, given that we had docshells
     return NS_ERROR_NOT_IMPLEMENTED;
   }
 
   NS_ASSERTION(ourDoc == ourParentDocument, "Unexpected parent document");
   NS_ASSERTION(otherDoc == otherParentDocument, "Unexpected parent document");
 
-  nsIPresShell* ourShell = ourDoc->GetShell();
-  nsIPresShell* otherShell = otherDoc->GetShell();
-  if (!ourShell || !otherShell) {
+  PresShell* ourPresShell = ourDoc->GetPresShell();
+  PresShell* otherPresShell = otherDoc->GetPresShell();
+  if (!ourPresShell || !otherPresShell) {
     return NS_ERROR_NOT_IMPLEMENTED;
   }
 
   if (ourDocshell->GetIsIsolatedMozBrowserElement() !=
       otherDocshell->GetIsIsolatedMozBrowserElement()) {
     return NS_ERROR_NOT_IMPLEMENTED;
   }
 
@@ -1571,18 +1571,18 @@ nsresult nsFrameLoader::SwapWithOtherLoa
 
   ourFrameFrame->EndSwapDocShells(otherFrame);
 
   // If the content being swapped came from windows on two screens with
   // incompatible backing resolution (e.g. dragging a tab between windows on
   // hi-dpi and low-dpi screens), it will have style data that is based on
   // the wrong appUnitsPerDevPixel value. So we tell the PresShells that their
   // backing scale factor may have changed. (Bug 822266)
-  ourShell->BackingScaleFactorChanged();
-  otherShell->BackingScaleFactorChanged();
+  ourPresShell->BackingScaleFactorChanged();
+  otherPresShell->BackingScaleFactorChanged();
 
   // Initialize browser API if needed now that owner content has changed
   InitializeBrowserAPI();
   aOther->InitializeBrowserAPI();
 
   return NS_OK;
 }
 
@@ -3092,17 +3092,17 @@ already_AddRefed<mozilla::dom::Promise> 
     return nullptr;
   }
 
   RefPtr<Document> document = GetOwnerContent()->GetOwnerDocument();
   if (NS_WARN_IF(!document)) {
     aRv = NS_ERROR_FAILURE;
     return nullptr;
   }
-  nsIPresShell* presShell = document->GetShell();
+  PresShell* presShell = document->GetPresShell();
   if (NS_WARN_IF(!presShell)) {
     aRv = NS_ERROR_FAILURE;
     return nullptr;
   }
 
   nscolor color;
   css::Loader* loader = document->CSSLoader();
   ServoStyleSet* set = presShell->StyleSet();
--- a/dom/base/nsGlobalWindowInner.cpp
+++ b/dom/base/nsGlobalWindowInner.cpp
@@ -91,16 +91,17 @@
 #include "mozilla/dom/WorkerCommon.h"
 #include "mozilla/dom/ToJSValue.h"
 #include "nsJSPrincipals.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/Debug.h"
 #include "mozilla/EventListenerManager.h"
 #include "mozilla/EventStates.h"
 #include "mozilla/MouseEvents.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/ProcessHangMonitor.h"
 #include "mozilla/ScrollTypes.h"
 #include "mozilla/ThrottledEventQueue.h"
 #include "AudioChannelService.h"
 #include "nsAboutProtocolUtils.h"
 #include "nsCharTraits.h"  // NS_IS_HIGH/LOW_SURROGATE
 #include "PostMessageEvent.h"
 #include "mozilla/dom/DocGroup.h"
@@ -118,17 +119,16 @@
 #include "nsIContent.h"
 #include "nsIDocShell.h"
 #include "mozilla/dom/Document.h"
 #include "Crypto.h"
 #include "nsDOMString.h"
 #include "nsIEmbeddingSiteWindow.h"
 #include "nsThreadUtils.h"
 #include "nsILoadContext.h"
-#include "nsIPresShell.h"
 #include "nsIScrollableFrame.h"
 #include "nsView.h"
 #include "nsViewManager.h"
 #include "nsISelectionController.h"
 #include "nsIPrompt.h"
 #include "nsIPromptService.h"
 #include "nsIPromptFactory.h"
 #include "nsIAddonPolicyService.h"
@@ -1131,19 +1131,19 @@ void nsGlobalWindowInner::FreeInnerObjec
     mDocumentURI = mDoc->GetDocumentURI();
     mDocBaseURI = mDoc->GetDocBaseURI();
 
     while (mDoc->EventHandlingSuppressed()) {
       mDoc->UnsuppressEventHandlingAndFireEvents(false);
     }
 
     if (mObservingDidRefresh) {
-      nsIPresShell* shell = mDoc->GetShell();
-      if (shell) {
-        Unused << shell->RemovePostRefreshObserver(this);
+      PresShell* presShell = mDoc->GetPresShell();
+      if (presShell) {
+        Unused << presShell->RemovePostRefreshObserver(this);
       }
     }
   }
 
   // Remove our reference to the document and the document principal.
   mFocusedElement = nullptr;
 
   if (mApplicationCache) {
@@ -6253,18 +6253,18 @@ already_AddRefed<Promise> nsGlobalWindow
     return nullptr;
   }
 
   if (!mDoc) {
     aError.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  nsIPresShell* shell = mDoc->GetShell();
-  if (!shell) {
+  PresShell* presShell = mDoc->GetPresShell();
+  if (!presShell) {
     aError.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   // We need to associate the lifetime of the Promise to the lifetime
   // of the caller's global. That way, if the window we're observing
   // refresh driver ticks on goes away before our observer is fired,
   // we can still resolve the Promise.
@@ -6277,23 +6277,23 @@ already_AddRefed<Promise> nsGlobalWindow
   RefPtr<Promise> resultPromise = Promise::Create(global, aError);
   if (aError.Failed()) {
     return nullptr;
   }
 
   UniquePtr<PromiseDocumentFlushedResolver> flushResolver(
       new PromiseDocumentFlushedResolver(resultPromise, aCallback));
 
-  if (!shell->NeedStyleFlush() && !shell->NeedLayoutFlush()) {
+  if (!presShell->NeedStyleFlush() && !presShell->NeedLayoutFlush()) {
     flushResolver->Call();
     return resultPromise.forget();
   }
 
   if (!mObservingDidRefresh) {
-    bool success = shell->AddPostRefreshObserver(this);
+    bool success = presShell->AddPostRefreshObserver(this);
     if (!success) {
       aError.Throw(NS_ERROR_FAILURE);
       return nullptr;
     }
     mObservingDidRefresh = true;
   }
 
   mDocumentFlushedResolvers.AppendElement(std::move(flushResolver));
@@ -6330,19 +6330,19 @@ void nsGlobalWindowInner::CallOrCancelDo
     if (!mDocumentFlushedResolvers.Length()) {
       break;
     }
 
     // If there are new items, the observer is not added for them when calling
     // PromiseDocumentFlushed.  Add here and leave.
     // FIXME: Handle this case inside PromiseDocumentFlushed (bug 1442824).
     if (mDoc) {
-      nsIPresShell* shell = mDoc->GetShell();
-      if (shell) {
-        (void)shell->AddPostRefreshObserver(this);
+      PresShell* presShell = mDoc->GetPresShell();
+      if (presShell) {
+        Unused << presShell->AddPostRefreshObserver(this);
         break;
       }
     }
 
     // If we fail adding observer, keep looping to resolve or reject all
     // promises.  This case happens while destroying window.
     // This violates the constraint that the promiseDocumentFlushed callback
     // only ever run when no flush needed, but it's necessary to resolve
@@ -6361,29 +6361,29 @@ void nsGlobalWindowInner::CancelDocument
 void nsGlobalWindowInner::DidRefresh() {
   auto rejectionGuard = MakeScopeExit([&] {
     CancelDocumentFlushedResolvers();
     mObservingDidRefresh = false;
   });
 
   MOZ_ASSERT(mDoc);
 
-  nsIPresShell* shell = mDoc->GetShell();
-  MOZ_ASSERT(shell);
-
-  if (shell->NeedStyleFlush() || shell->NeedLayoutFlush()) {
+  PresShell* presShell = mDoc->GetPresShell();
+  MOZ_ASSERT(presShell);
+
+  if (presShell->NeedStyleFlush() || presShell->NeedLayoutFlush()) {
     // By the time our observer fired, something has already invalidated
     // style or layout - or perhaps we're still in the middle of a flush that
     // was interrupted. In either case, we'll wait until the next refresh driver
     // tick instead and try again.
     rejectionGuard.release();
     return;
   }
 
-  bool success = shell->RemovePostRefreshObserver(this);
+  bool success = presShell->RemovePostRefreshObserver(this);
   if (!success) {
     return;
   }
 
   rejectionGuard.release();
 
   CallDocumentFlushedResolvers();
   mObservingDidRefresh = false;
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -51,16 +51,17 @@
 #include "js/Wrapper.h"
 #include "nsIArray.h"
 #include "nsIObjectInputStream.h"
 #include "nsIObjectOutputStream.h"
 #include "WrapperFactory.h"
 #include "nsGlobalWindow.h"
 #include "mozilla/AutoRestore.h"
 #include "mozilla/MainThreadIdlePeriod.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/StaticPrefs.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/dom/DOMException.h"
 #include "mozilla/dom/DOMExceptionBinding.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/ErrorEvent.h"
 #include "mozilla/dom/FetchUtil.h"
 #include "mozilla/dom/ScriptSettings.h"
@@ -84,17 +85,16 @@
 #include "mozilla/Attributes.h"
 #include "mozilla/dom/CanvasRenderingContext2DBinding.h"
 #include "mozilla/ContentEvents.h"
 #include "mozilla/CycleCollectedJSContext.h"
 #include "nsCycleCollectionNoteRootCallback.h"
 #include "GeckoProfiler.h"
 #include "mozilla/IdleTaskRunner.h"
 #include "nsIDocShell.h"
-#include "nsIPresShell.h"
 #include "nsViewManager.h"
 #include "mozilla/EventStateManager.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 const size_t gStackSize = 8192;
 
@@ -1938,17 +1938,17 @@ void nsJSContext::MaybeRunNextCollectorS
 
   Document* rootDocument = root->GetDocument();
   if (!rootDocument ||
       rootDocument->GetReadyStateEnum() != Document::READYSTATE_COMPLETE ||
       rootDocument->IsInBackgroundWindow()) {
     return;
   }
 
-  nsIPresShell* presShell = rootDocument->GetShell();
+  PresShell* presShell = rootDocument->GetPresShell();
   if (!presShell) {
     return;
   }
 
   nsViewManager* vm = presShell->GetViewManager();
   if (!vm) {
     return;
   }
--- a/dom/base/nsNodeUtils.cpp
+++ b/dom/base/nsNodeUtils.cpp
@@ -26,16 +26,17 @@
 #include "nsGenericHTMLElement.h"
 #include "mozilla/AnimationTarget.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/dom/Animation.h"
 #include "mozilla/dom/HTMLImageElement.h"
 #include "mozilla/dom/HTMLMediaElement.h"
 #include "mozilla/dom/KeyframeEffect.h"
+#include "mozilla/PresShell.h"
 #include "nsWrapperCacheInlines.h"
 #include "nsObjectLoadingContent.h"
 #include "nsDOMMutationObserver.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/CustomElementRegistry.h"
 #include "mozilla/dom/HTMLTemplateElement.h"
 #include "mozilla/dom/ShadowRoot.h"
 
@@ -62,18 +63,18 @@ enum class IsRemoveNotification {
   bool needsEnterLeave = doc->MayHaveDOMMutationObservers();                  \
   if (needsEnterLeave) {                                                      \
     nsDOMMutationObserver::EnterMutationHandling();                           \
   }                                                                           \
   nsINode* node = content_;                                                   \
   COMPOSED_DOC_DECL                                                           \
   NS_ASSERTION(node->OwnerDoc() == doc, "Bogus document");                    \
   if (remove_ == IsRemoveNotification::Yes && node->GetComposedDoc()) {       \
-    if (nsIPresShell* shell = doc->GetObservingShell()) {                     \
-      shell->func_ params_;                                                   \
+    if (PresShell* presShell = doc->GetObservingPresShell()) {                \
+      presShell->func_ params_;                                               \
     }                                                                         \
   }                                                                           \
   doc->BindingManager()->func_ params_;                                       \
   nsINode* last;                                                              \
   do {                                                                        \
     nsINode::nsSlots* slots = node->GetExistingSlots();                       \
     if (slots && !slots->mMutationObservers.IsEmpty()) {                      \
       NS_OBSERVER_AUTO_ARRAY_NOTIFY_OBSERVERS(                                \
@@ -88,18 +89,18 @@ enum class IsRemoveNotification {
   } while (node);                                                             \
   /* Whitelist NativeAnonymousChildListChange removal notifications from      \
    * the assertion since it runs from UnbindFromTree, and thus we don't       \
    * reach the document, but doesn't matter. */                               \
   MOZ_ASSERT((last == doc) == wasInComposedDoc ||                             \
              (remove_ == IsRemoveNotification::Yes &&                         \
               !strcmp(#func_, "NativeAnonymousChildListChange")));            \
   if (remove_ == IsRemoveNotification::No && last == doc) {                   \
-    if (nsIPresShell* shell = doc->GetObservingShell()) {                     \
-      shell->func_ params_;                                                   \
+    if (PresShell* presShell = doc->GetObservingPresShell()) {                \
+      presShell->func_ params_;                                               \
     }                                                                         \
   }                                                                           \
   if (needsEnterLeave) {                                                      \
     nsDOMMutationObserver::LeaveMutationHandling();                           \
   }                                                                           \
   PR_END_MACRO
 
 #define IMPL_ANIMATION_NOTIFICATION(func_, content_, params_) \
--- a/dom/base/nsObjectLoadingContent.cpp
+++ b/dom/base/nsObjectLoadingContent.cpp
@@ -21,17 +21,16 @@
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIObjectFrame.h"
 #include "nsIOService.h"
 #include "nsIPermissionManager.h"
 #include "nsPluginHost.h"
 #include "nsPluginInstanceOwner.h"
 #include "nsJSNPRuntime.h"
 #include "nsINestedURI.h"
-#include "nsIPresShell.h"
 #include "nsScriptSecurityManager.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIStreamConverterService.h"
 #include "nsIURILoader.h"
 #include "nsIURL.h"
 #include "nsIWebNavigation.h"
 #include "nsIWebNavigationInfo.h"
 #include "nsIScriptChannel.h"
@@ -87,16 +86,17 @@
 #include "mozilla/IMEStateManager.h"
 #include "mozilla/widget/IMEData.h"
 #include "mozilla/IntegerPrintfMacros.h"
 #include "mozilla/dom/HTMLObjectElementBinding.h"
 #include "mozilla/dom/HTMLEmbedElement.h"
 #include "mozilla/dom/HTMLObjectElement.h"
 #include "mozilla/net/UrlClassifierFeatureFactory.h"
 #include "mozilla/LoadInfo.h"
+#include "mozilla/PresShell.h"
 #include "nsChannelClassifier.h"
 #include "nsFocusManager.h"
 
 #ifdef XP_WIN
 // Thanks so much, Microsoft! :(
 #  ifdef CreateEvent
 #    undef CreateEvent
 #  endif
@@ -2480,19 +2480,19 @@ void nsObjectLoadingContent::NotifyState
       thisEl->NotifyUAWidgetTeardown();
     } else if (!hadProblemState && hasProblemState) {
       thisEl->AttachAndSetUAShadowRoot();
       thisEl->NotifyUAWidgetSetupOrChange();
     }
   } else if (aOldType != mType) {
     // If our state changed, then we already recreated frames
     // Otherwise, need to do that here
-    nsCOMPtr<nsIPresShell> shell = doc->GetShell();
-    if (shell) {
-      shell->PostRecreateFramesFor(thisEl);
+    RefPtr<PresShell> presShell = doc->GetPresShell();
+    if (presShell) {
+      presShell->PostRecreateFramesFor(thisEl);
     }
   }
 
   if (aSync) {
     MOZ_ASSERT(InActiveDocument(thisEl), "Something is confused");
     // Make sure that frames are actually constructed immediately.
     doc->FlushPendingNotifications(FlushType::Frames);
   }
--- a/dom/base/nsRange.cpp
+++ b/dom/base/nsRange.cpp
@@ -25,16 +25,17 @@
 #include "mozilla/dom/DocumentFragment.h"
 #include "mozilla/dom/DocumentType.h"
 #include "mozilla/dom/RangeBinding.h"
 #include "mozilla/dom/DOMRect.h"
 #include "mozilla/dom/DOMStringList.h"
 #include "mozilla/dom/ShadowRoot.h"
 #include "mozilla/dom/Selection.h"
 #include "mozilla/dom/Text.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/Likely.h"
 #include "nsCSSFrameConstructor.h"
 #include "nsStyleStruct.h"
 #include "nsStyleStructInlines.h"
 #include "nsComputedDOMStyle.h"
 #include "mozilla/dom/InspectorFontFace.h"
@@ -63,18 +64,18 @@ static void InvalidateAllFrames(nsINode*
     case nsINode::TEXT_NODE:
     case nsINode::ELEMENT_NODE: {
       nsIContent* content = static_cast<nsIContent*>(aNode);
       frame = content->GetPrimaryFrame();
       break;
     }
     case nsINode::DOCUMENT_NODE: {
       Document* doc = static_cast<Document*>(aNode);
-      nsIPresShell* shell = doc ? doc->GetShell() : nullptr;
-      frame = shell ? shell->GetRootFrame() : nullptr;
+      PresShell* presShell = doc ? doc->GetPresShell() : nullptr;
+      frame = presShell ? presShell->GetRootFrame() : nullptr;
       break;
     }
   }
   for (nsIFrame* f = frame; f; f = f->GetNextContinuation()) {
     f->InvalidateFrameSubtree();
   }
 }
 
@@ -2723,18 +2724,18 @@ static void ExtractRectFromOffset(nsIFra
       aR->SetWidth(aR->XMost() - point.x);
       aR->x = point.x;
     }
   }
 }
 
 static nsTextFrame* GetTextFrameForContent(nsIContent* aContent,
                                            bool aFlushLayout) {
-  Document* doc = aContent->OwnerDoc();
-  nsIPresShell* presShell = doc->GetShell();
+  RefPtr<Document> doc = aContent->OwnerDoc();
+  PresShell* presShell = doc->GetPresShell();
   if (!presShell) {
     return nullptr;
   }
 
   // Try to un-suppress whitespace if needed, but only if we'll be able to flush
   // to immediately see the results of the un-suppression. If we can't flush
   // here, then calling EnsureFrameForTextNodeIsCreatedAfterFlush would be
   // pointless anyway.
--- a/dom/canvas/CanvasRenderingContext2D.h
+++ b/dom/canvas/CanvasRenderingContext2D.h
@@ -15,16 +15,17 @@
 #include "gfxTextRun.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/dom/BasicRenderingContext2D.h"
 #include "mozilla/dom/CanvasGradient.h"
 #include "mozilla/dom/CanvasRenderingContext2DBinding.h"
 #include "mozilla/dom/CanvasPattern.h"
 #include "mozilla/gfx/Rect.h"
 #include "mozilla/gfx/2D.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/UniquePtr.h"
 #include "gfx2DGlue.h"
 #include "imgIEncoder.h"
 #include "nsLayoutUtils.h"
 #include "mozilla/EnumeratedArray.h"
 #include "FilterSupport.h"
 #include "SVGObserverUtils.h"
 #include "Layers.h"
@@ -387,17 +388,17 @@ class CanvasRenderingContext2D final : p
   virtual int32_t GetHeight() override { return GetSize().height; }
 
   // nsICanvasRenderingContextInternal
   /**
    * Gets the pres shell from either the canvas element or the doc shell
    */
   nsIPresShell* GetPresShell() final {
     if (mCanvasElement) {
-      return mCanvasElement->OwnerDoc()->GetShell();
+      return mCanvasElement->OwnerDoc()->GetPresShell();
     }
     if (mDocShell) {
       return mDocShell->GetPresShell();
     }
     return nullptr;
   }
   NS_IMETHOD SetDimensions(int32_t aWidth, int32_t aHeight) override;
   NS_IMETHOD InitializeWithDrawTarget(
--- a/dom/canvas/nsICanvasRenderingContextInternal.h
+++ b/dom/canvas/nsICanvasRenderingContextInternal.h
@@ -8,16 +8,17 @@
 
 #include "mozilla/gfx/2D.h"
 #include "nsISupports.h"
 #include "nsIInputStream.h"
 #include "nsIDocShell.h"
 #include "nsRefreshDriver.h"
 #include "mozilla/dom/HTMLCanvasElement.h"
 #include "mozilla/dom/OffscreenCanvas.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/RefPtr.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/NotNull.h"
 
 #define NS_ICANVASRENDERINGCONTEXTINTERNAL_IID       \
   {                                                  \
     0xb84f2fed, 0x9d4b, 0x430b, {                    \
       0xbd, 0xfb, 0x85, 0x57, 0x8a, 0xc2, 0xb4, 0x4b \
@@ -53,17 +54,17 @@ class nsICanvasRenderingContextInternal 
   void SetCanvasElement(mozilla::dom::HTMLCanvasElement* parentCanvas) {
     RemovePostRefreshObserver();
     mCanvasElement = parentCanvas;
     AddPostRefreshObserverIfNecessary();
   }
 
   virtual nsIPresShell* GetPresShell() {
     if (mCanvasElement) {
-      return mCanvasElement->OwnerDoc()->GetShell();
+      return mCanvasElement->OwnerDoc()->GetPresShell();
     }
     return nullptr;
   }
 
   void RemovePostRefreshObserver() {
     if (mRefreshDriver) {
       mRefreshDriver->RemovePostRefreshObserver(this);
       mRefreshDriver = nullptr;
--- a/dom/events/ContentEventHandler.cpp
+++ b/dom/events/ContentEventHandler.cpp
@@ -3,30 +3,30 @@
 /* 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 "ContentEventHandler.h"
 
 #include "mozilla/ContentIterator.h"
 #include "mozilla/IMEStateManager.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/TextComposition.h"
 #include "mozilla/TextEvents.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/HTMLUnknownElement.h"
 #include "mozilla/dom/Selection.h"
 #include "nsCaret.h"
 #include "nsCOMPtr.h"
 #include "nsContentUtils.h"
 #include "nsCopySupport.h"
 #include "nsElementTable.h"
 #include "nsFocusManager.h"
 #include "nsFontMetrics.h"
 #include "nsFrameSelection.h"
-#include "nsIPresShell.h"
 #include "nsIFrame.h"
 #include "nsIObjectFrame.h"
 #include "nsLayoutUtils.h"
 #include "nsPresContext.h"
 #include "nsQueryObject.h"
 #include "nsRange.h"
 #include "nsTextFragment.h"
 #include "nsTextFrame.h"
@@ -282,17 +282,17 @@ nsresult ContentEventHandler::InitRootCo
   // See bug 537041 comment 5, the range could have removed node.
   if (NS_WARN_IF(startNode->GetComposedDoc() != mDocument)) {
     return NS_ERROR_FAILURE;
   }
 
   NS_ASSERTION(startNode->GetComposedDoc() == endNode->GetComposedDoc(),
                "firstNormalSelectionRange crosses the document boundary");
 
-  mRootContent = startNode->GetSelectionRootContent(mDocument->GetShell());
+  mRootContent = startNode->GetSelectionRootContent(mDocument->GetPresShell());
   if (NS_WARN_IF(!mRootContent)) {
     return NS_ERROR_FAILURE;
   }
 
   return NS_OK;
 }
 
 nsresult ContentEventHandler::InitCommon(SelectionType aSelectionType,
@@ -304,18 +304,18 @@ nsresult ContentEventHandler::InitCommon
   mSelection = nullptr;
   mRootContent = nullptr;
   mFirstSelectedRawRange.Clear();
 
   nsresult rv = InitBasic(aRequireFlush);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsISelectionController> selectionController;
-  if (nsIPresShell* shell = mDocument->GetShell()) {
-    selectionController = shell->GetSelectionControllerForFocusedContent();
+  if (PresShell* presShell = mDocument->GetPresShell()) {
+    selectionController = presShell->GetSelectionControllerForFocusedContent();
   }
   if (NS_WARN_IF(!selectionController)) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   mSelection =
       selectionController->GetSelection(ToRawSelectionType(aSelectionType));
   if (NS_WARN_IF(!mSelection)) {
@@ -960,18 +960,18 @@ nsresult ContentEventHandler::ExpandToCl
   // boundaries. It's false, but no problem now, maybe.
   if (!aContent->IsText() || *aXPOffset == 0 ||
       *aXPOffset == aContent->TextLength()) {
     return NS_OK;
   }
 
   NS_ASSERTION(*aXPOffset <= aContent->TextLength(), "offset is out of range.");
 
-  MOZ_DIAGNOSTIC_ASSERT(mDocument->GetShell());
-  RefPtr<nsFrameSelection> fs = mDocument->GetShell()->FrameSelection();
+  MOZ_DIAGNOSTIC_ASSERT(mDocument->GetPresShell());
+  RefPtr<nsFrameSelection> fs = mDocument->GetPresShell()->FrameSelection();
   int32_t offsetInFrame;
   CaretAssociationHint hint =
       aForward ? CARET_ASSOCIATE_BEFORE : CARET_ASSOCIATE_AFTER;
   nsIFrame* frame = fs->GetFrameForNodeOffset(aContent, int32_t(*aXPOffset),
                                               hint, &offsetInFrame);
   if (frame) {
     int32_t startOffset, endOffset;
     nsresult rv = frame->GetOffsets(startOffset, endOffset);
@@ -2506,19 +2506,19 @@ nsresult ContentEventHandler::OnQueryCha
   nsresult rv = Init(aEvent);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   aEvent->mReply.mOffset = aEvent->mReply.mTentativeCaretOffset =
       WidgetQueryContentEvent::NOT_FOUND;
 
-  nsIPresShell* shell = mDocument->GetShell();
-  NS_ENSURE_TRUE(shell, NS_ERROR_FAILURE);
-  nsIFrame* rootFrame = shell->GetRootFrame();
+  PresShell* presShell = mDocument->GetPresShell();
+  NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
+  nsIFrame* rootFrame = presShell->GetRootFrame();
   NS_ENSURE_TRUE(rootFrame, NS_ERROR_FAILURE);
   nsIWidget* rootWidget = rootFrame->GetNearestWidget();
   NS_ENSURE_TRUE(rootWidget, NS_ERROR_FAILURE);
 
   // The root frame's widget might be different, e.g., the event was fired on
   // a popup but the rootFrame is the document root.
   if (rootWidget != aEvent->mWidget) {
     MOZ_ASSERT(aEvent->mWidget, "The event must have the widget");
@@ -2618,19 +2618,19 @@ nsresult ContentEventHandler::OnQueryDOM
     return rv;
   }
 
   aEvent->mSucceeded = false;
   aEvent->mReply.mWidgetIsHit = false;
 
   NS_ENSURE_TRUE(aEvent->mWidget, NS_ERROR_FAILURE);
 
-  nsIPresShell* shell = mDocument->GetShell();
-  NS_ENSURE_TRUE(shell, NS_ERROR_FAILURE);
-  nsIFrame* docFrame = shell->GetRootFrame();
+  PresShell* presShell = mDocument->GetPresShell();
+  NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
+  nsIFrame* docFrame = presShell->GetRootFrame();
   NS_ENSURE_TRUE(docFrame, NS_ERROR_FAILURE);
 
   LayoutDeviceIntPoint eventLoc =
       aEvent->mRefPoint + aEvent->mWidget->WidgetToScreenOffset();
   CSSIntRect docFrameRect = docFrame->GetScreenRect();
   CSSIntPoint eventLocCSS(
       docFrame->PresContext()->DevPixelsToIntCSSPixels(eventLoc.x) -
           docFrameRect.x,
--- a/dom/events/EventListenerManager.cpp
+++ b/dom/events/EventListenerManager.cpp
@@ -13,16 +13,17 @@
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventListenerManager.h"
 #include "mozilla/HalSensor.h"
 #include "mozilla/InternalMutationEvent.h"
 #include "mozilla/JSEventHandler.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/Event.h"
 #include "mozilla/dom/EventTargetBinding.h"
 #include "mozilla/dom/LoadedScript.h"
 #include "mozilla/dom/PopupBlocker.h"
 #include "mozilla/dom/ScriptLoader.h"
 #include "mozilla/dom/ScriptSettings.h"
@@ -440,19 +441,19 @@ void EventListenerManager::ProcessApzAwa
     if (nsCOMPtr<DOMEventTargetHelper> helper = do_QueryInterface(mTarget)) {
       if (nsPIDOMWindowInner* window = helper->GetOwner()) {
         doc = window->GetExtantDoc();
       }
     }
   }
 
   if (doc && gfxPlatform::AsyncPanZoomEnabled()) {
-    nsIPresShell* ps = doc->GetShell();
-    if (ps) {
-      nsIFrame* f = ps->GetRootFrame();
+    PresShell* presShell = doc->GetPresShell();
+    if (presShell) {
+      nsIFrame* f = presShell->GetRootFrame();
       if (f) {
         f->SchedulePaint();
       }
     }
   }
 }
 
 bool EventListenerManager::IsDeviceType(EventMessage aEventMessage) {
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -850,19 +850,19 @@ void EventStateManager::NotifyTargetUser
   MOZ_ASSERT(aEvent->mMessage == eKeyDown || aEvent->mMessage == eMouseDown ||
              aEvent->mMessage == ePointerDown || aEvent->mMessage == eTouchEnd);
   doc->NotifyUserGestureActivation();
 }
 
 already_AddRefed<EventStateManager> EventStateManager::ESMFromContentOrThis(
     nsIContent* aContent) {
   if (aContent) {
-    nsIPresShell* shell = aContent->OwnerDoc()->GetShell();
-    if (shell) {
-      nsPresContext* prescontext = shell->GetPresContext();
+    PresShell* presShell = aContent->OwnerDoc()->GetPresShell();
+    if (presShell) {
+      nsPresContext* prescontext = presShell->GetPresContext();
       if (prescontext) {
         RefPtr<EventStateManager> esm = prescontext->EventStateManager();
         if (esm) {
           return esm.forget();
         }
       }
     }
   }
@@ -4297,19 +4297,19 @@ void EventStateManager::NotifyMouseOver(
 
   // Check to see if we're a subdocument and if so update the parent
   // document's ESM state to indicate that the mouse is over the
   // content associated with our subdocument.
   EnsureDocument(mPresContext);
   if (Document* parentDoc = mDocument->GetParentDocument()) {
     if (nsCOMPtr<nsIContent> docContent =
             parentDoc->FindContentForSubDocument(mDocument)) {
-      if (nsIPresShell* parentShell = parentDoc->GetShell()) {
+      if (PresShell* parentPresShell = parentDoc->GetPresShell()) {
         RefPtr<EventStateManager> parentESM =
-            parentShell->GetPresContext()->EventStateManager();
+            parentPresShell->GetPresContext()->EventStateManager();
         parentESM->NotifyMouseOver(aMouseEvent, docContent);
       }
     }
   }
   // Firing the DOM event in the parent document could cause all kinds
   // of havoc.  Reverify and take care.
   if (wrapper->mLastOverElement == aContent) return;
 
--- a/dom/events/IMEStateManager.cpp
+++ b/dom/events/IMEStateManager.cpp
@@ -9,16 +9,17 @@
 #include "mozilla/IMEStateManager.h"
 
 #include "mozilla/Attributes.h"
 #include "mozilla/EditorBase.h"
 #include "mozilla/EventListenerManager.h"
 #include "mozilla/EventStates.h"
 #include "mozilla/MouseEvents.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/TextComposition.h"
 #include "mozilla/TextEvents.h"
 #include "mozilla/Unused.h"
 #include "mozilla/dom/HTMLFormElement.h"
 #include "mozilla/dom/MouseEventBinding.h"
 #include "mozilla/dom/TabParent.h"
 
 #include "HTMLInputElement.h"
@@ -27,17 +28,16 @@
 #include "nsCOMPtr.h"
 #include "nsContentUtils.h"
 #include "nsIContent.h"
 #include "mozilla/dom/Document.h"
 #include "nsIForm.h"
 #include "nsIFormControl.h"
 #include "nsINode.h"
 #include "nsIObserverService.h"
-#include "nsIPresShell.h"
 #include "nsISupports.h"
 #include "nsPresContext.h"
 
 namespace mozilla {
 
 using namespace dom;
 using namespace widget;
 
@@ -917,21 +917,21 @@ void IMEStateManager::UpdateIMEState(con
 
   if (sIsGettingNewIMEState) {
     MOZ_LOG(sISMLog, LogLevel::Debug,
             ("  UpdateIMEState(), "
              "does nothing because of called while getting new IME state"));
     return;
   }
 
-  nsCOMPtr<nsIPresShell> presShell;
+  RefPtr<PresShell> presShell;
   if (!aEditorBase) {
     MOZ_ASSERT(aContent, "we must have content");
     Document* doc = aContent->OwnerDoc();
-    presShell = doc->GetShell();
+    presShell = doc->GetPresShell();
   } else {
     presShell = aEditorBase->GetPresShell();
   }
 
   if (NS_WARN_IF(!presShell)) {
     MOZ_LOG(sISMLog, LogLevel::Error,
             ("  UpdateIMEState(), FAILED due to "
              "editor doesn't have PresShell"));
--- a/dom/events/PointerEventHandler.cpp
+++ b/dom/events/PointerEventHandler.cpp
@@ -622,18 +622,18 @@ bool PointerEventHandler::GetPointerPrim
   return false;
 }
 
 /* static */
 void PointerEventHandler::DispatchGotOrLostPointerCaptureEvent(
     bool aIsGotCapture, const WidgetPointerEvent* aPointerEvent,
     nsIContent* aCaptureTarget) {
   Document* targetDoc = aCaptureTarget->OwnerDoc();
-  nsCOMPtr<nsIPresShell> shell = targetDoc->GetShell();
-  if (NS_WARN_IF(!shell)) {
+  RefPtr<PresShell> presShell = targetDoc->GetPresShell();
+  if (NS_WARN_IF(!presShell)) {
     return;
   }
 
   if (!aIsGotCapture && !aCaptureTarget->IsInComposedDoc()) {
     // If the capturing element was removed from the DOM tree, fire
     // ePointerLostCapture at the document.
     PointerEventInit init;
     init.mPointerId = aPointerEvent->pointerId;
@@ -649,17 +649,17 @@ void PointerEventHandler::DispatchGotOrL
   }
   nsEventStatus status = nsEventStatus_eIgnore;
   WidgetPointerEvent localEvent(
       aPointerEvent->IsTrusted(),
       aIsGotCapture ? ePointerGotCapture : ePointerLostCapture,
       aPointerEvent->mWidget);
 
   localEvent.AssignPointerEventData(*aPointerEvent, true);
-  DebugOnly<nsresult> rv = shell->HandleEventWithTarget(
+  DebugOnly<nsresult> rv = presShell->HandleEventWithTarget(
       &localEvent, aCaptureTarget->GetPrimaryFrame(), aCaptureTarget, &status);
 
   NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
                        "DispatchGotOrLostPointerCaptureEvent failed");
 }
 
 /* static */
 void PointerEventHandler::MaybeCacheSpoofedPointerID(uint16_t aInputSource,
--- a/dom/html/ImageDocument.cpp
+++ b/dom/html/ImageDocument.cpp
@@ -7,31 +7,31 @@
 #include "ImageDocument.h"
 #include "mozilla/AutoRestore.h"
 #include "mozilla/ComputedStyle.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/Event.h"
 #include "mozilla/dom/ImageDocumentBinding.h"
 #include "mozilla/dom/HTMLImageElement.h"
 #include "mozilla/dom/MouseEvent.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/StaticPrefs.h"
 #include "nsRect.h"
 #include "nsIImageLoadingContent.h"
 #include "nsGenericHTMLElement.h"
 #include "nsDocShell.h"
 #include "DocumentInlines.h"
 #include "nsDOMTokenList.h"
 #include "nsIDOMEventListener.h"
 #include "nsIFrame.h"
 #include "nsGkAtoms.h"
 #include "imgIRequest.h"
 #include "imgILoader.h"
 #include "imgIContainer.h"
 #include "imgINotificationObserver.h"
-#include "nsIPresShell.h"
 #include "nsPresContext.h"
 #include "nsIChannel.h"
 #include "nsIContentPolicy.h"
 #include "nsContentPolicyUtils.h"
 #include "nsPIDOMWindow.h"
 #include "nsError.h"
 #include "nsURILoader.h"
 #include "nsIDocShell.h"
@@ -397,22 +397,22 @@ ImageDocument::DOMRestoreImageTo(int32_t
 }
 
 void ImageDocument::ScrollImageTo(int32_t aX, int32_t aY, bool restoreImage) {
   if (restoreImage) {
     RestoreImage();
     FlushPendingNotifications(FlushType::Layout);
   }
 
-  nsCOMPtr<nsIPresShell> shell = GetShell();
-  if (!shell) {
+  RefPtr<PresShell> presShell = GetPresShell();
+  if (!presShell) {
     return;
   }
 
-  nsIScrollableFrame* sf = shell->GetRootScrollFrameAsScrollable();
+  nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
   if (!sf) {
     return;
   }
 
   float ratio = GetRatio();
   // Don't try to scroll image if the document is not visible (mVisibleWidth or
   // mVisibleHeight is zero).
   if (ratio <= 0.0) {
@@ -830,19 +830,19 @@ float ImageDocument::GetZoomLevel() {
     }
   }
   return zoomLevel;
 }
 
 #if defined(MOZ_WIDGET_ANDROID)
 float ImageDocument::GetResolution() {
   float resolution = mOriginalResolution;
-  nsCOMPtr<nsIPresShell> shell = GetShell();
-  if (shell) {
-    resolution = shell->GetResolution();
+  RefPtr<PresShell> presShell = GetPresShell();
+  if (presShell) {
+    resolution = presShell->GetResolution();
   }
   return resolution;
 }
 #endif
 
 }  // namespace dom
 }  // namespace mozilla
 
--- a/dom/html/MediaDocument.cpp
+++ b/dom/html/MediaDocument.cpp
@@ -3,27 +3,27 @@
 /* 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 "MediaDocument.h"
 #include "nsGkAtoms.h"
 #include "nsRect.h"
 #include "nsPresContext.h"
-#include "nsIPresShell.h"
 #include "nsIScrollable.h"
 #include "nsViewManager.h"
 #include "nsITextToSubURI.h"
 #include "nsIURL.h"
 #include "nsIContentViewer.h"
 #include "nsIDocShell.h"
 #include "nsCharsetSource.h"  // kCharsetFrom* macro definition
 #include "nsNodeInfoManager.h"
 #include "nsContentUtils.h"
 #include "nsDocElementCreatedNotificationRunner.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/Services.h"
 #include "nsServiceManagerUtils.h"
 #include "nsIPrincipal.h"
 #include "nsIMultiPartChannel.h"
 #include "nsProxyRelease.h"
 
 namespace mozilla {
 namespace dom {
@@ -237,21 +237,21 @@ nsresult MediaDocument::CreateSyntheticD
 
   root->AppendChildTo(body, false);
 
   return NS_OK;
 }
 
 nsresult MediaDocument::StartLayout() {
   mMayStartLayout = true;
-  nsCOMPtr<nsIPresShell> shell = GetShell();
+  RefPtr<PresShell> presShell = GetPresShell();
   // Don't mess with the presshell if someone has already handled
   // its initial reflow.
-  if (shell && !shell->DidInitialize()) {
-    nsresult rv = shell->Initialize();
+  if (presShell && !presShell->DidInitialize()) {
+    nsresult rv = presShell->Initialize();
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   return NS_OK;
 }
 
 void MediaDocument::GetFileName(nsAString& aResult, nsIChannel* aChannel) {
   aResult.Truncate();
--- a/dom/html/PluginDocument.cpp
+++ b/dom/html/PluginDocument.cpp
@@ -2,26 +2,26 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 "MediaDocument.h"
 #include "nsIPluginDocument.h"
 #include "nsGkAtoms.h"
-#include "nsIPresShell.h"
 #include "nsIObjectFrame.h"
 #include "nsNPAPIPluginInstance.h"
 #include "DocumentInlines.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsNodeInfoManager.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsContentPolicyUtils.h"
 #include "nsIPropertyBag2.h"
 #include "mozilla/dom/Element.h"
+#include "mozilla/PresShell.h"
 #include "nsObjectLoadingContent.h"
 #include "GeckoProfiler.h"
 
 namespace mozilla {
 namespace dom {
 
 class PluginDocument final : public MediaDocument, public nsIPluginDocument {
  public:
@@ -177,17 +177,17 @@ nsresult PluginDocument::StartDocumentLo
   mStreamListener = new PluginStreamListener(this);
   NS_ASSERTION(aDocListener, "null aDocListener");
   NS_ADDREF(*aDocListener = mStreamListener);
 
   return rv;
 }
 
 nsresult PluginDocument::CreateSyntheticPluginDocument() {
-  NS_ASSERTION(!GetShell() || !GetShell()->DidInitialize(),
+  NS_ASSERTION(!GetPresShell() || !GetPresShell()->DidInitialize(),
                "Creating synthetic plugin document content too late");
 
   // make our generic document
   nsresult rv = MediaDocument::CreateSyntheticDocument();
   NS_ENSURE_SUCCESS(rv, rv);
   // then attach our plugin
 
   Element* body = GetBodyElement();
--- a/dom/html/nsHTMLDocument.cpp
+++ b/dom/html/nsHTMLDocument.cpp
@@ -3,16 +3,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsHTMLDocument.h"
 
 #include "nsIContentPolicy.h"
 #include "mozilla/DebugOnly.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/dom/HTMLAllCollection.h"
 #include "mozilla/dom/FeaturePolicyUtils.h"
 #include "nsCOMPtr.h"
 #include "nsGlobalWindow.h"
 #include "nsString.h"
 #include "nsPrintfCString.h"
 #include "nsReadableUtils.h"
 #include "nsUnicharUtils.h"
@@ -1427,17 +1428,17 @@ void nsHTMLDocument::Close(ErrorResult& 
   // one line of code here!
   // XXXbz as far as I can tell this may not be needed anymore; all
   // the testcases in bug 57636 pass without this line...  Leaving
   // it be for now, though.  In any case, there's no reason to do
   // this if we have no presshell, since in that case none of the
   // above about reusing frames applies.
   //
   // XXXhsivonen keeping this around for bug 577508 / 253951 still :-(
-  if (GetShell()) {
+  if (GetPresShell()) {
     FlushPendingNotifications(FlushType::Layout);
   }
 }
 
 void nsHTMLDocument::WriteCommon(const Sequence<nsString>& aText,
                                  bool aNewlineTerminate,
                                  mozilla::ErrorResult& rv) {
   // Fast path the common case
@@ -1868,18 +1869,20 @@ static void NotifyEditableStateChange(ns
   }
 }
 
 void nsHTMLDocument::TearingDownEditor() {
   if (IsEditingOn()) {
     EditingState oldState = mEditingState;
     mEditingState = eTearingDown;
 
-    nsCOMPtr<nsIPresShell> presShell = GetShell();
-    if (!presShell) return;
+    RefPtr<PresShell> presShell = GetPresShell();
+    if (!presShell) {
+      return;
+    }
 
     nsTArray<RefPtr<StyleSheet>> agentSheets;
     presShell->GetAgentStyleSheets(agentSheets);
 
     auto cache = nsLayoutStylesheetCache::Singleton();
 
     agentSheets.RemoveElement(cache->ContentEditableSheet());
     if (oldState == eDesignMode)
@@ -2013,17 +2016,17 @@ nsresult nsHTMLDocument::EditingStateCha
   bool spellRecheckAll = false;
   bool putOffToRemoveScriptBlockerUntilModifyingEditingState = false;
   htmlEditor = nullptr;
 
   {
     EditingState oldState = mEditingState;
     nsAutoEditingState push(this, eSettingUp);
 
-    nsCOMPtr<nsIPresShell> presShell = GetShell();
+    RefPtr<PresShell> presShell = GetPresShell();
     NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
 
     // Before making this window editable, we need to modify UA style sheet
     // because new style may change whether focused element will be focusable
     // or not.
     nsTArray<RefPtr<StyleSheet>> agentSheets;
     rv = presShell->GetAgentStyleSheets(agentSheets);
     NS_ENSURE_SUCCESS(rv, rv);
@@ -2195,17 +2198,17 @@ void nsHTMLDocument::MaybeDispatchCheckK
   checkEvent.mFlags.mOnlySystemGroupDispatch = true;
   // Post the event rather than dispatching it synchronously because we need
   // a call of SetKeyPressEventModel() before first key input.  Therefore, we
   // can avoid paying unnecessary runtime cost for most web apps.
   (new AsyncEventDispatcher(this, checkEvent))->PostDOMEvent();
 }
 
 void nsHTMLDocument::SetKeyPressEventModel(uint16_t aKeyPressEventModel) {
-  nsIPresShell* presShell = GetShell();
+  PresShell* presShell = GetPresShell();
   if (!presShell) {
     return;
   }
   presShell->SetKeyPressEventModel(aKeyPressEventModel);
 }
 
 void nsHTMLDocument::SetDesignMode(const nsAString& aDesignMode,
                                    nsIPrincipal& aSubjectPrincipal,
--- a/dom/html/nsTextEditorState.cpp
+++ b/dom/html/nsTextEditorState.cpp
@@ -3,17 +3,16 @@
 /* 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 "nsTextEditorState.h"
 #include "mozilla/TextInputListener.h"
 
 #include "nsCOMPtr.h"
-#include "nsIPresShell.h"
 #include "nsView.h"
 #include "nsCaret.h"
 #include "nsLayoutCID.h"
 #include "nsITextControlFrame.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsTextControlFrame.h"
 #include "nsIControllers.h"
 #include "nsITransactionManager.h"
@@ -30,16 +29,17 @@
 #include "mozilla/dom/Selection.h"
 #include "mozilla/TextEditRules.h"
 #include "mozilla/EventListenerManager.h"
 #include "nsContentUtils.h"
 #include "mozilla/Preferences.h"
 #include "nsTextNode.h"
 #include "nsIController.h"
 #include "mozilla/AutoRestore.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/TextEvents.h"
 #include "mozilla/dom/Event.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/dom/HTMLInputElement.h"
 #include "mozilla/dom/HTMLTextAreaElement.h"
 #include "mozilla/dom/Text.h"
 #include "nsNumberControlFrame.h"
 #include "nsFrameSelection.h"
@@ -794,17 +794,17 @@ void TextInputListener::OnSelectionChang
   bool collapsed = aSelection.IsCollapsed();
   if (!collapsed && (aReason & (nsISelectionListener::MOUSEUP_REASON |
                                 nsISelectionListener::KEYPRESS_REASON |
                                 nsISelectionListener::SELECTALL_REASON))) {
     nsIContent* content = mFrame->GetContent();
     if (content) {
       nsCOMPtr<Document> doc = content->GetComposedDoc();
       if (doc) {
-        nsCOMPtr<nsIPresShell> presShell = doc->GetShell();
+        RefPtr<PresShell> presShell = doc->GetPresShell();
         if (presShell) {
           nsEventStatus status = nsEventStatus_eIgnore;
           WidgetEvent event(true, eFormSelect);
 
           presShell->HandleEventWithTarget(&event, mFrame, content, &status);
         }
       }
     }
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -200,17 +200,17 @@ already_AddRefed<Document> TabChildBase:
   nsCOMPtr<Document> doc;
   WebNavigation()->GetDocument(getter_AddRefs(doc));
   return doc.forget();
 }
 
 already_AddRefed<nsIPresShell> TabChildBase::GetPresShell() const {
   nsCOMPtr<nsIPresShell> result;
   if (nsCOMPtr<Document> doc = GetDocument()) {
-    result = doc->GetShell();
+    result = doc->GetPresShell();
   }
   return result.forget();
 }
 
 void TabChildBase::DispatchMessageManagerMessage(const nsAString& aMessageName,
                                                  const nsAString& aJSONData) {
   AutoSafeJSContext cx;
   JS::Rooted<JS::Value> json(cx, JS::NullValue());
@@ -450,22 +450,22 @@ NS_IMETHODIMP
 TabChild::Observe(nsISupports* aSubject, const char* aTopic,
                   const char16_t* aData) {
   if (!strcmp(aTopic, BEFORE_FIRST_PAINT)) {
     if (AsyncPanZoomEnabled()) {
       nsCOMPtr<Document> subject(do_QueryInterface(aSubject));
       nsCOMPtr<Document> doc(GetDocument());
 
       if (subject == doc) {
-        nsCOMPtr<nsIPresShell> shell(doc->GetShell());
-        if (shell) {
-          shell->SetIsFirstPaint(true);
+        RefPtr<PresShell> presShell = doc->GetPresShell();
+        if (presShell) {
+          presShell->SetIsFirstPaint(true);
         }
 
-        APZCCallbackHelper::InitializeRootDisplayport(shell);
+        APZCCallbackHelper::InitializeRootDisplayport(presShell);
       }
     }
   }
 
   return NS_OK;
 }
 
 void TabChild::ContentReceivedInputBlock(const ScrollableLayerGuid& aGuid,
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -2166,17 +2166,17 @@ mozilla::ipc::IPCResult TabParent::RecvA
   MOZ_ASSERT(aEvent.mMessage == eKeyPress);
   WidgetKeyboardEvent localEvent(aEvent);
   localEvent.MarkAsHandledInRemoteProcess();
   localEvent.mMessage = eAccessKeyNotFound;
 
   // Here we convert the WidgetEvent that we received to an Event
   // to be able to dispatch it to the <browser> element as the target element.
   Document* doc = mFrameElement->OwnerDoc();
-  nsIPresShell* presShell = doc->GetShell();
+  PresShell* presShell = doc->GetPresShell();
   NS_ENSURE_TRUE(presShell, IPC_OK());
 
   if (presShell->CanDispatchEvent()) {
     nsPresContext* presContext = presShell->GetPresContext();
     NS_ENSURE_TRUE(presContext, IPC_OK());
 
     EventDispatcher::Dispatch(mFrameElement, presContext, &localEvent);
   }
@@ -2533,19 +2533,19 @@ mozilla::ipc::IPCResult TabParent::RecvS
     const InputContext& aContext, const InputContextAction& aAction) {
   IMEStateManager::SetInputContextForChildProcess(this, aContext, aAction);
   return IPC_OK();
 }
 
 already_AddRefed<nsIWidget> TabParent::GetTopLevelWidget() {
   nsCOMPtr<nsIContent> content = mFrameElement;
   if (content) {
-    nsIPresShell* shell = content->OwnerDoc()->GetShell();
-    if (shell) {
-      nsViewManager* vm = shell->GetViewManager();
+    PresShell* presShell = content->OwnerDoc()->GetPresShell();
+    if (presShell) {
+      nsViewManager* vm = presShell->GetViewManager();
       nsCOMPtr<nsIWidget> widget;
       vm->GetRootWidget(getter_AddRefs(widget));
       return widget.forget();
     }
   }
   return nullptr;
 }
 
@@ -3292,27 +3292,27 @@ mozilla::ipc::IPCResult TabParent::RecvA
 }
 
 mozilla::ipc::IPCResult TabParent::RecvInvokeDragSession(
     nsTArray<IPCDataTransfer>&& aTransfers, const uint32_t& aAction,
     Maybe<Shmem>&& aVisualDnDData, const uint32_t& aStride,
     const gfx::SurfaceFormat& aFormat, const LayoutDeviceIntRect& aDragRect,
     const IPC::Principal& aPrincipal) {
   mInitialDataTransferItems.Clear();
-  nsIPresShell* shell = mFrameElement->OwnerDoc()->GetShell();
-  if (!shell) {
+  PresShell* presShell = mFrameElement->OwnerDoc()->GetPresShell();
+  if (!presShell) {
     Unused << Manager()->SendEndDragSession(true, true, LayoutDeviceIntPoint(),
                                             0);
     // Continue sending input events with input priority when stopping the dnd
     // session.
     Manager()->SetInputPriorityEventEnabled(true);
     return IPC_OK();
   }
 
-  EventStateManager* esm = shell->GetPresContext()->EventStateManager();
+  EventStateManager* esm = presShell->GetPresContext()->EventStateManager();
   for (uint32_t i = 0; i < aTransfers.Length(); ++i) {
     mInitialDataTransferItems.AppendElement(std::move(aTransfers[i].items()));
   }
 
   nsCOMPtr<nsIDragService> dragService =
       do_GetService("@mozilla.org/widget/dragservice;1");
   if (dragService) {
     dragService->MaybeAddChildProcess(Manager());
--- a/dom/prototype/PrototypeDocumentContentSink.cpp
+++ b/dom/prototype/PrototypeDocumentContentSink.cpp
@@ -53,16 +53,17 @@
 #include "mozilla/dom/CDATASection.h"
 #include "mozilla/dom/Comment.h"
 #include "mozilla/dom/DocumentType.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/HTMLTemplateElement.h"
 #include "mozilla/dom/ProcessingInstruction.h"
 #include "mozilla/dom/ScriptLoader.h"
 #include "mozilla/LoadInfo.h"
+#include "mozilla/PresShell.h"
 
 #include "nsXULPrototypeCache.h"
 #include "nsXULElement.h"
 #include "mozilla/CycleCollectedJSContext.h"
 #include "js/CompilationAndEvaluation.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
@@ -637,19 +638,19 @@ nsresult PrototypeDocumentContentSink::D
   return NS_OK;
 }
 
 void PrototypeDocumentContentSink::StartLayout() {
   AUTO_PROFILER_LABEL_DYNAMIC_NSCSTRING(
       "PrototypeDocumentContentSink::StartLayout", LAYOUT,
       mDocumentURI->GetSpecOrDefault());
   mDocument->SetMayStartLayout(true);
-  nsCOMPtr<nsIPresShell> shell = mDocument->GetShell();
-  if (shell && !shell->DidInitialize()) {
-    nsresult rv = shell->Initialize();
+  RefPtr<PresShell> presShell = mDocument->GetPresShell();
+  if (presShell && !presShell->DidInitialize()) {
+    nsresult rv = presShell->Initialize();
     if (NS_FAILED(rv)) {
       return;
     }
   }
 }
 
 NS_IMETHODIMP
 PrototypeDocumentContentSink::StyleSheetLoaded(StyleSheet* aSheet,
--- a/dom/smil/SMILAnimationController.cpp
+++ b/dom/smil/SMILAnimationController.cpp
@@ -4,25 +4,25 @@
  * 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 "SMILAnimationController.h"
 
 #include <algorithm>
 
 #include "mozilla/AutoRestore.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/RestyleManager.h"
 #include "mozilla/SMILTimedElement.h"
 #include "mozilla/dom/DocumentInlines.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/SVGAnimationElement.h"
 #include "nsContentUtils.h"
 #include "nsCSSProps.h"
 #include "mozilla/dom/Document.h"
-#include "nsIPresShell.h"
 #include "nsIPresShellInlines.h"
 #include "nsITimer.h"
 #include "SMILCompositor.h"
 #include "SMILCSSProperty.h"
 
 using namespace mozilla::dom;
 
 namespace mozilla {
@@ -724,14 +724,14 @@ nsRefreshDriver* SMILAnimationController
     return nullptr;
   }
 
   nsPresContext* context = mDocument->GetPresContext();
   return context ? context->RefreshDriver() : nullptr;
 }
 
 void SMILAnimationController::FlagDocumentNeedsFlush() {
-  if (nsIPresShell* shell = mDocument->GetShell()) {
-    shell->SetNeedStyleFlush();
+  if (PresShell* presShell = mDocument->GetPresShell()) {
+    presShell->SetNeedStyleFlush();
   }
 }
 
 }  // namespace mozilla
--- a/dom/svg/SVGContentUtils.cpp
+++ b/dom/svg/SVGContentUtils.cpp
@@ -9,16 +9,17 @@
 #include "SVGContentUtils.h"
 
 // Keep others in (case-insensitive) order:
 #include "gfx2DGlue.h"
 #include "gfxMatrix.h"
 #include "gfxPlatform.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/dom/SVGSVGElement.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/RefPtr.h"
 #include "mozilla/SVGContextPaint.h"
 #include "mozilla/TextUtils.h"
 #include "nsComputedDOMStyle.h"
 #include "nsFontMetrics.h"
 #include "nsIFrame.h"
 #include "nsIScriptError.h"
 #include "nsLayoutUtils.h"
@@ -511,17 +512,17 @@ static gfx::Matrix GetCTMInternal(SVGEle
   }
 
   // XXX this does not take into account CSS transform, or that the non-SVG
   // content that we've hit may itself be inside an SVG foreignObject higher up
   Document* currentDoc = aElement->GetComposedDoc();
   float x = 0.0f, y = 0.0f;
   if (currentDoc &&
       element->NodeInfo()->Equals(nsGkAtoms::svg, kNameSpaceID_SVG)) {
-    nsIPresShell* presShell = currentDoc->GetShell();
+    PresShell* presShell = currentDoc->GetPresShell();
     if (presShell) {
       nsIFrame* frame = element->GetPrimaryFrame();
       nsIFrame* ancestorFrame = presShell->GetRootFrame();
       if (frame && ancestorFrame) {
         nsPoint point = frame->GetOffsetTo(ancestorFrame);
         x = nsPresContext::AppUnitsToFloatCSSPixels(point.x);
         y = nsPresContext::AppUnitsToFloatCSSPixels(point.y);
       }
--- a/dom/svg/SVGElement.cpp
+++ b/dom/svg/SVGElement.cpp
@@ -14,32 +14,32 @@
 #include "mozilla/dom/SVGTests.h"
 #include "mozilla/dom/SVGUnitTypesBinding.h"
 
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/DeclarationBlock.h"
 #include "mozilla/EventListenerManager.h"
 #include "mozilla/InternalMutationEvent.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/RestyleManager.h"
 #include "mozilla/SMILAnimationController.h"
 #include "mozilla/SVGContentUtils.h"
 #include "mozilla/Unused.h"
 
 #include "DOMSVGAnimatedEnumeration.h"
 #include "mozAutoDocUpdate.h"
 #include "nsAttrValueOrString.h"
 #include "nsCSSProps.h"
 #include "nsContentUtils.h"
 #include "nsICSSDeclaration.h"
 #include "nsIContentInlines.h"
 #include "mozilla/dom/Document.h"
 #include "nsError.h"
 #include "nsGkAtoms.h"
-#include "nsIPresShell.h"
 #include "nsIFrame.h"
 #include "nsQueryObject.h"
 #include "nsLayoutUtils.h"
 #include "SVGAnimatedNumberList.h"
 #include "SVGAnimatedLengthList.h"
 #include "SVGAnimatedPointList.h"
 #include "SVGAnimatedPathSegList.h"
 #include "SVGAnimatedTransformList.h"
@@ -100,34 +100,34 @@ JSObject* SVGElement::WrapNode(JSContext
   return SVGElement_Binding::Wrap(aCx, this, aGivenProto);
 }
 
 //----------------------------------------------------------------------
 // SVGElement methods
 
 void SVGElement::DidAnimateClass() {
   // For Servo, snapshot the element before we change it.
-  nsIPresShell* shell = OwnerDoc()->GetShell();
-  if (shell) {
-    if (nsPresContext* presContext = shell->GetPresContext()) {
+  PresShell* presShell = OwnerDoc()->GetPresShell();
+  if (presShell) {
+    if (nsPresContext* presContext = presShell->GetPresContext()) {
       presContext->RestyleManager()->ClassAttributeWillBeChangedBySMIL(this);
     }
   }
 
   nsAutoString src;
   mClassAttribute.GetAnimValue(src, this);
   if (!mClassAnimAttr) {
     mClassAnimAttr = new nsAttrValue();
   }
   mClassAnimAttr->ParseAtomArray(src);
 
   // FIXME(emilio): This re-selector-matches, but we do the snapshot stuff right
   // above... Is this needed anymore?
-  if (shell) {
-    shell->RestyleForAnimation(this, StyleRestyleHint_RESTYLE_SELF);
+  if (presShell) {
+    presShell->RestyleForAnimation(this, StyleRestyleHint_RESTYLE_SELF);
   }
 }
 
 nsresult SVGElement::Init() {
   // Set up length attributes - can't do this in the constructor
   // because we can't do a virtual call at that point
 
   LengthAttributesInfo lengthInfo = GetLengthInfo();
--- a/dom/svg/SVGSVGElement.cpp
+++ b/dom/svg/SVGSVGElement.cpp
@@ -7,16 +7,17 @@
 #include "mozilla/dom/SVGSVGElement.h"
 
 #include "mozilla/ContentEvents.h"
 #include "mozilla/dom/SVGSVGElementBinding.h"
 #include "mozilla/dom/SVGMatrix.h"
 #include "mozilla/dom/SVGRect.h"
 #include "mozilla/dom/SVGViewElement.h"
 #include "mozilla/EventDispatcher.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/SMILAnimationController.h"
 #include "mozilla/SMILTimeContainer.h"
 
 #include "DOMSVGAngle.h"
 #include "DOMSVGLength.h"
 #include "DOMSVGNumber.h"
 #include "DOMSVGPoint.h"
 #include "nsFrameSelection.h"
@@ -314,17 +315,17 @@ void SVGSVGElement::SetCurrentScaleTrans
   mPreviousTranslate = mCurrentTranslate;
 
   mCurrentScale = s;
   mCurrentTranslate = SVGPoint(x, y);
 
   // now dispatch the appropriate event if we are the root element
   Document* doc = GetUncomposedDoc();
   if (doc) {
-    nsCOMPtr<nsIPresShell> presShell = doc->GetShell();
+    RefPtr<PresShell> presShell = doc->GetPresShell();
     if (presShell && IsRoot()) {
       nsEventStatus status = nsEventStatus_eIgnore;
       if (mPreviousScale == mCurrentScale) {
         WidgetEvent svgScrollEvent(true, eSVGScroll);
         presShell->HandleDOMEventWithTarget(this, &svgScrollEvent, &status);
       }
       InvalidateTransformNotifyFrame();
     }
--- a/dom/xbl/XBLChildrenElement.cpp
+++ b/dom/xbl/XBLChildrenElement.cpp
@@ -1,18 +1,20 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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/dom/XBLChildrenElement.h"
-#include "nsCharSeparatedTokenizer.h"
+
+#include "mozilla/PresShell.h"
 #include "mozilla/dom/NodeListBinding.h"
 #include "nsAttrValueOrString.h"
+#include "nsCharSeparatedTokenizer.h"
 
 namespace mozilla {
 namespace dom {
 
 XBLChildrenElement::~XBLChildrenElement() {}
 
 NS_IMPL_ELEMENT_CLONE(XBLChildrenElement)
 
@@ -41,18 +43,18 @@ void XBLChildrenElement::DoRemoveDefault
   MOZ_ASSERT(HasChildren(), "Why bothering?");
   MOZ_ASSERT(GetParentElement());
 
   // We don't want to do this from frame construction while setting up the
   // binding initially.
   if (aNotify) {
     Element* parent = GetParentElement();
     if (Document* doc = parent->GetComposedDoc()) {
-      if (nsIPresShell* shell = doc->GetShell()) {
-        shell->DestroyFramesForAndRestyle(parent);
+      if (PresShell* presShell = doc->GetPresShell()) {
+        presShell->DestroyFramesForAndRestyle(parent);
       }
     }
   }
 
   for (nsIContent* child = static_cast<nsINode*>(this)->GetFirstChild(); child;
        child = child->GetNextSibling()) {
     MOZ_ASSERT(!child->GetPrimaryFrame());
     MOZ_ASSERT(!child->IsElement() || !child->AsElement()->HasServoData());
--- a/dom/xbl/nsBindingManager.cpp
+++ b/dom/xbl/nsBindingManager.cpp
@@ -14,17 +14,16 @@
 #include "nsIURL.h"
 #include "nsIChannel.h"
 #include "nsString.h"
 #include "plstr.h"
 #include "nsIContent.h"
 #include "nsIContentInlines.h"
 #include "mozilla/dom/Document.h"
 #include "nsContentUtils.h"
-#include "nsIPresShell.h"
 #include "nsIPresShellInlines.h"
 #include "nsIXMLContentSink.h"
 #include "nsContentCID.h"
 #include "mozilla/dom/XMLDocument.h"
 #include "nsIStreamListener.h"
 #include "ChildIterator.h"
 #include "nsITimer.h"
 
@@ -46,16 +45,17 @@
 
 #include "nsIScriptContext.h"
 #include "xpcpublic.h"
 #include "js/Wrapper.h"
 
 #include "nsThreadUtils.h"
 #include "mozilla/dom/NodeListBinding.h"
 #include "mozilla/dom/ScriptSettings.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/Unused.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 // Implement our nsISupports methods
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsBindingManager)
@@ -223,36 +223,35 @@ nsresult nsBindingManager::ClearBinding(
   // Hold strong ref in case removing the binding tries to close the
   // window or something.
   // XXXbz should that be ownerdoc?  Wouldn't we need a ref to the
   // currentdoc too?  What's the one that should be passed to
   // ChangeDocument?
   nsCOMPtr<Document> doc = aElement->OwnerDoc();
 
   // Destroy the frames here before the UnbindFromTree happens.
-  nsIPresShell* presShell = doc->GetShell();
-  if (presShell) {
+  if (PresShell* presShell = doc->GetPresShell()) {
     presShell->DestroyFramesForAndRestyle(aElement);
   }
 
   // Finally remove the binding...
   // XXXbz this doesn't remove the implementation!  Should fix!  Until
   // then we need the explicit UnhookEventHandlers here.
   binding->UnhookEventHandlers();
   binding->ChangeDocument(doc, nullptr);
   aElement->SetXBLBinding(nullptr, this);
   binding->MarkForDeath();
 
   // ...and recreate its frames. We need to do this since the frames may have
   // been removed and style may have changed due to the removal of the
   // anonymous children.
   // XXXbz this should be using the current doc (if any), not the owner doc.
-  presShell = doc->GetShell();  // get the shell again, just in case it changed
+  // get the shell again, just in case it changed
+  PresShell* presShell = doc->GetPresShell();
   NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
-
   presShell->PostRecreateFramesFor(aElement);
   return NS_OK;
 }
 
 nsresult nsBindingManager::LoadBindingDocument(Document* aBoundDoc,
                                                nsIURI* aURL,
                                                nsIPrincipal* aOriginPrincipal) {
   MOZ_ASSERT(aURL, "Must have a URI to load!");
@@ -284,18 +283,18 @@ nsresult nsBindingManager::AddToAttached
 
   // If we're in the middle of processing our queue already, don't
   // bother posting the event.
   if (!mProcessingAttachedStack && !mProcessAttachedQueueEvent) {
     PostProcessAttachedQueueEvent();
   }
 
   // Make sure that flushes will flush out the new items as needed.
-  if (nsIPresShell* shell = mDocument->GetShell()) {
-    shell->SetNeedStyleFlush();
+  if (PresShell* presShell = mDocument->GetPresShell()) {
+    presShell->SetNeedStyleFlush();
   }
 
   return NS_OK;
 }
 
 void nsBindingManager::PostProcessAttachedQueueEvent() {
   MOZ_ASSERT(NS_IsMainThread());
   if (!mDocument) {
--- a/dom/xbl/nsXBLPrototypeResources.cpp
+++ b/dom/xbl/nsXBLPrototypeResources.cpp
@@ -11,16 +11,17 @@
 #include "nsXBLPrototypeResources.h"
 #include "nsXBLPrototypeBinding.h"
 #include "nsIDocumentObserver.h"
 #include "mozilla/css/Loader.h"
 #include "nsIURI.h"
 #include "nsLayoutCID.h"
 #include "mozilla/dom/URL.h"
 #include "mozilla/DebugOnly.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/ServoBindings.h"
 #include "mozilla/ServoStyleRuleMap.h"
 #include "mozilla/StyleSheet.h"
 #include "mozilla/StyleSheetInlines.h"
 
 using namespace mozilla;
 using mozilla::dom::IsChromeURI;
 
@@ -89,19 +90,19 @@ nsresult nsXBLPrototypeResources::FlushS
     } else {
       newSheet = oldSheet;
     }
 
     mStyleSheetList.AppendElement(newSheet);
   }
 
   // There may be no shell during unlink.
-  if (auto* shell = doc->GetShell()) {
-    MOZ_ASSERT(shell->GetPresContext());
-    ComputeServoStyles(*shell->StyleSet());
+  if (PresShell* presShell = doc->GetPresShell()) {
+    MOZ_ASSERT(presShell->GetPresContext());
+    ComputeServoStyles(*presShell->StyleSet());
   }
 
   return NS_OK;
 }
 
 nsresult nsXBLPrototypeResources::Write(nsIObjectOutputStream* aStream) {
   if (mLoader) return mLoader->Write(aStream);
   return NS_OK;
--- a/dom/xbl/nsXBLResourceLoader.cpp
+++ b/dom/xbl/nsXBLResourceLoader.cpp
@@ -3,25 +3,25 @@
 /* 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 "nsTArray.h"
 #include "nsString.h"
 #include "mozilla/dom/Document.h"
 #include "nsIContent.h"
-#include "nsIPresShell.h"
 #include "nsXBLService.h"
 #include "nsIServiceManager.h"
 #include "nsXBLResourceLoader.h"
 #include "nsXBLPrototypeResources.h"
 #include "nsIDocumentObserver.h"
 #include "imgILoader.h"
 #include "imgRequestProxy.h"
 #include "mozilla/ComputedStyle.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/StyleSheet.h"
 #include "mozilla/StyleSheetInlines.h"
 #include "mozilla/css/Loader.h"
 #include "nsIURI.h"
 #include "nsNetUtil.h"
 #include "nsGkAtoms.h"
 #include "nsXBLPrototypeBinding.h"
 #include "nsContentUtils.h"
@@ -157,18 +157,18 @@ nsXBLResourceLoader::StyleSheetLoaded(St
 
   if (!mInLoadResourcesFunc) mPendingSheets--;
 
   if (mPendingSheets == 0) {
     // All stylesheets are loaded.
 
     // Our document might have been undisplayed after this sheet load
     // was started, so check before building the XBL cascade data.
-    if (nsIPresShell* shell = mBoundDocument->GetShell()) {
-      mResources->ComputeServoStyles(*shell->StyleSet());
+    if (PresShell* presShell = mBoundDocument->GetPresShell()) {
+      mResources->ComputeServoStyles(*presShell->StyleSet());
     }
 
     // XXX Check for mPendingScripts when scripts also come online.
     if (!mInLoadResourcesFunc) NotifyBoundElements();
   }
   return NS_OK;
 }
 
@@ -209,22 +209,22 @@ void nsXBLResourceLoader::NotifyBoundEle
       continue;
     }
 
     Document* doc = content->GetUncomposedDoc();
     if (!doc) {
       continue;
     }
 
-    nsIPresShell* shell = doc->GetShell();
-    if (!shell) {
+    PresShell* presShell = doc->GetPresShell();
+    if (!presShell) {
       continue;
     }
 
-    shell->PostRecreateFramesFor(content->AsElement());
+    presShell->PostRecreateFramesFor(content->AsElement());
   }
 
   // Clear out the whole array.
   mBoundElements.Clear();
 
   // Delete ourselves.
   mResources->ClearLoader();
 }
--- a/dom/xbl/nsXBLService.cpp
+++ b/dom/xbl/nsXBLService.cpp
@@ -31,30 +31,30 @@
 #include "nsXBLDocumentInfo.h"
 #include "nsCRT.h"
 #include "nsContentUtils.h"
 #include "nsSyncLoadService.h"
 #include "nsContentPolicyUtils.h"
 #include "nsTArray.h"
 #include "nsError.h"
 
-#include "nsIPresShell.h"
 #include "nsIDocumentObserver.h"
 #include "nsFrameManager.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIScriptError.h"
 #include "nsXBLSerialize.h"
 
 #ifdef MOZ_XUL
 #  include "nsXULPrototypeCache.h"
 #endif
 #include "nsIDOMEventListener.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/EventListenerManager.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/ServoStyleSet.h"
 #include "mozilla/RestyleManager.h"
 #include "mozilla/dom/ChildIterator.h"
 #include "mozilla/dom/Event.h"
 #include "mozilla/dom/Element.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
@@ -111,18 +111,18 @@ class nsXBLBindingRequest {
     bool ready = false;
     nsXBLService::GetInstance()->BindingReady(mBoundElement, mBindingURI,
                                               &ready);
     if (!ready) return;
 
     // Destroy the frames for mBoundElement. Do this after getting the binding,
     // since if the binding fetch fails then we don't want to destroy the
     // frames.
-    if (nsIPresShell* shell = doc->GetShell()) {
-      shell->DestroyFramesForAndRestyle(mBoundElement->AsElement());
+    if (PresShell* presShell = doc->GetPresShell()) {
+      presShell->DestroyFramesForAndRestyle(mBoundElement->AsElement());
     }
     MOZ_ASSERT(!mBoundElement->GetPrimaryFrame());
   }
 
   nsXBLBindingRequest(nsIURI* aURI, nsIContent* aBoundElement)
       : mBindingURI(aURI), mBoundElement(aBoundElement) {}
 };
 
@@ -355,17 +355,17 @@ static void EnsureSubtreeStyled(Element*
   if (!aElement->HasServoData()) {
     return;
   }
 
   if (Servo_Element_IsDisplayNone(aElement)) {
     return;
   }
 
-  nsIPresShell* presShell = aElement->OwnerDoc()->GetShell();
+  PresShell* presShell = aElement->OwnerDoc()->GetPresShell();
   if (!presShell || !presShell->DidInitialize()) {
     return;
   }
 
   ServoStyleSet* servoSet = presShell->StyleSet();
   StyleChildrenIterator iter(aElement);
   for (nsIContent* child = iter.GetNextChild(); child;
        child = iter.GetNextChild()) {
@@ -405,17 +405,17 @@ class MOZ_RAII AutoStyleElement {
     MOZ_ASSERT(mResolveStyle);
     if (mHadData) {
       RestyleManager::ClearServoDataFromSubtree(
           mElement, RestyleManager::IncludeRoot::No);
     }
   }
 
   ~AutoStyleElement() {
-    nsIPresShell* presShell = mElement->OwnerDoc()->GetShell();
+    PresShell* presShell = mElement->OwnerDoc()->GetPresShell();
     if (!mHadData || !presShell || !presShell->DidInitialize()) {
       return;
     }
 
     if (*mResolveStyle) {
       mElement->ClearServoData();
 
       ServoStyleSet* servoSet = presShell->StyleSet();
--- a/dom/xul/nsXULElement.cpp
+++ b/dom/xul/nsXULElement.cpp
@@ -13,24 +13,24 @@
 #include "nsIDOMXULCommandDispatcher.h"
 #include "nsIDOMXULSelectCntrlItemEl.h"
 #include "mozilla/dom/Document.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/EventListenerManager.h"
 #include "mozilla/EventStateManager.h"
 #include "mozilla/EventStates.h"
 #include "mozilla/DeclarationBlock.h"
+#include "mozilla/PresShell.h"
 #include "js/CompilationAndEvaluation.h"
 #include "js/SourceText.h"
 #include "nsFocusManager.h"
 #include "nsHTMLStyleSheet.h"
 #include "nsNameSpaceManager.h"
 #include "nsIObjectInputStream.h"
 #include "nsIObjectOutputStream.h"
-#include "nsIPresShell.h"
 #include "nsIPrincipal.h"
 #include "nsIScriptContext.h"
 #include "nsIScriptError.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIServiceManager.h"
 #include "nsIURL.h"
 #include "nsViewManager.h"
 #include "nsIWidget.h"
@@ -741,32 +741,32 @@ void nsXULElement::DoneAddingChildren(bo
   }
 }
 
 void nsXULElement::UnregisterAccessKey(const nsAString& aOldValue) {
   // If someone changes the accesskey, unregister the old one
   //
   Document* doc = GetComposedDoc();
   if (doc && !aOldValue.IsEmpty()) {
-    nsIPresShell* shell = doc->GetShell();
+    PresShell* presShell = doc->GetPresShell();
 
-    if (shell) {
+    if (presShell) {
       Element* element = this;
 
       // find out what type of content node this is
       if (mNodeInfo->Equals(nsGkAtoms::label)) {
         // For anonymous labels the unregistering must
         // occur on the binding parent control.
         // XXXldb: And what if the binding parent is null?
         nsIContent* bindingParent = GetBindingParent();
         element = bindingParent ? bindingParent->AsElement() : nullptr;
       }
 
       if (element) {
-        shell->GetPresContext()->EventStateManager()->UnregisterAccessKey(
+        presShell->GetPresContext()->EventStateManager()->UnregisterAccessKey(
             element, aOldValue.First());
       }
     }
   }
 }
 
 nsresult nsXULElement::BeforeSetAttr(int32_t aNamespaceID, nsAtom* aName,
                                      const nsAttrValueOrString* aValue,
--- a/editor/libeditor/EditorBase.h
+++ b/editor/libeditor/EditorBase.h
@@ -192,17 +192,17 @@ class EditorBase : public nsIEditor,
   virtual void PreDestroy(bool aDestroyingFrames);
 
   bool IsInitialized() const { return !!mDocument; }
   bool Destroyed() const { return mDidPreDestroy; }
 
   Document* GetDocument() const { return mDocument; }
 
   PresShell* GetPresShell() const {
-    return mDocument ? static_cast<PresShell*>(mDocument->GetShell()) : nullptr;
+    return mDocument ? mDocument->GetPresShell() : nullptr;
   }
   nsPresContext* GetPresContext() const {
     PresShell* presShell = GetPresShell();
     return presShell ? presShell->GetPresContext() : nullptr;
   }
   already_AddRefed<nsCaret> GetCaret() const {
     PresShell* presShell = GetPresShell();
     if (NS_WARN_IF(!presShell)) {
@@ -215,17 +215,17 @@ class EditorBase : public nsIEditor,
 
   nsISelectionController* GetSelectionController() const {
     if (mSelectionController) {
       return mSelectionController;
     }
     if (!mDocument) {
       return nullptr;
     }
-    return static_cast<PresShell*>(mDocument->GetShell());
+    return mDocument->GetPresShell();
   }
 
   nsresult GetSelection(SelectionType aSelectionType,
                         Selection** aSelection) const;
 
   Selection* GetSelection(
       SelectionType aSelectionType = SelectionType::eNormal) const {
     if (aSelectionType == SelectionType::eNormal &&
--- a/gfx/layers/apz/src/FocusTarget.cpp
+++ b/gfx/layers/apz/src/FocusTarget.cpp
@@ -6,18 +6,18 @@
 
 #include "mozilla/layers/FocusTarget.h"
 
 #include "mozilla/dom/BrowserBridgeChild.h"  // for BrowserBridgeChild
 #include "mozilla/dom/EventTarget.h"         // for EventTarget
 #include "mozilla/dom/TabParent.h"           // for TabParent
 #include "mozilla/EventDispatcher.h"         // for EventDispatcher
 #include "mozilla/layout/RenderFrame.h"      // For RenderFrame
+#include "mozilla/PresShell.h"               // For PresShell and nsIPresShell
 #include "nsIContentInlines.h"               // for nsINode::IsEditable()
-#include "nsIPresShell.h"                    // for nsIPresShell
 #include "nsLayoutUtils.h"                   // for nsLayoutUtils
 
 #define ENABLE_FT_LOGGING 0
 // #define ENABLE_FT_LOGGING 1
 
 #if ENABLE_FT_LOGGING
 #  define FT_LOG(FMT, ...)         \
     printf_stderr("FT (%s): " FMT, \
@@ -44,17 +44,17 @@ static already_AddRefed<nsIPresShell> Ge
     return nullptr;
   }
 
   RefPtr<Document> retargetEventDoc = window->GetExtantDoc();
   if (!retargetEventDoc) {
     return nullptr;
   }
 
-  nsCOMPtr<nsIPresShell> presShell = retargetEventDoc->GetShell();
+  nsCOMPtr<nsIPresShell> presShell = retargetEventDoc->GetPresShell();
   return presShell.forget();
 }
 
 static bool HasListenersForKeyEvents(nsIContent* aContent) {
   if (!aContent) {
     return false;
   }
 
--- a/gfx/layers/apz/util/APZCCallbackHelper.cpp
+++ b/gfx/layers/apz/util/APZCCallbackHelper.cpp
@@ -13,16 +13,17 @@
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/MouseEventBinding.h"
 #include "mozilla/dom/TabParent.h"
 #include "mozilla/IntegerPrintfMacros.h"
 #include "mozilla/layers/LayerTransactionChild.h"
 #include "mozilla/layers/ShadowLayers.h"
 #include "mozilla/layers/WebRenderLayerManager.h"
 #include "mozilla/layers/WebRenderBridgeChild.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/TouchEvents.h"
 #include "nsContainerFrame.h"
 #include "nsContentUtils.h"
 #include "nsIContent.h"
 #include "nsIDOMWindow.h"
 #include "nsIDOMWindowUtils.h"
 #include "mozilla/dom/Document.h"
 #include "nsIInterfaceRequestorUtils.h"
@@ -68,17 +69,17 @@ static ScreenMargin RecenterDisplayPort(
   margins.right = margins.left = margins.LeftRight() / 2;
   margins.top = margins.bottom = margins.TopBottom() / 2;
   return margins;
 }
 
 static already_AddRefed<nsIPresShell> GetPresShell(const nsIContent* aContent) {
   nsCOMPtr<nsIPresShell> result;
   if (dom::Document* doc = aContent->GetComposedDoc()) {
-    result = doc->GetShell();
+    result = doc->GetPresShell();
   }
   return result.forget();
 }
 
 static CSSPoint ScrollFrameTo(nsIScrollableFrame* aFrame,
                               const RepaintRequest& aRequest,
                               bool& aSuccessOut) {
   aSuccessOut = false;
@@ -431,21 +432,21 @@ void APZCCallbackHelper::InitializeRootD
 }
 
 nsPresContext* APZCCallbackHelper::GetPresContextForContent(
     nsIContent* aContent) {
   dom::Document* doc = aContent->GetComposedDoc();
   if (!doc) {
     return nullptr;
   }
-  nsIPresShell* shell = doc->GetShell();
-  if (!shell) {
+  PresShell* presShell = doc->GetPresShell();
+  if (!presShell) {
     return nullptr;
   }
-  return shell->GetPresContext();
+  return presShell->GetPresContext();
 }
 
 nsIPresShell* APZCCallbackHelper::GetRootContentDocumentPresShellForContent(
     nsIContent* aContent) {
   nsPresContext* context = GetPresContextForContent(aContent);
   if (!context) {
     return nullptr;
   }
@@ -456,21 +457,21 @@ nsIPresShell* APZCCallbackHelper::GetRoo
   return context->PresShell();
 }
 
 static nsIPresShell* GetRootDocumentPresShell(nsIContent* aContent) {
   dom::Document* doc = aContent->GetComposedDoc();
   if (!doc) {
     return nullptr;
   }
-  nsIPresShell* shell = doc->GetShell();
-  if (!shell) {
+  PresShell* presShell = doc->GetPresShell();
+  if (!presShell) {
     return nullptr;
   }
-  nsPresContext* context = shell->GetPresContext();
+  nsPresContext* context = presShell->GetPresContext();
   if (!context) {
     return nullptr;
   }
   context = context->GetRootPresContext();
   if (!context) {
     return nullptr;
   }
   return context->PresShell();
@@ -641,18 +642,18 @@ static dom::Element* GetRootDocumentElem
 static nsIFrame* UpdateRootFrameForTouchTargetDocument(nsIFrame* aRootFrame) {
 #if defined(MOZ_WIDGET_ANDROID)
   // Re-target so that the hit test is performed relative to the frame for the
   // Root Content Document instead of the Root Document which are different in
   // Android. See bug 1229752 comment 16 for an explanation of why this is
   // necessary.
   if (dom::Document* doc =
           aRootFrame->PresShell()->GetPrimaryContentDocument()) {
-    if (nsIPresShell* shell = doc->GetShell()) {
-      if (nsIFrame* frame = shell->GetRootFrame()) {
+    if (PresShell* presShell = doc->GetPresShell()) {
+      if (nsIFrame* frame = presShell->GetRootFrame()) {
         return frame;
       }
     }
   }
 #endif
   return aRootFrame;
 }
 
@@ -833,18 +834,18 @@ APZCCallbackHelper::SendSetTargetAPZCNot
     // race the original confirmation (which needs to go through a layers
     // transaction).
     APZCCH_LOG("Not resending target APZC confirmation for input block %" PRIu64
                "\n",
                aInputBlockId);
     return nullptr;
   }
   sLastTargetAPZCNotificationInputBlock = aInputBlockId;
-  if (nsIPresShell* shell = aDocument->GetShell()) {
-    if (nsIFrame* rootFrame = shell->GetRootFrame()) {
+  if (PresShell* presShell = aDocument->GetPresShell()) {
+    if (nsIFrame* rootFrame = presShell->GetRootFrame()) {
       rootFrame = UpdateRootFrameForTouchTargetDocument(rootFrame);
 
       bool waitForRefresh = false;
       nsTArray<SLGuidAndRenderRoot> targets;
 
       if (const WidgetTouchEvent* touchEvent = aEvent.AsTouchEvent()) {
         for (size_t i = 0; i < touchEvent->mTouches.Length(); i++) {
           waitForRefresh |= PrepareForSetTargetAPZCNotification(
@@ -861,17 +862,17 @@ APZCCallbackHelper::SendSetTargetAPZCNot
       // TODO: Do other types of events need to be handled?
 
       if (!targets.IsEmpty()) {
         if (waitForRefresh) {
           APZCCH_LOG(
               "At least one target got a new displayport, need to wait for "
               "refresh\n");
           return MakeUnique<DisplayportSetListener>(
-              aWidget, shell, aInputBlockId, std::move(targets));
+              aWidget, presShell, aInputBlockId, std::move(targets));
         }
         APZCCH_LOG("Sending target APZCs for input block %" PRIu64 "\n",
                    aInputBlockId);
         aWidget->SetConfirmedTargetAPZC(aInputBlockId, targets);
       }
     }
   }
   return nullptr;
@@ -879,18 +880,18 @@ APZCCallbackHelper::SendSetTargetAPZCNot
 
 void APZCCallbackHelper::SendSetAllowedTouchBehaviorNotification(
     nsIWidget* aWidget, dom::Document* aDocument,
     const WidgetTouchEvent& aEvent, uint64_t aInputBlockId,
     const SetAllowedTouchBehaviorCallback& aCallback) {
   if (!aWidget || !aDocument) {
     return;
   }
-  if (nsIPresShell* shell = aDocument->GetShell()) {
-    if (nsIFrame* rootFrame = shell->GetRootFrame()) {
+  if (PresShell* presShell = aDocument->GetPresShell()) {
+    if (nsIFrame* rootFrame = presShell->GetRootFrame()) {
       rootFrame = UpdateRootFrameForTouchTargetDocument(rootFrame);
 
       nsTArray<TouchBehaviorFlags> flags;
       for (uint32_t i = 0; i < aEvent.mTouches.Length(); i++) {
         flags.AppendElement(TouchActionHelper::GetAllowedTouchBehavior(
             aWidget, rootFrame, aEvent.mTouches[i]->mRefPoint));
       }
       aCallback(aInputBlockId, std::move(flags));
--- a/gfx/layers/apz/util/ActiveElementManager.cpp
+++ b/gfx/layers/apz/util/ActiveElementManager.cpp
@@ -3,16 +3,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ActiveElementManager.h"
 #include "mozilla/EventStateManager.h"
 #include "mozilla/EventStates.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/PresShell.h"
 #include "base/message_loop.h"
 #include "base/task.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/Document.h"
 
 #define AEM_LOG(...)
 // #define AEM_LOG(...) printf_stderr("AEM: " __VA_ARGS__)
 
@@ -126,21 +127,21 @@ void ActiveElementManager::HandleTouchEn
   AEM_LOG("Touch end, clearing pan state\n");
   mCanBePanSet = false;
 }
 
 static nsPresContext* GetPresContextFor(nsIContent* aContent) {
   if (!aContent) {
     return nullptr;
   }
-  nsIPresShell* shell = aContent->OwnerDoc()->GetShell();
-  if (!shell) {
+  PresShell* presShell = aContent->OwnerDoc()->GetPresShell();
+  if (!presShell) {
     return nullptr;
   }
-  return shell->GetPresContext();
+  return presShell->GetPresContext();
 }
 
 void ActiveElementManager::SetActive(dom::Element* aTarget) {
   AEM_LOG("Setting active %p\n", aTarget);
 
   if (nsPresContext* pc = GetPresContextFor(aTarget)) {
     pc->EventStateManager()->SetContentState(aTarget, NS_EVENT_STATE_ACTIVE);
   }
--- a/gfx/layers/apz/util/ChromeProcessController.cpp
+++ b/gfx/layers/apz/util/ChromeProcessController.cpp
@@ -3,26 +3,26 @@
 /* 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 "ChromeProcessController.h"
 
 #include "MainThreadUtils.h"    // for NS_IsMainThread()
 #include "base/message_loop.h"  // for MessageLoop
+#include "mozilla/PresShell.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/layers/CompositorBridgeParent.h"
 #include "mozilla/layers/APZCCallbackHelper.h"
 #include "mozilla/layers/APZEventState.h"
 #include "mozilla/layers/APZThreadUtils.h"
 #include "mozilla/layers/IAPZCTreeManager.h"
 #include "mozilla/layers/DoubleTapToZoom.h"
 #include "mozilla/dom/Document.h"
 #include "nsIInterfaceRequestorUtils.h"
-#include "nsIPresShell.h"
 #include "nsLayoutUtils.h"
 #include "nsView.h"
 
 using namespace mozilla;
 using namespace mozilla::layers;
 using namespace mozilla::widget;
 
 ChromeProcessController::ChromeProcessController(
@@ -136,17 +136,17 @@ void ChromeProcessController::HandleDoub
   if (!document.get()) {
     return;
   }
 
   // CalculateRectToZoomTo performs a hit test on the frame associated with the
   // Root Content Document. Unfortunately that frame does not know about the
   // resolution of the document and so we must remove it before calculating
   // the zoomToRect.
-  nsIPresShell* presShell = document->GetShell();
+  PresShell* presShell = document->GetPresShell();
   const float resolution = presShell->GetResolution();
   CSSPoint point(aPoint.x / resolution, aPoint.y / resolution);
   CSSRect zoomToRect = CalculateRectToZoomTo(document, point);
 
   uint32_t presShellId;
   ScrollableLayerGuid::ViewID viewId;
   if (APZCCallbackHelper::GetOrCreateScrollIdentifiers(
           document->GetDocumentElement(), &presShellId, &viewId)) {
--- a/gfx/layers/apz/util/ContentProcessController.cpp
+++ b/gfx/layers/apz/util/ContentProcessController.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 "ContentProcessController.h"
 
+#include "mozilla/PresShell.h"
 #include "mozilla/dom/TabChild.h"
 #include "mozilla/layers/APZCCallbackHelper.h"
 #include "mozilla/layers/APZChild.h"
 #include "nsIContentInlines.h"
 
 #include "InputData.h"  // for InputData
 
 namespace mozilla {
@@ -62,21 +63,21 @@ void ContentProcessController::NotifyMoz
     const ScrollableLayerGuid::ViewID& aScrollId, const nsString& aEvent) {
   if (mBrowser) {
     APZCCallbackHelper::NotifyMozMouseScrollEvent(aScrollId, aEvent);
   }
 }
 
 void ContentProcessController::NotifyFlushComplete() {
   if (mBrowser) {
-    nsCOMPtr<nsIPresShell> shell;
+    RefPtr<PresShell> presShell;
     if (nsCOMPtr<dom::Document> doc = mBrowser->GetDocument()) {
-      shell = doc->GetShell();
+      presShell = doc->GetPresShell();
     }
-    APZCCallbackHelper::NotifyFlushComplete(shell.get());
+    APZCCallbackHelper::NotifyFlushComplete(presShell);
   }
 }
 
 void ContentProcessController::NotifyAsyncScrollbarDragInitiated(
     uint64_t aDragBlockId, const ScrollableLayerGuid::ViewID& aScrollId,
     ScrollDirection aDirection) {
   APZCCallbackHelper::NotifyAsyncScrollbarDragInitiated(aDragBlockId, aScrollId,
                                                         aDirection);
--- a/gfx/layers/apz/util/DoubleTapToZoom.cpp
+++ b/gfx/layers/apz/util/DoubleTapToZoom.cpp
@@ -3,46 +3,46 @@
 /* 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 "DoubleTapToZoom.h"
 
 #include <algorithm>  // for std::min, std::max
 
+#include "mozilla/PresShell.h"
 #include "mozilla/AlreadyAddRefed.h"
 #include "mozilla/dom/Element.h"
 #include "nsCOMPtr.h"
 #include "nsIContent.h"
 #include "mozilla/dom/Document.h"
 #include "nsIDOMWindow.h"
 #include "nsIFrame.h"
 #include "nsIFrameInlines.h"
-#include "nsIPresShell.h"
 #include "nsLayoutUtils.h"
 #include "nsStyleConsts.h"
 
 namespace mozilla {
 namespace layers {
 
 namespace {
 
 using FrameForPointOption = nsLayoutUtils::FrameForPointOption;
 
 // Returns the DOM element found at |aPoint|, interpreted as being relative to
-// the root frame of |aShell|. If the point is inside a subdocument, returns
+// the root frame of |aPresShell|. If the point is inside a subdocument, returns
 // an element inside the subdocument, rather than the subdocument element
 // (and does so recursively).
 // The implementation was adapted from DocumentOrShadowRoot::ElementFromPoint(),
 // with the notable exception that we don't pass nsLayoutUtils::IGNORE_CROSS_DOC
 // to GetFrameForPoint(), so as to get the behaviour described above in the
 // presence of subdocuments.
 static already_AddRefed<dom::Element> ElementFromPoint(
-    const nsCOMPtr<nsIPresShell>& aShell, const CSSPoint& aPoint) {
-  nsIFrame* rootFrame = aShell->GetRootFrame();
+    const RefPtr<PresShell>& aPresShell, const CSSPoint& aPoint) {
+  nsIFrame* rootFrame = aPresShell->GetRootFrame();
   if (!rootFrame) {
     return nullptr;
   }
   nsIFrame* frame = nsLayoutUtils::GetFrameForPoint(
       rootFrame, CSSPoint::ToAppUnits(aPoint),
       {FrameForPointOption::IgnorePaintSuppression,
        FrameForPointOption::IgnoreRootScrollFrame});
   while (frame && (!frame->GetContent() ||
@@ -99,43 +99,44 @@ static bool IsRectZoomedIn(const CSSRect
 CSSRect CalculateRectToZoomTo(const RefPtr<dom::Document>& aRootContentDocument,
                               const CSSPoint& aPoint) {
   // Ensure the layout information we get is up-to-date.
   aRootContentDocument->FlushPendingNotifications(FlushType::Layout);
 
   // An empty rect as return value is interpreted as "zoom out".
   const CSSRect zoomOut;
 
-  nsCOMPtr<nsIPresShell> shell = aRootContentDocument->GetShell();
-  if (!shell) {
+  RefPtr<PresShell> presShell = aRootContentDocument->GetPresShell();
+  if (!presShell) {
     return zoomOut;
   }
 
-  nsIScrollableFrame* rootScrollFrame = shell->GetRootScrollFrameAsScrollable();
+  nsIScrollableFrame* rootScrollFrame =
+      presShell->GetRootScrollFrameAsScrollable();
   if (!rootScrollFrame) {
     return zoomOut;
   }
 
-  nsCOMPtr<dom::Element> element = ElementFromPoint(shell, aPoint);
+  nsCOMPtr<dom::Element> element = ElementFromPoint(presShell, aPoint);
   if (!element) {
     return zoomOut;
   }
 
   while (element && !ShouldZoomToElement(element)) {
     element = element->GetParentElement();
   }
 
   if (!element) {
     return zoomOut;
   }
 
   FrameMetrics metrics =
       nsLayoutUtils::CalculateBasicFrameMetrics(rootScrollFrame);
   CSSRect compositedArea(
-      CSSPoint::FromAppUnits(shell->GetVisualViewportOffset()),
+      CSSPoint::FromAppUnits(presShell->GetVisualViewportOffset()),
       metrics.CalculateCompositedSizeInCssPixels());
   const CSSCoord margin = 15;
   CSSRect rect =
       nsLayoutUtils::GetBoundingContentRect(element, rootScrollFrame);
 
   // If the element is taller than the visible area of the page scale
   // the height of the |rect| so that it has the same aspect ratio as
   // the root frame.  The clipped |rect| is centered on the y value of
--- a/layout/base/AccessibleCaretManager.cpp
+++ b/layout/base/AccessibleCaretManager.cpp
@@ -13,16 +13,17 @@
 #include "mozilla/AutoRestore.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/MouseEventBinding.h"
 #include "mozilla/dom/NodeFilterBinding.h"
 #include "mozilla/dom/Selection.h"
 #include "mozilla/dom/TreeWalker.h"
 #include "mozilla/IMEStateManager.h"
 #include "mozilla/IntegerPrintfMacros.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/StaticPrefs.h"
 #include "nsCaret.h"
 #include "nsContainerFrame.h"
 #include "nsContentUtils.h"
 #include "nsFocusManager.h"
 #include "nsFrame.h"
 #include "nsFrameSelection.h"
 #include "nsGenericHTMLElement.h"
--- a/layout/base/GeometryUtils.cpp
+++ b/layout/base/GeometryUtils.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 "GeometryUtils.h"
 
+#include "mozilla/PresShell.h"
 #include "mozilla/dom/CharacterData.h"
 #include "mozilla/dom/DOMPointBinding.h"
 #include "mozilla/dom/GeometryUtilsBinding.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/Text.h"
 #include "mozilla/dom/DOMPoint.h"
 #include "mozilla/dom/DOMQuad.h"
 #include "mozilla/dom/DOMRect.h"
@@ -28,29 +29,29 @@ enum GeometryNodeType {
   GEOMETRY_NODE_ELEMENT,
   GEOMETRY_NODE_TEXT,
   GEOMETRY_NODE_DOCUMENT
 };
 
 static nsIFrame* GetFrameForNode(nsINode* aNode, GeometryNodeType aType) {
   Document* doc = aNode->OwnerDoc();
   if (aType == GEOMETRY_NODE_TEXT) {
-    if (nsIPresShell* shell = doc->GetShell()) {
-      shell->FrameConstructor()->EnsureFrameForTextNodeIsCreatedAfterFlush(
+    if (PresShell* presShell = doc->GetPresShell()) {
+      presShell->FrameConstructor()->EnsureFrameForTextNodeIsCreatedAfterFlush(
           static_cast<CharacterData*>(aNode));
     }
   }
   doc->FlushPendingNotifications(FlushType::Layout);
 
   switch (aType) {
     case GEOMETRY_NODE_TEXT:
     case GEOMETRY_NODE_ELEMENT:
       return aNode->AsContent()->GetPrimaryFrame();
     case GEOMETRY_NODE_DOCUMENT: {
-      nsIPresShell* presShell = doc->GetShell();
+      PresShell* presShell = doc->GetPresShell();
       return presShell ? presShell->GetRootFrame() : nullptr;
     }
     default:
       MOZ_ASSERT(false, "Unknown GeometryNodeType");
       return nullptr;
   }
 }
 
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -1312,19 +1312,19 @@ void PresShell::Destroy() {
 
   mStyleSet->BeginShutdown();
   nsRefreshDriver* rd = GetPresContext()->RefreshDriver();
 
   // This shell must be removed from the document before the frame
   // hierarchy is torn down to avoid finding deleted frames through
   // this presshell while the frames are being torn down
   if (mDocument) {
-    NS_ASSERTION(mDocument->GetShell() == this, "Wrong shell?");
+    NS_ASSERTION(mDocument->GetPresShell() == this, "Wrong shell?");
     mDocument->ClearServoRestyleRoot();
-    mDocument->DeleteShell();
+    mDocument->DeletePresShell();
 
     if (mDocument->HasAnimationController()) {
       mDocument->GetAnimationController()->NotifyRefreshDriverDestroying(rd);
     }
     for (DocumentTimeline* timeline : mDocument->Timelines()) {
       timeline->NotifyRefreshDriverDestroying(rd);
     }
   }
@@ -3410,18 +3410,18 @@ nsresult nsIPresShell::ScrollContentInto
   data->mContentToScrollToFlags = aFlags;
   if (NS_FAILED(mContentToScrollTo->SetProperty(
           nsGkAtoms::scrolling, data,
           nsINode::DeleteProperty<PresShell::ScrollIntoViewData>))) {
     mContentToScrollTo = nullptr;
   }
 
   // Flush layout and attempt to scroll in the process.
-  if (nsIPresShell* shell = composedDoc->GetShell()) {
-    shell->SetNeedLayoutFlush();
+  if (PresShell* presShell = composedDoc->GetPresShell()) {
+    presShell->SetNeedLayoutFlush();
   }
   composedDoc->FlushPendingNotifications(FlushType::InterruptibleLayout);
 
   // If mContentToScrollTo is non-null, that means we interrupted the reflow
   // (or suppressed it altogether because we're suppressing interruptible
   // flushes right now) and won't necessarily get the position correct, but do
   // a best-effort scroll here.  The other option would be to do this inside
   // FlushPendingNotifications, but I'm not sure the repeated scrolling that
@@ -4035,18 +4035,18 @@ void PresShell::DoFlushPendingNotificati
   // it's safe to run script.
   bool hasHadScriptObject;
   if (mDocument->GetScriptHandlingObject(hasHadScriptObject) ||
       hasHadScriptObject) {
     isSafeToFlush = isSafeToFlush && nsContentUtils::IsSafeToRunScript();
   }
 
   // Don't flush if the doc is already in the bfcache.
-  if (MOZ_UNLIKELY(mDocument->GetShell() != this)) {
-    MOZ_DIAGNOSTIC_ASSERT(!mDocument->GetShell(),
+  if (MOZ_UNLIKELY(mDocument->GetPresShell() != this)) {
+    MOZ_DIAGNOSTIC_ASSERT(!mDocument->GetPresShell(),
                           "Where did this shell come from?");
     isSafeToFlush = false;
   }
 
   MOZ_DIAGNOSTIC_ASSERT(!mIsDestroying || !isSafeToFlush);
   MOZ_DIAGNOSTIC_ASSERT(mIsDestroying || mViewManager);
   MOZ_DIAGNOSTIC_ASSERT(mIsDestroying || mDocument->HasShellOrBFCacheEntry());
 
@@ -5848,34 +5848,34 @@ void PresShell::EnsureFrameInApproximate
     aFrame->IncApproximateVisibleCount();
     return;
   }
 
 #ifdef DEBUG
   // Make sure it's in this pres shell.
   nsCOMPtr<nsIContent> content = aFrame->GetContent();
   if (content) {
-    PresShell* shell = static_cast<PresShell*>(content->OwnerDoc()->GetShell());
-    MOZ_ASSERT(!shell || shell == this, "wrong shell");
+    PresShell* presShell = content->OwnerDoc()->GetPresShell();
+    MOZ_ASSERT(!presShell || presShell == this, "wrong shell");
   }
 #endif
 
   if (mApproximatelyVisibleFrames.EnsureInserted(aFrame)) {
     // We inserted a new entry.
     aFrame->IncApproximateVisibleCount();
   }
 }
 
 void PresShell::RemoveFrameFromApproximatelyVisibleList(nsIFrame* aFrame) {
 #ifdef DEBUG
   // Make sure it's in this pres shell.
   nsCOMPtr<nsIContent> content = aFrame->GetContent();
   if (content) {
-    PresShell* shell = static_cast<PresShell*>(content->OwnerDoc()->GetShell());
-    MOZ_ASSERT(!shell || shell == this, "wrong shell");
+    PresShell* presShell = content->OwnerDoc()->GetPresShell();
+    MOZ_ASSERT(!presShell || presShell == this, "wrong shell");
   }
 #endif
 
   if (AssumeAllFramesVisible()) {
     MOZ_ASSERT(mApproximatelyVisibleFrames.Count() == 0,
                "Shouldn't have any frames in the table");
     return;
   }
@@ -6371,19 +6371,19 @@ nsIFrame* PresShell::EventHandler::GetNe
   if (view) {
     frame = view->GetFrame();
   }
 
   return frame;
 }
 
 static bool FlushThrottledStyles(Document* aDocument, void* aData) {
-  nsIPresShell* shell = aDocument->GetShell();
-  if (shell && shell->IsVisible()) {
-    nsPresContext* presContext = shell->GetPresContext();
+  PresShell* presShell = aDocument->GetPresShell();
+  if (presShell && presShell->IsVisible()) {
+    nsPresContext* presContext = presShell->GetPresContext();
     if (presContext) {
       presContext->RestyleManager()->UpdateOnlyAnimationStyles();
     }
   }
 
   aDocument->EnumerateSubDocuments(FlushThrottledStyles, nullptr);
   return true;
 }
@@ -6403,17 +6403,17 @@ PresShell* PresShell::GetShellForEventTa
   if (aFrame) {
     return static_cast<PresShell*>(aFrame->PresShell());
   }
   if (aContent) {
     Document* doc = aContent->GetComposedDoc();
     if (!doc) {
       return nullptr;
     }
-    return static_cast<PresShell*>(doc->GetShell());
+    return doc->GetPresShell();
   }
   return nullptr;
 }
 
 /* static */
 PresShell* PresShell::GetShellForTouchEvent(WidgetGUIEvent* aEvent) {
   PresShell* shell = nullptr;
   switch (aEvent->mMessage) {
@@ -6942,17 +6942,17 @@ bool PresShell::EventHandler::MaybeHandl
   nsCOMPtr<nsPIDOMWindowOuter> window = GetFocusedDOMWindowInOurWindow();
   if (!window) {
     return false;
   }
   RefPtr<Document> retargetEventDoc = window->GetExtantDoc();
   if (!retargetEventDoc) {
     return false;
   }
-  nsCOMPtr<nsIPresShell> presShell = retargetEventDoc->GetShell();
+  RefPtr<PresShell> presShell = retargetEventDoc->GetPresShell();
   if (!presShell) {
     return false;
   }
 
   RefPtr<AccessibleCaretEventHub> eventHub =
       presShell->GetAccessibleCaretEventHub();
   if (!eventHub) {
     return false;
@@ -7069,31 +7069,31 @@ bool PresShell::EventHandler::GetRetarge
 }
 
 nsIFrame* PresShell::EventHandler::GetFrameForHandlingEventWith(
     WidgetGUIEvent* aGUIEvent, Document* aRetargetDocument,
     nsIFrame* aFrameForPresShell) {
   MOZ_ASSERT(aGUIEvent);
   MOZ_ASSERT(aRetargetDocument);
 
-  nsCOMPtr<nsIPresShell> retargetPresShell = aRetargetDocument->GetShell();
+  RefPtr<PresShell> retargetPresShell = aRetargetDocument->GetPresShell();
   // Even if the document doesn't have PresShell, i.e., it's invisible, we
   // need to dispatch only KeyboardEvent in its nearest visible document
   // because key focus shouldn't be caught by invisible document.
   if (!retargetPresShell) {
     if (!aGUIEvent->HasKeyEventMessage()) {
       return nullptr;
     }
     Document* retargetEventDoc = aRetargetDocument;
     while (!retargetPresShell) {
       retargetEventDoc = retargetEventDoc->GetParentDocument();
       if (!retargetEventDoc) {
         return nullptr;
       }
-      retargetPresShell = retargetEventDoc->GetShell();
+      retargetPresShell = retargetEventDoc->GetPresShell();
     }
   }
 
   // If the found PresShell is this instance, caller needs to keep handling
   // aGUIEvent by itself.  Therefore, return the given frame which was set
   // to aFrame of HandleEvent().
   if (retargetPresShell == mPresShell) {
     return aFrameForPresShell;
@@ -7547,18 +7547,17 @@ bool PresShell::EventHandler::MaybeHandl
   MOZ_ASSERT(aRv);
 
   Document* eventTargetDocument = aEventTargetElement->OwnerDoc();
   if (!eventTargetDocument || eventTargetDocument == GetDocument()) {
     *aRv = NS_OK;
     return false;
   }
 
-  RefPtr<PresShell> eventTargetPresShell =
-      static_cast<PresShell*>(eventTargetDocument->GetShell());
+  RefPtr<PresShell> eventTargetPresShell = eventTargetDocument->GetPresShell();
   if (!eventTargetPresShell) {
     *aRv = NS_OK;
     return true;  // No PresShell can handle the event.
   }
 
   EventHandler eventHandler(std::move(eventTargetPresShell));
   *aRv = eventHandler.HandleRetargetedEvent(aGUIEvent, aEventStatus,
                                             aEventTargetElement);
@@ -8252,17 +8251,17 @@ void PresShell::EventHandler::DispatchTo
     MOZ_ASSERT(touchEvent->IsTrusted());
     WidgetTouchEvent newEvent(true, touchEvent->mMessage, touchEvent->mWidget);
     newEvent.AssignTouchEventData(*touchEvent, false);
     newEvent.mTarget = targetPtr;
     newEvent.mFlags.mHandledByAPZ = touchEvent->mFlags.mHandledByAPZ;
 
     RefPtr<PresShell> contentPresShell;
     if (doc == GetDocument()) {
-      contentPresShell = static_cast<PresShell*>(doc->GetShell());
+      contentPresShell = doc->GetPresShell();
       if (contentPresShell) {
         // XXXsmaug huge hack. Pushing possibly capturing content,
         //         even though event target is something else.
         contentPresShell->PushCurrentEventInfo(content->GetPrimaryFrame(),
                                                content);
       }
     }
 
@@ -8829,19 +8828,20 @@ nsresult PresShell::RemoveOverrideStyleS
 static void FreezeElement(nsISupports* aSupports, void* /* unused */) {
   nsCOMPtr<nsIObjectLoadingContent> olc(do_QueryInterface(aSupports));
   if (olc) {
     olc->StopPluginInstance();
   }
 }
 
 static bool FreezeSubDocument(Document* aDocument, void* aData) {
-  nsIPresShell* shell = aDocument->GetShell();
-  if (shell) shell->Freeze();
-
+  PresShell* presShell = aDocument->GetPresShell();
+  if (presShell) {
+    presShell->Freeze();
+  }
   return true;
 }
 
 void PresShell::Freeze() {
   mUpdateApproximateFrameVisibilityEvent.Revoke();
 
   MaybeReleaseCapturingContent();
 
@@ -8899,19 +8899,20 @@ void PresShell::FireOrClearDelayedEvents
 static void ThawElement(nsISupports* aSupports, void* aShell) {
   nsCOMPtr<nsIObjectLoadingContent> olc(do_QueryInterface(aSupports));
   if (olc) {
     olc->AsyncStartPluginInstance();
   }
 }
 
 static bool ThawSubDocument(Document* aDocument, void* aData) {
-  nsIPresShell* shell = aDocument->GetShell();
-  if (shell) shell->Thaw();
-
+  PresShell* presShell = aDocument->GetPresShell();
+  if (presShell) {
+    presShell->Thaw();
+  }
   return true;
 }
 
 void PresShell::Thaw() {
   nsPresContext* presContext = GetPresContext();
   if (presContext &&
       presContext->RefreshDriver()->GetPresContext() == presContext) {
     presContext->RefreshDriver()->Thaw();
@@ -9915,41 +9916,44 @@ bool nsIPresShell::VerifyIncrementalRefl
   // Make the new presentation context the same size as our
   // presentation context.
   cx->SetVisibleArea(mPresContext->GetVisibleArea());
 
   // Create a new presentation shell to view the document. Use the
   // exact same style information that this document has.
   UniquePtr<ServoStyleSet> newSet = CloneStyleSet(StyleSet());
 
-  nsCOMPtr<nsIPresShell> sh = mDocument->CreateShell(cx, vm, std::move(newSet));
-  NS_ENSURE_TRUE(sh, false);
+  RefPtr<PresShell> presShell =
+      mDocument->CreatePresShell(cx, vm, std::move(newSet));
+  NS_ENSURE_TRUE(presShell, false);
   // Note that after we create the shell, we must make sure to destroy it
-  sh->SetVerifyReflowEnable(false);  // turn off verify reflow while we're
-                                     // reflowing the test frame tree
-  vm->SetPresShell(sh);
+  presShell->SetVerifyReflowEnable(
+      false);  // turn off verify reflow while we're
+               // reflowing the test frame tree
+  vm->SetPresShell(presShell);
   {
     nsAutoCauseReflowNotifier crNotifier(this);
-    sh->Initialize();
+    presShell->Initialize();
   }
   mDocument->BindingManager()->ProcessAttachedQueue();
-  sh->FlushPendingNotifications(FlushType::Layout);
-  sh->SetVerifyReflowEnable(true);  // turn on verify reflow again now that
-                                    // we're done reflowing the test frame tree
+  presShell->FlushPendingNotifications(FlushType::Layout);
+  presShell->SetVerifyReflowEnable(
+      true);  // turn on verify reflow again now that
+              // we're done reflowing the test frame tree
   // Force the non-primary presshell to unsuppress; it doesn't want to normally
   // because it thinks it's hidden
-  ((PresShell*)sh.get())->mPaintingSuppressed = false;
+  presShell->mPaintingSuppressed = false;
   if (VERIFY_REFLOW_NOISY & gVerifyReflowFlags) {
     printf("Verification Tree built, comparing...\n");
   }
 
   // Now that the document has been reflowed, use its frame tree to
   // compare against our frame tree.
   nsIFrame* root1 = mFrameConstructor->GetRootFrame();
-  nsIFrame* root2 = sh->GetRootFrame();
+  nsIFrame* root2 = presShell->GetRootFrame();
   bool ok = CompareTrees(mPresContext, root1, cx, root2);
   if (!ok && (VERIFY_REFLOW_NOISY & gVerifyReflowFlags)) {
     printf("Verify reflow failed, primary tree:\n");
     root1->List(stdout);
     printf("Verification tree:\n");
     root2->List(stdout);
   }
 
@@ -9957,28 +9961,28 @@ bool nsIPresShell::VerifyIncrementalRefl
   // Sample code for dumping page to png
   // XXX Needs to be made more flexible
   if (!ok) {
     nsString stra;
     static int num = 0;
     stra.AppendLiteral("C:\\mozilla\\mozilla\\debug\\filea");
     stra.AppendInt(num);
     stra.AppendLiteral(".png");
-    gfxUtils::WriteAsPNG(sh, stra);
+    gfxUtils::WriteAsPNG(presShell, stra);
     nsString strb;
     strb.AppendLiteral("C:\\mozilla\\mozilla\\debug\\fileb");
     strb.AppendInt(num);
     strb.AppendLiteral(".png");
-    gfxUtils::WriteAsPNG(sh, strb);
+    gfxUtils::WriteAsPNG(presShell, strb);
     ++num;
   }
 #  endif
 
-  sh->EndObservingDocument();
-  sh->Destroy();
+  presShell->EndObservingDocument();
+  presShell->Destroy();
   if (VERIFY_REFLOW_NOISY & gVerifyReflowFlags) {
     printf("Finished Verifying Reflow...\n");
   }
 
   return ok;
 }
 
 // Layout debugging hooks
@@ -10472,19 +10476,19 @@ void PresShell::QueryIsActive() {
     // this is a newly created PresShell so we'd like to invalidate anyway
     // upon being made active to ensure that the contents get painted.
     if (NS_SUCCEEDED(rv)) SetIsActive(isActive);
   }
 }
 
 // Helper for propagating mIsActive changes to external resources
 static bool SetExternalResourceIsActive(Document* aDocument, void* aClosure) {
-  nsIPresShell* shell = aDocument->GetShell();
-  if (shell) {
-    shell->SetIsActive(*static_cast<bool*>(aClosure));
+  PresShell* presShell = aDocument->GetPresShell();
+  if (presShell) {
+    presShell->SetIsActive(*static_cast<bool*>(aClosure));
   }
   return true;
 }
 
 static void SetPluginIsActive(nsISupports* aSupports, void* aClosure) {
   nsCOMPtr<nsIContent> content(do_QueryInterface(aSupports));
   if (!content) {
     return;
--- a/layout/base/PresShell.h
+++ b/layout/base/PresShell.h
@@ -166,16 +166,24 @@ class PresShell final : public nsIPresSh
 
   nsresult SetResolutionAndScaleTo(float aResolution,
                                    ChangeOrigin aOrigin) override;
   float GetCumulativeResolution() override;
   float GetCumulativeNonRootScaleResolution() override;
   void SetRestoreResolution(float aResolution,
                             LayoutDeviceIntSize aDisplaySize) override;
 
+  // Widget notificiations
+  void WindowSizeMoveDone() override;
+  void SysColorChanged() override { mPresContext->SysColorChanged(); }
+  void ThemeChanged() override { mPresContext->ThemeChanged(); }
+  void BackingScaleFactorChanged() override {
+    mPresContext->UIResolutionChangedSync();
+  }
+
   // nsIViewObserver interface
 
   void Paint(nsView* aViewToPaint, const nsRegion& aDirtyRegion,
              uint32_t aFlags) override;
   MOZ_CAN_RUN_SCRIPT nsresult HandleEvent(nsIFrame* aFrameForPresShell,
                                           WidgetGUIEvent* aEvent,
                                           bool aDontRetargetEvents,
                                           nsEventStatus* aEventStatus) override;
@@ -1279,23 +1287,16 @@ class PresShell final : public nsIPresSh
 
   PresShell* GetRootPresShell();
 
   nscolor GetDefaultBackgroundColorToDraw();
 
   // The callback for the mPaintSuppressionTimer timer.
   static void sPaintSuppressionCallback(nsITimer* aTimer, void* aPresShell);
 
-  // Widget notificiations
-  void WindowSizeMoveDone() override;
-  void SysColorChanged() override { mPresContext->SysColorChanged(); }
-  void ThemeChanged() override { mPresContext->ThemeChanged(); }
-  void BackingScaleFactorChanged() override {
-    mPresContext->UIResolutionChangedSync();
-  }
   Document* GetPrimaryContentDocument() override;
 
   void PausePainting() override;
   void ResumePainting() override;
 
   //////////////////////////////////////////////////////////////////////////////
   // Approximate frame visibility tracking implementation.
   //////////////////////////////////////////////////////////////////////////////
--- a/layout/base/TouchManager.cpp
+++ b/layout/base/TouchManager.cpp
@@ -56,17 +56,17 @@ static nsIContent* GetNonAnonymousAncest
 
 /*static*/
 void TouchManager::EvictTouchPoint(RefPtr<Touch>& aTouch,
                                    Document* aLimitToDocument) {
   nsCOMPtr<nsINode> node(do_QueryInterface(aTouch->mOriginalTarget));
   if (node) {
     Document* doc = node->GetComposedDoc();
     if (doc && (!aLimitToDocument || aLimitToDocument == doc)) {
-      nsIPresShell* presShell = doc->GetShell();
+      PresShell* presShell = doc->GetPresShell();
       if (presShell) {
         nsIFrame* frame = presShell->GetRootFrame();
         if (frame) {
           nsPoint pt(aTouch->mRefPoint.x, aTouch->mRefPoint.y);
           nsCOMPtr<nsIWidget> widget = frame->GetView()->GetNearestWidget(&pt);
           if (widget) {
             WidgetTouchEvent event(true, eTouchEnd, widget);
             event.mTime = PR_IntervalNow();
--- a/layout/base/nsDocumentViewer.cpp
+++ b/layout/base/nsDocumentViewer.cpp
@@ -2,31 +2,31 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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/. */
 
 /* container for a document and its presentation */
 
 #include "gfxContext.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/RestyleManager.h"
 #include "mozilla/ServoStyleSet.h"
 #include "nscore.h"
 #include "nsCOMPtr.h"
 #include "nsCRT.h"
 #include "nsString.h"
 #include "nsReadableUtils.h"
 #include "nsIContent.h"
 #include "nsIContentViewer.h"
 #include "nsIDocumentViewerPrint.h"
 #include "mozilla/dom/BeforeUnloadEvent.h"
 #include "mozilla/dom/PopupBlocker.h"
 #include "mozilla/dom/Document.h"
 #include "nsPresContext.h"
-#include "nsIPresShell.h"
 #include "nsIFrame.h"
 #include "nsIWritablePropertyBag2.h"
 #include "nsSubDocumentFrame.h"
 #include "nsGenericHTMLElement.h"
 #include "nsStubMutationObserver.h"
 
 #include "nsILinkHandler.h"
 #include "nsISelectionListener.h"
@@ -397,17 +397,17 @@ class nsDocumentViewer final : public ns
   RefPtr<nsDeviceContext> mDeviceContext;  // We create and own this baby
 
   // the following six items are explicitly in this order
   // so they will be destroyed in the reverse order (pinkerton, scc)
   nsCOMPtr<Document> mDocument;
   nsCOMPtr<nsIWidget> mWindow;  // may be null
   RefPtr<nsViewManager> mViewManager;
   RefPtr<nsPresContext> mPresContext;
-  nsCOMPtr<nsIPresShell> mPresShell;
+  RefPtr<PresShell> mPresShell;
 
   RefPtr<nsDocViewerSelectionListener> mSelectionListener;
   RefPtr<nsDocViewerFocusListener> mFocusListener;
 
   nsCOMPtr<nsIContentViewer> mPreviousViewer;
   nsCOMPtr<nsISHEntry> mSHEntry;
   // Observer that will prevent bfcaching if it gets notified.  This
   // is non-null precisely when mSHEntry is non-null.
@@ -725,18 +725,18 @@ nsresult nsDocumentViewer::InitPresentat
   if (GetIsPrintPreview()) return NS_OK;
 
   NS_ASSERTION(!mPresShell, "Someone should have destroyed the presshell!");
 
   // Create the style set...
   UniquePtr<ServoStyleSet> styleSet = CreateStyleSet(mDocument);
 
   // Now make the shell for the document
-  mPresShell =
-      mDocument->CreateShell(mPresContext, mViewManager, std::move(styleSet));
+  mPresShell = mDocument->CreatePresShell(mPresContext, mViewManager,
+                                          std::move(styleSet));
   if (!mPresShell) {
     return NS_ERROR_FAILURE;
   }
 
   if (aDoInitialReflow) {
     // Since Initialize() will create frames for *all* items
     // that are currently in the document tree, we need to flush
     // any pending notifications to prevent the content sink from
@@ -765,19 +765,19 @@ nsresult nsDocumentViewer::InitPresentat
     mPresContext->SetVisibleArea(nsRect(0, 0, width, height));
     mPresContext->SetTextZoom(mTextZoom);
     mPresContext->SetFullZoom(mPageZoom);
     mPresContext->SetOverrideDPPX(mOverrideDPPX);
   }
 
   p2a = mPresContext->AppUnitsPerDevPixel();  // zoom may have changed it
   if (aDoInitialReflow) {
-    nsCOMPtr<nsIPresShell> shell = mPresShell;
+    RefPtr<PresShell> presShell = mPresShell;
     // Initial reflow
-    shell->Initialize();
+    presShell->Initialize();
   }
 
   // now register ourselves as a selection listener, so that we get
   // called when the selection changes in the window
   if (!mSelectionListener) {
     nsDocViewerSelectionListener* selectionListener =
         new nsDocViewerSelectionListener();
 
@@ -875,17 +875,17 @@ nsresult nsDocumentViewer::InitInternal(
 
     // XXXbz this is a nasty hack to do with the fact that we create
     // presentations both in Init() and in Show()...  Ideally we would only do
     // it in one place (Show()) and require that callers call init(), open(),
     // show() in that order or something.
     if (!mPresContext &&
         (aParentWidget || containerView || mDocument->IsBeingUsedAsImage() ||
          (mDocument->GetDisplayDocument() &&
-          mDocument->GetDisplayDocument()->GetShell()))) {
+          mDocument->GetDisplayDocument()->GetPresShell()))) {
       // Create presentation context
       if (mIsPageMode) {
         // Presentation context already created in SetPageMode which is calling
         // this method
       } else {
         mPresContext = CreatePresContext(
             mDocument, nsPresContext::eContext_Galley, containerView);
       }
@@ -1004,18 +1004,18 @@ nsDocumentViewer::LoadComplete(nsresult 
   */
   RefPtr<nsDocumentViewer> kungFuDeathGrip(this);
 
   // Flush out layout so it's up-to-date by the time onload is called.
   // Note that this could destroy the window, so do this before
   // checking for our mDocument and its window.
   if (mPresShell && !mStopped) {
     // Hold strong ref because this could conceivably run script
-    nsCOMPtr<nsIPresShell> shell = mPresShell;
-    shell->FlushPendingNotifications(FlushType::Layout);
+    RefPtr<PresShell> presShell = mPresShell;
+    presShell->FlushPendingNotifications(FlushType::Layout);
   }
 
   nsresult rv = NS_OK;
   NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
 
   // First, get the window from the document...
   nsCOMPtr<nsPIDOMWindowOuter> window = mDocument->GetWindow();
 
@@ -1139,18 +1139,18 @@ nsDocumentViewer::LoadComplete(nsresult 
   if (!mStopped) {
     if (mDocument) {
       mDocument->ScrollToRef();
     }
 
     // Now that the document has loaded, we can tell the presshell
     // to unsuppress painting.
     if (mPresShell) {
-      nsCOMPtr<nsIPresShell> shell(mPresShell);
-      shell->UnsuppressPainting();
+      RefPtr<PresShell> presShell = mPresShell;
+      presShell->UnsuppressPainting();
       // mPresShell could have been removed now, see bug 378682/421432
       if (mPresShell) {
         mPresShell->LoadComplete();
       }
     }
   }
 
   // Release the JS bytecode cache from its wait on the load event, and
@@ -1862,18 +1862,18 @@ nsDocumentViewer::Stop(void) {
 
   if (!mHidden && (mLoaded || mStopped) && mPresContext && !mSHEntry)
     mPresContext->SetImageAnimationMode(imgIContainer::kDontAnimMode);
 
   mStopped = true;
 
   if (!mLoaded && mPresShell) {
     // Well, we might as well paint what we have so far.
-    nsCOMPtr<nsIPresShell> shell(mPresShell);  // bug 378682
-    shell->UnsuppressPainting();
+    RefPtr<PresShell> presShell = mPresShell;  // bug 378682
+    presShell->UnsuppressPainting();
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocumentViewer::GetDOMDocument(Document** aResult) {
   NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
@@ -2187,18 +2187,18 @@ nsDocumentViewer::Show(void) {
       rv = InitPresentationStuff(mDocument->MayStartLayout());
     }
 
     // If we get here the document load has already started and the
     // window is shown because some JS on the page caused it to be
     // shown...
 
     if (mPresShell) {
-      nsCOMPtr<nsIPresShell> shell(mPresShell);  // bug 378682
-      shell->UnsuppressPainting();
+      RefPtr<PresShell> presShell = mPresShell;  // bug 378682
+      presShell->UnsuppressPainting();
     }
   }
 
   // Notify observers that a new page has been shown. This will get run
   // from the event loop after we actually draw the page.
   RefPtr<nsDocumentShownDispatcher> event =
       new nsDocumentShownDispatcher(document);
   document->Dispatch(TaskCategory::Other, event.forget());
@@ -4265,17 +4265,17 @@ void nsDocumentViewer::SetPrintPreviewPr
 
   if (mPresShell) {
     DestroyPresShell();
   }
 
   mWindow = nullptr;
   mViewManager = aViewManager;
   mPresContext = aPresContext;
-  mPresShell = aPresShell;
+  mPresShell = static_cast<PresShell*>(aPresShell);
 
   if (ShouldAttachToTopLevel()) {
     DetachFromTopLevelWidget();
     nsView* rootView = mViewManager->GetRootView();
     rootView->AttachToTopLevelWidget(mParentWidget);
     mAttachedToParent = true;
   }
 }
--- a/layout/base/nsIPresShellInlines.h
+++ b/layout/base/nsIPresShellInlines.h
@@ -2,38 +2,39 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 nsIPresShellInlines_h
 #define nsIPresShellInlines_h
 
+#include "mozilla/PresShell.h"
 #include "mozilla/dom/Document.h"
 
 void nsIPresShell::SetNeedLayoutFlush() {
   mNeedLayoutFlush = true;
   if (mozilla::dom::Document* doc = mDocument->GetDisplayDocument()) {
-    if (nsIPresShell* shell = doc->GetShell()) {
+    if (mozilla::PresShell* shell = doc->GetPresShell()) {
       shell->mNeedLayoutFlush = true;
     }
   }
 
 #ifdef MOZ_GECKO_PROFILER
   if (!mReflowCause) {
     mReflowCause = profiler_get_backtrace();
   }
 #endif
 }
 
 void nsIPresShell::SetNeedStyleFlush() {
   mNeedStyleFlush = true;
   if (mozilla::dom::Document* doc = mDocument->GetDisplayDocument()) {
-    if (nsIPresShell* shell = doc->GetShell()) {
-      shell->mNeedStyleFlush = true;
+    if (mozilla::PresShell* presShell = doc->GetPresShell()) {
+      presShell->mNeedStyleFlush = true;
     }
   }
 
 #ifdef MOZ_GECKO_PROFILER
   if (!mStyleCause) {
     mStyleCause = profiler_get_backtrace();
   }
 #endif
@@ -42,18 +43,18 @@ void nsIPresShell::SetNeedStyleFlush() {
 void nsIPresShell::EnsureStyleFlush() {
   SetNeedStyleFlush();
   ObserveStyleFlushes();
 }
 
 void nsIPresShell::SetNeedThrottledAnimationFlush() {
   mNeedThrottledAnimationFlush = true;
   if (mozilla::dom::Document* doc = mDocument->GetDisplayDocument()) {
-    if (nsIPresShell* shell = doc->GetShell()) {
-      shell->mNeedThrottledAnimationFlush = true;
+    if (mozilla::PresShell* presShell = doc->GetPresShell()) {
+      presShell->mNeedThrottledAnimationFlush = true;
     }
   }
 }
 
 namespace mozilla {
 
 /* static */
 inline void PresShell::EventHandler::OnPresShellDestroy(Document* aDocument) {
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -15,16 +15,17 @@
 #include "mozilla/EventStateManager.h"
 #include "mozilla/FloatingPoint.h"
 #include "mozilla/gfx/gfxVars.h"
 #include "mozilla/gfx/PathHelpers.h"
 #include "mozilla/layers/PAPZ.h"
 #include "mozilla/Likely.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/MemoryReporting.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/ServoStyleSetInlines.h"
 #include "mozilla/StaticPrefs.h"
 #include "mozilla/Unused.h"
 #include "nsCharTraits.h"
 #include "mozilla/dom/Document.h"
 #include "nsFontMetrics.h"
 #include "nsPresContext.h"
 #include "nsPresContextInlines.h"
@@ -592,17 +593,17 @@ nsIContent* nsLayoutUtils::FindContentFo
   }
 }
 
 static nsIFrame* GetScrollFrameFromContent(nsIContent* aContent) {
   nsIFrame* frame = aContent->GetPrimaryFrame();
   if (aContent->OwnerDoc()->GetRootElement() == aContent) {
     nsIPresShell* presShell = frame ? frame->PresShell() : nullptr;
     if (!presShell) {
-      presShell = aContent->OwnerDoc()->GetShell();
+      presShell = aContent->OwnerDoc()->GetPresShell();
     }
     // We want the scroll frame, the root scroll frame differs from all
     // others in that the primary frame is not the scroll frame.
     nsIFrame* rootScrollFrame =
         presShell ? presShell->GetRootScrollFrame() : nullptr;
     if (rootScrollFrame) {
       frame = rootScrollFrame;
     }
@@ -9352,17 +9353,17 @@ CSSRect nsLayoutUtils::GetBoundingConten
     }
   }
   return result;
 }
 
 static already_AddRefed<nsIPresShell> GetPresShell(const nsIContent* aContent) {
   nsCOMPtr<nsIPresShell> result;
   if (Document* doc = aContent->GetComposedDoc()) {
-    result = doc->GetShell();
+    result = doc->GetPresShell();
   }
   return result.forget();
 }
 
 static void UpdateDisplayPortMarginsForPendingMetrics(
     const RepaintRequest& aMetrics) {
   nsIContent* content = nsLayoutUtils::FindContentFor(aMetrics.GetScrollId());
   if (!content) {
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -9,22 +9,22 @@
 #include "nsPresContext.h"
 #include "nsPresContextInlines.h"
 
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/Encoding.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventStateManager.h"
+#include "mozilla/PresShell.h"
 
 #include "base/basictypes.h"
 
 #include "nsCOMPtr.h"
 #include "nsCSSFrameConstructor.h"
-#include "nsIPresShell.h"
 #include "nsIPresShellInlines.h"
 #include "nsDocShell.h"
 #include "nsIContentViewer.h"
 #include "nsPIDOMWindow.h"
 #include "mozilla/ServoStyleSet.h"
 #include "nsIContent.h"
 #include "nsIFrame.h"
 #include "mozilla/dom/Document.h"
@@ -611,19 +611,20 @@ nsresult nsPresContext::Init(nsDeviceCon
     mRefreshDriver =
         mDocument->GetDisplayDocument()->GetPresContext()->RefreshDriver();
   } else {
     dom::Document* parent = mDocument->GetParentDocument();
     // Unfortunately, sometimes |parent| here has no presshell because
     // printing screws up things.  Assert that in other cases it does,
     // but whenever the shell is null just fall back on using our own
     // refresh driver.
-    NS_ASSERTION(!parent || mDocument->IsStaticDocument() || parent->GetShell(),
-                 "How did we end up with a presshell if our parent doesn't "
-                 "have one?");
+    NS_ASSERTION(
+        !parent || mDocument->IsStaticDocument() || parent->GetPresShell(),
+        "How did we end up with a presshell if our parent doesn't "
+        "have one?");
     if (parent && parent->GetPresContext()) {
       nsCOMPtr<nsIDocShellTreeItem> ourItem = mDocument->GetDocShell();
       if (ourItem) {
         nsCOMPtr<nsIDocShellTreeItem> parentItem;
         ourItem->GetSameTypeParent(getter_AddRefs(parentItem));
         if (parentItem) {
           Element* containingElement =
               parent->FindContentForSubDocument(mDocument);
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -16,16 +16,17 @@
 #include "mozilla/Attributes.h"
 #include "mozilla/ComputedStyle.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/dom/ElementInlines.h"
 #include "mozilla/dom/Selection.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/gfxVars.h"
 #include "mozilla/gfx/PathHelpers.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/Sprintf.h"
 #include "mozilla/StaticPrefs.h"
 
 #include "nsCOMPtr.h"
 #include "nsFlexContainerFrame.h"
 #include "nsFrameList.h"
 #include "nsPlaceholderFrame.h"
 #include "nsPluginFrame.h"
@@ -42,17 +43,16 @@
 #include "nsReadableUtils.h"
 #include "nsTableWrapperFrame.h"
 #include "nsView.h"
 #include "nsViewManager.h"
 #include "nsIScrollableFrame.h"
 #include "nsPresContext.h"
 #include "nsPresContextInlines.h"
 #include "nsStyleConsts.h"
-#include "nsIPresShell.h"
 #include "mozilla/Logging.h"
 #include "nsLayoutUtils.h"
 #include "LayoutLogging.h"
 #include "mozilla/RestyleManager.h"
 #include "nsInlineFrame.h"
 #include "nsFrameSelection.h"
 #include "nsGkAtoms.h"
 #include "nsCSSAnonBoxes.h"
@@ -4696,19 +4696,21 @@ NS_IMETHODIMP nsFrame::HandleRelease(nsP
     frameSelection = activeFrame->GetFrameSelection();
   }
 
   // Also check the selection of the capturing content which might be in a
   // different document.
   if (!frameSelection && captureContent) {
     Document* doc = captureContent->GetUncomposedDoc();
     if (doc) {
-      nsIPresShell* capturingShell = doc->GetShell();
-      if (capturingShell && capturingShell != PresContext()->GetPresShell()) {
-        frameSelection = capturingShell->FrameSelection();
+      mozilla::PresShell* capturingPresShell = doc->GetPresShell();
+      if (capturingPresShell &&
+          capturingPresShell !=
+              static_cast<mozilla::PresShell*>(PresContext()->GetPresShell())) {
+        frameSelection = capturingPresShell->FrameSelection();
       }
     }
   }
 
   if (frameSelection) {
     frameSelection->SetDragState(false);
     frameSelection->StopAutoScrollTimer();
     nsIScrollableFrame* scrollFrame = nsLayoutUtils::GetNearestScrollableFrame(
--- a/layout/generic/nsSubDocumentFrame.cpp
+++ b/layout/generic/nsSubDocumentFrame.cpp
@@ -8,28 +8,30 @@
  * rendering object for replaced elements that contain a document, such
  * as <frame>, <iframe>, and some <object>s
  */
 
 #include "nsSubDocumentFrame.h"
 
 #include "gfxPrefs.h"
 
+#include "mozilla/Preferences.h"
+#include "mozilla/PresShell.h"
+#include "mozilla/dom/Document.h"
+#include "mozilla/dom/HTMLFrameElement.h"
 #include "mozilla/layout/RenderFrame.h"
 
 #include "nsCOMPtr.h"
 #include "nsGenericHTMLElement.h"
 #include "nsGenericHTMLFrameElement.h"
 #include "nsAttrValueInlines.h"
 #include "nsIDocShell.h"
 #include "nsIContentViewer.h"
 #include "nsIContentInlines.h"
 #include "nsPresContext.h"
-#include "nsIPresShell.h"
-#include "mozilla/dom/Document.h"
 #include "nsView.h"
 #include "nsViewManager.h"
 #include "nsGkAtoms.h"
 #include "nsStyleConsts.h"
 #include "nsFrameSetFrame.h"
 #include "nsIScrollable.h"
 #include "nsNameSpaceManager.h"
 #include "nsDisplayList.h"
@@ -37,18 +39,16 @@
 #include "nsIObjectLoadingContent.h"
 #include "nsLayoutUtils.h"
 #include "FrameLayerBuilder.h"
 #include "nsPluginFrame.h"
 #include "nsContentUtils.h"
 #include "nsIPermissionManager.h"
 #include "nsServiceManagerUtils.h"
 #include "nsQueryObject.h"
-#include "mozilla/Preferences.h"
-#include "mozilla/dom/HTMLFrameElement.h"
 #include "RetainedDisplayListBuilder.h"
 
 using namespace mozilla;
 using mozilla::dom::Document;
 using mozilla::layout::RenderFrame;
 
 static bool sShowPreviousPage = true;
 
@@ -1019,22 +1019,22 @@ static void DestroyDisplayItemDataForFra
       DestroyDisplayItemDataForFrames(childFrames.get());
     }
   }
 }
 
 static bool BeginSwapDocShellsForDocument(Document* aDocument, void*) {
   MOZ_ASSERT(aDocument, "null document");
 
-  nsIPresShell* shell = aDocument->GetShell();
-  if (shell) {
+  PresShell* presShell = aDocument->GetPresShell();
+  if (presShell) {
     // Disable painting while the views are detached, see bug 946929.
-    shell->SetNeverPainting(true);
+    presShell->SetNeverPainting(true);
 
-    nsIFrame* rootFrame = shell->GetRootFrame();
+    nsIFrame* rootFrame = presShell->GetRootFrame();
     if (rootFrame) {
       ::DestroyDisplayItemDataForFrames(rootFrame);
     }
   }
   aDocument->EnumerateActivityObservers(nsPluginFrame::BeginSwapDocShells,
                                         nullptr);
   aDocument->EnumerateSubDocuments(BeginSwapDocShellsForDocument, nullptr);
   return true;
--- a/layout/inspector/InspectorUtils.cpp
+++ b/layout/inspector/InspectorUtils.cpp
@@ -12,27 +12,27 @@
 #include "gfxTextRun.h"
 #include "nsArray.h"
 #include "nsAutoPtr.h"
 #include "nsIServiceManager.h"
 #include "nsString.h"
 #include "nsIStyleSheetLinkingElement.h"
 #include "nsIContentInlines.h"
 #include "mozilla/dom/Document.h"
-#include "nsIPresShell.h"
 #include "nsIDOMWindow.h"
 #include "nsXBLBinding.h"
 #include "nsXBLPrototypeBinding.h"
 #include "nsIMutableArray.h"
 #include "nsBindingManager.h"
 #include "ChildIterator.h"
 #include "nsComputedDOMStyle.h"
 #include "mozilla/EventStateManager.h"
 #include "nsAtom.h"
 #include "nsRange.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/StyleSheetInlines.h"
 #include "mozilla/dom/CharacterData.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/CSSStyleRule.h"
 #include "mozilla/dom/InspectorUtilsBinding.h"
 #include "mozilla/dom/ToJSValue.h"
 #include "nsCSSProps.h"
 #include "nsCSSValue.h"
@@ -53,17 +53,17 @@ using namespace mozilla::dom;
 namespace mozilla {
 namespace dom {
 
 /* static */
 void InspectorUtils::GetAllStyleSheets(GlobalObject& aGlobalObject,
                                        Document& aDocument, bool aDocumentOnly,
                                        nsTArray<RefPtr<StyleSheet>>& aResult) {
   // Get the agent, then user and finally xbl sheets in the style set.
-  nsIPresShell* presShell = aDocument.GetShell();
+  PresShell* presShell = aDocument.GetPresShell();
 
   if (presShell) {
     ServoStyleSet* styleSet = presShell->StyleSet();
 
     if (!aDocumentOnly) {
       SheetType sheetType = SheetType::Agent;
       for (int32_t i = 0; i < styleSet->SheetCount(sheetType); i++) {
         aResult.AppendElement(styleSet->StyleSheetAt(sheetType, i));
@@ -163,27 +163,27 @@ void InspectorUtils::GetCSSStyleRules(
       GetCleanComputedStyleForElement(&aElement, pseudoElt);
   if (!computedStyle) {
     // This can fail for elements that are not in the document or
     // if the document they're in doesn't have a presshell.  Bail out.
     return;
   }
 
   Document* doc = aElement.OwnerDoc();
-  nsIPresShell* shell = doc->GetShell();
-  if (!shell) {
+  PresShell* presShell = doc->GetPresShell();
+  if (!presShell) {
     return;
   }
 
   nsTArray<const RawServoStyleRule*> rawRuleList;
   Servo_ComputedValues_GetStyleRuleList(computedStyle, &rawRuleList);
 
   AutoTArray<ServoStyleRuleMap*, 1> maps;
   {
-    ServoStyleSet* styleSet = shell->StyleSet();
+    ServoStyleSet* styleSet = presShell->StyleSet();
     ServoStyleRuleMap* map = styleSet->StyleRuleMap();
     maps.AppendElement(map);
   }
 
   // Collect style rule maps for bindings.
   for (nsIContent* bindingContent = &aElement; bindingContent;
        bindingContent = bindingContent->GetBindingParent()) {
     for (nsXBLBinding* binding = bindingContent->GetXBLBinding(); binding;
@@ -593,17 +593,17 @@ already_AddRefed<ComputedStyle> Inspecto
     dom::Element* aElement, nsAtom* aPseudo) {
   MOZ_ASSERT(aElement);
 
   Document* doc = aElement->GetComposedDoc();
   if (!doc) {
     return nullptr;
   }
 
-  nsIPresShell* presShell = doc->GetShell();
+  PresShell* presShell = doc->GetPresShell();
   if (!presShell) {
     return nullptr;
   }
 
   nsPresContext* presContext = presShell->GetPresContext();
   if (!presContext) {
     return nullptr;
   }
--- a/layout/painting/RetainedDisplayListBuilder.cpp
+++ b/layout/painting/RetainedDisplayListBuilder.cpp
@@ -9,16 +9,17 @@
 
 #include "DisplayListChecker.h"
 #include "gfxPrefs.h"
 #include "nsPlaceholderFrame.h"
 #include "nsSubDocumentFrame.h"
 #include "nsViewManager.h"
 #include "nsCanvasFrame.h"
 #include "mozilla/AutoRestore.h"
+#include "mozilla/PresShell.h"
 
 /**
  * Code for doing display list building for a modified subset of the window,
  * and then merging it into the existing display list (for the full window).
  *
  * The approach primarily hinges on the observation that the 'true' ordering
  * of display items is represented by a DAG (only items that intersect in 2d
  * space have a defined ordering). Our display list is just one of a many
@@ -719,17 +720,17 @@ struct CbData {
 };
 
 static nsIFrame* GetRootFrameForPainting(nsDisplayListBuilder* aBuilder,
                                          Document* aDocument) {
   // Although this is the actual subdocument, it might not be
   // what painting uses. Walk up to the nsSubDocumentFrame owning
   // us, and then ask that which subdoc it's going to paint.
 
-  nsIPresShell* presShell = aDocument->GetShell();
+  PresShell* presShell = aDocument->GetPresShell();
   if (!presShell) {
     return nullptr;
   }
   nsView* rootView = presShell->GetViewManager()->GetRootView();
   if (!rootView) {
     return nullptr;
   }
 
@@ -747,20 +748,21 @@ static nsIFrame* GetRootFrameForPainting
 
   nsIFrame* subDocFrame = subDocView->GetFrame();
   if (!subDocFrame) {
     return nullptr;
   }
 
   nsSubDocumentFrame* subdocumentFrame = do_QueryFrame(subDocFrame);
   MOZ_ASSERT(subdocumentFrame);
-  presShell = subdocumentFrame->GetSubdocumentPresShellForPainting(
-      aBuilder->IsIgnoringPaintSuppression()
-          ? nsSubDocumentFrame::IGNORE_PAINT_SUPPRESSION
-          : 0);
+  presShell = static_cast<PresShell*>(
+      subdocumentFrame->GetSubdocumentPresShellForPainting(
+          aBuilder->IsIgnoringPaintSuppression()
+              ? nsSubDocumentFrame::IGNORE_PAINT_SUPPRESSION
+              : 0));
   return presShell ? presShell->GetRootFrame() : nullptr;
 }
 
 static bool SubDocEnumCb(Document* aDocument, void* aData) {
   MOZ_ASSERT(aDocument);
   MOZ_ASSERT(aData);
 
   CbData* data = static_cast<CbData*>(aData);
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -23,21 +23,21 @@
 #include "mozilla/dom/KeyframeEffect.h"
 #include "mozilla/dom/Selection.h"
 #include "mozilla/dom/ServiceWorkerRegistrar.h"
 #include "mozilla/dom/ServiceWorkerRegistration.h"
 #include "mozilla/dom/SVGElement.h"
 #include "mozilla/dom/TouchEvent.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/layers/PLayerTransaction.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/ShapeUtils.h"
 #include "nsCSSRendering.h"
 #include "nsCSSRenderingGradients.h"
 #include "nsISelectionController.h"
-#include "nsIPresShell.h"
 #include "nsRegion.h"
 #include "nsStyleStructInlines.h"
 #include "nsStyleTransformMatrix.h"
 #include "nsTransitionManager.h"
 #include "gfxMatrix.h"
 #include "gfxPrefs.h"
 #include "nsSVGIntegrationUtils.h"
 #include "nsSVGUtils.h"
@@ -2536,20 +2536,20 @@ bool nsDisplayList::ComputeVisibilityFor
   mIsOpaque = !aVisibleRegion->Intersects(aListVisibleBounds);
   return anyVisible;
 }
 
 static bool TriggerPendingAnimationsOnSubDocuments(Document* aDocument,
                                                    void* aReadyTime) {
   PendingAnimationTracker* tracker = aDocument->GetPendingAnimationTracker();
   if (tracker) {
-    nsIPresShell* shell = aDocument->GetShell();
+    PresShell* presShell = aDocument->GetPresShell();
     // If paint-suppression is in effect then we haven't finished painting
     // this document yet so we shouldn't start animations
-    if (!shell || !shell->IsPaintingSuppressed()) {
+    if (!presShell || !presShell->IsPaintingSuppressed()) {
       const TimeStamp& readyTime = *static_cast<TimeStamp*>(aReadyTime);
       tracker->TriggerPendingAnimationsOnNextTick(readyTime);
     }
   }
   aDocument->EnumerateSubDocuments(TriggerPendingAnimationsOnSubDocuments,
                                    aReadyTime);
   return true;
 }
--- a/layout/printing/nsPrintJob.cpp
+++ b/layout/printing/nsPrintJob.cpp
@@ -78,20 +78,20 @@ static const char kPrintingPromptService
 #include "mozilla/layout/RemotePrintJobChild.h"
 #include "nsISupportsUtils.h"
 #include "nsIScriptContext.h"
 #include "nsIDocumentObserver.h"
 #include "nsISelectionListener.h"
 #include "nsContentCID.h"
 #include "nsLayoutCID.h"
 #include "nsContentUtils.h"
-#include "nsIPresShell.h"
 #include "nsLayoutStylesheetCache.h"
 #include "nsLayoutUtils.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/PresShell.h"
 #include "Text.h"
 
 #include "nsWidgetsCID.h"
 #include "nsIDeviceContextSpec.h"
 #include "nsDeviceContextSpecProxy.h"
 #include "nsViewManager.h"
 
 #include "nsIPageSequenceFrame.h"
@@ -2233,17 +2233,17 @@ nsresult nsPrintJob::ReflowPrintObject(c
   aPO->mViewManager = new nsViewManager();
 
   rv = aPO->mViewManager->Init(printData->mPrintDC);
   NS_ENSURE_SUCCESS(rv, rv);
 
   UniquePtr<ServoStyleSet> styleSet =
       mDocViewerPrint->CreateStyleSet(aPO->mDocument);
 
-  aPO->mPresShell = aPO->mDocument->CreateShell(
+  aPO->mPresShell = aPO->mDocument->CreatePresShell(
       aPO->mPresContext, aPO->mViewManager, std::move(styleSet));
   if (!aPO->mPresShell) {
     return NS_ERROR_FAILURE;
   }
 
   // If we're printing selection then remove the unselected nodes from our
   // cloned document.
   int16_t printRangeType = nsIPrintSettings::kRangeAllPages;
@@ -2421,24 +2421,24 @@ static nsINode* GetCorrespondingNodeInDo
   }
 
   return correspondingNode;
 }
 
 static NS_NAMED_LITERAL_STRING(kEllipsis, u"\x2026");
 
 static nsresult DeleteUnselectedNodes(Document* aOrigDoc, Document* aDoc) {
-  nsIPresShell* origShell = aOrigDoc->GetShell();
-  nsIPresShell* shell = aDoc->GetShell();
-  NS_ENSURE_STATE(origShell && shell);
+  PresShell* origPresShell = aOrigDoc->GetPresShell();
+  PresShell* presShell = aDoc->GetPresShell();
+  NS_ENSURE_STATE(origPresShell && presShell);
 
   RefPtr<Selection> origSelection =
-      origShell->GetCurrentSelection(SelectionType::eNormal);
+      origPresShell->GetCurrentSelection(SelectionType::eNormal);
   RefPtr<Selection> selection =
-      shell->GetCurrentSelection(SelectionType::eNormal);
+      presShell->GetCurrentSelection(SelectionType::eNormal);
   NS_ENSURE_STATE(origSelection && selection);
 
   nsINode* bodyNode = aDoc->GetBodyElement();
   nsINode* startNode = bodyNode;
   uint32_t startOffset = 0;
   uint32_t ellipsisOffset = 0;
 
   int32_t rangeCount = origSelection->RangeCount();
--- a/layout/style/FontFaceSet.cpp
+++ b/layout/style/FontFaceSet.cpp
@@ -17,16 +17,17 @@
 #include "mozilla/dom/FontFaceSetLoadEvent.h"
 #include "mozilla/dom/FontFaceSetLoadEventBinding.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/FontPropertyTypes.h"
 #include "mozilla/net/ReferrerPolicy.h"
 #include "mozilla/AsyncEventDispatcher.h"
 #include "mozilla/Logging.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/ServoBindings.h"
 #include "mozilla/ServoCSSParser.h"
 #include "mozilla/ServoStyleSet.h"
 #include "mozilla/ServoUtils.h"
 #include "mozilla/Sprintf.h"
 #include "mozilla/StaticPrefs.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/LoadInfo.h"
@@ -37,17 +38,16 @@
 #include "nsIClassOfService.h"
 #include "nsIConsoleService.h"
 #include "nsIContentPolicy.h"
 #include "nsIContentSecurityPolicy.h"
 #include "nsIDocShell.h"
 #include "mozilla/dom/Document.h"
 #include "nsILoadContext.h"
 #include "nsINetworkPredictor.h"
-#include "nsIPresShell.h"
 #include "nsIPresShellInlines.h"
 #include "nsIPrincipal.h"
 #include "nsISupportsPriority.h"
 #include "nsIWebNavigation.h"
 #include "nsNetUtil.h"
 #include "nsIProtocolHandler.h"
 #include "nsIInputStream.h"
 #include "nsLayoutUtils.h"
@@ -1704,18 +1704,18 @@ void FontFaceSet::FlushUserFontSet() {
   }
 }
 
 void FontFaceSet::MarkUserFontSetDirty() {
   if (mDocument) {
     // Ensure we trigger at least a style flush, that will eventually flush the
     // user font set. Otherwise the font loads that that flush may cause could
     // never be triggered.
-    if (nsIPresShell* shell = mDocument->GetShell()) {
-      shell->EnsureStyleFlush();
+    if (PresShell* presShell = mDocument->GetPresShell()) {
+      presShell->EnsureStyleFlush();
     }
     mDocument->MarkUserFontSetDirty();
   }
 }
 
 nsPresContext* FontFaceSet::GetPresContext() {
   if (!mDocument) {
     return nullptr;
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -8,16 +8,17 @@
 #include "mozilla/ServoStyleSetInlines.h"
 
 #include "gfxPlatformFontList.h"
 #include "mozilla/AutoRestyleTimelineMarker.h"
 #include "mozilla/DocumentStyleRootIterator.h"
 #include "mozilla/EffectCompositor.h"
 #include "mozilla/IntegerRange.h"
 #include "mozilla/LookAndFeel.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/ServoBindings.h"
 #include "mozilla/RestyleManager.h"
 #include "mozilla/ServoStyleRuleMap.h"
 #include "mozilla/ServoTypes.h"
 #include "mozilla/SMILAnimationController.h"
 #include "mozilla/StyleAnimationValue.h"
 #include "mozilla/css/Loader.h"
 #include "mozilla/dom/AnonymousContent.h"
@@ -1341,18 +1342,18 @@ bool ServoStyleSet::MayTraverseFrom(cons
   if (!parent->AsElement()->HasServoData()) {
     return false;
   }
 
   return !Servo_Element_IsDisplayNone(parent->AsElement());
 }
 
 bool ServoStyleSet::ShouldTraverseInParallel() const {
-  MOZ_ASSERT(mDocument->GetShell(), "Styling a document without a shell?");
-  if (!mDocument->GetShell()->IsActive()) {
+  MOZ_ASSERT(mDocument->GetPresShell(), "Styling a document without a shell?");
+  if (!mDocument->GetPresShell()->IsActive()) {
     return false;
   }
 #ifdef MOZ_GECKO_PROFILER
   if (profiler_feature_active(ProfilerFeature::SequentialStyle)) {
     return false;
   }
 #endif
   return true;
--- a/layout/style/StyleAnimationValue.cpp
+++ b/layout/style/StyleAnimationValue.cpp
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* Utilities for animation of computed style values */
 
 #include "mozilla/StyleAnimationValue.h"
 
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/MathAlgorithms.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/ServoStyleSet.h"
 #include "mozilla/Tuple.h"
 #include "mozilla/UniquePtr.h"
 #include "nsAutoPtr.h"
 #include "nsCOMArray.h"
 #include "nsString.h"
 #include "mozilla/ComputedStyle.h"
 #include "nsComputedDOMStyle.h"
@@ -311,35 +312,35 @@ AnimationValue AnimationValue::FromStrin
 
   AnimationValue result;
 
   nsCOMPtr<Document> doc = aElement->GetComposedDoc();
   if (!doc) {
     return result;
   }
 
-  nsCOMPtr<nsIPresShell> shell = doc->GetShell();
-  if (!shell) {
+  RefPtr<PresShell> presShell = doc->GetPresShell();
+  if (!presShell) {
     return result;
   }
 
   // GetComputedStyle() flushes style, so we shouldn't assume that any
   // non-owning references we have are still valid.
   RefPtr<ComputedStyle> computedStyle =
       nsComputedDOMStyle::GetComputedStyle(aElement, nullptr);
   MOZ_ASSERT(computedStyle);
 
   RefPtr<RawServoDeclarationBlock> declarations = ServoCSSParser::ParseProperty(
       aProperty, aValue, ServoCSSParser::GetParsingEnvironment(doc));
 
   if (!declarations) {
     return result;
   }
 
-  result.mServo = shell->StyleSet()->ComputeAnimationValue(
+  result.mServo = presShell->StyleSet()->ComputeAnimationValue(
       aElement, declarations, computedStyle);
   return result;
 }
 
 /* static */
 already_AddRefed<RawServoAnimationValue> AnimationValue::FromAnimatable(
     nsCSSPropertyID aProperty, const layers::Animatable& aAnimatable) {
   RefPtr<RawServoAnimationValue> result;
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -7,16 +7,17 @@
 /* DOM object returned from element.getComputedStyle() */
 
 #include "nsComputedDOMStyle.h"
 
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/FloatingPoint.h"
 #include "mozilla/FontPropertyTypes.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/StaticPtr.h"
 
 #include "nsError.h"
 #include "nsIFrame.h"
 #include "nsIFrameInlines.h"
 #include "mozilla/ComputedStyle.h"
 #include "nsIScrollableFrame.h"
 #include "nsContentUtils.h"
@@ -94,27 +95,27 @@ already_AddRefed<CSSValue> GetBackground
   }
 
   return valueList.forget();
 }
 
 // Whether aDocument needs to restyle for aElement
 static bool DocumentNeedsRestyle(const Document* aDocument, Element* aElement,
                                  nsAtom* aPseudo) {
-  nsIPresShell* shell = aDocument->GetShell();
-  if (!shell) {
+  PresShell* presShell = aDocument->GetPresShell();
+  if (!presShell) {
     return true;
   }
 
-  nsPresContext* presContext = shell->GetPresContext();
+  nsPresContext* presContext = presShell->GetPresContext();
   MOZ_ASSERT(presContext);
 
   // Unfortunately we don't know if the sheet change affects mElement or not, so
   // just assume it will and that we need to flush normally.
-  ServoStyleSet* styleSet = shell->StyleSet();
+  ServoStyleSet* styleSet = presShell->StyleSet();
   if (styleSet->StyleSheetsHaveChanged()) {
     return true;
   }
 
   // Pending media query updates can definitely change style on the element. For
   // example, if you change the zoom factor and then call getComputedStyle, you
   // should be able to observe the style with the new media queries.
   //
@@ -565,27 +566,28 @@ already_AddRefed<ComputedStyle>
 nsComputedDOMStyle::GetUnanimatedComputedStyleNoFlush(Element* aElement,
                                                       nsAtom* aPseudo) {
   RefPtr<ComputedStyle> style = GetComputedStyleNoFlush(aElement, aPseudo);
   if (!style) {
     return nullptr;
   }
 
   PseudoStyleType pseudoType = GetPseudoType(aPseudo);
-  nsIPresShell* shell = aElement->OwnerDoc()->GetShell();
-  MOZ_ASSERT(shell, "How in the world did we get a style a few lines above?");
+  PresShell* presShell = aElement->OwnerDoc()->GetPresShell();
+  MOZ_ASSERT(presShell,
+             "How in the world did we get a style a few lines above?");
 
   Element* elementOrPseudoElement =
       EffectCompositor::GetElementToRestyle(aElement, pseudoType);
   if (!elementOrPseudoElement) {
     return nullptr;
   }
 
-  return shell->StyleSet()->GetBaseContextForElement(elementOrPseudoElement,
-                                                     style);
+  return presShell->StyleSet()->GetBaseContextForElement(elementOrPseudoElement,
+                                                         style);
 }
 
 nsMargin nsComputedDOMStyle::GetAdjustedValuesForBoxSizing() {
   // We want the width/height of whatever parts 'width' or 'height' controls,
   // which can be different depending on the value of the 'box-sizing' property.
   const nsStylePosition* stylePos = StylePosition();
 
   nsMargin adjustment;
@@ -822,17 +824,17 @@ void nsComputedDOMStyle::UpdateCurrentSt
   if (presShellForContent && presShellForContent->GetDocument() != document) {
     presShellForContent->GetDocument()->FlushPendingNotifications(
         FlushType::Style);
     if (presShellForContent->IsDestroying()) {
       presShellForContent = nullptr;
     }
   }
 
-  mPresShell = document->GetShell();
+  mPresShell = document->GetPresShell();
   if (!mPresShell || !mPresShell->GetPresContext()) {
     ClearComputedStyle();
     return;
   }
 
   // We need to use GetUndisplayedRestyleGeneration instead of
   // GetRestyleGeneration, because the caching of mComputedStyle is an
   // optimization that is useful only for displayed elements.
--- a/layout/style/nsHTMLStyleSheet.cpp
+++ b/layout/style/nsHTMLStyleSheet.cpp
@@ -9,19 +9,19 @@
  * HTML attributes
  */
 
 #include "nsHTMLStyleSheet.h"
 #include "nsMappedAttributes.h"
 #include "nsGkAtoms.h"
 #include "nsPresContext.h"
 #include "mozilla/EventStates.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/dom/Document.h"
 #include "mozilla/dom/DocumentInlines.h"
-#include "nsIPresShell.h"
 #include "nsStyleConsts.h"
 #include "nsError.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/dom/Element.h"
 #include "nsHashKeys.h"
 #include "mozilla/OperatorNewExtensions.h"
 #include "mozilla/RestyleManager.h"
 #include "mozilla/ServoBindings.h"
@@ -86,17 +86,17 @@ void nsHTMLStyleSheet::Reset() {
   mServoActiveLinkDecl = nullptr;
 
   mMappedAttrTable.Clear();
   mMappedAttrsDirty = false;
 }
 
 nsresult nsHTMLStyleSheet::ImplLinkColorSetter(
     RefPtr<RawServoDeclarationBlock> &aDecl, nscolor aColor) {
-  if (!mDocument || !mDocument->GetShell()) {
+  if (!mDocument || !mDocument->GetPresShell()) {
     return NS_OK;
   }
 
   MOZ_ASSERT(!ServoStyleSet::IsInServoTraversal());
   aDecl = Servo_DeclarationBlock_CreateEmpty().Consume();
   Servo_DeclarationBlock_SetColorValue(aDecl.get(), eCSSProperty_color, aColor);
 
   // Now make sure we restyle any links that might need it.  This
--- a/layout/xul/BoxObject.cpp
+++ b/layout/xul/BoxObject.cpp
@@ -1,18 +1,18 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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/dom/BoxObject.h"
 #include "nsCOMPtr.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/dom/Document.h"
-#include "nsIPresShell.h"
 #include "nsPresContext.h"
 #include "nsIContent.h"
 #include "nsContainerFrame.h"
 #include "nsIDocShell.h"
 #include "nsReadableUtils.h"
 #include "nsView.h"
 #include "nsLayoutUtils.h"
 #include "nsISupportsPrimitives.h"
@@ -111,17 +111,17 @@ nsIPresShell* BoxObject::GetPresShell(bo
   if (!doc) {
     return nullptr;
   }
 
   if (aFlushLayout) {
     doc->FlushPendingNotifications(FlushType::Layout);
   }
 
-  return doc->GetShell();
+  return doc->GetPresShell();
 }
 
 nsresult BoxObject::GetOffsetRect(nsIntRect& aRect) {
   aRect.SetRect(0, 0, 0, 0);
 
   if (!mContent) return NS_ERROR_NOT_INITIALIZED;
 
   // Get the Frame for our content
--- a/layout/xul/nsXULPopupManager.cpp
+++ b/layout/xul/nsXULPopupManager.cpp
@@ -38,16 +38,17 @@
 #include "mozilla/dom/KeyboardEvent.h"
 #include "mozilla/dom/KeyboardEventBinding.h"
 #include "mozilla/dom/MouseEvent.h"
 #include "mozilla/dom/UIEvent.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventStateManager.h"
 #include "mozilla/LookAndFeel.h"
 #include "mozilla/MouseEvents.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/Services.h"
 #include "mozilla/widget/nsAutoRollup.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 static_assert(KeyboardEvent_Binding::DOM_VK_HOME ==
                       KeyboardEvent_Binding::DOM_VK_END + 1 &&
@@ -533,18 +534,20 @@ void nsXULPopupManager::PopupResized(nsI
   popup->SetAttr(kNameSpaceID_None, nsGkAtoms::height, height, true);
 }
 
 nsMenuPopupFrame* nsXULPopupManager::GetPopupFrameForContent(
     nsIContent* aContent, bool aShouldFlush) {
   if (aShouldFlush) {
     Document* document = aContent->GetUncomposedDoc();
     if (document) {
-      nsCOMPtr<nsIPresShell> presShell = document->GetShell();
-      if (presShell) presShell->FlushPendingNotifications(FlushType::Layout);
+      RefPtr<PresShell> presShell = document->GetPresShell();
+      if (presShell) {
+        presShell->FlushPendingNotifications(FlushType::Layout);
+      }
     }
   }
 
   return do_QueryFrame(aContent->GetPrimaryFrame());
 }
 
 nsMenuChainItem* nsXULPopupManager::GetTopVisibleMenu() {
   nsMenuChainItem* item = mPopups;
@@ -589,17 +592,17 @@ void nsXULPopupManager::InitTriggerEvent
     WidgetEvent* event = aEvent->WidgetEventPtr();
     if (event) {
       WidgetInputEvent* inputEvent = event->AsInputEvent();
       if (inputEvent) {
         mCachedModifiers = inputEvent->mModifiers;
       }
       Document* doc = aPopup->GetUncomposedDoc();
       if (doc) {
-        nsIPresShell* presShell = doc->GetShell();
+        PresShell* presShell = doc->GetPresShell();
         nsPresContext* presContext;
         if (presShell && (presContext = presShell->GetPresContext())) {
           nsPresContext* rootDocPresContext = presContext->GetRootPresContext();
           if (!rootDocPresContext) return;
           nsIFrame* rootDocumentRootFrame =
               rootDocPresContext->PresShell()->GetRootFrame();
           if ((event->mClass == eMouseEventClass ||
                event->mClass == eMouseScrollEventClass ||
@@ -779,18 +782,20 @@ static void CheckCaretDrawingState() {
     if (!window) return;
 
     auto* piWindow = nsPIDOMWindowOuter::From(window);
     MOZ_ASSERT(piWindow);
 
     nsCOMPtr<Document> focusedDoc = piWindow->GetDoc();
     if (!focusedDoc) return;
 
-    nsIPresShell* presShell = focusedDoc->GetShell();
-    if (!presShell) return;
+    PresShell* presShell = focusedDoc->GetPresShell();
+    if (!presShell) {
+      return;
+    }
 
     RefPtr<nsCaret> caret = presShell->GetCaret();
     if (!caret) return;
     caret->SchedulePaint();
   }
 }
 
 void nsXULPopupManager::ShowPopupCallback(nsIContent* aPopup,
--- a/layout/xul/nsXULTooltipListener.cpp
+++ b/layout/xul/nsXULTooltipListener.cpp
@@ -20,18 +20,19 @@
 #include "nsPIDOMWindow.h"
 #ifdef MOZ_XUL
 #  include "nsXULPopupManager.h"
 #endif
 #include "nsIPopupContainer.h"
 #include "nsTreeColumns.h"
 #include "nsContentUtils.h"
 #include "mozilla/ErrorResult.h"
+#include "mozilla/LookAndFeel.h"
 #include "mozilla/Preferences.h"
-#include "mozilla/LookAndFeel.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/Event.h"  // for Event
 #include "mozilla/dom/MouseEvent.h"
 #include "mozilla/dom/TreeColumnBinding.h"
 #include "mozilla/dom/XULTreeElementBinding.h"
 #include "mozilla/TextEvents.h"
 
 using namespace mozilla;
@@ -519,34 +520,34 @@ nsresult nsXULTooltipListener::FindToolt
 
   if (window->Closed()) {
     return NS_OK;
   }
 
   // non-XUL elements should just use the default tooltip
   if (!aTarget->IsXULElement()) {
     nsIPopupContainer* popupContainer =
-        nsIPopupContainer::GetPopupContainer(document->GetShell());
+        nsIPopupContainer::GetPopupContainer(document->GetPresShell());
     NS_ENSURE_STATE(popupContainer);
     if (RefPtr<Element> tooltip = popupContainer->GetDefaultTooltip()) {
       tooltip.forget(aTooltip);
       return NS_OK;
     }
     return NS_ERROR_FAILURE;
   }
 
   nsAutoString tooltipText;
   if (aTarget->IsElement()) {
     aTarget->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::tooltiptext,
                                   tooltipText);
   }
   if (!tooltipText.IsEmpty()) {
     // specifying tooltiptext means we will always use the default tooltip
     nsIPopupContainer* popupContainer =
-        nsIPopupContainer::GetPopupContainer(document->GetShell());
+        nsIPopupContainer::GetPopupContainer(document->GetPresShell());
     NS_ENSURE_STATE(popupContainer);
     if (RefPtr<Element> tooltip = popupContainer->GetDefaultTooltip()) {
       tooltip->SetAttr(kNameSpaceID_None, nsGkAtoms::label, tooltipText, true);
       tooltip.forget(aTooltip);
     }
     return NS_OK;
   }
 
@@ -579,17 +580,17 @@ nsresult nsXULTooltipListener::FindToolt
       }
     }
   }
 
 #ifdef MOZ_XUL
   // titletips should just use the default tooltip
   if (mIsSourceTree && mNeedTitletip) {
     nsIPopupContainer* popupContainer =
-        nsIPopupContainer::GetPopupContainer(document->GetShell());
+        nsIPopupContainer::GetPopupContainer(document->GetPresShell());
     NS_ENSURE_STATE(popupContainer);
     NS_IF_ADDREF(*aTooltip = popupContainer->GetDefaultTooltip());
   }
 #endif
 
   return NS_OK;
 }
 
--- a/servo/components/style/gecko/media_queries.rs
+++ b/servo/components/style/gecko/media_queries.rs
@@ -164,16 +164,17 @@ impl Device {
 
     /// Gets the pres context associated with this document.
     #[inline]
     pub fn pres_context(&self) -> Option<&structs::nsPresContext> {
         unsafe {
             self.document()
                 .mPresShell
                 .as_ref()?
+                ._base
                 .mPresContext
                 .mRawPtr
                 .as_ref()
         }
     }
 
     /// Gets the preference stylesheet prefs for our document.
     #[inline]
--- a/toolkit/components/find/nsWebBrowserFind.cpp
+++ b/toolkit/components/find/nsWebBrowserFind.cpp
@@ -12,32 +12,32 @@
 
 #include "nsIComponentManager.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsPIDOMWindow.h"
 #include "nsIURI.h"
 #include "nsIDocShell.h"
-#include "nsIPresShell.h"
 #include "nsPresContext.h"
 #include "mozilla/dom/Document.h"
 #include "nsISelectionController.h"
 #include "nsIFrame.h"
 #include "nsITextControlFrame.h"
 #include "nsReadableUtils.h"
 #include "nsIContent.h"
 #include "nsContentCID.h"
 #include "nsIServiceManager.h"
 #include "nsIObserverService.h"
 #include "nsISupportsPrimitives.h"
 #include "nsFind.h"
 #include "nsError.h"
 #include "nsFocusManager.h"
 #include "nsRange.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/Services.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/Selection.h"
 #include "nsISimpleEnumerator.h"
 #include "nsContentUtils.h"
 #include "nsGenericHTMLElement.h"
 
 #if DEBUG
@@ -319,17 +319,17 @@ nsWebBrowserFind::SetMatchCase(bool aMat
 
 void nsWebBrowserFind::SetSelectionAndScroll(nsPIDOMWindowOuter* aWindow,
                                              nsRange* aRange) {
   RefPtr<Document> doc = aWindow->GetDoc();
   if (!doc) {
     return;
   }
 
-  nsIPresShell* presShell = doc->GetShell();
+  PresShell* presShell = doc->GetPresShell();
   if (!presShell) {
     return;
   }
 
   nsCOMPtr<nsINode> node = aRange->GetStartContainer();
   nsCOMPtr<nsIContent> content(do_QueryInterface(node));
   nsIFrame* frame = content->GetPrimaryFrame();
   if (!frame) {
@@ -702,17 +702,17 @@ nsresult nsWebBrowserFind::OnEndSearchFr
 
 already_AddRefed<Selection> nsWebBrowserFind::GetFrameSelection(
     nsPIDOMWindowOuter* aWindow) {
   RefPtr<Document> doc = aWindow->GetDoc();
   if (!doc) {
     return nullptr;
   }
 
-  nsIPresShell* presShell = doc->GetShell();
+  PresShell* presShell = doc->GetPresShell();
   if (!presShell) {
     return nullptr;
   }
 
   // text input controls have their independent selection controllers that we
   // must use when they have focus.
   nsPresContext* presContext = presShell->GetPresContext();
 
@@ -729,18 +729,17 @@ already_AddRefed<Selection> nsWebBrowser
   if (frame) {
     frame->GetSelectionController(presContext, getter_AddRefs(selCon));
     sel = selCon->GetSelection(nsISelectionController::SELECTION_NORMAL);
     if (sel && sel->RangeCount() > 0) {
       return sel.forget();
     }
   }
 
-  selCon = do_QueryInterface(presShell);
-  sel = selCon->GetSelection(nsISelectionController::SELECTION_NORMAL);
+  sel = presShell->GetSelection(nsISelectionController::SELECTION_NORMAL);
   return sel.forget();
 }
 
 nsresult nsWebBrowserFind::ClearFrameSelection(nsPIDOMWindowOuter* aWindow) {
   NS_ENSURE_ARG(aWindow);
   RefPtr<Selection> selection = GetFrameSelection(aWindow);
   if (selection) {
     selection->RemoveAllRanges(IgnoreErrors());
--- a/toolkit/components/sessionstore/SessionStoreUtils.cpp
+++ b/toolkit/components/sessionstore/SessionStoreUtils.cpp
@@ -257,17 +257,17 @@ void SessionStoreUtils::RestoreDocShellC
     } else if (token.EqualsLiteral("ContentRetargetingOnChildren")) {
       aDocShell->SetAllowContentRetargetingOnChildren(false);
     }
   }
 }
 
 static void CollectCurrentScrollPosition(JSContext* aCx, Document& aDocument,
                                          Nullable<CollectedData>& aRetVal) {
-  nsIPresShell* presShell = aDocument.GetShell();
+  PresShell* presShell = aDocument.GetPresShell();
   if (!presShell) {
     return;
   }
   nsPoint scrollPos = presShell->GetVisualViewportOffset();
   int scrollX = nsPresContext::AppUnitsToIntCSSPixels(scrollPos.x);
   int scrollY = nsPresContext::AppUnitsToIntCSSPixels(scrollPos.y);
 
   if ((scrollX != 0) || (scrollY != 0)) {
--- a/toolkit/components/typeaheadfind/nsTypeAheadFind.cpp
+++ b/toolkit/components/typeaheadfind/nsTypeAheadFind.cpp
@@ -3,16 +3,17 @@
  * 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 "nsCOMPtr.h"
 #include "nsMemory.h"
 #include "nsIServiceManager.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/ModuleUtils.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/Services.h"
 #include "nsIWebBrowserChrome.h"
 #include "nsCURILoader.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsNetUtil.h"
 #include "nsIURL.h"
 #include "nsIURI.h"
 #include "nsIDocShell.h"
@@ -1127,17 +1128,17 @@ nsTypeAheadFind::GetFoundRange(nsRange**
 }
 
 NS_IMETHODIMP
 nsTypeAheadFind::IsRangeVisible(nsRange* aRange, bool aMustBeInViewPort,
                                 bool* aResult) {
   nsCOMPtr<nsINode> node = aRange->GetStartContainer();
 
   Document* doc = node->OwnerDoc();
-  nsCOMPtr<nsIPresShell> presShell = doc->GetShell();
+  RefPtr<PresShell> presShell = doc->GetPresShell();
   if (!presShell) {
     return NS_ERROR_UNEXPECTED;
   }
   RefPtr<nsPresContext> presContext = presShell->GetPresContext();
   RefPtr<nsRange> ignored;
   *aResult = IsRangeVisible(presShell, presContext, aRange, aMustBeInViewPort,
                             false, getter_AddRefs(ignored), nullptr);
   return NS_OK;
@@ -1313,17 +1314,17 @@ bool nsTypeAheadFind::IsRangeVisible(nsI
 
   return false;
 }
 
 NS_IMETHODIMP
 nsTypeAheadFind::IsRangeRendered(nsRange* aRange, bool* aResult) {
   nsINode* node = aRange->GetStartContainer();
 
-  nsCOMPtr<nsIPresShell> presShell = node->OwnerDoc()->GetShell();
+  RefPtr<PresShell> presShell = node->OwnerDoc()->GetPresShell();
   if (!presShell) {
     return NS_ERROR_UNEXPECTED;
   }
   RefPtr<nsPresContext> presContext = presShell->GetPresContext();
   *aResult = IsRangeRendered(presShell, presContext, aRange);
   return NS_OK;
 }
 
--- a/uriloader/base/nsDocLoader.cpp
+++ b/uriloader/base/nsDocLoader.cpp
@@ -754,22 +754,22 @@ void nsDocLoader::DocLoaderIsEmpty(bool 
               nsEventStatus unused = nsEventStatus_eIgnore;
               doc->SetLoadEventFiring(true);
               EventDispatcher::Dispatch(window, nullptr, &event, nullptr,
                                         &unused);
               doc->SetLoadEventFiring(false);
 
               // Now unsuppress painting on the presshell, if we
               // haven't done that yet.
-              nsCOMPtr<nsIPresShell> shell = doc->GetShell();
-              if (shell && !shell->IsDestroying()) {
-                shell->UnsuppressPainting();
+              RefPtr<PresShell> presShell = doc->GetPresShell();
+              if (presShell && !presShell->IsDestroying()) {
+                presShell->UnsuppressPainting();
 
-                if (!shell->IsDestroying()) {
-                  shell->LoadComplete();
+                if (!presShell->IsDestroying()) {
+                  presShell->LoadComplete();
                 }
               }
             }
           }
         }
         if (parent) {
           parent->ChildDoneWithOnload(this);
         }
--- a/widget/android/GeckoSystemStateListener.h
+++ b/widget/android/GeckoSystemStateListener.h
@@ -2,21 +2,21 @@
  * 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 GeckoSystemStateListener_h
 #define GeckoSystemStateListener_h
 
 #include "GeneratedJNINatives.h"
+#include "mozilla/Assertions.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/dom/Document.h"
-#include "nsIPresShell.h"
 #include "nsIWindowMediator.h"
 #include "nsPIDOMWindow.h"
-#include "mozilla/Assertions.h"
 
 namespace mozilla {
 
 class GeckoSystemStateListener final
     : public java::GeckoSystemStateListener::Natives<GeckoSystemStateListener> {
   GeckoSystemStateListener() = delete;
 
  public:
@@ -39,17 +39,17 @@ class GeckoSystemStateListener final
         break;
       }
 
       if (nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryInterface(elements)) {
         if (window->Closed()) {
           continue;
         }
         if (dom::Document* doc = window->GetExtantDoc()) {
-          if (nsIPresShell* presShell = doc->GetShell()) {
+          if (PresShell* presShell = doc->GetPresShell()) {
             presShell->ThemeChanged();
           }
         }
       }
     }
   }
 };
 
--- a/widget/cocoa/nsDragService.mm
+++ b/widget/cocoa/nsDragService.mm
@@ -18,16 +18,17 @@
 #include "nsCOMPtr.h"
 #include "nsPrimitiveHelpers.h"
 #include "nsLinebreakConverter.h"
 #include "nsIMacUtils.h"
 #include "nsINode.h"
 #include "nsRect.h"
 #include "nsPoint.h"
 #include "nsIIOService.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/dom/Document.h"
 #include "nsIContent.h"
 #include "nsView.h"
 #include "nsCocoaUtils.h"
 #include "mozilla/gfx/2D.h"
 #include "gfxPlatform.h"
 #include "nsDeviceContext.h"
 
@@ -598,21 +599,17 @@ void nsDragService::DragMovedWithView(NS
   // If the image has changed, call enumerateDraggingItemsWithOptions to get
   // the item being dragged and update its image.
   if (mDragImageChanged && mNativeDragView) {
     mDragImageChanged = false;
 
     nsPresContext* pc = nullptr;
     nsCOMPtr<nsIContent> content = do_QueryInterface(mImage);
     if (content) {
-      RefPtr<dom::Document> document = content->OwnerDoc();
-      if (document) {
-        nsIPresShell* shell = document->GetShell();
-        pc = shell ? shell->GetPresContext() : nullptr;
-      }
+      pc = content->OwnerDoc()->GetPresContext();
     }
 
     if (pc) {
       void (^changeImageBlock)(NSDraggingItem*, NSInteger, BOOL*) =
           ^(NSDraggingItem* draggingItem, NSInteger idx, BOOL* stop) {
             // We never add more than one item right now, but check just in case.
             if (idx > 0) {
               return;
--- a/widget/gtk/nsDragService.cpp
+++ b/widget/gtk/nsDragService.cpp
@@ -23,16 +23,17 @@
 #include "prthread.h"
 #include <dlfcn.h>
 #include <gtk/gtk.h>
 #include <gdk/gdkx.h>
 #include "nsCRT.h"
 #include "mozilla/BasicEvents.h"
 #include "mozilla/Services.h"
 #include "mozilla/ClearOnShutdown.h"
+#include "mozilla/PresShell.h"
 
 #include "gfxXlibSurface.h"
 #include "gfxContext.h"
 #include "nsImageToPixbuf.h"
 #include "nsPresContext.h"
 #include "nsIContent.h"
 #include "mozilla/dom/Document.h"
 #include "nsViewManager.h"
@@ -256,18 +257,20 @@ static void OnSourceGrabEventAfter(GtkWi
   // recommends an interval of 350ms +/- 200ms.
   sMotionEventTimerID = g_timeout_add_full(
       G_PRIORITY_DEFAULT_IDLE, 350, DispatchMotionEventCopy, nullptr, nullptr);
 }
 
 static GtkWindow *GetGtkWindow(dom::Document *aDocument) {
   if (!aDocument) return nullptr;
 
-  nsCOMPtr<nsIPresShell> presShell = aDocument->GetShell();
-  if (!presShell) return nullptr;
+  PresShell *presShell = aDocument->GetPresShell();
+  if (!presShell) {
+    return nullptr;
+  }
 
   RefPtr<nsViewManager> vm = presShell->GetViewManager();
   if (!vm) return nullptr;
 
   nsCOMPtr<nsIWidget> widget;
   vm->GetRootWidget(getter_AddRefs(widget));
   if (!widget) return nullptr;
 
--- a/widget/nsBaseDragService.cpp
+++ b/widget/nsBaseDragService.cpp
@@ -13,17 +13,16 @@
 #include "nsXPCOM.h"
 #include "nsISupportsPrimitives.h"
 #include "nsCOMPtr.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIFrame.h"
 #include "nsFrameLoaderOwner.h"
 #include "mozilla/dom/Document.h"
 #include "nsIContent.h"
-#include "nsIPresShell.h"
 #include "nsViewManager.h"
 #include "nsINode.h"
 #include "nsPresContext.h"
 #include "nsIImageLoadingContent.h"
 #include "imgIContainer.h"
 #include "imgIRequest.h"
 #include "ImageRegion.h"
 #include "nsQueryObject.h"
@@ -31,16 +30,17 @@
 #include "nsXULPopupManager.h"
 #include "nsMenuPopupFrame.h"
 #include "SVGImageContext.h"
 #ifdef MOZ_XUL
 #  include "nsTreeBodyFrame.h"
 #endif
 #include "mozilla/MouseEvents.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/PresShell.h"
 #include "mozilla/dom/BindingDeclarations.h"
 #include "mozilla/dom/DataTransferItemList.h"
 #include "mozilla/dom/DataTransfer.h"
 #include "mozilla/dom/DragEvent.h"
 #include "mozilla/dom/MouseEventBinding.h"
 #include "mozilla/dom/Selection.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/Unused.h"
@@ -453,17 +453,17 @@ void nsBaseDragService::DiscardInternalT
     }
   }
 }
 
 NS_IMETHODIMP
 nsBaseDragService::FireDragEventAtSource(EventMessage aEventMessage,
                                          uint32_t aKeyModifiers) {
   if (mSourceNode && mSourceDocument && !mSuppressLevel) {
-    nsCOMPtr<nsIPresShell> presShell = mSourceDocument->GetShell();
+    RefPtr<PresShell> presShell = mSourceDocument->GetPresShell();
     if (presShell) {
       nsEventStatus status = nsEventStatus_eIgnore;
       WidgetDragEvent event(true, aEventMessage, nullptr);
       event.inputSource = mInputSource;
       if (aEventMessage == eDragEnd) {
         event.mRefPoint = mEndDragPoint;
         event.mUserCancelled = mUserCancelled;
       }
@@ -506,17 +506,17 @@ nsBaseDragService::DragMoved(int32_t aX,
 
 static nsIPresShell* GetPresShellForContent(nsINode* aDOMNode) {
   nsCOMPtr<nsIContent> content = do_QueryInterface(aDOMNode);
   if (!content) return nullptr;
 
   RefPtr<Document> document = content->GetComposedDoc();
   if (document) {
     document->FlushPendingNotifications(FlushType::Display);
-    return document->GetShell();
+    return document->GetPresShell();
   }
 
   return nullptr;
 }
 
 nsresult nsBaseDragService::DrawDrag(nsINode* aDOMNode,
                                      const Maybe<CSSIntRegion>& aRegion,
                                      CSSIntPoint aScreenPosition,