Bug 1516366 - Move base classes from nsDocument to nsIDocument. r=smaug
authorEmilio Cobos Álvarez <emilio@crisal.io>
Wed, 26 Dec 2018 03:32:55 +0100
changeset 452137 83c1af1bfaafa5a5a6bcb1097fb51396359d1cc9
parent 452136 afc9a2a4fbf95505ec65b6c0dd4e0ea3f8ea8673
child 452138 d3d4a2c095db6a77d3ec2ea4cd6363ec8bc793f6
push id35287
push usercsabou@mozilla.com
push dateSun, 30 Dec 2018 09:31:19 +0000
treeherdermozilla-central@19fc512f3c95 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1516366
milestone66.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 1516366 - Move base classes from nsDocument to nsIDocument. r=smaug This is a big step in order to merge both. Also allows to remove some very silly casts, though it causes us to add some ToSupports around to deal with ambiguity of casts from nsIDocument to nsISupports, and add a dummy nsISupports implementation that will go away later in the series. Differential Revision: https://phabricator.services.mozilla.com/D15352
docshell/base/nsDocShell.cpp
dom/animation/AnimationEffect.h
dom/base/nsContentSink.cpp
dom/base/nsDocument.cpp
dom/base/nsDocument.h
dom/base/nsFocusManager.cpp
dom/base/nsGlobalWindowOuter.cpp
dom/base/nsIDocument.h
dom/base/nsImageLoadingContent.cpp
dom/base/nsObjectLoadingContent.cpp
dom/bindings/BindingDeclarations.h
dom/events/EventStateManager.cpp
dom/html/ImageDocument.cpp
dom/html/nsHTMLContentSink.cpp
dom/ipc/TabChild.cpp
dom/xhr/XMLHttpRequestMainThread.cpp
dom/xml/XMLDocument.cpp
dom/xml/nsXMLContentSink.cpp
dom/xml/nsXMLFragmentContentSink.cpp
dom/xul/XULDocument.cpp
dom/xul/nsXULContentSink.cpp
image/imgLoader.cpp
layout/base/GeometryUtils.cpp
layout/base/MobileViewportManager.cpp
layout/base/PresShell.cpp
layout/base/ZoomConstraintsClient.cpp
layout/base/nsDocumentViewer.cpp
layout/base/nsLayoutUtils.cpp
layout/generic/nsGfxScrollFrame.cpp
layout/style/MediaQueryList.cpp
parser/html/nsHtml5TreeOpExecutor.cpp
toolkit/components/browser/nsWebBrowser.cpp
uriloader/prefetch/OfflineCacheUpdateChild.cpp
uriloader/prefetch/OfflineCacheUpdateGlue.cpp
uriloader/prefetch/nsOfflineCacheUpdateService.cpp
xpfe/appshell/nsContentTreeOwner.cpp
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -11061,24 +11061,17 @@ nsDocShell::AddState(JS::Handle<JS::Valu
           0;
       if (NS_FAILED(secMan->CheckSameOriginURI(currentURI, newURI, true,
                                                isPrivateWin)) ||
           !currentUserPass.Equals(newUserPass)) {
         return NS_ERROR_DOM_SECURITY_ERR;
       }
     } else {
       // It's a file:// URI
-      nsCOMPtr<nsIScriptObjectPrincipal> docScriptObj =
-          do_QueryInterface(document);
-
-      if (!docScriptObj) {
-        return NS_ERROR_DOM_SECURITY_ERR;
-      }
-
-      nsCOMPtr<nsIPrincipal> principal = docScriptObj->GetPrincipal();
+      nsCOMPtr<nsIPrincipal> principal = document->GetPrincipal();
 
       if (!principal ||
           NS_FAILED(principal->CheckMayLoad(newURI, true, false))) {
         return NS_ERROR_DOM_SECURITY_ERR;
       }
     }
 
     if (currentURI) {
--- a/dom/animation/AnimationEffect.h
+++ b/dom/animation/AnimationEffect.h
@@ -36,17 +36,17 @@ class AnimationEffect : public nsISuppor
 
   virtual KeyframeEffect* AsKeyframeEffect() { return nullptr; }
 
   virtual ElementPropertyTransition* AsTransition() { return nullptr; }
   virtual const ElementPropertyTransition* AsTransition() const {
     return nullptr;
   }
 
-  nsISupports* GetParentObject() const { return mDocument; }
+  nsISupports* GetParentObject() const { return ToSupports(mDocument); }
 
   bool IsCurrent() const;
   bool IsInEffect() const;
   bool HasFiniteActiveDuration() const {
     return SpecifiedTiming().ActiveDuration() != TimeDuration::Forever();
   }
 
   // AnimationEffect interface
--- a/dom/base/nsContentSink.cpp
+++ b/dom/base/nsContentSink.cpp
@@ -906,21 +906,16 @@ void nsContentSink::Preconnect(const nsA
 
 nsresult nsContentSink::SelectDocAppCache(
     nsIApplicationCache* aLoadApplicationCache, nsIURI* aManifestURI,
     bool aFetchedWithHTTPGetOrEquiv, CacheSelectionAction* aAction) {
   nsresult rv;
 
   *aAction = CACHE_SELECTION_NONE;
 
-  nsCOMPtr<nsIApplicationCacheContainer> applicationCacheDocument =
-      do_QueryInterface(mDocument);
-  NS_ASSERTION(applicationCacheDocument,
-               "mDocument must implement nsIApplicationCacheContainer.");
-
   if (aLoadApplicationCache) {
     nsCOMPtr<nsIURI> groupURI;
     rv = aLoadApplicationCache->GetManifestURI(getter_AddRefs(groupURI));
     NS_ENSURE_SUCCESS(rv, rv);
 
     bool equal = false;
     rv = groupURI->Equals(aManifestURI, &equal);
     NS_ENSURE_SUCCESS(rv, rv);
@@ -939,17 +934,17 @@ nsresult nsContentSink::SelectDocAppCach
       mDocumentURI->GetAsciiSpec(docURISpec);
       aLoadApplicationCache->GetClientID(clientID);
       SINK_TRACE(static_cast<LogModule*>(gContentSinkLogModuleInfo),
                  SINK_TRACE_CALLS,
                  ("Selection: assigning app cache %s to document %s",
                   clientID.get(), docURISpec.get()));
 #endif
 
-      rv = applicationCacheDocument->SetApplicationCache(aLoadApplicationCache);
+      rv = mDocument->SetApplicationCache(aLoadApplicationCache);
       NS_ENSURE_SUCCESS(rv, rv);
 
       // Document will be added as implicit entry to the cache as part of
       // the update process.
       *aAction = CACHE_SELECTION_UPDATE;
     }
   } else {
     // The document was not loaded from an application cache
@@ -976,32 +971,27 @@ nsresult nsContentSink::SelectDocAppCach
   *aManifestURI = nullptr;
   *aAction = CACHE_SELECTION_NONE;
 
   nsresult rv;
 
   if (aLoadApplicationCache) {
     // The document was loaded from an application cache, use that
     // application cache as the document's application cache.
-    nsCOMPtr<nsIApplicationCacheContainer> applicationCacheDocument =
-        do_QueryInterface(mDocument);
-    NS_ASSERTION(applicationCacheDocument,
-                 "mDocument must implement nsIApplicationCacheContainer.");
-
 #ifdef DEBUG
     nsAutoCString docURISpec, clientID;
     mDocumentURI->GetAsciiSpec(docURISpec);
     aLoadApplicationCache->GetClientID(clientID);
     SINK_TRACE(static_cast<LogModule*>(gContentSinkLogModuleInfo),
                SINK_TRACE_CALLS,
                ("Selection, no manifest: assigning app cache %s to document %s",
                 clientID.get(), docURISpec.get()));
 #endif
 
-    rv = applicationCacheDocument->SetApplicationCache(aLoadApplicationCache);
+    rv = mDocument->SetApplicationCache(aLoadApplicationCache);
     NS_ENSURE_SUCCESS(rv, rv);
 
     // Return the uri and invoke the update process for the selected
     // application cache.
     rv = aLoadApplicationCache->GetManifestURI(aManifestURI);
     NS_ENSURE_SUCCESS(rv, rv);
 
     *aAction = CACHE_SELECTION_UPDATE;
@@ -1558,22 +1548,22 @@ void nsContentSink::WillBuildModelImpl()
 
 /* static */
 void nsContentSink::NotifyDocElementCreated(nsIDocument* aDoc) {
   MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
 
   nsCOMPtr<nsIObserverService> observerService =
       mozilla::services::GetObserverService();
   if (observerService) {
-    observerService->NotifyObservers(aDoc, "document-element-inserted",
-                                     EmptyString().get());
+    observerService->NotifyObservers(
+        ToSupports(aDoc), "document-element-inserted", EmptyString().get());
   }
 
   nsContentUtils::DispatchChromeEvent(
-      aDoc, aDoc, NS_LITERAL_STRING("DOMDocElementInserted"), CanBubble::eYes,
-      Cancelable::eNo);
+      aDoc, ToSupports(aDoc), NS_LITERAL_STRING("DOMDocElementInserted"),
+      CanBubble::eYes, Cancelable::eNo);
 }
 
 NS_IMETHODIMP
 nsContentSink::GetName(nsACString& aName) {
   aName.AssignLiteral("nsContentSink_timer");
   return NS_OK;
 }
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -787,17 +787,17 @@ void nsExternalResourceMap::Traverse(
   // mPendingLoads will get cleared out as the requests complete, so
   // no need to worry about those here.
   for (auto iter = mMap.ConstIter(); !iter.Done(); iter.Next()) {
     nsExternalResourceMap::ExternalResource* resource = iter.UserData();
 
     NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*aCallback,
                                        "mExternalResourceMap.mMap entry"
                                        "->mDocument");
-    aCallback->NoteXPCOMChild(resource->mDocument);
+    aCallback->NoteXPCOMChild(ToSupports(resource->mDocument));
 
     NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*aCallback,
                                        "mExternalResourceMap.mMap entry"
                                        "->mViewer");
     aCallback->NoteXPCOMChild(resource->mViewer);
 
     NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*aCallback,
                                        "mExternalResourceMap.mMap entry"
@@ -894,17 +894,18 @@ nsresult nsExternalResourceMap::AddExter
   newResource->mLoadGroup = aLoadGroup;
   if (doc) {
     TransferZoomLevels(aDisplayDocument, doc);
     TransferShowingState(aDisplayDocument, doc);
   }
 
   const nsTArray<nsCOMPtr<nsIObserver>>& obs = load->Observers();
   for (uint32_t i = 0; i < obs.Length(); ++i) {
-    obs[i]->Observe(doc, "external-resource-document-created", nullptr);
+    obs[i]->Observe(ToSupports(doc), "external-resource-document-created",
+                    nullptr);
   }
 
   return rv;
 }
 
 NS_IMPL_ISUPPORTS(nsExternalResourceMap::PendingLoad, nsIStreamListener,
                   nsIRequestObserver)
 
@@ -1619,16 +1620,30 @@ nsDocument::~nsDocument() {
 
   ClearAllBoxObjects();
 
   mPendingTitleChangeEvent.Revoke();
 
   mPlugins.Clear();
 }
 
+// In practice these three are always overriden by the nsDocument version, we
+// just need them to avoid making nsIDocument::AddRef / Release ambiguous.
+//
+// We can get rid of these once we merge nsIDocument and nsDocument.
+NS_IMETHODIMP_(MozExternalRefCountType) nsIDocument::Release() {
+  MOZ_CRASH("Should never be reachable");
+}
+NS_IMETHODIMP_(MozExternalRefCountType) nsIDocument::AddRef() {
+  MOZ_CRASH("Should never be reachable");
+}
+NS_IMETHODIMP nsIDocument::QueryInterface(REFNSIID aIID, void** aInstancePtr) {
+  MOZ_CRASH("Should never be reachable");
+}
+
 NS_INTERFACE_TABLE_HEAD(nsDocument)
   NS_WRAPPERCACHE_INTERFACE_TABLE_ENTRY
   NS_INTERFACE_TABLE_BEGIN
     NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(nsDocument, nsISupports, nsINode)
     NS_INTERFACE_TABLE_ENTRY(nsDocument, nsINode)
     NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIDocument)
     NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIScriptObjectPrincipal)
     NS_INTERFACE_TABLE_ENTRY(nsDocument, mozilla::dom::EventTarget)
@@ -1799,17 +1814,17 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
   if (tmp->mSubDocuments) {
     for (auto iter = tmp->mSubDocuments->Iter(); !iter.Done(); iter.Next()) {
       auto entry = static_cast<SubDocMapEntry*>(iter.Get());
 
       NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSubDocuments entry->mKey");
       cb.NoteXPCOMChild(entry->mKey);
       NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb,
                                          "mSubDocuments entry->mSubDocument");
-      cb.NoteXPCOMChild(entry->mSubDocument);
+      cb.NoteXPCOMChild(ToSupports(entry->mSubDocument));
     }
   }
 
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCSSLoader)
 
   // We own only the items in mDOMMediaQueryLists that have listeners;
   // this reference is managed by their AddListener and RemoveListener
   // methods.
@@ -3003,18 +3018,16 @@ void nsIDocument::RemoveFromIdTable(Elem
       !entry->HasIdElementExposedAsHTMLDocumentProperty()) {
     IncrementExpandoGeneration(*this);
   }
   if (entry->IsEmpty()) {
     mIdentifierMap.RemoveEntry(entry);
   }
 }
 
-nsIPrincipal* nsDocument::GetPrincipal() { return NodePrincipal(); }
-
 extern bool sDisablePrefetchHTTPSPref;
 
 void nsIDocument::SetPrincipal(nsIPrincipal* aNewPrincipal) {
   if (aNewPrincipal && mAllowDNSPrefetch && sDisablePrefetchHTTPSPref) {
     nsCOMPtr<nsIURI> uri;
     aNewPrincipal->GetURI(getter_AddRefs(uri));
     bool isHTTPS;
     if (!uri || NS_FAILED(uri->SchemeIs("https", &isHTTPS)) || isHTTPS) {
@@ -3091,26 +3104,24 @@ void nsIDocument::NoteScriptTrackingStat
   }
 }
 
 bool nsIDocument::IsScriptTracking(const nsACString& aURL) const {
   return mTrackingScripts.Contains(aURL);
 }
 
 NS_IMETHODIMP
-nsDocument::GetApplicationCache(nsIApplicationCache** aApplicationCache) {
+nsIDocument::GetApplicationCache(nsIApplicationCache** aApplicationCache) {
   NS_IF_ADDREF(*aApplicationCache = mApplicationCache);
-
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDocument::SetApplicationCache(nsIApplicationCache* aApplicationCache) {
+nsIDocument::SetApplicationCache(nsIApplicationCache* aApplicationCache) {
   mApplicationCache = aApplicationCache;
-
   return NS_OK;
 }
 
 void nsIDocument::GetContentType(nsAString& aContentType) {
   CopyUTF8toUTF16(GetContentTypeInternal(), aContentType);
 }
 
 void nsIDocument::SetContentType(const nsAString& aContentType) {
@@ -4089,17 +4100,17 @@ void nsIDocument::SetStyleSheetApplicabl
 }
 
 void nsIDocument::NotifyStyleSheetApplicableStateChanged() {
   mSSApplicableStateNotificationPending = false;
   nsCOMPtr<nsIObserverService> observerService =
       mozilla::services::GetObserverService();
   if (observerService) {
     observerService->NotifyObservers(
-        this, "style-sheet-applicable-state-changed", nullptr);
+        ToSupports(this), "style-sheet-applicable-state-changed", nullptr);
   }
 }
 
 static SheetType ConvertAdditionalSheetType(
     nsIDocument::additionalSheetType aType) {
   switch (aType) {
     case nsIDocument::eAgentSheet:
       return SheetType::Agent;
@@ -4701,27 +4712,27 @@ void nsIDocument::DispatchContentLoadedE
   if (mTiming) {
     mTiming->NotifyDOMContentLoadedStart(nsIDocument::GetDocumentURI());
   }
 
   // Dispatch observer notification to notify observers document is interactive.
   nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
   if (os) {
     nsIPrincipal* principal = NodePrincipal();
-    os->NotifyObservers(this,
+    os->NotifyObservers(ToSupports(this),
                         nsContentUtils::IsSystemPrincipal(principal)
                             ? "chrome-document-interactive"
                             : "content-document-interactive",
                         nullptr);
   }
 
   // Fire a DOM event notifying listeners that this document has been
   // loaded (excluding images and other loads initiated by this
   // document).
-  nsContentUtils::DispatchTrustedEvent(this, this,
+  nsContentUtils::DispatchTrustedEvent(this, ToSupports(this),
                                        NS_LITERAL_STRING("DOMContentLoaded"),
                                        CanBubble::eYes, Cancelable::eNo);
 
   if (auto* const window = GetInnerWindow()) {
     const RefPtr<ServiceWorkerContainer> serviceWorker =
         window->Navigator()->ServiceWorker();
 
     // This could cause queued messages from a service worker to get
@@ -4782,35 +4793,33 @@ void nsIDocument::DispatchContentLoadedE
         // target is not in the same document, so the event would never reach
         // the ancestor document if we used the normal event
         // dispatching code.
 
         WidgetEvent* innerEvent = event->WidgetEventPtr();
         if (innerEvent) {
           nsEventStatus status = nsEventStatus_eIgnore;
 
-          RefPtr<nsPresContext> context = parent->GetPresContext();
-
-          if (context) {
-            EventDispatcher::Dispatch(parent, context, innerEvent, event,
-                                      &status);
+          if (RefPtr<nsPresContext> context = parent->GetPresContext()) {
+            EventDispatcher::Dispatch(ToSupports(parent), context, innerEvent,
+                                      event, &status);
           }
         }
       }
 
       parent = parent->GetParentDocument();
     } while (parent);
   }
 
   // If the document has a manifest attribute, fire a MozApplicationManifest
   // event.
   Element* root = GetRootElement();
   if (root && root->HasAttr(kNameSpaceID_None, nsGkAtoms::manifest)) {
     nsContentUtils::DispatchChromeEvent(
-        this, this, NS_LITERAL_STRING("MozApplicationManifest"),
+        this, ToSupports(this), NS_LITERAL_STRING("MozApplicationManifest"),
         CanBubble::eYes, Cancelable::eYes);
   }
 
   nsPIDOMWindowInner* inner = GetInnerWindow();
   if (inner) {
     inner->NoteDOMContentLoaded();
   }
 
@@ -5915,17 +5924,17 @@ void nsIDocument::DoNotifyPossibleTitleC
       nsCOMPtr<nsIBaseWindow> docShellWin = do_QueryInterface(container);
       if (docShellWin) {
         docShellWin->SetTitle(title);
       }
     }
   }
 
   // Fire a DOM event for the title change.
-  nsContentUtils::DispatchChromeEvent(this, static_cast<nsIDocument*>(this),
+  nsContentUtils::DispatchChromeEvent(this, ToSupports(this),
                                       NS_LITERAL_STRING("DOMTitleChanged"),
                                       CanBubble::eYes, Cancelable::eYes);
 }
 
 already_AddRefed<BoxObject> nsIDocument::GetBoxObjectFor(Element* aElement,
                                                          ErrorResult& aRv) {
   if (!aElement) {
     aRv.Throw(NS_ERROR_UNEXPECTED);
@@ -6486,17 +6495,17 @@ nsINode* nsIDocument::AdoptNode(nsINode&
     if (!newScope && GetScopeObject() &&
         GetScopeObject()->GetGlobalJSObject()) {
       // Make sure cx is in a semi-sane compartment before we call WrapNative.
       // It's kind of irrelevant, given that we're passing aAllowWrapping =
       // false, and documents should always insist on being wrapped in an
       // canonical scope. But we try to pass something sane anyway.
       JSAutoRealm ar(cx, GetScopeObject()->GetGlobalJSObject());
       JS::Rooted<JS::Value> v(cx);
-      rv = nsContentUtils::WrapNative(cx, this, this, &v,
+      rv = nsContentUtils::WrapNative(cx, ToSupports(this), this, &v,
                                       /* aAllowWrapping = */ false);
       if (rv.Failed()) return nullptr;
       newScope = &v.toObject();
     }
   }
 
   nsCOMArray<nsINode> nodesWithProperties;
   nsNodeUtils::Adopt(adoptedNode, sameDocument ? nullptr : mNodeInfoManager,
@@ -7818,17 +7827,17 @@ void nsIDocument::OnPageShow(bool aPersi
 
   UpdateVisibilityState();
 
   if (!mIsBeingUsedAsImage) {
     // Dispatch observer notification to notify observers page is shown.
     nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
     if (os) {
       nsIPrincipal* principal = NodePrincipal();
-      os->NotifyObservers(this,
+      os->NotifyObservers(ToSupports(this),
                           nsContentUtils::IsSystemPrincipal(principal)
                               ? "chrome-page-shown"
                               : "content-page-shown",
                           nullptr);
     }
 
     nsCOMPtr<EventTarget> target = aDispatchStartTarget;
     if (!target) {
@@ -7915,17 +7924,17 @@ void nsIDocument::OnPageHide(bool aPersi
 
   ExitPointerLock();
 
   if (!mIsBeingUsedAsImage) {
     // Dispatch observer notification to notify observers page is hidden.
     nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
     if (os) {
       nsIPrincipal* principal = NodePrincipal();
-      os->NotifyObservers(this,
+      os->NotifyObservers(ToSupports(this),
                           nsContentUtils::IsSystemPrincipal(principal)
                               ? "chrome-page-hidden"
                               : "content-page-hidden",
                           nullptr);
     }
 
     // Now send out a PageHide event.
     nsCOMPtr<EventTarget> target = aDispatchStartTarget;
@@ -10881,17 +10890,17 @@ void nsIDocument::UnlockPointer(nsIDocum
       CanBubble::eYes, ChromeOnlyDispatch::eYes);
   asyncDispatcher->RunDOMEventWhenSafe();
 }
 
 void nsIDocument::UpdateVisibilityState() {
   dom::VisibilityState oldState = mVisibilityState;
   mVisibilityState = ComputeVisibilityState();
   if (oldState != mVisibilityState) {
-    nsContentUtils::DispatchTrustedEvent(this, static_cast<nsIDocument*>(this),
+    nsContentUtils::DispatchTrustedEvent(this, ToSupports(this),
                                          NS_LITERAL_STRING("visibilitychange"),
                                          CanBubble::eYes, Cancelable::eNo);
     EnumerateActivityObservers(NotifyActivityChanged, nullptr);
   }
 
   if (mVisibilityState == dom::VisibilityState::Visible) {
     MaybeActiveMediaComponents();
   }
@@ -12526,24 +12535,17 @@ bool nsIDocument::IsThirdParty() {
   }
 
   if (parentDocument->IsThirdParty()) {
     mIsThirdParty.emplace(true);
     return mIsThirdParty.value();
   }
 
   nsCOMPtr<nsIPrincipal> principal = NodePrincipal();
-  nsCOMPtr<nsIScriptObjectPrincipal> sop =
-      do_QueryInterface(parentDocument, &rv);
-  if (NS_WARN_IF(NS_FAILED(rv) || !sop)) {
-    // Failure
-    mIsThirdParty.emplace(true);
-    return mIsThirdParty.value();
-  }
-  nsCOMPtr<nsIPrincipal> parentPrincipal = sop->GetPrincipal();
+  nsCOMPtr<nsIPrincipal> parentPrincipal = parentDocument->GetPrincipal();
 
   bool principalsMatch = false;
   rv = principal->Equals(parentPrincipal, &principalsMatch);
 
   if (NS_WARN_IF(NS_FAILED(rv))) {
     // Failure
     mIsThirdParty.emplace(true);
     return mIsThirdParty.value();
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -12,29 +12,26 @@
 #define nsDocument_h___
 
 #include "nsIDocument.h"
 
 #include "jsfriendapi.h"
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
 #include "nsCRT.h"
-#include "nsIWeakReferenceUtils.h"
 #include "nsTArray.h"
 #include "nsIdentifierMapEntry.h"
 #include "nsStubDocumentObserver.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIContent.h"
 #include "nsIPrincipal.h"
 #include "nsIParser.h"
 #include "nsBindingManager.h"
 #include "nsRefPtrHashtable.h"
 #include "nsJSThingHashtable.h"
-#include "nsIScriptObjectPrincipal.h"
-#include "nsIRadioGroupContainer.h"
 #include "nsILayoutHistoryState.h"
 #include "nsIRequest.h"
 #include "nsILoadGroup.h"
 #include "nsTObserverArray.h"
 #include "nsStubMutationObserver.h"
 #include "nsIChannel.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsContentList.h"
@@ -90,22 +87,17 @@ class nsOnloadBlocker final : public nsI
   NS_DECL_ISUPPORTS
   NS_DECL_NSIREQUEST
 
  private:
   ~nsOnloadBlocker() {}
 };
 
 // Base class for our document implementations.
-class nsDocument : public nsIDocument,
-                   public nsSupportsWeakReference,
-                   public nsIScriptObjectPrincipal,
-                   public nsIRadioGroupContainer,
-                   public nsIApplicationCacheContainer,
-                   public nsStubMutationObserver {
+class nsDocument : public nsIDocument {
   friend class nsIDocument;
 
  public:
   typedef mozilla::dom::Element Element;
   typedef mozilla::net::ReferrerPolicy ReferrerPolicy;
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
@@ -130,93 +122,41 @@ class nsDocument : public nsIDocument,
                                                        JSObject* aObject);
   static bool AreWebAnimationsTimelinesEnabled(JSContext* aCx,
                                                JSObject* aObject);
 
   virtual void EndUpdate() override;
   virtual void BeginLoad() override;
   virtual void EndLoad() override;
 
-  // nsIRadioGroupContainer
-  NS_IMETHOD WalkRadioGroup(const nsAString& aName, nsIRadioVisitor* aVisitor,
-                            bool aFlushContent) override {
-    return DocumentOrShadowRoot::WalkRadioGroup(aName, aVisitor, aFlushContent);
-  }
-  virtual void SetCurrentRadioButton(
-      const nsAString& aName, mozilla::dom::HTMLInputElement* aRadio) override {
-    DocumentOrShadowRoot::SetCurrentRadioButton(aName, aRadio);
-  }
-  virtual mozilla::dom::HTMLInputElement* GetCurrentRadioButton(
-      const nsAString& aName) override {
-    return DocumentOrShadowRoot::GetCurrentRadioButton(aName);
-  }
-  NS_IMETHOD
-  GetNextRadioButton(const nsAString& aName, const bool aPrevious,
-                     mozilla::dom::HTMLInputElement* aFocusedRadio,
-                     mozilla::dom::HTMLInputElement** aRadioOut) override {
-    return DocumentOrShadowRoot::GetNextRadioButton(aName, aPrevious,
-                                                    aFocusedRadio, aRadioOut);
-  }
-  virtual void AddToRadioGroup(
-      const nsAString& aName, mozilla::dom::HTMLInputElement* aRadio) override {
-    DocumentOrShadowRoot::AddToRadioGroup(aName, aRadio);
-  }
-  virtual void RemoveFromRadioGroup(
-      const nsAString& aName, mozilla::dom::HTMLInputElement* aRadio) override {
-    DocumentOrShadowRoot::RemoveFromRadioGroup(aName, aRadio);
-  }
-  virtual uint32_t GetRequiredRadioCount(
-      const nsAString& aName) const override {
-    return DocumentOrShadowRoot::GetRequiredRadioCount(aName);
-  }
-  virtual void RadioRequiredWillChange(const nsAString& aName,
-                                       bool aRequiredAdded) override {
-    DocumentOrShadowRoot::RadioRequiredWillChange(aName, aRequiredAdded);
-  }
-  virtual bool GetValueMissingState(const nsAString& aName) const override {
-    return DocumentOrShadowRoot::GetValueMissingState(aName);
-  }
-  virtual void SetValueMissingState(const nsAString& aName,
-                                    bool aValue) override {
-    return DocumentOrShadowRoot::SetValueMissingState(aName, aValue);
-  }
-
-  // Check whether shadow DOM is enabled for the document this node belongs to.
-  // Same as above, but also checks that the caller is either chrome or some
-  // addon.
+  // Checks that the caller is either chrome or some addon.
   static bool IsCallerChromeOrAddon(JSContext* aCx, JSObject* aObject);
 
  public:
   using mozilla::dom::DocumentOrShadowRoot::GetElementById;
   using mozilla::dom::DocumentOrShadowRoot::GetElementsByClassName;
   using mozilla::dom::DocumentOrShadowRoot::GetElementsByTagName;
   using mozilla::dom::DocumentOrShadowRoot::GetElementsByTagNameNS;
 
   // EventTarget
   void GetEventTargetParent(mozilla::EventChainPreVisitor& aVisitor) override;
   virtual mozilla::EventListenerManager* GetOrCreateListenerManager() override;
   virtual mozilla::EventListenerManager* GetExistingListenerManager()
       const override;
 
-  // nsIScriptObjectPrincipal
-  virtual nsIPrincipal* GetPrincipal() override;
-
-  // nsIApplicationCacheContainer
-  NS_DECL_NSIAPPLICATIONCACHECONTAINER
-
   virtual nsresult Init();
 
   virtual void Destroy() override;
   virtual void RemovedFromDocShell() override;
 
   virtual void BlockOnload() override;
   virtual void UnblockOnload(bool aFireSync) override;
 
   NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsDocument,
-                                                                   nsIDocument)
+                                                                   nsINode)
 
   void SetLoadedAsData(bool aLoadedAsData) { mLoadedAsData = aLoadedAsData; }
   void SetLoadedAsInteractiveData(bool aLoadedAsInteractiveData) {
     mLoadedAsInteractiveData = aLoadedAsInteractiveData;
   }
 
   nsresult CloneDocHelper(nsDocument* clone) const;
 
@@ -263,20 +203,16 @@ class nsDocument : public nsIDocument,
   // cause nsIDocument's layout to be wrong in the Rust side.
   //
   // This can be fixed after updating to rust 1.25 and updating bindgen to
   // include https://github.com/rust-lang-nursery/rust-bindgen/pull/1271.
   js::ExpandoAndGeneration mExpandoAndGeneration;
 
   friend class nsCallRequestFullscreen;
 
-  // The application cache that this document is associated with, if
-  // any.  This can change during the lifetime of the document.
-  nsCOMPtr<nsIApplicationCache> mApplicationCache;
-
   nsCOMPtr<nsIContent> mFirstBaseNodeWithHref;
 
  private:
   friend class nsUnblockOnloadEvent;
 
   // These are not implemented and not supported.
   nsDocument(const nsDocument& aOther);
   nsDocument& operator=(const nsDocument& aOther);
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -1682,17 +1682,18 @@ bool nsFocusManager::Blur(nsPIDOMWindowO
 
     SetFocusedWindowInternal(nullptr);
     mFocusedElement = nullptr;
 
     // pass 1 for the focus method when calling SendFocusOrBlurEvent just so
     // that the check is made for suppressed documents. Check to ensure that
     // the document isn't null in case someone closed it during the blur above
     nsIDocument* doc = window->GetExtantDoc();
-    if (doc) SendFocusOrBlurEvent(eBlur, presShell, doc, doc, 1, false);
+    if (doc)
+      SendFocusOrBlurEvent(eBlur, presShell, doc, ToSupports(doc), 1, false);
     if (mFocusedWindow == nullptr)
       SendFocusOrBlurEvent(eBlur, presShell, doc,
                            window->GetCurrentInnerWindow(), 1, false);
 
     // check if a different window was focused
     result = (mFocusedWindow == nullptr && mActiveWindow);
   } else if (mActiveWindow) {
     // Otherwise, the blur of the element without blurring the document
@@ -1799,17 +1800,17 @@ void nsFocusManager::Focus(nsPIDOMWindow
     // The focus change should be notified to IMEStateManager from here if
     // the focused element is a designMode editor since any content won't
     // receive focus event.
     if (doc && doc->HasFlag(NODE_IS_EDITABLE)) {
       IMEStateManager::OnChangeFocus(presShell->GetPresContext(), nullptr,
                                      GetFocusMoveActionCause(aFlags));
     }
     if (doc) {
-      SendFocusOrBlurEvent(eFocus, presShell, doc, doc,
+      SendFocusOrBlurEvent(eFocus, presShell, doc, ToSupports(doc),
                            aFlags & FOCUSMETHOD_MASK, aWindowRaised);
     }
     if (mFocusedWindow == aWindow && mFocusedElement == nullptr) {
       SendFocusOrBlurEvent(eFocus, presShell, doc,
                            aWindow->GetCurrentInnerWindow(),
                            aFlags & FOCUSMETHOD_MASK, aWindowRaised);
     }
   }
--- a/dom/base/nsGlobalWindowOuter.cpp
+++ b/dom/base/nsGlobalWindowOuter.cpp
@@ -2054,17 +2054,17 @@ void nsGlobalWindowOuter::PreloadLocalSt
 }
 
 void nsGlobalWindowOuter::DispatchDOMWindowCreated() {
   if (!mDoc) {
     return;
   }
 
   // Fire DOMWindowCreated at chrome event listeners
-  nsContentUtils::DispatchChromeEvent(mDoc, mDoc,
+  nsContentUtils::DispatchChromeEvent(mDoc, ToSupports(mDoc),
                                       NS_LITERAL_STRING("DOMWindowCreated"),
                                       CanBubble::eYes, Cancelable::eNo);
 
   nsCOMPtr<nsIObserverService> observerService =
       mozilla::services::GetObserverService();
 
   // The event dispatching could possibly cause docshell destory, and
   // consequently cause mDoc to be set to nullptr by DropOuterWindowDocs(),
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -20,26 +20,29 @@
 #include "nsIInterfaceRequestor.h"
 #include "nsILoadContext.h"
 #include "nsILoadGroup.h"  // for member (in nsCOMPtr)
 #include "nsINode.h"       // for base class
 #include "nsIParser.h"
 #include "nsIPresShell.h"
 #include "nsIChannelEventSink.h"
 #include "nsIProgressEventSink.h"
+#include "nsIRadioGroupContainer.h"
+#include "nsIScriptObjectPrincipal.h"
 #include "nsISecurityEventSink.h"
 #include "nsIScriptGlobalObject.h"  // for member (in nsCOMPtr)
 #include "nsIServiceManager.h"
 #include "nsIURI.h"  // for use in inline functions
 #include "nsIUUIDGenerator.h"
 #include "nsIWebProgressListener.h"  // for nsIWebProgressListener
 #include "nsIWeakReferenceUtils.h"   // for nsWeakPtr
 #include "nsPIDOMWindow.h"           // for use in inline functions
 #include "nsPropertyTable.h"         // for member
 #include "nsStringFwd.h"
+#include "nsStubMutationObserver.h"
 #include "nsTHashtable.h"  // for member
 #include "nsURIHashKey.h"
 #include "mozilla/net/ReferrerPolicy.h"  // for member
 #include "mozilla/UseCounter.h"
 #include "mozilla/WeakPtr.h"
 #include "Units.h"
 #include "nsContentListDeclarations.h"
 #include "nsExpirationTracker.h"
@@ -429,37 +432,94 @@ class nsExternalResourceMap {
 
 // For classifying a flash document based on its principal.
 class PrincipalFlashClassifier;
 
 // Document interface.  This is implemented by all document objects in
 // Gecko.
 class nsIDocument : public nsINode,
                     public mozilla::dom::DocumentOrShadowRoot,
+                    public nsSupportsWeakReference,
+                    public nsIRadioGroupContainer,
+                    public nsIScriptObjectPrincipal,
+                    public nsIApplicationCacheContainer,
+                    public nsStubMutationObserver,
                     public mozilla::dom::DispatcherTrait {
   typedef mozilla::dom::GlobalObject GlobalObject;
 
  protected:
   using Encoding = mozilla::Encoding;
   template <typename T>
   using NotNull = mozilla::NotNull<T>;
 
  public:
   typedef nsExternalResourceMap::ExternalResourceLoad ExternalResourceLoad;
   typedef mozilla::FullscreenRequest FullscreenRequest;
   typedef mozilla::net::ReferrerPolicy ReferrerPolicyEnum;
   typedef mozilla::dom::Element Element;
   typedef mozilla::dom::SVGElement SVGElement;
 
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IDOCUMENT_IID)
+  NS_DECL_ISUPPORTS_INHERITED
 
 #ifdef MOZILLA_INTERNAL_API
   nsIDocument();
 #endif
 
+  // nsIApplicationCacheContainer
+  NS_DECL_NSIAPPLICATIONCACHECONTAINER
+
+  // nsIRadioGroupContainer
+  NS_IMETHOD WalkRadioGroup(const nsAString& aName, nsIRadioVisitor* aVisitor,
+                            bool aFlushContent) final {
+    return DocumentOrShadowRoot::WalkRadioGroup(aName, aVisitor, aFlushContent);
+  }
+
+  void SetCurrentRadioButton(const nsAString& aName,
+                             mozilla::dom::HTMLInputElement* aRadio) final {
+    DocumentOrShadowRoot::SetCurrentRadioButton(aName, aRadio);
+  }
+
+  mozilla::dom::HTMLInputElement* GetCurrentRadioButton(
+      const nsAString& aName) final {
+    return DocumentOrShadowRoot::GetCurrentRadioButton(aName);
+  }
+
+  NS_IMETHOD
+  GetNextRadioButton(const nsAString& aName, const bool aPrevious,
+                     mozilla::dom::HTMLInputElement* aFocusedRadio,
+                     mozilla::dom::HTMLInputElement** aRadioOut) final {
+    return DocumentOrShadowRoot::GetNextRadioButton(aName, aPrevious,
+                                                    aFocusedRadio, aRadioOut);
+  }
+  void AddToRadioGroup(const nsAString& aName,
+                       mozilla::dom::HTMLInputElement* aRadio) final {
+    DocumentOrShadowRoot::AddToRadioGroup(aName, aRadio);
+  }
+  void RemoveFromRadioGroup(const nsAString& aName,
+                            mozilla::dom::HTMLInputElement* aRadio) final {
+    DocumentOrShadowRoot::RemoveFromRadioGroup(aName, aRadio);
+  }
+  uint32_t GetRequiredRadioCount(const nsAString& aName) const final {
+    return DocumentOrShadowRoot::GetRequiredRadioCount(aName);
+  }
+  void RadioRequiredWillChange(const nsAString& aName,
+                               bool aRequiredAdded) final {
+    DocumentOrShadowRoot::RadioRequiredWillChange(aName, aRequiredAdded);
+  }
+  bool GetValueMissingState(const nsAString& aName) const final {
+    return DocumentOrShadowRoot::GetValueMissingState(aName);
+  }
+  void SetValueMissingState(const nsAString& aName, bool aValue) final {
+    return DocumentOrShadowRoot::SetValueMissingState(aName, aValue);
+  }
+
+  // nsIScriptObjectPrincipal
+  nsIPrincipal* GetPrincipal() final { return NodePrincipal(); }
+
   // This helper class must be set when we dispatch beforeunload and unload
   // events in order to avoid unterminate sync XHRs.
   class MOZ_RAII PageUnloadingEventTimeStamp {
     nsCOMPtr<nsIDocument> mDocument;
     bool mSet;
 
    public:
     explicit PageUnloadingEventTimeStamp(nsIDocument* aDocument)
@@ -3318,16 +3378,20 @@ class nsIDocument : public nsINode,
   void InitializeLocalization(nsTArray<nsString>& aResourceIds);
 
   void ParseWidthAndHeightInMetaViewport(const nsAString& aWidthString,
                                          const nsAString& aHeightString,
                                          const nsAString& aScaleString);
 
   nsTArray<nsString> mL10nResources;
 
+  // The application cache that this document is associated with, if
+  // any.  This can change during the lifetime of the document.
+  nsCOMPtr<nsIApplicationCache> mApplicationCache;
+
  public:
   bool IsThirdParty();
 
   bool IsScopedStyleEnabled();
 
   nsINode* GetServoRestyleRoot() const { return mServoRestyleRoot; }
 
   uint32_t GetServoRestyleRootDirtyBits() const {
@@ -4492,9 +4556,13 @@ inline nsIDocument* nsINode::AsDocument(
   return static_cast<nsIDocument*>(this);
 }
 
 inline const nsIDocument* nsINode::AsDocument() const {
   MOZ_ASSERT(IsDocument());
   return static_cast<const nsIDocument*>(this);
 }
 
+inline nsISupports* ToSupports(nsIDocument* aDoc) {
+  return static_cast<nsINode*>(aDoc);
+}
+
 #endif /* nsIDocument_h___ */
--- a/dom/base/nsImageLoadingContent.cpp
+++ b/dom/base/nsImageLoadingContent.cpp
@@ -783,18 +783,18 @@ nsImageLoadingContent::LoadImageWithChan
   // Shouldn't that be done before the start of the load?
   // XXX what about shouldProcess?
 
   // Our state might change. Watch it.
   AutoStateChanger changer(this, true);
 
   // Do the load.
   RefPtr<imgRequestProxy>& req = PrepareNextRequest(eImageLoadType_Normal);
-  nsresult rv = loader->LoadImageWithChannel(aChannel, this, doc, aListener,
-                                             getter_AddRefs(req));
+  nsresult rv = loader->LoadImageWithChannel(aChannel, this, ToSupports(doc),
+                                             aListener, getter_AddRefs(req));
   if (NS_SUCCEEDED(rv)) {
     CloneScriptedRequests(req);
     TrackImage(req);
     ResetAnimationIfNeeded();
     return NS_OK;
   }
 
   MOZ_ASSERT(!req, "Shouldn't have non-null request here");
--- a/dom/base/nsObjectLoadingContent.cpp
+++ b/dom/base/nsObjectLoadingContent.cpp
@@ -257,17 +257,17 @@ class nsSimplePluginEvent : public Runna
         mTarget(aTarget),
         mDocument(aTarget->GetComposedDoc()),
         mEvent(aEvent) {
     MOZ_ASSERT(aTarget && mDocument);
   }
 
   nsSimplePluginEvent(nsIDocument* aTarget, const nsAString& aEvent)
       : mozilla::Runnable("nsSimplePluginEvent"),
-        mTarget(aTarget),
+        mTarget(ToSupports(aTarget)),
         mDocument(aTarget),
         mEvent(aEvent) {
     MOZ_ASSERT(aTarget);
   }
 
   nsSimplePluginEvent(nsIContent* aTarget, nsIDocument* aDocument,
                       const nsAString& aEvent)
       : mozilla::Runnable("nsSimplePluginEvent"),
--- a/dom/bindings/BindingDeclarations.h
+++ b/dom/bindings/BindingDeclarations.h
@@ -420,17 +420,17 @@ inline nsWrapperCache* GetWrapperCache(c
   return GetWrapperCache(aObject.get());
 }
 
 enum class ReflectionScope { Content, XBL, UAWidget };
 
 struct MOZ_STACK_CLASS ParentObject {
   template <class T>
   MOZ_IMPLICIT ParentObject(T* aObject)
-      : mObject(aObject),
+      : mObject(ToSupports(aObject)),
         mWrapperCache(GetWrapperCache(aObject)),
         mReflectionScope(ReflectionScope::Content) {}
 
   template <class T, template <typename> class SmartPtr>
   MOZ_IMPLICIT ParentObject(const SmartPtr<T>& aObject)
       : mObject(aObject.get()),
         mWrapperCache(GetWrapperCache(aObject.get())),
         mReflectionScope(ReflectionScope::Content) {}
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -2097,17 +2097,17 @@ void EventStateManager::DoScrollZoom(nsI
     EnsureDocument(mPresContext);
     if (Preferences::GetBool("browser.zoom.full") ||
         content->OwnerDoc()->IsSyntheticDocument()) {
       ChangeFullZoom(change);
     } else {
       ChangeTextSize(change);
     }
     nsContentUtils::DispatchChromeEvent(
-        mDocument, static_cast<nsIDocument*>(mDocument),
+        mDocument, ToSupports(mDocument),
         NS_LITERAL_STRING("ZoomChangeUsingMouseWheel"), CanBubble::eYes,
         Cancelable::eYes);
   }
 }
 
 static nsIFrame* GetParentFrameToScroll(nsIFrame* aFrame) {
   if (!aFrame) return nullptr;
 
--- a/dom/html/ImageDocument.cpp
+++ b/dom/html/ImageDocument.cpp
@@ -126,17 +126,17 @@ ImageListener::OnStartRequest(nsIRequest
 
   return MediaDocumentStreamListener::OnStartRequest(request, ctxt);
 }
 
 NS_IMETHODIMP
 ImageListener::OnStopRequest(nsIRequest* aRequest, nsISupports* aCtxt,
                              nsresult aStatus) {
   ImageDocument* imgDoc = static_cast<ImageDocument*>(mDocument.get());
-  nsContentUtils::DispatchChromeEvent(imgDoc, static_cast<nsIDocument*>(imgDoc),
+  nsContentUtils::DispatchChromeEvent(imgDoc, ToSupports(imgDoc),
                                       NS_LITERAL_STRING("ImageContentLoaded"),
                                       CanBubble::eYes, Cancelable::eYes);
   return MediaDocumentStreamListener::OnStopRequest(aRequest, aCtxt, aStatus);
 }
 
 ImageDocument::ImageDocument()
     : MediaDocument(),
       mVisibleWidth(0.0),
--- a/dom/html/nsHTMLContentSink.cpp
+++ b/dom/html/nsHTMLContentSink.cpp
@@ -945,17 +945,17 @@ nsresult HTMLContentSink::FlushTags() {
 
   return mCurrentContext ? mCurrentContext->FlushTags() : NS_OK;
 }
 
 void HTMLContentSink::SetDocumentCharset(NotNull<const Encoding*> aEncoding) {
   MOZ_ASSERT_UNREACHABLE("<meta charset> case doesn't occur with about:blank");
 }
 
-nsISupports* HTMLContentSink::GetTarget() { return mDocument; }
+nsISupports* HTMLContentSink::GetTarget() { return ToSupports(mDocument); }
 
 bool HTMLContentSink::IsScriptExecuting() { return IsScriptExecutingImpl(); }
 
 void HTMLContentSink::ContinueInterruptedParsingIfEnabled() {
   if (mParser && mParser->IsParserEnabled()) {
     static_cast<nsIParser*>(mParser.get())->ContinueInterruptedParsing();
   }
 }
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -439,17 +439,17 @@ bool TabChild::AsyncPanZoomEnabled() con
 NS_IMETHODIMP
 TabChild::Observe(nsISupports* aSubject, const char* aTopic,
                   const char16_t* aData) {
   if (!strcmp(aTopic, BEFORE_FIRST_PAINT)) {
     if (AsyncPanZoomEnabled()) {
       nsCOMPtr<nsIDocument> subject(do_QueryInterface(aSubject));
       nsCOMPtr<nsIDocument> doc(GetDocument());
 
-      if (SameCOMIdentity(subject, doc)) {
+      if (subject == doc) {
         nsCOMPtr<nsIPresShell> shell(doc->GetShell());
         if (shell) {
           shell->SetIsFirstPaint(true);
         }
 
         APZCCallbackHelper::InitializeRootDisplayport(shell);
       }
     }
--- a/dom/xhr/XMLHttpRequestMainThread.cpp
+++ b/dom/xhr/XMLHttpRequestMainThread.cpp
@@ -704,17 +704,18 @@ void XMLHttpRequestMainThread::GetRespon
       return;
     }
     case XMLHttpRequestResponseType::Document: {
       if (!mResponseXML || mState != XMLHttpRequest_Binding::DONE) {
         aResponse.setNull();
         return;
       }
 
-      aRv = nsContentUtils::WrapNative(aCx, mResponseXML, aResponse);
+      aRv =
+          nsContentUtils::WrapNative(aCx, ToSupports(mResponseXML), aResponse);
       return;
     }
     case XMLHttpRequestResponseType::Json: {
       if (mState != XMLHttpRequest_Binding::DONE) {
         aResponse.setNull();
         return;
       }
 
--- a/dom/xml/XMLDocument.cpp
+++ b/dom/xml/XMLDocument.cpp
@@ -540,17 +540,17 @@ void XMLDocument::EndLoad() {
   nsDocument::EndLoad();
   if (mSynchronousDOMContentLoaded) {
     mSynchronousDOMContentLoaded = false;
     nsDocument::SetReadyStateInternal(nsIDocument::READYSTATE_COMPLETE);
     // Generate a document load event for the case when an XML
     // document was loaded as pure data without any presentation
     // attached to it.
     WidgetEvent event(true, eLoad);
-    EventDispatcher::Dispatch(static_cast<nsIDocument*>(this), nullptr, &event);
+    EventDispatcher::Dispatch(ToSupports(this), nullptr, &event);
   }
 }
 
 /* virtual */ void XMLDocument::DocAddSizeOfExcludingThis(
     nsWindowSizes& aWindowSizes) const {
   nsDocument::DocAddSizeOfExcludingThis(aWindowSizes);
 }
 
--- a/dom/xml/nsXMLContentSink.cpp
+++ b/dom/xml/nsXMLContentSink.cpp
@@ -732,17 +732,17 @@ nsresult nsXMLContentSink::MaybeProcessX
 }
 
 void nsXMLContentSink::SetDocumentCharset(NotNull<const Encoding*> aEncoding) {
   if (mDocument) {
     mDocument->SetDocumentCharacterSet(aEncoding);
   }
 }
 
-nsISupports* nsXMLContentSink::GetTarget() { return mDocument; }
+nsISupports* nsXMLContentSink::GetTarget() { return ToSupports(mDocument); }
 
 bool nsXMLContentSink::IsScriptExecuting() { return IsScriptExecutingImpl(); }
 
 nsresult nsXMLContentSink::FlushText(bool aReleaseTextNode) {
   nsresult rv = NS_OK;
 
   if (mTextLength != 0) {
     if (mLastTextNode) {
--- a/dom/xml/nsXMLFragmentContentSink.cpp
+++ b/dom/xml/nsXMLFragmentContentSink.cpp
@@ -163,17 +163,19 @@ nsXMLFragmentContentSink::DidBuildModel(
   return NS_OK;
 }
 
 void nsXMLFragmentContentSink::SetDocumentCharset(
     NotNull<const Encoding*> aEncoding) {
   MOZ_ASSERT_UNREACHABLE("fragments shouldn't set charset");
 }
 
-nsISupports* nsXMLFragmentContentSink::GetTarget() { return mTargetDocument; }
+nsISupports* nsXMLFragmentContentSink::GetTarget() {
+  return ToSupports(mTargetDocument);
+}
 
 ////////////////////////////////////////////////////////////////////////
 
 bool nsXMLFragmentContentSink::SetDocElement(int32_t aNameSpaceID,
                                              nsAtom* aTagName,
                                              nsIContent* aContent) {
   // this is a fragment, not a document
   return false;
--- a/dom/xul/XULDocument.cpp
+++ b/dom/xul/XULDocument.cpp
@@ -984,19 +984,18 @@ nsresult XULDocument::DoneWalking() {
 
     // For performance reasons, we want to trigger the DocumentL10n's
     // `TriggerInitialDocumentTranslation` within the same microtask that will
     // be created for a `MozBeforeInitialXULLayout` event listener.
     AddEventListener(NS_LITERAL_STRING("MozBeforeInitialXULLayout"),
                      mDocumentL10n, true, false);
 
     nsContentUtils::DispatchTrustedEvent(
-        this, static_cast<nsIDocument*>(this),
-        NS_LITERAL_STRING("MozBeforeInitialXULLayout"), CanBubble::eYes,
-        Cancelable::eNo);
+        this, ToSupports(this), NS_LITERAL_STRING("MozBeforeInitialXULLayout"),
+        CanBubble::eYes, Cancelable::eNo);
 
     RemoveEventListener(NS_LITERAL_STRING("MozBeforeInitialXULLayout"),
                         mDocumentL10n, true);
 
     // Before starting layout, check whether we're a toplevel chrome
     // window.  If we are, setup some state so that we don't have to restyle
     // the whole tree after StartLayout.
     if (nsCOMPtr<nsIXULWindow> win = GetXULWindowIfToplevelChrome()) {
--- a/dom/xul/nsXULContentSink.cpp
+++ b/dom/xul/nsXULContentSink.cpp
@@ -227,17 +227,17 @@ void XULContentSinkImpl::SetDocumentChar
   nsCOMPtr<nsIDocument> doc = do_QueryReferent(mDocument);
   if (doc) {
     doc->SetDocumentCharacterSet(aEncoding);
   }
 }
 
 nsISupports* XULContentSinkImpl::GetTarget() {
   nsCOMPtr<nsIDocument> doc = do_QueryReferent(mDocument);
-  return doc;
+  return ToSupports(doc);
 }
 
 //----------------------------------------------------------------------
 
 nsresult XULContentSinkImpl::Init(nsIDocument* aDocument,
                                   nsXULPrototypeDocument* aPrototype) {
   MOZ_ASSERT(aDocument != nullptr, "null ptr");
   if (!aDocument) return NS_ERROR_NULL_POINTER;
--- a/image/imgLoader.cpp
+++ b/image/imgLoader.cpp
@@ -2150,21 +2150,21 @@ nsresult imgLoader::LoadImage(
     attrs = aTriggeringPrincipal->OriginAttributesRef();
   }
   ImageCacheKey key(aURI, attrs, aLoadingDocument, rv);
   NS_ENSURE_SUCCESS(rv, rv);
   imgCacheTable& cache = GetCache(key);
 
   if (cache.Get(key, getter_AddRefs(entry)) && entry) {
     bool newChannelCreated = false;
-    if (ValidateEntry(entry, aURI, aInitialDocumentURI, aReferrerURI,
-                      aReferrerPolicy, aLoadGroup, aObserver, aLoadingDocument,
-                      aLoadingDocument, requestFlags, aContentPolicyType, true,
-                      &newChannelCreated, _retval, aTriggeringPrincipal,
-                      corsmode)) {
+    if (ValidateEntry(
+            entry, aURI, aInitialDocumentURI, aReferrerURI, aReferrerPolicy,
+            aLoadGroup, aObserver, ToSupports(aLoadingDocument),
+            aLoadingDocument, requestFlags, aContentPolicyType, true,
+            &newChannelCreated, _retval, aTriggeringPrincipal, corsmode)) {
       request = entry->GetRequest();
 
       // If this entry has no proxies, its request has no reference to the
       // entry.
       if (entry->HasNoProxies()) {
         LOG_FUNC_WITH_PARAM(gImgLog,
                             "imgLoader::LoadImage() adding proxyless entry",
                             "uri", key.URI());
@@ -2180,19 +2180,20 @@ nsresult imgLoader::LoadImage(
       entry->Touch();
 
       if (!newChannelCreated) {
         // This is ugly but it's needed to report CSP violations. We have 3
         // scenarios:
         // - we don't have cache. We are not in this if() stmt. A new channel is
         //   created and that triggers the CSP checks.
         // - We have a cache entry and this is blocked by CSP directives.
-        DebugOnly<bool> shouldLoad = ShouldLoadCachedImage(
-            request, aLoadingDocument, aTriggeringPrincipal, aContentPolicyType,
-            /* aSendCSPViolationReports */ true);
+        DebugOnly<bool> shouldLoad =
+            ShouldLoadCachedImage(request, ToSupports(aLoadingDocument),
+                                  aTriggeringPrincipal, aContentPolicyType,
+                                  /* aSendCSPViolationReports */ true);
         MOZ_ASSERT(shouldLoad);
       }
     } else {
       // We can't use this entry. We'll try to load it off the network, and if
       // successful, overwrite the old entry in the cache with a new one.
       entry = nullptr;
     }
   }
@@ -2239,18 +2240,19 @@ nsresult imgLoader::LoadImage(
           Unused << httpChannel->SetRequestContextID(aRequestContextID);
         }
       }
     }
 
     nsCOMPtr<nsILoadGroup> channelLoadGroup;
     newChannel->GetLoadGroup(getter_AddRefs(channelLoadGroup));
     rv = request->Init(aURI, aURI, /* aHadInsecureRedirect = */ false,
-                       channelLoadGroup, newChannel, entry, aLoadingDocument,
-                       aTriggeringPrincipal, corsmode, aReferrerPolicy);
+                       channelLoadGroup, newChannel, entry,
+                       ToSupports(aLoadingDocument), aTriggeringPrincipal,
+                       corsmode, aReferrerPolicy);
     if (NS_FAILED(rv)) {
       return NS_ERROR_FAILURE;
     }
 
     // Add the initiator type for this image load
     nsCOMPtr<nsITimedChannel> timedChannel = do_QueryInterface(newChannel);
     if (timedChannel) {
       timedChannel->SetInitiatorType(initiatorType);
--- a/layout/base/GeometryUtils.cpp
+++ b/layout/base/GeometryUtils.cpp
@@ -152,22 +152,22 @@ static nsRect GetBoxRectForFrame(nsIFram
       return r;
   }
 
   return r;
 }
 
 class AccumulateQuadCallback : public nsLayoutUtils::BoxCallback {
  public:
-  AccumulateQuadCallback(nsISupports* aParentObject,
+  AccumulateQuadCallback(nsIDocument* aParentObject,
                          nsTArray<RefPtr<DOMQuad> >& aResult,
                          nsIFrame* aRelativeToFrame,
                          const nsPoint& aRelativeToBoxTopLeft,
                          CSSBoxType aBoxType)
-      : mParentObject(aParentObject),
+      : mParentObject(ToSupports(aParentObject)),
         mResult(aResult),
         mRelativeToFrame(aRelativeToFrame),
         mRelativeToBoxTopLeft(aRelativeToBoxTopLeft),
         mBoxType(aBoxType) {
     if (mBoxType == CSSBoxType::Margin) {
       // Don't include the caption margin when computing margins for a
       // table
       mIncludeCaptionBoxForTable = false;
--- a/layout/base/MobileViewportManager.cpp
+++ b/layout/base/MobileViewportManager.cpp
@@ -154,17 +154,17 @@ MobileViewportManager::HandleEvent(dom::
     }
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 MobileViewportManager::Observe(nsISupports* aSubject, const char* aTopic,
                                const char16_t* aData) {
-  if (SameCOMIdentity(aSubject, mDocument) &&
+  if (SameCOMIdentity(aSubject, ToSupports(mDocument)) &&
       BEFORE_FIRST_PAINT.EqualsASCII(aTopic)) {
     MVM_LOG("%p: got a before-first-paint event\n", this);
     if (!mPainted) {
       // before-first-paint message arrived before load event
       SetInitialViewport();
     }
   }
   return NS_OK;
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -515,18 +515,18 @@ class nsBeforeFirstPaintDispatcher : pub
         mDocument(aDocument) {}
 
   // Fires the "before-first-paint" event so that interested parties (right now,
   // the mobile browser) are aware of it.
   NS_IMETHOD Run() override {
     nsCOMPtr<nsIObserverService> observerService =
         mozilla::services::GetObserverService();
     if (observerService) {
-      observerService->NotifyObservers(mDocument, "before-first-paint",
-                                       nullptr);
+      observerService->NotifyObservers(ToSupports(mDocument),
+                                       "before-first-paint", nullptr);
     }
     return NS_OK;
   }
 
  private:
   nsCOMPtr<nsIDocument> mDocument;
 };
 
@@ -1439,17 +1439,17 @@ void nsIPresShell::SetAuthorStyleDisable
   if (aStyleDisabled != mStyleSet->GetAuthorStyleDisabled()) {
     mStyleSet->SetAuthorStyleDisabled(aStyleDisabled);
     ApplicableStylesChanged();
 
     nsCOMPtr<nsIObserverService> observerService =
         mozilla::services::GetObserverService();
     if (observerService) {
       observerService->NotifyObservers(
-          mDocument, "author-style-disabled-changed", nullptr);
+          ToSupports(mDocument), "author-style-disabled-changed", nullptr);
     }
   }
 }
 
 bool nsIPresShell::GetAuthorStyleDisabled() const {
   return mStyleSet->GetAuthorStyleDisabled();
 }
 
--- a/layout/base/ZoomConstraintsClient.cpp
+++ b/layout/base/ZoomConstraintsClient.cpp
@@ -139,17 +139,17 @@ ZoomConstraintsClient::HandleEvent(dom::
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 ZoomConstraintsClient::Observe(nsISupports* aSubject, const char* aTopic,
                                const char16_t* aData) {
-  if (SameCOMIdentity(aSubject, mDocument) &&
+  if (SameCOMIdentity(aSubject, ToSupports(mDocument)) &&
       BEFORE_FIRST_PAINT.EqualsASCII(aTopic)) {
     ZCC_LOG("Got a before-first-paint event in %p\n", this);
     RefreshZoomConstraints();
   } else if (NS_PREF_CHANGED.EqualsASCII(aTopic)) {
     ZCC_LOG("Got a pref-change event in %p\n", this);
     // We need to run this later because all the pref change listeners need
     // to execute before we can be guaranteed that gfxPrefs::ForceUserScalable()
     // returns the updated value.
--- a/layout/base/nsDocumentViewer.cpp
+++ b/layout/base/nsDocumentViewer.cpp
@@ -1081,17 +1081,17 @@ nsDocumentViewer::LoadComplete(nsresult 
         timing->NotifyLoadEventStart();
       }
 
       // Dispatch observer notification to notify observers document load is
       // complete.
       nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
       if (os) {
         nsIPrincipal* principal = d->NodePrincipal();
-        os->NotifyObservers(d,
+        os->NotifyObservers(ToSupports(d),
                             nsContentUtils::IsSystemPrincipal(principal)
                                 ? "chrome-document-loaded"
                                 : "content-document-loaded",
                             nullptr);
       }
 
       // Notify any devtools about the load.
       RefPtr<TimelineConsumers> timelines = TimelineConsumers::Get();
@@ -2847,19 +2847,19 @@ nsDocumentViewer::SetTextZoom(float aTex
     pc->SetTextZoom(aTextZoom);
   }
 
   // And do the external resources
   mDocument->EnumerateExternalResources(SetExtResourceTextZoom, &ZoomInfo);
 
   // Dispatch TextZoomChange event only if text zoom value has changed.
   if (textZoomChange) {
-    nsContentUtils::DispatchChromeEvent(
-        mDocument, static_cast<nsIDocument*>(mDocument),
-        NS_LITERAL_STRING("TextZoomChange"), CanBubble::eYes, Cancelable::eYes);
+    nsContentUtils::DispatchChromeEvent(mDocument, ToSupports(mDocument),
+                                        NS_LITERAL_STRING("TextZoomChange"),
+                                        CanBubble::eYes, Cancelable::eYes);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocumentViewer::GetTextZoom(float* aTextZoom) {
   NS_ENSURE_ARG_POINTER(aTextZoom);
@@ -2964,19 +2964,19 @@ nsDocumentViewer::SetFullZoom(float aFul
   }
 
   // And do the external resources
   mDocument->EnumerateExternalResources(SetExtResourceFullZoom, &ZoomInfo);
 
   // Dispatch FullZoomChange event only if fullzoom value really was been
   // changed
   if (fullZoomChange) {
-    nsContentUtils::DispatchChromeEvent(
-        mDocument, static_cast<nsIDocument*>(mDocument),
-        NS_LITERAL_STRING("FullZoomChange"), CanBubble::eYes, Cancelable::eYes);
+    nsContentUtils::DispatchChromeEvent(mDocument, ToSupports(mDocument),
+                                        NS_LITERAL_STRING("FullZoomChange"),
+                                        CanBubble::eYes, Cancelable::eYes);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocumentViewer::GetFullZoom(float* aFullZoom) {
   NS_ENSURE_ARG_POINTER(aFullZoom);
@@ -4377,12 +4377,13 @@ void nsDocumentViewer::SetPrintPreviewPr
 }
 
 // Fires the "document-shown" event so that interested parties are aware of it.
 NS_IMETHODIMP
 nsDocumentShownDispatcher::Run() {
   nsCOMPtr<nsIObserverService> observerService =
       mozilla::services::GetObserverService();
   if (observerService) {
-    observerService->NotifyObservers(mDocument, "document-shown", nullptr);
+    observerService->NotifyObservers(ToSupports(mDocument), "document-shown",
+                                     nullptr);
   }
   return NS_OK;
 }
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -8567,18 +8567,18 @@ void MaybeSetupTransactionIdAllocator(la
   aMetrics.BSize(aLineWM) += aFramePadding.BStartEnd(aFrameWM);
 }
 
 /* static */ bool nsLayoutUtils::HasDocumentLevelListenersForApzAwareEvents(
     nsIPresShell* aShell) {
   if (nsIDocument* doc = aShell->GetDocument()) {
     WidgetEvent event(true, eVoidEvent);
     nsTArray<EventTarget*> targets;
-    nsresult rv = EventDispatcher::Dispatch(doc, nullptr, &event, nullptr,
-                                            nullptr, nullptr, &targets);
+    nsresult rv = EventDispatcher::Dispatch(
+        ToSupports(doc), nullptr, &event, nullptr, nullptr, nullptr, &targets);
     NS_ENSURE_SUCCESS(rv, false);
     for (size_t i = 0; i < targets.Length(); i++) {
       if (targets[i]->IsApzAware()) {
         return true;
       }
     }
   }
   return false;
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -4909,19 +4909,19 @@ void ScrollFrameHelper::FireScrollEvent(
   ActiveLayerTracker::SetCurrentScrollHandlerFrame(mOuter);
   WidgetGUIEvent event(true, eScroll, nullptr);
   nsEventStatus status = nsEventStatus_eIgnore;
   // Fire viewport scroll events at the document (where they
   // will bubble to the window)
   mozilla::layers::ScrollLinkedEffectDetector detector(
       content->GetComposedDoc());
   if (mIsRoot) {
-    nsIDocument* doc = content->GetUncomposedDoc();
-    if (doc) {
-      EventDispatcher::Dispatch(doc, prescontext, &event, nullptr, &status);
+    if (nsIDocument* doc = content->GetUncomposedDoc()) {
+      EventDispatcher::Dispatch(ToSupports(doc), prescontext, &event, nullptr,
+                                &status);
     }
   } else {
     // scroll events fired at elements don't bubble (although scroll events
     // fired at documents do, to the window)
     event.mFlags.mBubbles = false;
     EventDispatcher::Dispatch(content, prescontext, &event, nullptr, &status);
   }
   ActiveLayerTracker::SetCurrentScrollHandlerFrame(nullptr);
@@ -6190,20 +6190,18 @@ ScrollFrameHelper::ScrolledAreaEvent::Ru
 void ScrollFrameHelper::FireScrolledAreaEvent() {
   mScrolledAreaEvent.Forget();
 
   InternalScrollAreaEvent event(true, eScrolledAreaChanged, nullptr);
   nsPresContext* prescontext = mOuter->PresContext();
   nsIContent* content = mOuter->GetContent();
 
   event.mArea = mScrolledFrame->GetScrollableOverflowRectRelativeToParent();
-
-  nsIDocument* doc = content->GetUncomposedDoc();
-  if (doc) {
-    EventDispatcher::Dispatch(doc, prescontext, &event, nullptr);
+  if (nsIDocument* doc = content->GetUncomposedDoc()) {
+    EventDispatcher::Dispatch(ToSupports(doc), prescontext, &event, nullptr);
   }
 }
 
 uint32_t nsIScrollableFrame::GetPerceivedScrollingDirections() const {
   nscoord oneDevPixel =
       GetScrolledFrame()->PresContext()->AppUnitsPerDevPixel();
   uint32_t directions = GetScrollbarVisibility();
   nsRect scrollRange = GetScrollRange();
--- a/layout/style/MediaQueryList.cpp
+++ b/layout/style/MediaQueryList.cpp
@@ -138,17 +138,19 @@ void MediaQueryList::RecomputeMatches() 
     // XXXbz What's the right behavior here?  Spec doesn't say.
     return;
   }
 
   mMatches = mMediaList->Matches(presContext);
   mMatchesValid = true;
 }
 
-nsISupports* MediaQueryList::GetParentObject() const { return mDocument; }
+nsISupports* MediaQueryList::GetParentObject() const {
+  return ToSupports(mDocument);
+}
 
 JSObject* MediaQueryList::WrapObject(JSContext* aCx,
                                      JS::Handle<JSObject*> aGivenProto) {
   return MediaQueryList_Binding::Wrap(aCx, this, aGivenProto);
 }
 
 void MediaQueryList::MaybeNotify() {
   mMatchesValid = false;
--- a/parser/html/nsHtml5TreeOpExecutor.cpp
+++ b/parser/html/nsHtml5TreeOpExecutor.cpp
@@ -229,17 +229,19 @@ nsHtml5TreeOpExecutor::SetParser(nsParse
 
 void nsHtml5TreeOpExecutor::FlushPendingNotifications(FlushType aType) {
   if (aType >= FlushType::EnsurePresShellInitAndFrames) {
     // Bug 577508 / 253951
     nsContentSink::StartLayout(true);
   }
 }
 
-nsISupports* nsHtml5TreeOpExecutor::GetTarget() { return mDocument; }
+nsISupports* nsHtml5TreeOpExecutor::GetTarget() {
+  return ToSupports(mDocument);
+}
 
 nsresult nsHtml5TreeOpExecutor::MarkAsBroken(nsresult aReason) {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   mBroken = aReason;
   if (mStreamParser) {
     mStreamParser->Terminate();
   }
   // We are under memory pressure, but let's hope the following allocation
--- a/toolkit/components/browser/nsWebBrowser.cpp
+++ b/toolkit/components/browser/nsWebBrowser.cpp
@@ -882,17 +882,17 @@ nsWebBrowser::SaveDocument(nsISupports* 
   // attached to the web browser.
 
   nsCOMPtr<nsISupports> doc;
   if (aDocumentish) {
     doc = aDocumentish;
   } else {
     nsCOMPtr<nsIDocument> domDoc;
     GetDocument(getter_AddRefs(domDoc));
-    doc = domDoc.forget();
+    doc = already_AddRefed<nsISupports>(ToSupports(domDoc.forget().take()));
   }
   if (!doc) {
     return NS_ERROR_FAILURE;
   }
 
   // Create a throwaway persistence object to do the work
   nsresult rv;
   mPersist = do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID, &rv);
--- a/uriloader/prefetch/OfflineCacheUpdateChild.cpp
+++ b/uriloader/prefetch/OfflineCacheUpdateChild.cpp
@@ -129,35 +129,31 @@ void OfflineCacheUpdateChild::SetDocumen
   mDocument = aDocument;
 }
 
 nsresult OfflineCacheUpdateChild::AssociateDocument(
     nsIDocument *aDocument, nsIApplicationCache *aApplicationCache) {
   // Check that the document that requested this update was
   // previously associated with an application cache.  If not, it
   // should be associated with the new one.
-  nsCOMPtr<nsIApplicationCacheContainer> container =
-      do_QueryInterface(aDocument);
-  if (!container) return NS_OK;
-
   nsCOMPtr<nsIApplicationCache> existingCache;
-  nsresult rv = container->GetApplicationCache(getter_AddRefs(existingCache));
+  nsresult rv = aDocument->GetApplicationCache(getter_AddRefs(existingCache));
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!existingCache) {
     if (LOG_ENABLED()) {
       nsAutoCString clientID;
       if (aApplicationCache) {
         aApplicationCache->GetClientID(clientID);
       }
       LOG(("Update %p: associating app cache %s to document %p", this,
            clientID.get(), aDocument));
     }
 
-    rv = container->SetApplicationCache(aApplicationCache);
+    rv = aDocument->SetApplicationCache(aApplicationCache);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
 // OfflineCacheUpdateChild::nsIOfflineCacheUpdate
--- a/uriloader/prefetch/OfflineCacheUpdateGlue.cpp
+++ b/uriloader/prefetch/OfflineCacheUpdateGlue.cpp
@@ -178,35 +178,35 @@ OfflineCacheUpdateGlue::UpdateStateChang
 NS_IMETHODIMP
 OfflineCacheUpdateGlue::ApplicationCacheAvailable(
     nsIApplicationCache *aApplicationCache) {
   NS_ENSURE_ARG(aApplicationCache);
 
   // Check that the document that requested this update was
   // previously associated with an application cache.  If not, it
   // should be associated with the new one.
-  nsCOMPtr<nsIApplicationCacheContainer> container =
-      do_QueryInterface(mDocument);
-  if (!container) return NS_OK;
+  if (!mDocument) {
+    return NS_OK;
+  }
 
   nsCOMPtr<nsIApplicationCache> existingCache;
-  nsresult rv = container->GetApplicationCache(getter_AddRefs(existingCache));
+  nsresult rv = mDocument->GetApplicationCache(getter_AddRefs(existingCache));
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!existingCache) {
     if (LOG_ENABLED()) {
       nsAutoCString clientID;
       if (aApplicationCache) {
         aApplicationCache->GetClientID(clientID);
       }
       LOG(("Update %p: associating app cache %s to document %p", this,
            clientID.get(), mDocument.get()));
     }
 
-    rv = container->SetApplicationCache(aApplicationCache);
+    rv = mDocument->SetApplicationCache(aApplicationCache);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   return NS_OK;
 }
 
 }  // namespace docshell
 }  // namespace mozilla
--- a/uriloader/prefetch/nsOfflineCacheUpdateService.cpp
+++ b/uriloader/prefetch/nsOfflineCacheUpdateService.cpp
@@ -161,19 +161,17 @@ nsOfflineCachePendingUpdate::OnStateChan
   nsCOMPtr<mozIDOMWindowProxy> windowProxy;
   aWebProgress->GetDOMWindow(getter_AddRefs(windowProxy));
   if (!windowProxy) return NS_OK;
 
   auto *outerWindow = nsPIDOMWindowOuter::From(windowProxy);
   nsPIDOMWindowInner *innerWindow = outerWindow->GetCurrentInnerWindow();
 
   nsCOMPtr<nsIDocument> progressDoc = outerWindow->GetDoc();
-  if (!progressDoc) return NS_OK;
-
-  if (!SameCOMIdentity(progressDoc, updateDoc)) {
+  if (!progressDoc || progressDoc != updateDoc) {
     return NS_OK;
   }
 
   LOG(("nsOfflineCachePendingUpdate::OnStateChange [%p, doc=%p]", this,
        progressDoc.get()));
 
   // Only schedule the update if the document loaded successfully
   if (NS_SUCCEEDED(aStatus)) {
--- a/xpfe/appshell/nsContentTreeOwner.cpp
+++ b/xpfe/appshell/nsContentTreeOwner.cpp
@@ -644,18 +644,17 @@ NS_IMETHODIMP nsContentTreeOwner::SetTit
       //
       // location bar is turned off, find the browser location
       //
       // use the document's ContentPrincipal to find the true owner
       // in case of javascript: or data: documents
       //
       nsCOMPtr<nsIDocShellTreeItem> dsitem;
       GetPrimaryContentShell(getter_AddRefs(dsitem));
-      nsCOMPtr<nsIScriptObjectPrincipal> doc =
-          do_QueryInterface(dsitem ? dsitem->GetDocument() : nullptr);
+      nsCOMPtr<nsIDocument> doc = dsitem ? dsitem->GetDocument() : nullptr;
       if (doc) {
         nsCOMPtr<nsIURI> uri;
         nsIPrincipal* principal = doc->GetPrincipal();
         if (principal) {
           principal->GetURI(getter_AddRefs(uri));
           if (uri) {
             //
             // remove any user:pass information