bug 966059 - add nsIDocShell::GetWindow and GetDocument r=smaug
authorTrevor Saunders <trev.saunders@gmail.com>
Thu, 09 Jan 2014 21:03:47 -0500
changeset 185034 77cb01391beffb1e271681d6a6c684096a2009df
parent 185033 0acfd585d47ccea35ad3ff3815b112b3bd89a2dc
child 185035 ca0fc67da7cba0542dd62bfbaa8db688fcc8bfca
push id44009
push usertrev.saunders@gmail.com
push dateTue, 27 May 2014 15:18:44 +0000
treeherdermozilla-inbound@ca0fc67da7cb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs966059
milestone32.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
bug 966059 - add nsIDocShell::GetWindow and GetDocument r=smaug
accessible/src/base/Logging.cpp
content/base/src/nsContentAreaDragDrop.cpp
content/base/src/nsContentUtils.cpp
content/base/src/nsCopySupport.cpp
content/base/src/nsDocument.cpp
content/base/src/nsFrameLoader.cpp
content/base/src/nsInProcessTabChildGlobal.cpp
content/canvas/src/CanvasRenderingContext2D.cpp
content/xul/document/src/XULDocument.cpp
docshell/base/nsDSURIContentListener.cpp
docshell/base/nsDocShell.cpp
docshell/base/nsDocShellEditorData.cpp
docshell/base/nsIDocShell.idl
docshell/base/nsIDocShellTreeItem.idl
dom/base/nsDOMWindowList.cpp
dom/base/nsFocusManager.cpp
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
dom/base/nsHistory.cpp
dom/base/nsLocation.cpp
dom/base/nsPluginArray.cpp
dom/browser-element/BrowserElementParent.cpp
dom/events/UIEvent.cpp
dom/media/MediaManager.cpp
dom/smil/TimeEvent.cpp
embedding/browser/webBrowser/nsWebBrowser.cpp
embedding/components/find/src/nsWebBrowserFind.cpp
embedding/components/windowwatcher/src/nsWindowWatcher.cpp
embedding/components/windowwatcher/src/nsWindowWatcher.h
layout/base/nsDocumentViewer.cpp
layout/base/nsLayoutUtils.cpp
layout/base/nsPresContext.cpp
layout/base/nsPresShell.cpp
layout/printing/nsPrintEngine.cpp
layout/svg/nsSVGOuterSVGFrame.cpp
layout/xul/nsXULPopupManager.cpp
toolkit/components/satchel/nsFormFillController.cpp
toolkit/xre/nsNativeAppSupportWin.cpp
xpfe/appshell/src/nsAppShellService.cpp
xpfe/appshell/src/nsContentTreeOwner.cpp
xpfe/appshell/src/nsWebShellWindow.cpp
xpfe/appshell/src/nsWindowMediator.cpp
xpfe/appshell/src/nsXULWindow.cpp
--- a/accessible/src/base/Logging.cpp
+++ b/accessible/src/base/Logging.cpp
@@ -403,18 +403,17 @@ logging::DocLoad(const char* aMsg, nsIWe
     MsgEnd();
     return;
   }
 
   DocAccessible* document = GetExistingDocAccessible(documentNode);
 
   LogDocInfo(documentNode, document);
 
-  nsCOMPtr<nsIWebNavigation> webNav(do_GetInterface(DOMWindow));
-  nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(webNav));
+  nsCOMPtr<nsIDocShell> docShell = window->GetDocShell();
   printf("\n    ");
   LogShellLoadType(docShell);
   printf("\n");
   LogRequest(aRequest);
   printf("\n");
   printf("    state flags: %x", aStateFlags);
   bool isDocLoading;
   aWebProgress->GetIsLoadingDocument(&isDocLoading);
--- a/content/base/src/nsContentAreaDragDrop.cpp
+++ b/content/base/src/nsContentAreaDragDrop.cpp
@@ -401,18 +401,17 @@ DragDataProducer::Produce(DataTransfer* 
       }
       findFormParent = findFormParent->GetParent();
     }
   }
     
   // if set, serialize the content under this node
   nsCOMPtr<nsIContent> nodeToSerialize;
 
-  nsCOMPtr<nsIWebNavigation> webnav = do_GetInterface(mWindow);
-  nsCOMPtr<nsIDocShellTreeItem> dsti = do_QueryInterface(webnav);
+  nsCOMPtr<nsIDocShellTreeItem> dsti = mWindow->GetDocShell();
   const bool isChromeShell =
     dsti && dsti->ItemType() == nsIDocShellTreeItem::typeChrome;
 
   // In chrome shells, only allow dragging inside editable areas.
   if (isChromeShell && !editingElement)
     return NS_OK;
 
   if (isChromeShell && textControl) {
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -5051,18 +5051,22 @@ nsContentUtils::CheckForSubFrameDrop(nsI
                                      WidgetDragEvent* aDropEvent)
 {
   nsCOMPtr<nsIContent> target = do_QueryInterface(aDropEvent->originalTarget);
   if (!target) {
     return true;
   }
   
   nsIDocument* targetDoc = target->OwnerDoc();
-  nsCOMPtr<nsIWebNavigation> twebnav = do_GetInterface(targetDoc->GetWindow());
-  nsCOMPtr<nsIDocShellTreeItem> tdsti = do_QueryInterface(twebnav);
+  nsPIDOMWindow* targetWin = targetDoc->GetWindow();
+  if (!targetWin) {
+    return true;
+  }
+
+  nsCOMPtr<nsIDocShellTreeItem> tdsti = targetWin->GetDocShell();
   if (!tdsti) {
     return true;
   }
 
   // Always allow dropping onto chrome shells.
   if (tdsti->ItemType() == nsIDocShellTreeItem::typeChrome) {
     return false;
   }
@@ -5894,17 +5898,17 @@ nsContentUtils::FlushLayoutForTree(nsIDO
 
     nsCOMPtr<nsIDocShell> docShell = piWin->GetDocShell();
     if (docShell) {
         int32_t i = 0, i_end;
         docShell->GetChildCount(&i_end);
         for (; i < i_end; ++i) {
             nsCOMPtr<nsIDocShellTreeItem> item;
             docShell->GetChildAt(i, getter_AddRefs(item));
-            nsCOMPtr<nsIDOMWindow> win = do_GetInterface(item);
+            nsCOMPtr<nsIDOMWindow> win = item->GetWindow();
             if (win) {
                 FlushLayoutForTree(win);
             }
         }
     }
 }
 
 void nsContentUtils::RemoveNewlines(nsString &aString)
--- a/content/base/src/nsCopySupport.cpp
+++ b/content/base/src/nsCopySupport.cpp
@@ -632,17 +632,17 @@ nsCopySupport::FireClipboardEvent(int32_
     if (!content)
       return false;
   }
 
   // It seems to be unsafe to fire an event handler during reflow (bug 393696)
   if (!nsContentUtils::IsSafeToRunScript())
     return false;
 
-  nsCOMPtr<nsIDocShell> docShell = do_GetInterface(piWindow);
+  nsCOMPtr<nsIDocShell> docShell = piWindow->GetDocShell();
   const bool chromeShell =
     docShell && docShell->ItemType() == nsIDocShellTreeItem::typeChrome;
 
   // next, fire the cut, copy or paste event
   bool doDefault = true;
   nsRefPtr<DataTransfer> clipboardData;
   if (chromeShell || Preferences::GetBool("dom.event.clipboardevents.enabled", true)) {
     clipboardData =
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -4567,20 +4567,20 @@ nsDocument::SetIsTopLevelContentDocument
 nsPIDOMWindow *
 nsDocument::GetWindowInternal() const
 {
   MOZ_ASSERT(!mWindow, "This should not be called when mWindow is not null!");
   // Let's use mScriptGlobalObject. Even if the document is already removed from
   // the docshell, the outer window might be still obtainable from the it.
   nsCOMPtr<nsPIDOMWindow> win;
   if (mRemovedFromDocShell) {
-    nsCOMPtr<nsIInterfaceRequestor> requestor(mDocumentContainer);
-    if (requestor) {
-      // The docshell returns the outer window we are done.
-      win = do_GetInterface(requestor);
+    // The docshell returns the outer window we are done.
+    nsCOMPtr<nsIDocShell> kungfuDeathGrip(mDocumentContainer);
+    if (mDocumentContainer) {
+      win = mDocumentContainer->GetWindow();
     }
   } else {
     win = do_QueryInterface(mScriptGlobalObject);
     if (win) {
       // mScriptGlobalObject is always the inner window, let's get the outer.
       win = win->GetOuterWindow();
     } else if (mMasterDocument) {
       // For script execution in the imported document we need the window of
@@ -10981,17 +10981,17 @@ IsInActiveTab(nsIDocument* aDoc)
     return false;
   }
 
   nsCOMPtr<nsIDocShellTreeItem> rootItem;
   docshell->GetRootTreeItem(getter_AddRefs(rootItem));
   if (!rootItem) {
     return false;
   }
-  nsCOMPtr<nsIDOMWindow> rootWin = do_GetInterface(rootItem);
+  nsCOMPtr<nsIDOMWindow> rootWin = rootItem->GetWindow();
   if (!rootWin) {
     return false;
   }
 
   nsIFocusManager* fm = nsFocusManager::GetFocusManager();
   if (!fm) {
     return false;
   }
--- a/content/base/src/nsFrameLoader.cpp
+++ b/content/base/src/nsFrameLoader.cpp
@@ -648,19 +648,19 @@ nsFrameLoader::Finalize()
   }
   mDocShell = nullptr;
 }
 
 static void
 FirePageHideEvent(nsIDocShellTreeItem* aItem,
                   EventTarget* aChromeEventHandler)
 {
-  nsCOMPtr<nsIDocument> internalDoc = do_GetInterface(aItem);
-  NS_ASSERTION(internalDoc, "What happened here?");
-  internalDoc->OnPageHide(true, aChromeEventHandler);
+  nsCOMPtr<nsIDocument> doc = aItem->GetDocument();
+  NS_ASSERTION(doc, "What happened here?");
+  doc->OnPageHide(true, aChromeEventHandler);
 
   int32_t childCount = 0;
   aItem->GetChildCount(&childCount);
   nsAutoTArray<nsCOMPtr<nsIDocShellTreeItem>, 8> kids;
   kids.AppendElements(childCount);
   for (int32_t i = 0; i < childCount; ++i) {
     aItem->GetChildAt(i, getter_AddRefs(kids[i]));
   }
@@ -690,20 +690,20 @@ FirePageShowEvent(nsIDocShellTreeItem* a
   }
 
   for (uint32_t i = 0; i < kids.Length(); ++i) {
     if (kids[i]) {
       FirePageShowEvent(kids[i], aChromeEventHandler, aFireIfShowing);
     }
   }
 
-  nsCOMPtr<nsIDocument> internalDoc = do_GetInterface(aItem);
-  NS_ASSERTION(internalDoc, "What happened here?");
-  if (internalDoc->IsShowing() == aFireIfShowing) {
-    internalDoc->OnPageShow(true, aChromeEventHandler);
+  nsCOMPtr<nsIDocument> doc = aItem->GetDocument();
+  NS_ASSERTION(doc, "What happened here?");
+  if (doc->IsShowing() == aFireIfShowing) {
+    doc->OnPageShow(true, aChromeEventHandler);
   }
 }
 
 static void
 SetTreeOwnerAndChromeEventHandlerOnDocshellTree(nsIDocShellTreeItem* aItem,
                                                 nsIDocShellTreeOwner* aOwner,
                                                 EventTarget* aHandler)
 {
@@ -1151,18 +1151,18 @@ nsFrameLoader::SwapWithOtherLoader(nsFra
 
   // Make sure our parents are the same type too
   int32_t ourParentType = ourParentItem->ItemType();
   int32_t otherParentType = otherParentItem->ItemType();
   if (ourParentType != otherParentType) {
     return NS_ERROR_NOT_IMPLEMENTED;
   }
 
-  nsCOMPtr<nsPIDOMWindow> ourWindow = do_GetInterface(ourDocshell);
-  nsCOMPtr<nsPIDOMWindow> otherWindow = do_GetInterface(otherDocshell);
+  nsCOMPtr<nsPIDOMWindow> ourWindow = ourDocshell->GetWindow();
+  nsCOMPtr<nsPIDOMWindow> otherWindow = otherDocshell->GetWindow();
 
   nsCOMPtr<Element> ourFrameElement =
     ourWindow->GetFrameElementInternal();
   nsCOMPtr<Element> otherFrameElement =
     otherWindow->GetFrameElementInternal();
 
   nsCOMPtr<EventTarget> ourChromeEventHandler =
     do_QueryInterface(ourWindow->GetChromeEventHandler());
@@ -1406,19 +1406,21 @@ nsFrameLoader::Destroy()
       nsCOMPtr<nsIDocShellTreeOwner> owner = do_GetInterface(parentItem);
       if (owner) {
         owner->ContentShellRemoved(mDocShell);
       }
     }
   }
   
   // Let our window know that we are gone
-  nsCOMPtr<nsPIDOMWindow> win_private(do_GetInterface(mDocShell));
-  if (win_private) {
-    win_private->SetFrameElementInternal(nullptr);
+  if (mDocShell) {
+    nsCOMPtr<nsPIDOMWindow> win_private(mDocShell->GetWindow());
+    if (win_private) {
+      win_private->SetFrameElementInternal(nullptr);
+    }
   }
 
   if ((mNeedsAsyncDestroy || !doc ||
        NS_FAILED(doc->FinalizeFrameLoader(this))) && mDocShell) {
     nsCOMPtr<nsIRunnable> event = new nsAsyncDocShellDestroyer(mDocShell);
     NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
     NS_DispatchToCurrentThread(event);
 
@@ -1672,26 +1674,26 @@ nsFrameLoader::MaybeCreateDocShell()
     // Our parent shell is a content shell. Get the chrome event
     // handler from it and use that for our shell as well.
 
     docShell->GetChromeEventHandler(getter_AddRefs(chromeEventHandler));
   }
 
   mDocShell->SetChromeEventHandler(chromeEventHandler);
 
-  // This is nasty, this code (the do_GetInterface(mDocShell) below)
+  // This is nasty, this code (the mDocShell->GetWindow() below)
   // *must* come *after* the above call to
   // mDocShell->SetChromeEventHandler() for the global window to get
   // the right chrome event handler.
 
   // Tell the window about the frame that hosts it.
   nsCOMPtr<Element> frame_element = mOwnerContent;
   NS_ASSERTION(frame_element, "frame loader owner element not a DOM element!");
 
-  nsCOMPtr<nsPIDOMWindow> win_private(do_GetInterface(mDocShell));
+  nsCOMPtr<nsPIDOMWindow> win_private(mDocShell->GetWindow());
   nsCOMPtr<nsIBaseWindow> base_win(do_QueryInterface(mDocShell));
   if (win_private) {
     win_private->SetFrameElementInternal(frame_element);
   }
 
   // This is kinda whacky, this call doesn't really create anything,
   // but it must be called to make sure things are properly
   // initialized.
@@ -1873,24 +1875,25 @@ nsFrameLoader::GetWindowDimensions(nsRec
   if (!doc) {
     return NS_ERROR_FAILURE;
   }
 
   if (doc->IsResourceDoc()) {
     return NS_ERROR_FAILURE;
   }
 
-  nsCOMPtr<nsIWebNavigation> parentAsWebNav =
-    do_GetInterface(doc->GetWindow());
-
-  if (!parentAsWebNav) {
+  nsCOMPtr<nsPIDOMWindow> win = doc->GetWindow();
+  if (!win) {
     return NS_ERROR_FAILURE;
   }
 
-  nsCOMPtr<nsIDocShellTreeItem> parentAsItem(do_QueryInterface(parentAsWebNav));
+  nsCOMPtr<nsIDocShellTreeItem> parentAsItem(win->GetDocShell());
+  if (!parentAsItem) {
+    return NS_ERROR_FAILURE;
+  }
 
   nsCOMPtr<nsIDocShellTreeOwner> parentOwner;
   if (NS_FAILED(parentAsItem->GetTreeOwner(getter_AddRefs(parentOwner))) ||
       !parentOwner) {
     return NS_ERROR_FAILURE;
   }
 
   nsCOMPtr<nsIBaseWindow> treeOwnerAsWin(do_GetInterface(parentOwner));
@@ -2047,24 +2050,25 @@ nsFrameLoader::TryRemoteBrowser()
     return false;
   }
 
   if (doc->IsResourceDoc()) {
     // Don't allow subframe loads in external reference documents
     return false;
   }
 
-  nsCOMPtr<nsIWebNavigation> parentAsWebNav =
-    do_GetInterface(doc->GetWindow());
-
-  if (!parentAsWebNav) {
+  nsCOMPtr<nsPIDOMWindow> parentWin = doc->GetWindow();
+  if (!parentWin) {
     return false;
   }
 
-  nsCOMPtr<nsIDocShellTreeItem> parentAsItem(do_QueryInterface(parentAsWebNav));
+  nsCOMPtr<nsIDocShellTreeItem> parentAsItem(parentWin->GetDocShell());
+  if (!parentAsItem) {
+    return false;
+  }
 
   // <iframe mozbrowser> gets to skip these checks.
   if (!OwnerIsBrowserOrAppFrame()) {
     if (parentAsItem->ItemType() != nsIDocShellTreeItem::typeChrome) {
       return false;
     }
 
     if (!mOwnerContent->IsXUL()) {
@@ -2122,17 +2126,17 @@ nsFrameLoader::TryRemoteBrowser()
   NS_ENSURE_TRUE(rv, false);
 
   nsCOMPtr<Element> ownerElement = mOwnerContent;
   mRemoteBrowser = ContentParent::CreateBrowserOrApp(context, ownerElement);
   if (mRemoteBrowser) {
     mChildID = mRemoteBrowser->Manager()->ChildID();
     nsCOMPtr<nsIDocShellTreeItem> rootItem;
     parentAsItem->GetRootTreeItem(getter_AddRefs(rootItem));
-    nsCOMPtr<nsIDOMWindow> rootWin = do_GetInterface(rootItem);
+    nsCOMPtr<nsIDOMWindow> rootWin = rootItem->GetWindow();
     nsCOMPtr<nsIDOMChromeWindow> rootChromeWin = do_QueryInterface(rootWin);
     NS_ABORT_IF_FALSE(rootChromeWin, "How did we not get a chrome window here?");
 
     nsCOMPtr<nsIBrowserDOMWindow> browserDOMWin;
     rootChromeWin->GetBrowserDOMWindow(getter_AddRefs(browserDOMWin));
     mRemoteBrowser->SetBrowserDOMWindow(browserDOMWin);
 
     mContentParent = mRemoteBrowser->Manager();
@@ -2217,25 +2221,28 @@ nsFrameLoader::SendCrossProcessKeyEvent(
 
 nsresult
 nsFrameLoader::CreateStaticClone(nsIFrameLoader* aDest)
 {
   nsFrameLoader* dest = static_cast<nsFrameLoader*>(aDest);
   dest->MaybeCreateDocShell();
   NS_ENSURE_STATE(dest->mDocShell);
 
-  nsCOMPtr<nsIDocument> dummy = do_GetInterface(dest->mDocShell);
+  nsCOMPtr<nsIDocument> dummy = dest->mDocShell->GetDocument();
   nsCOMPtr<nsIContentViewer> viewer;
   dest->mDocShell->GetContentViewer(getter_AddRefs(viewer));
   NS_ENSURE_STATE(viewer);
 
   nsCOMPtr<nsIDocShell> origDocShell;
   GetDocShell(getter_AddRefs(origDocShell));
-  nsCOMPtr<nsIDocument> doc = do_GetInterface(origDocShell);
+  NS_ENSURE_STATE(origDocShell);
+
+  nsCOMPtr<nsIDocument> doc = origDocShell->GetDocument();
   NS_ENSURE_STATE(doc);
+
   nsCOMPtr<nsIDocument> clonedDoc = doc->CreateStaticClone(dest->mDocShell);
   nsCOMPtr<nsIDOMDocument> clonedDOMDoc = do_QueryInterface(clonedDoc);
 
   viewer->SetDOMDocument(clonedDOMDoc);
   return NS_OK;
 }
 
 bool
--- a/content/base/src/nsInProcessTabChildGlobal.cpp
+++ b/content/base/src/nsInProcessTabChildGlobal.cpp
@@ -162,17 +162,21 @@ NS_INTERFACE_MAP_END_INHERITING(DOMEvent
 
 NS_IMPL_ADDREF_INHERITED(nsInProcessTabChildGlobal, DOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(nsInProcessTabChildGlobal, DOMEventTargetHelper)
 
 NS_IMETHODIMP
 nsInProcessTabChildGlobal::GetContent(nsIDOMWindow** aContent)
 {
   *aContent = nullptr;
-  nsCOMPtr<nsIDOMWindow> window = do_GetInterface(mDocShell);
+  if (!mDocShell) {
+    return NS_OK;
+  }
+
+  nsCOMPtr<nsIDOMWindow> window = mDocShell->GetWindow();
   window.swap(*aContent);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsInProcessTabChildGlobal::GetDocShell(nsIDocShell** aDocShell)
 {
   NS_IF_ADDREF(*aDocShell = mDocShell);
@@ -215,20 +219,22 @@ nsInProcessTabChildGlobal::DelayedDiscon
 {
   // Don't let the event escape
   mOwner = nullptr;
 
   // Fire the "unload" event
   DOMEventTargetHelper::DispatchTrustedEvent(NS_LITERAL_STRING("unload"));
 
   // Continue with the Disconnect cleanup
-  nsCOMPtr<nsPIDOMWindow> win = do_GetInterface(mDocShell);
-  if (win) {
-    MOZ_ASSERT(win->IsOuterWindow());
-    win->SetChromeEventHandler(win->GetChromeEventHandler());
+  if (mDocShell) {
+    nsCOMPtr<nsPIDOMWindow> win = mDocShell->GetWindow();
+    if (win) {
+      MOZ_ASSERT(win->IsOuterWindow());
+      win->SetChromeEventHandler(win->GetChromeEventHandler());
+    }
   }
   mDocShell = nullptr;
   mChromeMessageManager = nullptr;
   if (mMessageManager) {
     static_cast<nsFrameMessageManager*>(mMessageManager.get())->Disconnect();
     mMessageManager = nullptr;
   }
   if (mListenerManager) {
--- a/content/canvas/src/CanvasRenderingContext2D.cpp
+++ b/content/canvas/src/CanvasRenderingContext2D.cpp
@@ -3722,18 +3722,23 @@ CanvasRenderingContext2D::AsyncDrawXULEl
   nsRefPtr<nsFrameLoader> frameloader = loaderOwner->GetFrameLoader();
   if (!frameloader) {
     error.Throw(NS_ERROR_FAILURE);
     return;
   }
 
   PBrowserParent *child = frameloader->GetRemoteBrowser();
   if (!child) {
-    nsCOMPtr<nsIDOMWindow> window =
-      do_GetInterface(frameloader->GetExistingDocShell());
+    nsIDocShell* docShell = frameLoader->GetExistingDocShell();
+    if (!docShell) {
+      error.Throw(NS_ERROR_FAILURE);
+      return;
+    }
+
+    nsCOMPtr<nsIDOMWindow> window = docShell->GetWindow();
     if (!window) {
       error.Throw(NS_ERROR_FAILURE);
       return;
     }
 
     return DrawWindow(window, x, y, w, h, bgColor, flags);
   }
 
--- a/content/xul/document/src/XULDocument.cpp
+++ b/content/xul/document/src/XULDocument.cpp
@@ -4695,19 +4695,21 @@ XULDocument::ParserObserver::OnStopReque
     mDocument = nullptr;
 
     return rv;
 }
 
 already_AddRefed<nsPIWindowRoot>
 XULDocument::GetWindowRoot()
 {
-    nsCOMPtr<nsIInterfaceRequestor> ir(mDocumentContainer);
-    nsCOMPtr<nsIDOMWindow> window(do_GetInterface(ir));
-    nsCOMPtr<nsPIDOMWindow> piWin(do_QueryInterface(window));
+  if (!mDocumentContainer) {
+    return nullptr;
+  }
+
+    nsCOMPtr<nsPIDOMWindow> piWin = mDocumentContainer->GetWindow();
     return piWin ? piWin->GetTopWindowRoot() : nullptr;
 }
 
 bool
 XULDocument::IsDocumentRightToLeft()
 {
     // setting the localedir attribute on the root element forces a
     // specific direction for the document.
--- a/docshell/base/nsDSURIContentListener.cpp
+++ b/docshell/base/nsDSURIContentListener.cpp
@@ -129,17 +129,18 @@ nsDSURIContentListener::DoContent(const 
 
     if (NS_FAILED(rv)) { 
       // we don't know how to handle the content
       *aContentHandler = nullptr;
       return rv;
     }
 
     if (loadFlags & nsIChannel::LOAD_RETARGETED_DOCUMENT_URI) {
-        nsCOMPtr<nsIDOMWindow> domWindow = do_GetInterface(static_cast<nsIDocShell*>(mDocShell));
+        nsCOMPtr<nsIDOMWindow> domWindow = mDocShell ? mDocShell->GetWindow()
+          : nullptr;
         NS_ENSURE_TRUE(domWindow, NS_ERROR_FAILURE);
         domWindow->Focus();
     }
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
@@ -281,17 +282,17 @@ bool nsDSURIContentListener::CheckOneFra
     if (!mDocShell) {
         return true;
     }
 
     // We need to check the location of this window and the location of the top
     // window, if we're not the top.  X-F-O: SAMEORIGIN requires that the
     // document must be same-origin with top window.  X-F-O: DENY requires that
     // the document must never be framed.
-    nsCOMPtr<nsIDOMWindow> thisWindow = do_GetInterface(static_cast<nsIDocShell*>(mDocShell));
+    nsCOMPtr<nsIDOMWindow> thisWindow = mDocShell->GetWindow();
     // If we don't have DOMWindow there is no risk of clickjacking
     if (!thisWindow)
         return true;
 
     // GetScriptableTop, not GetTop, because we want this to respect
     // <iframe mozbrowser> boundaries.
     nsCOMPtr<nsIDOMWindow> topWindow;
     thisWindow->GetScriptableTop(getter_AddRefs(topWindow));
@@ -323,17 +324,17 @@ bool nsDSURIContentListener::CheckOneFra
            parentDocShellItem) {
 
         nsCOMPtr<nsIDocShell> curDocShell = do_QueryInterface(curDocShellItem);
         if (curDocShell && curDocShell->GetIsBrowserOrApp()) {
           break;
         }
 
         bool system = false;
-        topDoc = do_GetInterface(parentDocShellItem);
+        topDoc = parentDocShellItem->GetDocument();
         if (topDoc) {
             if (NS_SUCCEEDED(ssm->IsSystemPrincipal(topDoc->NodePrincipal(),
                                                     &system)) && system) {
                 // Found a system-principled doc: last docshell was top.
                 break;
             }
         }
         else {
@@ -350,17 +351,17 @@ bool nsDSURIContentListener::CheckOneFra
     // If the value of the header is DENY, and the previous condition is
     // not met (current docshell is not the top docshell), prohibit the
     // load.
     if (policy.LowerCaseEqualsLiteral("deny")) {
         ReportXFOViolation(curDocShellItem, uri, eDENY);
         return false;
     }
 
-    topDoc = do_GetInterface(curDocShellItem);
+    topDoc = curDocShellItem->GetDocument();
     nsCOMPtr<nsIURI> topUri;
     topDoc->NodePrincipal()->GetURI(getter_AddRefs(topUri));
 
     // If the X-Frame-Options value is SAMEORIGIN, then the top frame in the
     // parent chain must be from the same origin as this document.
     if (policy.LowerCaseEqualsLiteral("sameorigin")) {
         rv = ssm->CheckSameOriginURI(uri, topUri, true);
         if (NS_FAILED(rv)) {
@@ -447,33 +448,31 @@ bool nsDSURIContentListener::CheckFrameO
     return true;
 }
 
 void
 nsDSURIContentListener::ReportXFOViolation(nsIDocShellTreeItem* aTopDocShellItem,
                                            nsIURI* aThisURI,
                                            XFOHeader aHeader)
 {
-    nsresult rv = NS_OK;
+  MOZ_ASSERT(aTopDocShellItem, "Need a top docshell");
 
-    nsCOMPtr<nsPIDOMWindow> topOuterWindow = do_GetInterface(aTopDocShellItem);
+    nsCOMPtr<nsPIDOMWindow> topOuterWindow = aTopDocShellItem->GetWindow();
     if (!topOuterWindow)
         return;
 
     NS_ASSERTION(topOuterWindow->IsOuterWindow(), "Huh?");
     nsPIDOMWindow* topInnerWindow = topOuterWindow->GetCurrentInnerWindow();
     if (!topInnerWindow)
         return;
 
     nsCOMPtr<nsIURI> topURI;
 
-    nsCOMPtr<nsIDocument> document;
-
-    document = do_GetInterface(aTopDocShellItem);
-    rv = document->NodePrincipal()->GetURI(getter_AddRefs(topURI));
+    nsCOMPtr<nsIDocument> document = aTopDocShellItem->GetDocument();
+    nsresult rv = document->NodePrincipal()->GetURI(getter_AddRefs(topURI));
     if (NS_FAILED(rv))
         return;
 
     if (!topURI)
         return;
 
     nsCString topURIString;
     nsCString thisURIString;
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -1120,18 +1120,17 @@ NS_IMETHODIMP nsDocShell::GetInterface(c
     else if (aIID.Equals(NS_GET_IID(nsIContentFrameMessageManager))) {
       nsCOMPtr<nsITabChild> tabChild =
         do_GetInterface(static_cast<nsIDocShell*>(this));
       nsCOMPtr<nsIContentFrameMessageManager> mm;
       if (tabChild) {
         tabChild->
           GetMessageManager(getter_AddRefs(mm));
       } else {
-        nsCOMPtr<nsPIDOMWindow> win =
-          do_GetInterface(static_cast<nsIDocShell*>(this));
+        nsCOMPtr<nsPIDOMWindow> win = GetWindow();
         if (win) {
           mm = do_QueryInterface(win->GetParentTarget());
         }
       }
       *aSink = mm.get();
     }
     else {
       return nsDocLoader::GetInterface(aIID, aSink);
@@ -1743,22 +1742,24 @@ nsDocShell::ValidateOrigin(nsIDocShellTr
                            nsIDocShellTreeItem* aTargetTreeItem)
 {
     // We want to bypass this check for chrome callers, but only if there's
     // JS on the stack. System callers still need to do it.
     if (nsContentUtils::GetCurrentJSContext() && nsContentUtils::IsCallerChrome()) {
         return true;
     }
 
+    MOZ_ASSERT(aOriginTreeItem && aTargetTreeItem, "need two docshells");
+
     // Get origin document principal
-    nsCOMPtr<nsIDocument> originDocument(do_GetInterface(aOriginTreeItem));
+    nsCOMPtr<nsIDocument> originDocument = aOriginTreeItem->GetDocument();
     NS_ENSURE_TRUE(originDocument, false);
 
     // Get target principal
-    nsCOMPtr<nsIDocument> targetDocument(do_GetInterface(aTargetTreeItem));
+    nsCOMPtr<nsIDocument> targetDocument = aTargetTreeItem->GetDocument();
     NS_ENSURE_TRUE(targetDocument, false);
 
     bool equal;
     nsresult rv = originDocument->NodePrincipal()->Equals(targetDocument->NodePrincipal(),
                                                           &equal);
     if (NS_SUCCEEDED(rv) && equal) {
         return true;
     }
@@ -2088,41 +2089,41 @@ nsDocShell::GetChannelIsUnsafe(bool *aUn
     }
 
     return jarChannel->GetIsUnsafe(aUnsafe);
 }
 
 NS_IMETHODIMP
 nsDocShell::GetHasMixedActiveContentLoaded(bool* aHasMixedActiveContentLoaded)
 {
-    nsCOMPtr<nsIDocument> doc(do_GetInterface(GetAsSupports(this)));
+    nsCOMPtr<nsIDocument> doc(GetDocument());
     *aHasMixedActiveContentLoaded = doc && doc->GetHasMixedActiveContentLoaded();
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocShell::GetHasMixedActiveContentBlocked(bool* aHasMixedActiveContentBlocked)
 {
-    nsCOMPtr<nsIDocument> doc(do_GetInterface(GetAsSupports(this)));
+    nsCOMPtr<nsIDocument> doc(GetDocument());
     *aHasMixedActiveContentBlocked = doc && doc->GetHasMixedActiveContentBlocked();
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocShell::GetHasMixedDisplayContentLoaded(bool* aHasMixedDisplayContentLoaded)
 {
-    nsCOMPtr<nsIDocument> doc(do_GetInterface(GetAsSupports(this)));
+    nsCOMPtr<nsIDocument> doc(GetDocument());
     *aHasMixedDisplayContentLoaded = doc && doc->GetHasMixedDisplayContentLoaded();
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocShell::GetHasMixedDisplayContentBlocked(bool* aHasMixedDisplayContentBlocked)
 {
-    nsCOMPtr<nsIDocument> doc(do_GetInterface(GetAsSupports(this)));
+    nsCOMPtr<nsIDocument> doc(GetDocument());
     *aHasMixedDisplayContentBlocked = doc && doc->GetHasMixedDisplayContentBlocked();
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocShell::GetAllowPlugins(bool * aAllowPlugins)
 {
     NS_ENSURE_ARG_POINTER(aAllowPlugins);
@@ -2446,36 +2447,33 @@ nsDocShell::GetFullscreenAllowed(bool* a
 
     // Assume false until we determine otherwise...
     *aFullscreenAllowed = false;
 
     // For non-browsers/apps, check that the enclosing iframe element
     // has the allowfullscreen attribute set to true. If any ancestor
     // iframe does not have mozallowfullscreen=true, then fullscreen is
     // prohibited.
-    nsCOMPtr<nsPIDOMWindow> win = do_GetInterface(GetAsSupports(this));
+    nsCOMPtr<nsPIDOMWindow> win = GetWindow();
     if (!win) {
         return NS_OK;
     }
     nsCOMPtr<nsIContent> frameElement = do_QueryInterface(win->GetFrameElementInternal());
     if (frameElement &&
         frameElement->IsHTML(nsGkAtoms::iframe) &&
         !frameElement->HasAttr(kNameSpaceID_None, nsGkAtoms::allowfullscreen) &&
         !frameElement->HasAttr(kNameSpaceID_None, nsGkAtoms::mozallowfullscreen)) {
         return NS_OK;
     }
 
     // If we have no parent then we're the root docshell; no ancestor of the
     // original docshell doesn't have a allowfullscreen attribute, so
     // report fullscreen as allowed.
-    nsCOMPtr<nsIDocShellTreeItem> dsti = do_GetInterface(GetAsSupports(this));
-    NS_ENSURE_TRUE(dsti, NS_OK);
-
     nsCOMPtr<nsIDocShellTreeItem> parentTreeItem;
-    dsti->GetParent(getter_AddRefs(parentTreeItem));
+    GetParent(getter_AddRefs(parentTreeItem));
     if (!parentTreeItem) {
         *aFullscreenAllowed = true;
         return NS_OK;
     }
     // Otherwise, we have a parent, continue the checking for
     // mozFullscreenAllowed in the parent docshell's ancestors.
     nsCOMPtr<nsIDocShell> parent = do_QueryInterface(parentTreeItem);
     NS_ENSURE_TRUE(parent, NS_OK);
@@ -3243,17 +3241,17 @@ nsDocShell::CanAccessItem(nsIDocShellTre
         return false;
     }
 
     if (!aConsiderOpener) {
         // All done here
         return false;
     }
 
-    nsCOMPtr<nsIDOMWindow> targetWindow = do_GetInterface(aTargetItem);
+    nsCOMPtr<nsIDOMWindow> targetWindow = aTargetItem->GetWindow();
     if (!targetWindow) {
         NS_ERROR("This should not happen, really");
         return false;
     }
 
     nsCOMPtr<nsIDOMWindow> targetOpener;
     targetWindow->GetOpener(getter_AddRefs(targetOpener));
     nsCOMPtr<nsIWebNavigation> openerWebNav(do_GetInterface(targetOpener));
@@ -3264,17 +3262,17 @@ nsDocShell::CanAccessItem(nsIDocShellTre
     }
 
     return CanAccessItem(openerItem, aAccessingItem, false);    
 }
 
 static bool
 ItemIsActive(nsIDocShellTreeItem *aItem)
 {
-    nsCOMPtr<nsIDOMWindow> window(do_GetInterface(aItem));
+    nsCOMPtr<nsIDOMWindow> window = aItem->GetWindow();
 
     if (window) {
         bool isClosed;
 
         if (NS_SUCCEEDED(window->GetClosed(&isClosed)) && !isClosed) {
             return true;
         }
     }
@@ -4121,16 +4119,30 @@ nsDocShell::GetCurrentSHEntry(nsISHEntry
 
 nsIScriptGlobalObject*
 nsDocShell::GetScriptGlobalObject()
 {
     NS_ENSURE_SUCCESS(EnsureScriptEnvironment(), nullptr);
     return mScriptGlobal;
 }
 
+nsIDocument*
+nsDocShell::GetDocument()
+{
+  NS_ENSURE_SUCCESS(EnsureContentViewer(), nullptr);
+  return mContentViewer->GetDocument();
+}
+
+nsPIDOMWindow*
+nsDocShell::GetWindow()
+{
+  NS_ENSURE_SUCCESS(EnsureScriptEnvironment(), nullptr);
+  return mScriptGlobal;
+}
+
 NS_IMETHODIMP
 nsDocShell::SetDeviceSizeIsPageSize(bool aValue)
 {
     if (mDeviceSizeIsPageSize != aValue) {
       mDeviceSizeIsPageSize = aValue;
       nsRefPtr<nsPresContext> presContext;
       GetPresContext(getter_AddRefs(presContext));
       if (presContext) {
@@ -4920,17 +4932,17 @@ nsDocShell::Reload(uint32_t aReloadFlags
     /* If you change this part of code, make sure bug 45297 does not re-occur */
     if (mOSHE) {
         rv = LoadHistoryEntry(mOSHE, loadType);
     }
     else if (mLSHE) { // In case a reload happened before the current load is done
         rv = LoadHistoryEntry(mLSHE, loadType);
     }
     else {
-        nsCOMPtr<nsIDocument> doc(do_GetInterface(GetAsSupports(this)));
+        nsCOMPtr<nsIDocument> doc(GetDocument());
 
         // Do not inherit owner from document
         uint32_t flags = INTERNAL_LOAD_FLAGS_NONE;
         nsAutoString srcdoc;
         nsIPrincipal* principal = nullptr;
         nsAutoString contentTypeHint;
         nsCOMPtr<nsIURI> baseURI;
         if (doc) {
@@ -5764,17 +5776,17 @@ nsDocShell::GetAllowMixedContentAndConne
   *aIsRootDocShell = false;
 
   nsCOMPtr<nsIDocShellTreeItem> sameTypeRoot;
   GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRoot));
   NS_ASSERTION(sameTypeRoot, "No document shell root tree item from document shell tree item!");
   *aIsRootDocShell = sameTypeRoot.get() == static_cast<nsIDocShellTreeItem *>(this);
 
   // now get the document from sameTypeRoot
-  nsCOMPtr<nsIDocument> rootDoc = do_GetInterface(sameTypeRoot);
+  nsCOMPtr<nsIDocument> rootDoc = sameTypeRoot->GetDocument();
   if (rootDoc) {
     nsCOMPtr<nsIPrincipal> rootPrincipal = rootDoc->NodePrincipal();
 
     // For things with system principal (e.g. scratchpad) there is no uri
     // aRootHasSecureConnection should be false.
     nsCOMPtr<nsIURI> rootUri;
     if (nsContentUtils::IsSystemPrincipal(rootPrincipal) ||
         NS_FAILED(rootPrincipal->GetURI(getter_AddRefs(rootUri))) || !rootUri ||
@@ -7210,30 +7222,30 @@ nsDocShell::EnsureContentViewer()
     if (mIsBeingDestroyed)
         return NS_ERROR_FAILURE;
 
     nsCOMPtr<nsIURI> baseURI;
     nsIPrincipal* principal = GetInheritedPrincipal(false);
     nsCOMPtr<nsIDocShellTreeItem> parentItem;
     GetSameTypeParent(getter_AddRefs(parentItem));
     if (parentItem) {
-        nsCOMPtr<nsPIDOMWindow> domWin = do_GetInterface(GetAsSupports(this));
+        nsCOMPtr<nsPIDOMWindow> domWin = GetWindow();
         if (domWin) {
             nsCOMPtr<nsIContent> parentContent =
                 do_QueryInterface(domWin->GetFrameElementInternal());
             if (parentContent) {
                 baseURI = parentContent->GetBaseURI();
             }
         }
     }
 
     nsresult rv = CreateAboutBlankContentViewer(principal, baseURI);
 
     if (NS_SUCCEEDED(rv)) {
-        nsCOMPtr<nsIDocument> doc(do_GetInterface(GetAsSupports(this)));
+        nsCOMPtr<nsIDocument> doc(GetDocument());
         NS_ASSERTION(doc,
                      "Should have doc if CreateAboutBlankContentViewer "
                      "succeeded!");
 
         doc->SetIsInitialDocument(true);
     }
 
     return rv;
@@ -7613,17 +7625,17 @@ nsDocShell::FinishRestore()
             child->FinishRestore();
         }
     }
 
     if (mOSHE && mOSHE->HasDetachedEditor()) {
       ReattachEditorToWindow(mOSHE);
     }
 
-    nsCOMPtr<nsIDocument> doc = do_GetInterface(GetAsSupports(this));
+    nsCOMPtr<nsIDocument> doc = GetDocument();
     if (doc) {
         // Finally, we remove the request from the loadgroup.  This will
         // cause onStateChange(STATE_STOP) to fire, which will fire the
         // pageshow event to the chrome.
 
         nsIChannel *channel = doc->GetChannel();
         if (channel) {
             mIsRestoringDocument = true;
@@ -7976,50 +7988,51 @@ nsDocShell::RestoreFromHistory()
         newMUDV->SetAuthorStyleDisabled(styleDisabled);
     }
 
     nsCOMPtr<nsIDocument> document = do_QueryInterface(domDoc);
     uint32_t parentSuspendCount = 0;
     if (document) {
         nsCOMPtr<nsIDocShellTreeItem> parent;
         GetParent(getter_AddRefs(parent));
-        nsCOMPtr<nsIDocument> d = do_GetInterface(parent);
-        if (d) {
+        if (parent) {
+          nsCOMPtr<nsIDocument> d = parent->GetDocument();
+          if (d) {
             if (d->EventHandlingSuppressed()) {
                 document->SuppressEventHandling(nsIDocument::eEvents,
                                                 d->EventHandlingSuppressed());
             }
 
             // Ick, it'd be nicer to not rewalk all of the subdocs here.
             if (d->AnimationsPaused()) {
                 document->SuppressEventHandling(nsIDocument::eAnimationsOnly,
                                                 d->AnimationsPaused());
             }
 
             nsCOMPtr<nsPIDOMWindow> parentWindow = d->GetWindow();
             if (parentWindow) {
-                parentSuspendCount = parentWindow->TimeoutSuspendCount();
-            }
+              parentSuspendCount = parentWindow->TimeoutSuspendCount();
+            }
+          }
         }
 
         // Use the uri from the mLSHE we had when we entered this function
         // (which need not match the document's URI if anchors are involved),
         // since that's the history entry we're loading.  Note that if we use
         // origLSHE we don't have to worry about whether the entry in question
         // is still mLSHE or whether it's now mOSHE.
         nsCOMPtr<nsIURI> uri;
         origLSHE->GetURI(getter_AddRefs(uri));
         SetCurrentURI(uri, document->GetChannel(), true, 0);
     }
 
     // This is the end of our CreateContentViewer() replacement.
     // Now we simulate a load.  First, we restore the state of the javascript
     // window object.
-    nsCOMPtr<nsPIDOMWindow> privWin =
-        do_GetInterface(static_cast<nsIInterfaceRequestor*>(this));
+    nsCOMPtr<nsPIDOMWindow> privWin = GetWindow();
     NS_ASSERTION(privWin, "could not get nsPIDOMWindow interface");
 
     rv = privWin->RestoreWindowState(windowState);
     NS_ENSURE_SUCCESS(rv, rv);
 
     // Now, dispatch a title change event which would happen as the
     // <head> is parsed.
     document->NotifyPossibleTitleChange(false);
@@ -8599,17 +8612,17 @@ nsDocShell::SetupNewViewer(nsIContentVie
     // viewer still set to hidden.
 
     return NS_OK;
 }
 
 nsresult
 nsDocShell::SetDocCurrentStateObj(nsISHEntry *shEntry)
 {
-    nsCOMPtr<nsIDocument> document = do_GetInterface(GetAsSupports(this));
+    nsCOMPtr<nsIDocument> document = GetDocument();
     NS_ENSURE_TRUE(document, NS_ERROR_FAILURE);
 
     nsCOMPtr<nsIStructuredCloneContainer> scContainer;
     if (shEntry) {
         nsresult rv = shEntry->GetStateData(getter_AddRefs(scContainer));
         NS_ENSURE_SUCCESS(rv, rv);
 
         // If shEntry is null, just set the document's state object to null.
@@ -8645,17 +8658,17 @@ nsDocShell::CheckLoadingPermissions()
     // It's just designed to preserve the old semantics during a mass-conversion
     // patch.
     NS_ENSURE_TRUE(nsContentUtils::GetCurrentJSContext(), NS_OK);
 
     // Check if the caller is from the same origin as this docshell,
     // or any of its ancestors.
     nsCOMPtr<nsIDocShellTreeItem> item(this);
     do {
-        nsCOMPtr<nsIScriptGlobalObject> sgo(do_GetInterface(item));
+        nsCOMPtr<nsIScriptGlobalObject> sgo = do_GetInterface(item);
         nsCOMPtr<nsIScriptObjectPrincipal> sop(do_QueryInterface(sgo));
 
         nsIPrincipal *p;
         if (!sop || !(p = sop->GetPrincipal())) {
             return NS_ERROR_UNEXPECTED;
         }
 
         if (nsContentUtils::SubjectPrincipal()->Subsumes(p)) {
@@ -9032,18 +9045,17 @@ nsDocShell::InternalLoad(nsIURI * aURI,
 
             if (doc) {
                 sandboxFlags = doc->GetSandboxFlags();
                 if (sandboxFlags & SANDBOXED_AUXILIARY_NAVIGATION) {
                     return NS_ERROR_DOM_INVALID_ACCESS_ERR;
                 }
             }
 
-            nsCOMPtr<nsPIDOMWindow> win =
-                do_GetInterface(GetAsSupports(this));
+            nsCOMPtr<nsPIDOMWindow> win = GetWindow();
             NS_ENSURE_TRUE(win, NS_ERROR_NOT_AVAILABLE);
 
             nsDependentString name(aWindowTarget);
             nsCOMPtr<nsIDOMWindow> newWin;
             nsAutoCString spec;
             if (aURI)
                 aURI->GetSpec(spec);
             rv = win->OpenNoNavigate(NS_ConvertUTF8toUTF16(spec),
@@ -9094,18 +9106,17 @@ nsDocShell::InternalLoad(nsIURI * aURI,
                 if (isNewWindow) {
                     //
                     // At this point, a new window has been created, but the
                     // URI did not have any data associated with it...
                     //
                     // So, the best we can do, is to tear down the new window
                     // that was just created!
                     //
-                    nsCOMPtr<nsIDOMWindow> domWin =
-                        do_GetInterface(targetDocShell);
+                    nsCOMPtr<nsIDOMWindow> domWin = targetDocShell->GetWindow();
                     if (domWin) {
                         domWin->Close();
                     }
                 }
                 //
                 // NS_ERROR_NO_CONTENT should not be returned to the
                 // caller... This is an internal error code indicating that
                 // the URI had no data associated with it - probably a 
@@ -9406,18 +9417,17 @@ nsDocShell::InternalLoad(nsIURI * aURI,
                     history->SetURITitle(aURI, mTitle);
                 }
                 else if (mGlobalHistory) {
                     mGlobalHistory->SetPageTitle(aURI, mTitle);
                 }
             }
 
             // Set the doc's URI according to the new history entry's URI.
-            nsCOMPtr<nsIDocument> doc =
-              do_GetInterface(GetAsSupports(this));
+            nsCOMPtr<nsIDocument> doc = GetDocument();
             NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
             doc->SetDocumentURI(aURI);
 
             SetDocCurrentStateObj(mOSHE);
 
             // Dispatch the popstate and hashchange events, as appropriate.
             //
             // The event dispatch below can cause us to re-enter script and
@@ -9618,17 +9628,17 @@ nsDocShell::GetInheritedPrincipal(bool a
         document = mContentViewer->GetDocument();
         inheritedFromCurrent = true;
     }
 
     if (!document) {
         nsCOMPtr<nsIDocShellTreeItem> parentItem;
         GetSameTypeParent(getter_AddRefs(parentItem));
         if (parentItem) {
-            document = do_GetInterface(parentItem);
+            document = parentItem->GetDocument();
         }
     }
 
     if (!document) {
         if (!aConsiderCurrentDocument) {
             return nullptr;
         }
 
@@ -9705,25 +9715,27 @@ nsDocShell::DoURILoad(nsIURI * aURI,
     // check for Content Security Policy to pass along with the
     // new channel we are creating
     nsCOMPtr<nsIChannelPolicy> channelPolicy;
     if (IsFrame()) {
         // check the parent docshell for a CSP
         nsCOMPtr<nsIContentSecurityPolicy> csp;
         nsCOMPtr<nsIDocShellTreeItem> parentItem;
         GetSameTypeParent(getter_AddRefs(parentItem));
-        nsCOMPtr<nsIDocument> doc = do_GetInterface(parentItem);
-        if (doc) {
+        if (parentItem) {
+          nsCOMPtr<nsIDocument> doc = parentItem->GetDocument();
+          if (doc) {
             rv = doc->NodePrincipal()->GetCsp(getter_AddRefs(csp));
             NS_ENSURE_SUCCESS(rv, rv);
             if (csp) {
-                channelPolicy = do_CreateInstance("@mozilla.org/nschannelpolicy;1");
-                channelPolicy->SetContentSecurityPolicy(csp);
-                channelPolicy->SetLoadType(nsIContentPolicy::TYPE_SUBDOCUMENT);
-            }
+              channelPolicy = do_CreateInstance("@mozilla.org/nschannelpolicy;1");
+              channelPolicy->SetContentSecurityPolicy(csp);
+              channelPolicy->SetLoadType(nsIContentPolicy::TYPE_SUBDOCUMENT);
+            }
+          }
         }
 
         // Only allow view-source scheme in top-level docshells. view-source is
         // the only scheme to which this applies at the moment due to potential
         // timing attacks to read data from cross-origin iframes. If this widens
         // we should add a protocol flag for whether the scheme is allowed in
         // frames and use something like nsNetUtil::NS_URIChainHasFlags.
         nsCOMPtr<nsIURI> tempURI = aURI;
@@ -10626,29 +10638,28 @@ nsDocShell::AddState(JS::Handle<JS::Valu
 
     // pushState effectively becomes replaceState when we've started a network
     // load but haven't adopted its document yet.  This mirrors what we do with
     // changes to the hash at this stage of the game.
     if (JustStartedNetworkLoad()) {
         aReplace = true;
     }
 
-    nsCOMPtr<nsIDocument> document = do_GetInterface(GetAsSupports(this));
+    nsCOMPtr<nsIDocument> document = GetDocument();
     NS_ENSURE_TRUE(document, NS_ERROR_FAILURE);
 
     // Step 1: Serialize aData using structured clone.
     nsCOMPtr<nsIStructuredCloneContainer> scContainer;
 
     // scContainer->Init might cause arbitrary JS to run, and this code might
     // navigate the page we're on, potentially to a different origin! (bug
     // 634834)  To protect against this, we abort if our principal changes due
     // to the InitFromJSVal() call.
     {
-        nsCOMPtr<nsIDocument> origDocument =
-            do_GetInterface(GetAsSupports(this));
+        nsCOMPtr<nsIDocument> origDocument = GetDocument();
         if (!origDocument)
             return NS_ERROR_DOM_SECURITY_ERR;
         nsCOMPtr<nsIPrincipal> origPrincipal = origDocument->NodePrincipal();
 
         scContainer = new nsStructuredCloneContainer();
         JSContext *cx = aCx;
         nsCxPusher pusher;
         if (!cx) {
@@ -10659,18 +10670,17 @@ nsDocShell::AddState(JS::Handle<JS::Valu
 
         // If we're running in the document's context and the structured clone
         // failed, clear the context's pending exception.  See bug 637116.
         if (NS_FAILED(rv) && !aCx) {
             JS_ClearPendingException(aCx);
         }
         NS_ENSURE_SUCCESS(rv, rv);
 
-        nsCOMPtr<nsIDocument> newDocument =
-            do_GetInterface(GetAsSupports(this));
+        nsCOMPtr<nsIDocument> newDocument = GetDocument();
         if (!newDocument)
             return NS_ERROR_DOM_SECURITY_ERR;
         nsCOMPtr<nsIPrincipal> newPrincipal = newDocument->NodePrincipal();
 
         bool principalsEqual = false;
         origPrincipal->Equals(newPrincipal, &principalsEqual);
         NS_ENSURE_TRUE(principalsEqual, NS_ERROR_DOM_SECURITY_ERR);
     }
@@ -12211,28 +12221,28 @@ nsDocShell::GetAssociatedWindow(nsIDOMWi
 {
     CallGetInterface(this, aWindow);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocShell::GetTopWindow(nsIDOMWindow** aWindow)
 {
-    nsCOMPtr<nsIDOMWindow> win = do_GetInterface(GetAsSupports(this));
+    nsCOMPtr<nsIDOMWindow> win = GetWindow();
     if (win) {
         win->GetTop(aWindow);
     }
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocShell::GetTopFrameElement(nsIDOMElement** aElement)
 {
     *aElement = nullptr;
-    nsCOMPtr<nsIDOMWindow> win = do_GetInterface(GetAsSupports(this));
+    nsCOMPtr<nsIDOMWindow> win = GetWindow();
     if (!win) {
         return NS_OK;
     }
 
     nsCOMPtr<nsIDOMWindow> top;
     win->GetScriptableTop(getter_AddRefs(top));
     NS_ENSURE_TRUE(top, NS_ERROR_FAILURE);
 
@@ -12340,19 +12350,17 @@ nsresult
 nsDocShell::EnsureCommandHandler()
 {
   if (!mCommandManager)
   {
     nsCOMPtr<nsPICommandUpdater> commandUpdater =
       do_CreateInstance("@mozilla.org/embedcomp/command-manager;1");
     if (!commandUpdater) return NS_ERROR_OUT_OF_MEMORY;
     
-    nsCOMPtr<nsIDOMWindow> domWindow =
-      do_GetInterface(static_cast<nsIInterfaceRequestor *>(this));
-
+    nsCOMPtr<nsIDOMWindow> domWindow = GetWindow();
     nsresult rv = commandUpdater->Init(domWindow);
     if (NS_SUCCEEDED(rv))
       mCommandManager = do_QueryInterface(commandUpdater);
   }
   
   return mCommandManager ? NS_OK : NS_ERROR_FAILURE;
 }
 
--- a/docshell/base/nsDocShellEditorData.cpp
+++ b/docshell/base/nsDocShellEditorData.cpp
@@ -3,17 +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 "nsDocShellEditorData.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsComponentManagerUtils.h"
-#include "nsIDOMWindow.h"
+#include "nsPIDOMWindow.h"
 #include "nsIDOMDocument.h"
 #include "nsIEditor.h"
 #include "nsIEditingSession.h"
 #include "nsIDocShell.h"
 
 /*---------------------------------------------------------------------------
 
   nsDocShellEditorData
@@ -97,18 +97,19 @@ nsDocShellEditorData::GetEditable()
 
 ----------------------------------------------------------------------------*/
 nsresult
 nsDocShellEditorData::CreateEditor()
 {
   nsCOMPtr<nsIEditingSession>   editingSession;    
   nsresult rv = GetEditingSession(getter_AddRefs(editingSession));
   if (NS_FAILED(rv)) return rv;
-  
-  nsCOMPtr<nsIDOMWindow>    domWindow = do_GetInterface(mDocShell);
+ 
+  nsCOMPtr<nsIDOMWindow>    domWindow =
+    mDocShell ? mDocShell->GetWindow() : nullptr;
   rv = editingSession->SetupEditorOnWindow(domWindow);
   if (NS_FAILED(rv)) return rv;
   
   return NS_OK;
 }
 
 
 /*---------------------------------------------------------------------------
@@ -196,17 +197,18 @@ nsDocShellEditorData::EnsureEditingSessi
 }
 
 nsresult
 nsDocShellEditorData::DetachFromWindow()
 {
   NS_ASSERTION(mEditingSession,
                "Can't detach when we don't have a session to detach!");
   
-  nsCOMPtr<nsIDOMWindow> domWindow = do_GetInterface(mDocShell);
+  nsCOMPtr<nsIDOMWindow> domWindow =
+    mDocShell ? mDocShell->GetWindow() : nullptr;
   nsresult rv = mEditingSession->DetachFromWindow(domWindow);
   NS_ENSURE_SUCCESS(rv, rv);
 
   mIsDetached = true;
   mDetachedMakeEditable = mMakeEditable;
   mMakeEditable = false;
 
   nsCOMPtr<nsIDOMDocument> domDoc;
@@ -220,17 +222,18 @@ nsDocShellEditorData::DetachFromWindow()
   return NS_OK;
 }
 
 nsresult
 nsDocShellEditorData::ReattachToWindow(nsIDocShell* aDocShell)
 {
   mDocShell = aDocShell;
 
-  nsCOMPtr<nsIDOMWindow> domWindow = do_GetInterface(mDocShell);
+  nsCOMPtr<nsIDOMWindow> domWindow =
+    mDocShell ? mDocShell->GetWindow() : nullptr;
   nsresult rv = mEditingSession->ReattachToWindow(domWindow);
   NS_ENSURE_SUCCESS(rv, rv);
 
   mIsDetached = false;
   mMakeEditable = mDetachedMakeEditable;
 
   nsCOMPtr<nsIDOMDocument> domDoc;
   domWindow->GetDocument(getter_AddRefs(domDoc));
--- a/docshell/base/nsIDocShell.idl
+++ b/docshell/base/nsIDocShell.idl
@@ -40,17 +40,17 @@ interface nsIPrincipal;
 interface nsIWebBrowserPrint;
 interface nsIVariant;
 interface nsIPrivacyTransitionObserver;
 interface nsIReflowObserver;
 interface nsIScrollObserver;
 
 typedef unsigned long nsLoadFlags;
 
-[scriptable, builtinclass, uuid(e46d924d-c20f-4add-8cf5-1e1c817b2181)]
+[scriptable, builtinclass, uuid(3ca96c12-b69d-4b54-83c5-25a18d32a22b)]
 interface nsIDocShell : nsIDocShellTreeItem
 {
   /**
    * Loads a given URI.  This will give priority to loading the requested URI
    * in the object implementing	this interface.  If it can't be loaded here
    * however, the URL dispatcher will go through its normal process of content
    * loading.
    *
--- a/docshell/base/nsIDocShellTreeItem.idl
+++ b/docshell/base/nsIDocShellTreeItem.idl
@@ -2,25 +2,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 "nsISupports.idl"
 
 interface nsIDocShellTreeOwner;
+interface nsIDocument;
+interface nsPIDOMWindow;
 
 
 /**
  * The nsIDocShellTreeItem supplies the methods that are required of any item
  * that wishes to be able to live within the docshell tree either as a middle
  * node or a leaf. 
  */
 
-[scriptable, uuid(f897f4af-f67e-4115-9d37-ce09f71122e2)]
+[scriptable, uuid(edb99640-8378-4106-8673-e701a086eb1c)]
 interface nsIDocShellTreeItem : nsISupports
 {
 	/*
 	name of the DocShellTreeItem
 	*/
 	attribute AString name;
 
         /**
@@ -170,10 +172,13 @@ interface nsIDocShellTreeItem : nsISuppo
 
 	Note the search is depth first when recursing.
 	*/
 	nsIDocShellTreeItem findChildWithName(in wstring aName,
 	                                      in boolean aRecurse,
 	                                      in boolean aSameType,
 	                                      in nsIDocShellTreeItem aRequestor,
 	                                      in nsIDocShellTreeItem aOriginalRequestor);
+
+  [noscript,nostdcall,notxpcom] nsIDocument getDocument();
+  [noscript,nostdcall,notxpcom] nsPIDOMWindow getWindow();
 };
 
--- a/dom/base/nsDOMWindowList.cpp
+++ b/dom/base/nsDOMWindowList.cpp
@@ -86,17 +86,17 @@ nsDOMWindowList::IndexedGetter(uint32_t 
 {
   aFound = false;
 
   nsCOMPtr<nsIDocShellTreeItem> item = GetDocShellTreeItemAt(aIndex);
   if (!item) {
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMWindow> window = do_GetInterface(item);
+  nsCOMPtr<nsIDOMWindow> window = item->GetWindow();
   MOZ_ASSERT(window);
 
   aFound = true;
   return window.forget();
 }
 
 NS_IMETHODIMP 
 nsDOMWindowList::Item(uint32_t aIndex, nsIDOMWindow** aReturn)
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -657,18 +657,17 @@ nsFocusManager::WindowRaised(nsIDOMWindo
     EnsureCurrentWidgetFocused();
     return NS_OK;
   }
 
   // lower the existing window, if any. This shouldn't happen usually.
   if (mActiveWindow)
     WindowLowered(mActiveWindow);
 
-  nsCOMPtr<nsIWebNavigation> webnav(do_GetInterface(aWindow));
-  nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(webnav));
+  nsCOMPtr<nsIDocShellTreeItem> docShellAsItem = window->GetDocShell();
   // If there's no docShellAsItem, this window must have been closed,
   // in that case there is no tree owner.
   NS_ENSURE_TRUE(docShellAsItem, NS_OK);
 
   // set this as the active window
   mActiveWindow = window;
 
   // ensure that the window is enabled and visible
@@ -800,20 +799,22 @@ nsFocusManager::ContentRemoved(nsIDocume
     else {
       // Check if the node that was focused is an iframe or similar by looking
       // if it has a subdocument. This would indicate that this focused iframe
       // and its descendants will be going away. We will need to move the
       // focus somewhere else, so just clear the focus in the toplevel window
       // so that no element is focused.
       nsIDocument* subdoc = aDocument->GetSubDocumentFor(content);
       if (subdoc) {
-        nsCOMPtr<nsISupports> container = subdoc->GetContainer();
-        nsCOMPtr<nsPIDOMWindow> childWindow = do_GetInterface(container);
-        if (childWindow && IsSameOrAncestor(childWindow, mFocusedWindow)) {
-          ClearFocus(mActiveWindow);
+        nsCOMPtr<nsIDocShell> docShell = subdoc->GetDocShell();
+        if (docShell) {
+          nsCOMPtr<nsPIDOMWindow> childWindow = docShell->GetWindow();
+          if (childWindow && IsSameOrAncestor(childWindow, mFocusedWindow)) {
+            ClearFocus(mActiveWindow);
+          }
         }
       }
     }
 
     NotifyFocusStateChange(content, shouldShowFocusRing, false);
   }
 
   return NS_OK;
@@ -963,24 +964,26 @@ nsFocusManager::WindowHidden(nsIDOMWindo
     return NS_OK;
   }
 
   // if the window being hidden is an ancestor of the focused window, adjust
   // the focused window so that it points to the one being hidden. This
   // ensures that the focused window isn't in a chain of frames that doesn't
   // exist any more.
   if (window != mFocusedWindow) {
-    nsCOMPtr<nsIWebNavigation> webnav(do_GetInterface(mFocusedWindow));
-    nsCOMPtr<nsIDocShellTreeItem> dsti = do_QueryInterface(webnav);
+    nsCOMPtr<nsIDocShellTreeItem> dsti =
+      mFocusedWindow ? mFocusedWindow->GetDocShell() : nullptr;
     if (dsti) {
       nsCOMPtr<nsIDocShellTreeItem> parentDsti;
       dsti->GetParent(getter_AddRefs(parentDsti));
-      nsCOMPtr<nsPIDOMWindow> parentWindow = do_GetInterface(parentDsti);
-      if (parentWindow)
-        parentWindow->SetFocusedNode(nullptr);
+      if (parentDsti) {
+        nsCOMPtr<nsPIDOMWindow> parentWindow = parentDsti->GetWindow();
+        if (parentWindow)
+          parentWindow->SetFocusedNode(nullptr);
+      }
     }
 
     SetFocusedWindowInternal(window);
   }
 
   return NS_OK;
 }
 
@@ -1139,23 +1142,22 @@ nsFocusManager::SetFocusInner(nsIContent
       return;
     }
   }
 
   // to check if the new element is in the active window, compare the
   // new root docshell for the new element with the active window's docshell.
   bool isElementInActiveWindow = false;
 
-  nsCOMPtr<nsIWebNavigation> webnav = do_GetInterface(newWindow);
-  nsCOMPtr<nsIDocShellTreeItem> dsti = do_QueryInterface(webnav);
+  nsCOMPtr<nsIDocShellTreeItem> dsti = newWindow->GetDocShell();
   nsCOMPtr<nsPIDOMWindow> newRootWindow;
   if (dsti) {
     nsCOMPtr<nsIDocShellTreeItem> root;
     dsti->GetRootTreeItem(getter_AddRefs(root));
-    newRootWindow = do_GetInterface(root);
+    newRootWindow = root ? root->GetWindow() : nullptr;
 
     isElementInActiveWindow = (mActiveWindow && newRootWindow == mActiveWindow);
   }
 
   // Exit fullscreen if we're focusing a windowed plugin on a non-MacOSX
   // system. We don't control event dispatch to windowed plugins on non-MacOSX,
   // so we can't display the "Press ESC to leave fullscreen mode" warning on
   // key input if a windowed plugin is focused, so just exit fullscreen
@@ -1271,42 +1273,43 @@ nsFocusManager::SetFocusInner(nsIContent
       RaiseWindow(newRootWindow);
   }
 }
 
 bool
 nsFocusManager::IsSameOrAncestor(nsPIDOMWindow* aPossibleAncestor,
                                  nsPIDOMWindow* aWindow)
 {
-  nsCOMPtr<nsIWebNavigation> awebnav(do_GetInterface(aPossibleAncestor));
-  nsCOMPtr<nsIDocShellTreeItem> ancestordsti = do_QueryInterface(awebnav);
-
-  nsCOMPtr<nsIWebNavigation> fwebnav(do_GetInterface(aWindow));
-  nsCOMPtr<nsIDocShellTreeItem> dsti = do_QueryInterface(fwebnav);
+  if (!aWindow || !aPossibleAncestor) {
+    return false;
+  }
+
+  nsCOMPtr<nsIDocShellTreeItem> ancestordsti = aPossibleAncestor->GetDocShell();
+  nsCOMPtr<nsIDocShellTreeItem> dsti = aWindow->GetDocShell();
   while (dsti) {
     if (dsti == ancestordsti)
       return true;
     nsCOMPtr<nsIDocShellTreeItem> parentDsti;
     dsti->GetParent(getter_AddRefs(parentDsti));
     dsti.swap(parentDsti);
   }
 
   return false;
 }
 
 already_AddRefed<nsPIDOMWindow>
 nsFocusManager::GetCommonAncestor(nsPIDOMWindow* aWindow1,
                                   nsPIDOMWindow* aWindow2)
 {
-  nsCOMPtr<nsIWebNavigation> webnav(do_GetInterface(aWindow1));
-  nsCOMPtr<nsIDocShellTreeItem> dsti1 = do_QueryInterface(webnav);
+  NS_ENSURE_TRUE(aWindow1 && aWindow2, nullptr);
+
+  nsCOMPtr<nsIDocShellTreeItem> dsti1 = aWindow1->GetDocShell();
   NS_ENSURE_TRUE(dsti1, nullptr);
 
-  webnav = do_GetInterface(aWindow2);
-  nsCOMPtr<nsIDocShellTreeItem> dsti2 = do_QueryInterface(webnav);
+  nsCOMPtr<nsIDocShellTreeItem> dsti2 = aWindow2->GetDocShell();
   NS_ENSURE_TRUE(dsti2, nullptr);
 
   nsAutoTArray<nsIDocShellTreeItem*, 30> parents1, parents2;
   do {
     parents1.AppendElement(dsti1);
     nsCOMPtr<nsIDocShellTreeItem> parentDsti1;
     dsti1->GetParent(getter_AddRefs(parentDsti1));
     dsti1.swap(parentDsti1);
@@ -1326,41 +1329,43 @@ nsFocusManager::GetCommonAncestor(nsPIDO
     nsIDocShellTreeItem* child1 = parents1.ElementAt(--pos1);
     nsIDocShellTreeItem* child2 = parents2.ElementAt(--pos2);
     if (child1 != child2) {
       break;
     }
     parent = child1;
   }
 
-  nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(parent);
+  nsCOMPtr<nsPIDOMWindow> window = parent ? parent->GetWindow() : nullptr;
   return window.forget();
 }
 
 void
 nsFocusManager::AdjustWindowFocus(nsPIDOMWindow* aWindow,
                                   bool aCheckPermission)
 {
   bool isVisible = IsWindowVisible(aWindow);
 
   nsCOMPtr<nsPIDOMWindow> window(aWindow);
   while (window) {
     // get the containing <iframe> or equivalent element so that it can be
     // focused below.
     nsCOMPtr<nsIContent> frameContent =
       do_QueryInterface(window->GetFrameElementInternal());
 
-    nsCOMPtr<nsIWebNavigation> webnav(do_GetInterface(window));
-    nsCOMPtr<nsIDocShellTreeItem> dsti = do_QueryInterface(webnav);
+    nsCOMPtr<nsIDocShellTreeItem> dsti = window->GetDocShell();
     if (!dsti) 
       return;
     nsCOMPtr<nsIDocShellTreeItem> parentDsti;
     dsti->GetParent(getter_AddRefs(parentDsti));
-
-    window = do_GetInterface(parentDsti);
+    if (!parentDsti) {
+      return;
+    }
+
+    window = parentDsti->GetWindow();
     if (window) {
       // if the parent window is visible but aWindow was not, then we have
       // likely moved up and out from a hidden tab to the browser window, or a
       // similar such arrangement. Stop adjusting the current nodes.
       if (IsWindowVisible(window) != isVisible)
         break;
 
       // When aCheckPermission is true, we should check whether the caller can
@@ -2000,18 +2005,18 @@ nsFocusManager::RaiseWindow(nsPIDOMWindo
   nsViewManager* vm = presShell->GetViewManager();
   if (vm) {
     nsCOMPtr<nsIWidget> widget;
     vm->GetRootWidget(getter_AddRefs(widget));
     if (widget)
       widget->SetFocus(true);
   }
 #else
-  nsCOMPtr<nsIWebNavigation> webnav = do_GetInterface(aWindow);
-  nsCOMPtr<nsIBaseWindow> treeOwnerAsWin = do_QueryInterface(webnav);
+  nsCOMPtr<nsIBaseWindow> treeOwnerAsWin =
+    do_QueryInterface(aWindow->GetDocShell());
   if (treeOwnerAsWin) {
     nsCOMPtr<nsIWidget> widget;
     treeOwnerAsWin->GetMainWidget(getter_AddRefs(widget));
     if (widget)
       widget->SetFocus(true);
   }
 #endif
 }
@@ -2576,24 +2581,24 @@ nsFocusManager::DetermineElementToMoveFo
     // reached the beginning or end of the document. Traverse up to the parent
     // document and try again.
     nsCOMPtr<nsIDocShellTreeItem> docShellParent;
     docShell->GetParent(getter_AddRefs(docShellParent));
     if (docShellParent) {
       // move up to the parent shell and try again from there.
 
       // first, get the frame element this window is inside.
-      nsCOMPtr<nsPIDOMWindow> piWindow = do_GetInterface(docShell);
+      nsCOMPtr<nsPIDOMWindow> piWindow = docShell->GetWindow();
       NS_ENSURE_TRUE(piWindow, NS_ERROR_FAILURE);
 
       // Next, retrieve the parent docshell, document and presshell.
       docShell = do_QueryInterface(docShellParent);
       NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
 
-      nsCOMPtr<nsPIDOMWindow> piParentWindow = do_GetInterface(docShellParent);
+      nsCOMPtr<nsPIDOMWindow> piParentWindow = docShellParent->GetWindow();
       NS_ENSURE_TRUE(piParentWindow, NS_ERROR_FAILURE);
       doc = piParentWindow->GetExtantDoc();
       NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
 
       presShell = doc->GetShell();
 
       rootContent = doc->GetRootElement();
       startContent = do_QueryInterface(piWindow->GetFrameElementInternal());
@@ -2627,17 +2632,17 @@ nsFocusManager::DetermineElementToMoveFo
     }
     else {
       // no parent, so call the tree owner. This will tell the embedder that
       // it should take the focus.
       bool tookFocus;
       docShell->TabToTreeOwner(forward, &tookFocus);
       // if the tree owner, took the focus, blur the current content
       if (tookFocus) {
-        nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(docShell);
+        nsCOMPtr<nsPIDOMWindow> window = docShell->GetWindow();
         if (window->GetFocusedNode() == mFocusedContent)
           Blur(mFocusedWindow, nullptr, true, true);
         else
           window->SetFocusedNode(nullptr);
         return NS_OK;
       }
 
       // reset the tab index and start again from the beginning or end
@@ -3179,24 +3184,19 @@ nsFocusManager::GetNextTabbableDocument(
         break;
       }
       content = content->GetParent();
     }
   }
   else if (mFocusedWindow) {
     startDocShell = mFocusedWindow->GetDocShell();
     doc = mFocusedWindow->GetExtantDoc();
-  }
-  else {
-    nsCOMPtr<nsIWebNavigation> webnav = do_GetInterface(mActiveWindow);
-    startDocShell = do_QueryInterface(webnav);
-
-    if (mActiveWindow) {
-      doc = mActiveWindow->GetExtantDoc();
-    }
+  } else if (mActiveWindow) {
+    startDocShell = mActiveWindow->GetDocShell();
+    doc = mActiveWindow->GetExtantDoc();
   }
 
   if (!startDocShell)
     return nullptr;
 
   // perform a depth first search (preorder) of the docshell tree
   // looking for an HTML Frame or a chrome document
   nsIContent* content = aStartContent;
@@ -3246,17 +3246,17 @@ nsFocusManager::GetNextTabbableDocument(
         }
 
         // When going back to the previous document, check for any focusable
         // popups in that previous document first.
         checkPopups = true;
       }
 
       curItem = nextItem;
-      nextFrame = do_GetInterface(nextItem);
+      nextFrame = nextItem ? nextItem->GetWindow() : nullptr;
     }
 
     if (!nextFrame)
       return nullptr;
 
     // Clear currentPopup for the next iteration
     currentPopup = nullptr;
 
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -3373,17 +3373,17 @@ nsPIDOMWindow::GetDocBaseURI() const
 void
 nsPIDOMWindow::MaybeCreateDoc()
 {
   MOZ_ASSERT(!mDoc);
   if (nsIDocShell* docShell = GetDocShell()) {
     // Note that |document| here is the same thing as our mDoc, but we
     // don't have to explicitly set the member variable because the docshell
     // has already called SetNewDocument().
-    nsCOMPtr<nsIDocument> document = do_GetInterface(docShell);
+    nsCOMPtr<nsIDocument> document = docShell->GetDocument();
   }
 }
 
 Element*
 nsPIDOMWindow::GetFrameElementInternal() const
 {
   if (mOuterWindow) {
     return mOuterWindow->GetFrameElementInternal();
@@ -3796,19 +3796,18 @@ nsGlobalWindow::GetRealParent(nsIDOMWind
   if (!mDocShell) {
     return NS_OK;
   }
 
   nsCOMPtr<nsIDocShell> parent;
   mDocShell->GetSameTypeParentIgnoreBrowserAndAppBoundaries(getter_AddRefs(parent));
 
   if (parent) {
-    nsCOMPtr<nsIScriptGlobalObject> globalObject(do_GetInterface(parent));
-    NS_ENSURE_SUCCESS(CallQueryInterface(globalObject.get(), aParent),
-                      NS_ERROR_FAILURE);
+    nsCOMPtr<nsPIDOMWindow> win = parent->GetWindow();
+    win.forget(aParent);
   }
   else {
     *aParent = static_cast<nsIDOMWindow*>(this);
     NS_ADDREF(*aParent);
   }
   return NS_OK;
 }
 
@@ -3963,17 +3962,21 @@ nsGlobalWindow::GetContentInternal(Error
     if (!treeOwner) {
       aError.Throw(NS_ERROR_FAILURE);
       return nullptr;
     }
 
     treeOwner->GetPrimaryContentShell(getter_AddRefs(primaryContent));
   }
 
-  domWindow = do_GetInterface(primaryContent);
+  if (!primaryContent) {
+    return nullptr;
+  }
+
+  domWindow = primaryContent->GetWindow();
   return domWindow.forget();
 }
 
 NS_IMETHODIMP
 nsGlobalWindow::GetContent(nsIDOMWindow** aContent)
 {
   ErrorResult rv;
   *aContent = GetContentInternal(rv).take();
@@ -5704,29 +5707,28 @@ nsGlobalWindow::Length()
 
 NS_IMETHODIMP
 nsGlobalWindow::GetLength(uint32_t* aLength)
 {
   *aLength = Length();
   return NS_OK;
 }
 
-already_AddRefed<nsIDOMWindow>
+nsPIDOMWindow*
 nsGlobalWindow::GetChildWindow(const nsAString& aName)
 {
   nsCOMPtr<nsIDocShell> docShell(GetDocShell());
   NS_ENSURE_TRUE(docShell, nullptr);
 
   nsCOMPtr<nsIDocShellTreeItem> child;
   docShell->FindChildWithName(PromiseFlatString(aName).get(),
                               false, true, nullptr, nullptr,
                               getter_AddRefs(child));
 
-  nsCOMPtr<nsIDOMWindow> child_win(do_GetInterface(child));
-  return child_win.forget();
+  return child ? child->GetWindow() : nullptr;
 }
 
 bool
 nsGlobalWindow::DispatchCustomEvent(const char *aEventName)
 {
   bool defaultActionEnabled = true;
   nsContentUtils::DispatchTrustedEvent(mDoc,
                                        GetOuterWindow(),
@@ -5883,17 +5885,17 @@ nsGlobalWindow::SetFullScreenInternal(bo
     return NS_OK;
   }
 
   // SetFullScreen needs to be called on the root window, so get that
   // via the DocShell tree, and if we are not already the root,
   // call SetFullScreen on that window instead.
   nsCOMPtr<nsIDocShellTreeItem> rootItem;
   mDocShell->GetRootTreeItem(getter_AddRefs(rootItem));
-  nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(rootItem);
+  nsCOMPtr<nsPIDOMWindow> window = rootItem ? rootItem->GetWindow() : nullptr;
   if (!window)
     return NS_ERROR_FAILURE;
   if (rootItem != mDocShell)
     return window->SetFullScreenInternal(aFullScreen, aRequireTrust);
 
   // make sure we don't try to set full screen on a non-chrome window,
   // which might happen in embedding world
   if (mDocShell->ItemType() != nsIDocShellTreeItem::typeChrome)
@@ -5967,17 +5969,17 @@ nsGlobalWindow::GetFullScreen(ErrorResul
   FORWARD_TO_OUTER_OR_THROW(GetFullScreen, (aError), aError, false);
 
   // Get the fullscreen value of the root window, to always have the value
   // accurate, even when called from content.
   if (mDocShell) {
     nsCOMPtr<nsIDocShellTreeItem> rootItem;
     mDocShell->GetRootTreeItem(getter_AddRefs(rootItem));
     if (rootItem != mDocShell) {
-      nsCOMPtr<nsIDOMWindow> window = do_GetInterface(rootItem);
+      nsCOMPtr<nsIDOMWindow> window = rootItem->GetWindow();
       if (window) {
         bool fullScreen = false;
         aError = window->GetFullScreen(&fullScreen);
         return fullScreen;
       }
     }
   }
 
@@ -6440,17 +6442,17 @@ nsGlobalWindow::Focus(ErrorResult& aErro
                     (opener == caller &&
                      RevisePopupAbuseLevel(gPopupControlState) < openAbused);
 
   nsCOMPtr<nsIDOMWindow> activeWindow;
   fm->GetActiveWindow(getter_AddRefs(activeWindow));
 
   nsCOMPtr<nsIDocShellTreeItem> rootItem;
   mDocShell->GetRootTreeItem(getter_AddRefs(rootItem));
-  nsCOMPtr<nsIDOMWindow> rootWin = do_GetInterface(rootItem);
+  nsCOMPtr<nsIDOMWindow> rootWin = rootItem ? rootItem->GetWindow() : nullptr;
   bool isActive = (rootWin == activeWindow);
 
   nsCOMPtr<nsIBaseWindow> treeOwnerAsWin = GetTreeOwnerWindow();
   if (treeOwnerAsWin && (canFocus || isActive)) {
     bool isEnabled = true;
     if (NS_SUCCEEDED(treeOwnerAsWin->GetEnabled(&isEnabled)) && !isEnabled) {
       NS_WARNING( "Should not try to set the focus on a disabled window" );
       return;
@@ -6483,17 +6485,18 @@ nsGlobalWindow::Focus(ErrorResult& aErro
   if (lookForPresShell) {
     mDocShell->GetEldestPresShell(getter_AddRefs(presShell));
   }
 
   nsCOMPtr<nsIDocShellTreeItem> parentDsti;
   mDocShell->GetParent(getter_AddRefs(parentDsti));
 
   // set the parent's current focus to the frame containing this window.
-  nsCOMPtr<nsPIDOMWindow> parent = do_GetInterface(parentDsti);
+  nsCOMPtr<nsPIDOMWindow> parent =
+    parentDsti ? parentDsti->GetWindow() : nullptr;
   if (parent) {
     nsCOMPtr<nsIDocument> parentdoc = parent->GetDoc();
     if (!parentdoc) {
       return;
     }
 
     nsIContent* frame = parentdoc->FindContentForSubDocument(mDoc);
     nsCOMPtr<nsIDOMElement> frameElement = do_QueryInterface(frame);
@@ -8414,17 +8417,18 @@ nsGlobalWindow::ReallyCloseWindow()
 
     // but if we're a browser window we could be in some nasty
     // self-destroying cascade that we should mostly ignore
 
     if (mDocShell) {
       nsCOMPtr<nsIBrowserDOMWindow> bwin;
       nsCOMPtr<nsIDocShellTreeItem> rootItem;
       mDocShell->GetRootTreeItem(getter_AddRefs(rootItem));
-      nsCOMPtr<nsIDOMWindow> rootWin(do_GetInterface(rootItem));
+      nsCOMPtr<nsIDOMWindow> rootWin =
+       rootItem ? rootItem->GetWindow() : nullptr;
       nsCOMPtr<nsIDOMChromeWindow> chromeWin(do_QueryInterface(rootWin));
       if (chromeWin)
         chromeWin->GetBrowserDOMWindow(getter_AddRefs(bwin));
 
       if (rootWin) {
         /* Normally we destroy the entire window, but not if
            this DOM window belongs to a tabbed browser and doesn't
            correspond to a tab. This allows a well-behaved tab
@@ -9779,17 +9783,21 @@ nsGlobalWindow::SetKeyboardIndicators(UI
   nsCOMPtr<nsIDocShell> docShell = GetDocShell();
   if (docShell) {
     int32_t childCount = 0;
     docShell->GetChildCount(&childCount);
 
     for (int32_t i = 0; i < childCount; ++i) {
       nsCOMPtr<nsIDocShellTreeItem> childShell;
       docShell->GetChildAt(i, getter_AddRefs(childShell));
-      nsCOMPtr<nsPIDOMWindow> childWindow = do_GetInterface(childShell);
+      if (!childShell) {
+        continue;
+      }
+
+      nsCOMPtr<nsPIDOMWindow> childWindow = childShell->GetWindow();
       if (childWindow) {
         childWindow->SetKeyboardIndicators(aShowAccelerators, aShowFocusRings);
       }
     }
   }
 
   bool newShouldShowFocusRing = ShouldShowFocusRing();
   if (mHasFocus && mFocusedNode &&
@@ -11373,17 +11381,17 @@ nsGlobalWindow::FireDelayedDOMEvents()
     int32_t childCount = 0;
     docShell->GetChildCount(&childCount);
 
     for (int32_t i = 0; i < childCount; ++i) {
       nsCOMPtr<nsIDocShellTreeItem> childShell;
       docShell->GetChildAt(i, getter_AddRefs(childShell));
       NS_ASSERTION(childShell, "null child shell");
 
-      nsCOMPtr<nsPIDOMWindow> pWin = do_GetInterface(childShell);
+      nsCOMPtr<nsPIDOMWindow> pWin = childShell->GetWindow();
       if (pWin) {
         nsGlobalWindow *win =
           static_cast<nsGlobalWindow*>
                      (static_cast<nsPIDOMWindow*>(pWin));
         win->FireDelayedDOMEvents();
       }
     }
   }
@@ -12743,17 +12751,17 @@ nsGlobalWindow::SuspendTimeouts(uint32_t
     int32_t childCount = 0;
     docShell->GetChildCount(&childCount);
 
     for (int32_t i = 0; i < childCount; ++i) {
       nsCOMPtr<nsIDocShellTreeItem> childShell;
       docShell->GetChildAt(i, getter_AddRefs(childShell));
       NS_ASSERTION(childShell, "null child shell");
 
-      nsCOMPtr<nsPIDOMWindow> pWin = do_GetInterface(childShell);
+      nsCOMPtr<nsPIDOMWindow> pWin = childShell->GetWindow();
       if (pWin) {
         nsGlobalWindow *win =
           static_cast<nsGlobalWindow*>
                      (static_cast<nsPIDOMWindow*>(pWin));
         NS_ASSERTION(win->IsOuterWindow(), "Expected outer window");
         nsGlobalWindow* inner = win->GetCurrentInnerWindowInternal();
 
         // This is a bit hackish. Only freeze/suspend windows which are truly our
@@ -12851,17 +12859,17 @@ nsGlobalWindow::ResumeTimeouts(bool aTha
     int32_t childCount = 0;
     docShell->GetChildCount(&childCount);
 
     for (int32_t i = 0; i < childCount; ++i) {
       nsCOMPtr<nsIDocShellTreeItem> childShell;
       docShell->GetChildAt(i, getter_AddRefs(childShell));
       NS_ASSERTION(childShell, "null child shell");
 
-      nsCOMPtr<nsPIDOMWindow> pWin = do_GetInterface(childShell);
+      nsCOMPtr<nsPIDOMWindow> pWin = childShell->GetWindow();
       if (pWin) {
         nsGlobalWindow *win =
           static_cast<nsGlobalWindow*>
                      (static_cast<nsPIDOMWindow*>(pWin));
 
         NS_ASSERTION(win->IsOuterWindow(), "Expected outer window");
         nsGlobalWindow* inner = win->GetCurrentInnerWindowInternal();
 
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -541,17 +541,17 @@ public:
 
   inline nsGlobalWindow* GetScriptableTop()
   {
     nsCOMPtr<nsIDOMWindow> top;
     GetScriptableTop(getter_AddRefs(top));
     return static_cast<nsGlobalWindow *>(top.get());
   }
 
-  already_AddRefed<nsIDOMWindow> GetChildWindow(const nsAString& aName);
+  nsPIDOMWindow* GetChildWindow(const nsAString& aName);
 
   // These return true if we've reached the state in this top level window
   // where we ask the user if further dialogs should be blocked.
   //
   // DialogsAreBeingAbused must be called on the scriptable top inner window.
   //
   // ShouldPromptToBlockDialogs is implemented in terms of
   // DialogsAreBeingAbused, and will get the scriptable top inner window
--- a/dom/base/nsHistory.cpp
+++ b/dom/base/nsHistory.cpp
@@ -148,17 +148,20 @@ nsHistory::Go(int32_t aDelta, ErrorResul
   nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mInnerWindow));
   if (!win || !win->HasActiveDocument()) {
     aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
 
     return;
   }
 
   if (!aDelta) {
-    nsCOMPtr<nsPIDOMWindow> window(do_GetInterface(GetDocShell()));
+    nsCOMPtr<nsPIDOMWindow> window;
+    if (nsIDocShell* docShell = GetDocShell()) {
+      window = docShell->GetWindow();
+    }
 
     if (window && window->IsHandlingResizeEvent()) {
       // history.go(0) (aka location.reload()) was called on a window
       // that is handling a resize event. Sites do this since Netscape
       // 4.x needed it, but we don't, and it's a horrible experience
       // for nothing.  In stead of reloading the page, just clear
       // style data and reflow the page since some sites may use this
       // trick to work around gecko reflow bugs, and this should have
--- a/dom/base/nsLocation.cpp
+++ b/dom/base/nsLocation.cpp
@@ -49,18 +49,20 @@ GetDocumentCharacterSetForURI(const nsAS
     }
   }
 
   return NS_OK;
 }
 
 nsLocation::nsLocation(nsIDocShell *aDocShell)
 {
+  MOZ_ASSERT(aDocShell);
+
   mDocShell = do_GetWeakReference(aDocShell);
-  nsCOMPtr<nsIDOMWindow> outer = do_GetInterface(aDocShell);
+  nsCOMPtr<nsIDOMWindow> outer = aDocShell->GetWindow();
   mOuter = do_GetWeakReference(outer);
 }
 
 nsLocation::~nsLocation()
 {
 }
 
 DOMCI_DATA(Location, nsLocation)
@@ -530,17 +532,18 @@ nsLocation::SetHrefWithBase(const nsAStr
       nsIScriptContext *scriptContext =
         nsJSUtils::GetDynamicScriptContext(cx);
 
       if (scriptContext) {
         if (scriptContext->GetProcessingScriptTag()) {
           // Now check to make sure that the script is running in our window,
           // since we only want to replace if the location is set by a
           // <script> tag in the same window.  See bug 178729.
-          nsCOMPtr<nsIScriptGlobalObject> ourGlobal(do_GetInterface(docShell));
+          nsCOMPtr<nsIScriptGlobalObject> ourGlobal =
+            docShell ? docShell->GetScriptGlobalObject() : nullptr;
           inScriptTag = (ourGlobal == scriptContext->GetGlobalObject());
         }
       }  
     } //cx
 
     return SetURI(newUri, aReplace || inScriptTag);
   }
 
@@ -781,17 +784,17 @@ NS_IMETHODIMP
 nsLocation::Reload(bool aForceget)
 {
   if (!CallerSubsumes())
     return NS_ERROR_DOM_SECURITY_ERR;
 
   nsresult rv;
   nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mDocShell));
   nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(docShell));
-  nsCOMPtr<nsPIDOMWindow> window(do_GetInterface(docShell));
+  nsCOMPtr<nsPIDOMWindow> window = docShell ? docShell->GetWindow() : nullptr;
 
   if (window && window->IsHandlingResizeEvent()) {
     // location.reload() was called on a window that is handling a
     // resize event. Sites do this since Netscape 4.x needed it, but
     // we don't, and it's a horrible experience for nothing. In stead
     // of reloading the page, just clear style data and reflow the
     // page since some sites may use this trick to work around gecko
     // reflow bugs, and this should have the same effect.
@@ -896,17 +899,17 @@ nsLocation::GetSourceBaseURL(JSContext* 
   nsCOMPtr<nsIScriptGlobalObject> sgo = nsJSUtils::GetDynamicScriptGlobal(cx);
   // If this JS context doesn't have an associated DOM window, we effectively
   // have no script entry point stack. This doesn't generally happen with the DOM,
   // but can sometimes happen with extension code in certain IPC configurations.
   // If this happens, try falling back on the current document associated with
   // the docshell. If that fails, just return null and hope that the caller passed
   // an absolute URI.
   if (!sgo && GetDocShell()) {
-    sgo = do_GetInterface(GetDocShell());
+    sgo = GetDocShell()->GetScriptGlobalObject();
   }
   NS_ENSURE_TRUE(sgo, NS_OK);
   nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(sgo);
   NS_ENSURE_TRUE(window, NS_ERROR_UNEXPECTED);
   nsIDocument* doc = window->GetDoc();
   NS_ENSURE_TRUE(doc, NS_OK);
   *sourceURL = doc->GetBaseURI().take();
   return NS_OK;
--- a/dom/base/nsPluginArray.cpp
+++ b/dom/base/nsPluginArray.cpp
@@ -265,17 +265,17 @@ nsPluginArray::Observe(nsISupports *aSub
   }
 
   return NS_OK;
 }
 
 bool
 nsPluginArray::AllowPlugins() const
 {
-  nsCOMPtr<nsIDocShell> docShell = do_GetInterface(mWindow);
+  nsCOMPtr<nsIDocShell> docShell = mWindow ? mWindow->GetDocShell() : nullptr;
 
   return docShell && docShell->PluginsAllowedInCurrentDoc();
 }
 
 static bool
 HasStringPrefix(const nsCString& str, const nsACString& prefix) {
   return str.Compare(prefix.BeginReading(), false, prefix.Length()) == 0;
 }
--- a/dom/browser-element/BrowserElementParent.cpp
+++ b/dom/browser-element/BrowserElementParent.cpp
@@ -278,17 +278,17 @@ BrowserElementParent::OpenWindowInProces
   nsCOMPtr<nsIFrameLoader> frameLoader;
   popupFrameElement->GetFrameLoader(getter_AddRefs(frameLoader));
   NS_ENSURE_TRUE(frameLoader, BrowserElementParent::OPEN_WINDOW_IGNORED);
 
   nsCOMPtr<nsIDocShell> docshell;
   frameLoader->GetDocShell(getter_AddRefs(docshell));
   NS_ENSURE_TRUE(docshell, BrowserElementParent::OPEN_WINDOW_IGNORED);
 
-  nsCOMPtr<nsIDOMWindow> window = do_GetInterface(docshell);
+  nsCOMPtr<nsIDOMWindow> window = docshell->GetWindow();
   window.forget(aReturnWindow);
 
   return !!*aReturnWindow ? opened : BrowserElementParent::OPEN_WINDOW_CANCELLED;
 }
 
 class DispatchAsyncScrollEventRunnable : public nsRunnable
 {
 public:
--- a/dom/events/UIEvent.cpp
+++ b/dom/events/UIEvent.cpp
@@ -10,16 +10,17 @@
 #include "mozilla/Assertions.h"
 #include "mozilla/ContentEvents.h"
 #include "mozilla/EventStateManager.h"
 #include "mozilla/TextEvents.h"
 #include "nsCOMPtr.h"
 #include "nsContentUtils.h"
 #include "nsIContent.h"
 #include "nsIInterfaceRequestorUtils.h"
+#include "nsIDocShell.h"
 #include "nsIDOMWindow.h"
 #include "nsIDOMNode.h"
 #include "nsIFrame.h"
 #include "prtime.h"
 
 namespace mozilla {
 namespace dom {
 
@@ -63,22 +64,20 @@ UIEvent::UIEvent(EventTarget* aOwner,
     default:
       mDetail = 0;
       break;
   }
 
   mView = nullptr;
   if (mPresContext)
   {
-    nsISupports* container = mPresContext->GetContainerWeak();
-    if (container)
+    nsIDocShell* docShell = mPresContext->GetDocShell();
+    if (docShell)
     {
-       nsCOMPtr<nsIDOMWindow> window = do_GetInterface(container);
-       if (window)
-          mView = do_QueryInterface(window);
+       mView = docShell->GetWindow();
     }
   }
 }
 
 // static
 already_AddRefed<UIEvent>
 UIEvent::Constructor(const GlobalObject& aGlobal,
                      const nsAString& aType,
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -1981,17 +1981,17 @@ MediaManager::MediaCaptureWindowStateInt
     // iterate any children of *this* window (iframes, etc)
     nsCOMPtr<nsIDocShell> docShell = piWin->GetDocShell();
     if (docShell) {
       int32_t i, count;
       docShell->GetChildCount(&count);
       for (i = 0; i < count; ++i) {
         nsCOMPtr<nsIDocShellTreeItem> item;
         docShell->GetChildAt(i, getter_AddRefs(item));
-        nsCOMPtr<nsPIDOMWindow> win = do_GetInterface(item);
+        nsCOMPtr<nsPIDOMWindow> win = item ? item->GetWindow() : nullptr;
 
         MediaCaptureWindowStateInternal(win, aVideo, aAudio);
         if (*aAudio && *aVideo) {
           return NS_OK; // no need to continue iterating
         }
       }
     }
   }
--- a/dom/smil/TimeEvent.cpp
+++ b/dom/smil/TimeEvent.cpp
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/TimeEvent.h"
 #include "mozilla/BasicEvents.h"
+#include "nsIDocShell.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsPresContext.h"
 
 namespace mozilla {
 namespace dom {
 
 TimeEvent::TimeEvent(EventTarget* aOwner,
                      nsPresContext* aPresContext,
@@ -29,22 +30,19 @@ TimeEvent::TimeEvent(EventTarget* aOwner
   if (mEvent->eventStructType == NS_SMIL_TIME_EVENT) {
     mDetail = mEvent->AsUIEvent()->detail;
   }
 
   mEvent->mFlags.mBubbles = false;
   mEvent->mFlags.mCancelable = false;
 
   if (mPresContext) {
-    nsISupports* container = mPresContext->GetContainerWeak();
-    if (container) {
-      nsCOMPtr<nsIDOMWindow> window = do_GetInterface(container);
-      if (window) {
-        mView = do_QueryInterface(window);
-      }
+    nsCOMPtr<nsIDocShell> docShell = mPresContext->GetDocShell();
+    if (docShell) {
+      mView = docShell->GetWindow();
     }
   }
 }
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED(TimeEvent, Event,
                                    mView)
 
 NS_IMPL_ADDREF_INHERITED(TimeEvent, Event)
--- a/embedding/browser/webBrowser/nsWebBrowser.cpp
+++ b/embedding/browser/webBrowser/nsWebBrowser.cpp
@@ -358,23 +358,19 @@ NS_IMETHODIMP nsWebBrowser::SetParentURI
    if (listener)
        return listener->SetParentContentListener(aParentContentListener);
    return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP nsWebBrowser::GetContentDOMWindow(nsIDOMWindow **_retval)
 {
     NS_ENSURE_STATE(mDocShell);
-    nsresult rv = NS_OK;
-    nsCOMPtr<nsIDOMWindow> retval = do_GetInterface(mDocShell, &rv);
-    if (NS_FAILED(rv)) return rv;
-
-    *_retval = retval;
-    NS_ADDREF(*_retval);
-    return rv;
+    nsCOMPtr<nsIDOMWindow> retval = mDocShell->GetWindow();
+    retval.forget(_retval);
+    return *_retval ? NS_OK : NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP nsWebBrowser::GetIsActive(bool *rv)
 {
   *rv = mIsActive;
   return NS_OK;
 }
 
@@ -507,16 +503,28 @@ NS_IMETHODIMP nsWebBrowser::FindItemWith
    NS_ENSURE_STATE(mDocShell);
    NS_ASSERTION(mDocShellTreeOwner, "This should always be set when in this situation");
 
    return mDocShell->FindItemWithName(aName, 
       static_cast<nsIDocShellTreeOwner*>(mDocShellTreeOwner),
       aOriginalRequestor, _retval);
 }
 
+nsIDocument*
+nsWebBrowser::GetDocument()
+{
+  return mDocShell ? mDocShell->GetDocument() : nullptr;
+}
+
+nsPIDOMWindow*
+nsWebBrowser::GetWindow()
+{
+  return mDocShell ? mDocShell->GetWindow() : nullptr;
+}
+
 NS_IMETHODIMP nsWebBrowser::GetTreeOwner(nsIDocShellTreeOwner** aTreeOwner)
 {  
     NS_ENSURE_ARG_POINTER(aTreeOwner);
     *aTreeOwner = nullptr;
     if(mDocShellTreeOwner)
     {
         if (mDocShellTreeOwner->mTreeOwner)
         {
@@ -1477,17 +1485,17 @@ NS_IMETHODIMP nsWebBrowser::GetMainWidge
 
    NS_IF_ADDREF(*mainWidget);
 
    return NS_OK;
 }
 
 NS_IMETHODIMP nsWebBrowser::SetFocus()
 {
-  nsCOMPtr<nsIDOMWindow> window = do_GetInterface(mDocShell);
+  nsCOMPtr<nsIDOMWindow> window = GetWindow();
   NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
 
   nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
   return fm ? fm->SetFocusedWindow(window) : NS_OK;
 }
 
 NS_IMETHODIMP nsWebBrowser::GetTitle(char16_t** aTitle)
 {
@@ -1642,31 +1650,31 @@ static void DrawThebesLayer(ThebesLayer*
   nsIntRect dirtyRect = aRegionToDraw.GetBounds();
   aContext->Rectangle(gfxRect(dirtyRect.x, dirtyRect.y, dirtyRect.width, dirtyRect.height));
   aContext->Fill();  
 }
 
 void nsWebBrowser::WindowRaised(nsIWidget* aWidget)
 {
 #if defined(DEBUG_smaug)
-  nsCOMPtr<nsIDOMDocument> domDocument = do_GetInterface(mDocShell);
+  nsCOMPtr<nsIDocument> document = mDocShell->GetDocument();
   nsAutoString documentURI;
-  domDocument->GetDocumentURI(documentURI);
+  document->GetDocumentURI(documentURI);
   printf("nsWebBrowser::NS_ACTIVATE %p %s\n", (void*)this,
          NS_ConvertUTF16toUTF8(documentURI).get());
 #endif
   Activate();
 }
 
 void nsWebBrowser::WindowLowered(nsIWidget* aWidget)
 {
 #if defined(DEBUG_smaug)
-  nsCOMPtr<nsIDOMDocument> domDocument = do_GetInterface(mDocShell);
+  nsCOMPtr<nsIDocument> document = mDocShell->GetDocument();
   nsAutoString documentURI;
-  domDocument->GetDocumentURI(documentURI);
+  document->GetDocumentURI(documentURI);
   printf("nsWebBrowser::NS_DEACTIVATE %p %s\n", (void*)this,
          NS_ConvertUTF16toUTF8(documentURI).get());
 #endif
   Deactivate();
 }
 
 bool nsWebBrowser::PaintWindow(nsIWidget* aWidget, nsIntRegion aRegion)
 {
@@ -1693,43 +1701,43 @@ NS_IMETHODIMP nsWebBrowser::GetPrimaryCo
   NS_ENSURE_TRUE(mDocShellTreeOwner, NS_ERROR_FAILURE);
   mDocShellTreeOwner->GetPrimaryContentShell(getter_AddRefs(item));
   NS_ENSURE_TRUE(item, NS_ERROR_FAILURE);
 
   nsCOMPtr<nsIDocShell> docShell;
   docShell = do_QueryInterface(item);
   NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
   
-  nsCOMPtr<nsIDOMWindow> domWindow = do_GetInterface(docShell);
+  nsCOMPtr<nsIDOMWindow> domWindow = docShell->GetWindow();
   NS_ENSURE_TRUE(domWindow, NS_ERROR_FAILURE);
 
   *aDOMWindow = domWindow;
   NS_ADDREF(*aDOMWindow);
   return NS_OK;
   
 }
 //*****************************************************************************
 // nsWebBrowser::nsIWebBrowserFocus
 //*****************************************************************************   
 
 /* void activate (); */
 NS_IMETHODIMP nsWebBrowser::Activate(void)
 {
   nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
-  nsCOMPtr<nsIDOMWindow> window = do_GetInterface(mDocShell);
+  nsCOMPtr<nsIDOMWindow> window = GetWindow();
   if (fm && window)
     return fm->WindowRaised(window);
   return NS_OK;
 }
 
 /* void deactivate (); */
 NS_IMETHODIMP nsWebBrowser::Deactivate(void)
 {
   nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
-  nsCOMPtr<nsIDOMWindow> window = do_GetInterface(mDocShell);
+  nsCOMPtr<nsIDOMWindow> window = GetWindow();
   if (fm && window)
     return fm->WindowLowered(window);
   return NS_OK;
 }
 
 /* void setFocusAtFirstElement (); */
 NS_IMETHODIMP nsWebBrowser::SetFocusAtFirstElement(void)
 {
@@ -1743,17 +1751,19 @@ NS_IMETHODIMP nsWebBrowser::SetFocusAtLa
 }
 
 /* attribute nsIDOMWindow focusedWindow; */
 NS_IMETHODIMP nsWebBrowser::GetFocusedWindow(nsIDOMWindow * *aFocusedWindow)
 {
   NS_ENSURE_ARG_POINTER(aFocusedWindow);
   *aFocusedWindow = nullptr;
 
-  nsCOMPtr<nsIDOMWindow> window = do_GetInterface(mDocShell);
+  NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);
+
+  nsCOMPtr<nsIDOMWindow> window = mDocShell->GetWindow();
   NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
 
   nsCOMPtr<nsIDOMElement> focusedElement;
   nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
   return fm ? fm->GetFocusedElementForWindow(window, true, aFocusedWindow,
                                              getter_AddRefs(focusedElement)) : NS_OK;
 }
 
@@ -1762,18 +1772,19 @@ NS_IMETHODIMP nsWebBrowser::SetFocusedWi
   nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
   return fm ? fm->SetFocusedWindow(aFocusedWindow) : NS_OK;
 }
 
 /* attribute nsIDOMElement focusedElement; */
 NS_IMETHODIMP nsWebBrowser::GetFocusedElement(nsIDOMElement * *aFocusedElement)
 {
   NS_ENSURE_ARG_POINTER(aFocusedElement);
+  NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);
 
-  nsCOMPtr<nsIDOMWindow> window = do_GetInterface(mDocShell);
+  nsCOMPtr<nsIDOMWindow> window = mDocShell->GetWindow();
   NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
 
   nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
   return fm ? fm->GetFocusedElementForWindow(window, true, nullptr, aFocusedElement) : NS_OK;
 }
 
 NS_IMETHODIMP nsWebBrowser::SetFocusedElement(nsIDOMElement * aFocusedElement)
 {
--- a/embedding/components/find/src/nsWebBrowserFind.cpp
+++ b/embedding/components/find/src/nsWebBrowserFind.cpp
@@ -151,18 +151,20 @@ NS_IMETHODIMP nsWebBrowserFind::FindNext
         nsCOMPtr<nsISupports> curSupports;
         rv = docShellEnumerator->GetNext(getter_AddRefs(curSupports));
         if (NS_FAILED(rv)) break;
         curItem = do_QueryInterface(curSupports, &rv);
         if (NS_FAILED(rv)) break;
 
         if (doFind)
         {
-            searchFrame = do_GetInterface(curItem, &rv);
-            if (NS_FAILED(rv)) break;
+            searchFrame = curItem->GetWindow();
+            if (!searchFrame) {
+              break;
+            }
 
             OnStartSearchFrame(searchFrame);
 
             // Beware! This may flush notifications via synchronous
             // ScrollSelectionIntoView.
             rv = SearchInFrame(searchFrame, false, outDidFind);
             if (NS_FAILED(rv)) return rv;
             if (*outDidFind)
@@ -196,18 +198,21 @@ NS_IMETHODIMP nsWebBrowserFind::FindNext
     while (NS_SUCCEEDED(docShellEnumerator->HasMoreElements(&hasMore)) && hasMore)
     {
         nsCOMPtr<nsISupports> curSupports;
         rv = docShellEnumerator->GetNext(getter_AddRefs(curSupports));
         if (NS_FAILED(rv)) break;
         curItem = do_QueryInterface(curSupports, &rv);
         if (NS_FAILED(rv)) break;
 
-        searchFrame = do_GetInterface(curItem, &rv);
-        if (NS_FAILED(rv)) break;
+        searchFrame = curItem->GetWindow();
+        if (!searchFrame) {
+          rv = NS_ERROR_FAILURE;
+          break;
+        }
 
         if (curItem.get() == startingItem.get())
         {
             // Beware! This may flush notifications via synchronous
             // ScrollSelectionIntoView.
             rv = SearchInFrame(searchFrame, true, outDidFind);
             if (NS_FAILED(rv)) return rv;
             if (*outDidFind)
--- a/embedding/components/windowwatcher/src/nsWindowWatcher.cpp
+++ b/embedding/components/windowwatcher/src/nsWindowWatcher.cpp
@@ -796,20 +796,18 @@ nsWindowWatcher::OpenWindowInternal(nsID
 
   if (windowIsNew) {
     // Now set the opener principal on the new window.  Note that we need to do
     // this no matter whether we were opened from JS; if there is nothing on
     // the JS stack, just use the principal of our parent window.  In those
     // cases we do _not_ set the parent window principal as the owner of the
     // load--since we really don't know who the owner is, just leave it null.
     nsCOMPtr<nsPIDOMWindow> newWindow = do_QueryInterface(*_retval);
-#ifdef DEBUG
-    nsCOMPtr<nsPIDOMWindow> newDebugWindow = do_GetInterface(newDocShell);
-    NS_ASSERTION(newWindow == newDebugWindow, "Different windows??");
-#endif
+    NS_ASSERTION(newWindow == newDocShell->GetWindow(), "Different windows??");
+
     // The principal of the initial about:blank document gets set up in
     // nsWindowWatcher::AddWindow. Make sure to call it. In the common case
     // this call already happened when the window was created, but
     // SetInitialPrincipalToSubject is safe to call multiple times.
     if (newWindow) {
       newWindow->SetInitialPrincipalToSubject();
     }
   }
@@ -1307,18 +1305,20 @@ nsWindowWatcher::GetWindowByName(const c
     startItem->FindItemWithName(aTargetName, nullptr, nullptr,
                                 getter_AddRefs(treeItem));
   }
   else {
     // Note: original requestor is null here, per idl comments
     FindItemWithName(aTargetName, nullptr, nullptr, getter_AddRefs(treeItem));
   }
 
-  nsCOMPtr<nsIDOMWindow> domWindow = do_GetInterface(treeItem);
-  domWindow.swap(*aResult);
+  if (treeItem) {
+    nsCOMPtr<nsIDOMWindow> domWindow = treeItem->GetWindow();
+    domWindow.forget(aResult);
+  }
 
   return NS_OK;
 }
 
 bool
 nsWindowWatcher::AddEnumerator(nsWatcherWindowEnumerator* inEnumerator)
 {
   // (requires a lock; assumes it's called by someone holding the lock)
@@ -1729,17 +1729,17 @@ nsWindowWatcher::GetCallerTreeItem(nsIDo
 
   if (!callerItem) {
     callerItem = aParentItem;
   }
 
   return callerItem.forget();
 }
 
-already_AddRefed<nsIDOMWindow>
+nsPIDOMWindow*
 nsWindowWatcher::SafeGetWindowByName(const nsAString& aName,
                                      nsIDOMWindow* aCurrentWindow)
 {
   nsCOMPtr<nsIDocShellTreeItem> startItem;
   GetWindowTreeItem(aCurrentWindow, getter_AddRefs(startItem));
 
   nsCOMPtr<nsIDocShellTreeItem> callerItem = GetCallerTreeItem(startItem);
 
@@ -1750,35 +1750,36 @@ nsWindowWatcher::SafeGetWindowByName(con
     startItem->FindItemWithName(flatName.get(), nullptr, callerItem,
                                 getter_AddRefs(foundItem));
   }
   else {
     FindItemWithName(flatName.get(), nullptr, callerItem,
                      getter_AddRefs(foundItem));
   }
 
-  nsCOMPtr<nsIDOMWindow> foundWin = do_GetInterface(foundItem);
-  return foundWin.forget();
+  return foundItem ? foundItem->GetWindow() : nullptr;
 }
 
 /* Fetch the nsIDOMWindow corresponding to the given nsIDocShellTreeItem.
    This forces the creation of a script context, if one has not already
    been created. Note it also sets the window's opener to the parent,
    if applicable -- because it's just convenient, that's all. null aParent
    is acceptable. */
 nsresult
 nsWindowWatcher::ReadyOpenedDocShellItem(nsIDocShellTreeItem *aOpenedItem,
                                          nsIDOMWindow        *aParent,
                                          bool                aWindowIsNew,
                                          nsIDOMWindow        **aOpenedWindow)
 {
   nsresult rv = NS_ERROR_FAILURE;
 
+  NS_ENSURE_ARG(aOpenedWindow);
+
   *aOpenedWindow = 0;
-  nsCOMPtr<nsPIDOMWindow> piOpenedWindow(do_GetInterface(aOpenedItem));
+  nsCOMPtr<nsPIDOMWindow> piOpenedWindow = aOpenedItem->GetWindow();
   if (piOpenedWindow) {
     if (aParent) {
       piOpenedWindow->SetOpenerWindow(aParent, aWindowIsNew); // damnit
 
       if (aWindowIsNew) {
 #ifdef DEBUG
         // Assert that we're not loading things right now.  If we are, when
         // that load completes it will clobber whatever principals we set up
--- a/embedding/components/windowwatcher/src/nsWindowWatcher.h
+++ b/embedding/components/windowwatcher/src/nsWindowWatcher.h
@@ -17,16 +17,17 @@
 #include "nsIPromptFactory.h"
 #include "nsPIWindowWatcher.h"
 #include "nsTArray.h"
 #include "js/TypeDecls.h"
 
 class  nsIURI;
 class  nsIDocShellTreeItem;
 class  nsIDocShellTreeOwner;
+class nsPIDOMWindow;
 class  nsIWebBrowserChrome;
 class  nsString;
 class  nsWatcherWindowEnumerator;
 class  nsIScriptContext;
 class  nsPromptService;
 struct nsWatcherWindowEntry;
 struct SizeSpec;
 
@@ -59,17 +60,17 @@ protected:
 
   // Get the caller tree item.  Look on the JS stack, then fall back
   // to the parent if there's nothing there.
   already_AddRefed<nsIDocShellTreeItem>
     GetCallerTreeItem(nsIDocShellTreeItem* aParentItem);
   
   // Unlike GetWindowByName this will look for a caller on the JS
   // stack, and then fall back on aCurrentWindow if it can't find one.
-  already_AddRefed<nsIDOMWindow>
+  nsPIDOMWindow*
     SafeGetWindowByName(const nsAString& aName, nsIDOMWindow* aCurrentWindow);
 
   // Just like OpenWindowJS, but knows whether it got called via OpenWindowJS
   // (which means called from script) or called via OpenWindow.
   nsresult OpenWindowInternal(nsIDOMWindow *aParent,
                               const char *aUrl,
                               const char *aName,
                               const char *aFeatures,
--- a/layout/base/nsDocumentViewer.cpp
+++ b/layout/base/nsDocumentViewer.cpp
@@ -561,29 +561,33 @@ nsDocumentViewer::LoadStart(nsIDocument*
   if (!mDocument) {
     mDocument = aDocument;
   }
 }
 
 nsresult
 nsDocumentViewer::SyncParentSubDocMap()
 {
-  nsCOMPtr<nsIDocShellTreeItem> item(mContainer);
-  nsCOMPtr<nsPIDOMWindow> pwin(do_GetInterface(item));
+  nsCOMPtr<nsIDocShell> docShell(mContainer);
+  if (!docShell) {
+    return NS_OK;
+  }
+
+  nsCOMPtr<nsPIDOMWindow> pwin(docShell->GetWindow());
   nsCOMPtr<nsIContent> content;
 
   if (mDocument && pwin) {
     content = do_QueryInterface(pwin->GetFrameElementInternal());
   }
 
   if (content) {
     nsCOMPtr<nsIDocShellTreeItem> parent;
-    item->GetParent(getter_AddRefs(parent));
-
-    nsCOMPtr<nsIDOMWindow> parent_win(do_GetInterface(parent));
+    docShell->GetParent(getter_AddRefs(parent));
+
+    nsCOMPtr<nsIDOMWindow> parent_win = parent ? parent->GetWindow() : nullptr;
 
     if (parent_win) {
       nsCOMPtr<nsIDOMDocument> dom_doc;
       parent_win->GetDocument(getter_AddRefs(dom_doc));
 
       nsCOMPtr<nsIDocument> parent_doc(do_QueryInterface(dom_doc));
 
       if (parent_doc) {
@@ -1790,17 +1794,17 @@ nsDocumentViewer::SetDocumentInternal(ns
       mDocument->Destroy();
     }
     // Replace the old document with the new one. Do this only when
     // the new document really is a new document.
     mDocument = aDocument;
 
     // Set the script global object on the new document
     nsCOMPtr<nsPIDOMWindow> window =
-      do_GetInterface(static_cast<nsIDocShell*>(mContainer.get()));
+      mContainer ? mContainer->GetWindow() : nullptr;
     if (window) {
       window->SetNewDocument(aDocument, nullptr, aForceReuseInnerWindow);
     }
 
     // Clear the list of old child docshells. Child docshells for the new
     // document will be constructed as frames are created.
     if (!aDocument->IsStaticDocument()) {
       nsCOMPtr<nsIDocShell> node(mContainer);
@@ -2448,31 +2452,29 @@ nsDocumentViewer::DetachFromTopLevelWidg
 }
 
 nsView*
 nsDocumentViewer::FindContainerView()
 {
   nsView* containerView = nullptr;
 
   if (mContainer) {
-    nsCOMPtr<nsIDocShellTreeItem> docShellItem(mContainer);
-    nsCOMPtr<nsPIDOMWindow> pwin(do_GetInterface(docShellItem));
+    nsCOMPtr<nsIDocShell> docShell(mContainer);
+    nsCOMPtr<nsPIDOMWindow> pwin(docShell->GetWindow());
     if (pwin) {
       nsCOMPtr<nsIContent> containerElement = do_QueryInterface(pwin->GetFrameElementInternal());
       if (!containerElement) {
         return nullptr;
       }
       nsCOMPtr<nsIPresShell> parentPresShell;
-      if (docShellItem) {
-        nsCOMPtr<nsIDocShellTreeItem> parentDocShellItem;
-        docShellItem->GetParent(getter_AddRefs(parentDocShellItem));
-        if (parentDocShellItem) {
-          nsCOMPtr<nsIDocShell> parentDocShell = do_QueryInterface(parentDocShellItem);
-          parentPresShell = parentDocShell->GetPresShell();
-        }
+      nsCOMPtr<nsIDocShellTreeItem> parentDocShellItem;
+      docShell->GetParent(getter_AddRefs(parentDocShellItem));
+      if (parentDocShellItem) {
+        nsCOMPtr<nsIDocShell> parentDocShell = do_QueryInterface(parentDocShellItem);
+        parentPresShell = parentDocShell->GetPresShell();
       }
       if (!parentPresShell) {
         nsCOMPtr<nsIDocument> parentDoc = containerElement->GetCurrentDoc();
         if (parentDoc) {
           parentPresShell = parentDoc->GetShell();
         }
       }
       if (!parentPresShell) {
@@ -4325,20 +4327,21 @@ nsDocumentViewer::OnDonePrinting()
     } else {
       mPrintEngine = nullptr;
       pe->Destroy();
     }
 
     // We are done printing, now cleanup 
     if (mDeferredWindowClose) {
       mDeferredWindowClose = false;
-      nsCOMPtr<nsIDOMWindow> win =
-        do_GetInterface(static_cast<nsIDocShell*>(mContainer));
-      if (win)
-        win->Close();
+      if (mContainer) {
+        nsCOMPtr<nsIDOMWindow> win = mContainer->GetWindow();
+        if (win)
+          win->Close();
+      }
     } else if (mClosingWhilePrinting) {
       if (mDocument) {
         mDocument->SetScriptGlobalObject(nullptr);
         mDocument->Destroy();
         mDocument = nullptr;
       }
       mClosingWhilePrinting = false;
     }
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -5387,17 +5387,17 @@ nsLayoutUtils::GetDeviceContextForScreen
   }
 
   nsCOMPtr<nsIDocShell> docShell = aWindow->GetDocShell();
   while (docShell) {
     // Now make sure our size is up to date.  That will mean that the device
     // context does the right thing on multi-monitor systems when we return it to
     // the caller.  It will also make sure that our prescontext has been created,
     // if we're supposed to have one.
-    nsCOMPtr<nsPIDOMWindow> win = do_GetInterface(docShell);
+    nsCOMPtr<nsPIDOMWindow> win = docShell->GetWindow();
     if (!win) {
       // No reason to go on
       return nullptr;
     }
 
     win->EnsureSizeUpToDate();
 
     nsRefPtr<nsPresContext> presContext;
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -1637,17 +1637,21 @@ bool
 nsPresContext::IsTopLevelWindowInactive()
 {
   nsCOMPtr<nsIDocShellTreeItem> treeItem(mContainer);
   if (!treeItem)
     return false;
 
   nsCOMPtr<nsIDocShellTreeItem> rootItem;
   treeItem->GetRootTreeItem(getter_AddRefs(rootItem));
-  nsCOMPtr<nsPIDOMWindow> domWindow(do_GetInterface(rootItem));
+  if (!rootItem) {
+    return false;
+  }
+
+  nsCOMPtr<nsPIDOMWindow> domWindow = rootItem->GetWindow();
 
   return domWindow && !domWindow->IsActive();
 }
 
 nsITheme*
 nsPresContext::GetTheme()
 {
   if (!sNoTheme && !mTheme) {
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -5146,18 +5146,22 @@ PresShell::AddCanvasBackgroundColorItem(
   }
 
   aList.AppendNewToBottom(
     new (&aBuilder) nsDisplaySolidColor(&aBuilder, aFrame, aBounds, bgcolor));
 }
 
 static bool IsTransparentContainerElement(nsPresContext* aPresContext)
 {
-  nsCOMPtr<nsIDocShellTreeItem> docShellItem = aPresContext->GetDocShell();
-  nsCOMPtr<nsPIDOMWindow> pwin(do_GetInterface(docShellItem));
+  nsCOMPtr<nsIDocShell> docShell = aPresContext->GetDocShell();
+  if (!docShell) {
+    return false;
+  }
+
+  nsCOMPtr<nsPIDOMWindow> pwin = docShell->GetWindow();
   if (!pwin)
     return false;
   nsCOMPtr<nsIContent> containerElement =
     do_QueryInterface(pwin->GetFrameElementInternal());
   return containerElement &&
          containerElement->HasAttr(kNameSpaceID_None, nsGkAtoms::transparent);
 }
 
@@ -7062,18 +7066,21 @@ PresShell::GetTouchEventTargetDocument()
   if (!owner) {
     return nullptr;
   }
 
   // now get the primary content shell (active tab)
   nsCOMPtr<nsIDocShellTreeItem> item;
   owner->GetPrimaryContentShell(getter_AddRefs(item));
   nsCOMPtr<nsIDocShell> childDocShell = do_QueryInterface(item);
-  nsCOMPtr<nsIDocument> result = do_GetInterface(childDocShell);
-  return result;
+  if (!childDocShell) {
+    return nullptr;
+  }
+
+  return childDocShell->GetDocument();
 }
 #endif
 
 #ifdef DEBUG
 void
 PresShell::ShowEventTargetDebug()
 {
   if (nsFrame::GetShowEventTargetFrameBorder() &&
--- a/layout/printing/nsPrintEngine.cpp
+++ b/layout/printing/nsPrintEngine.cpp
@@ -338,17 +338,21 @@ nsPrintEngine::Cancelled()
 // some events from being processed while in PrintPreview 
 //
 // No return code - if this fails, there isn't much we can do
 void
 nsPrintEngine::InstallPrintPreviewListener()
 {
   if (!mPrt->mPPEventListeners) {
     nsCOMPtr<nsIDocShell> docShell = do_QueryReferent(mContainer);
-    nsCOMPtr<nsPIDOMWindow> win(do_GetInterface(docShell));
+    if (!docShell) {
+      return;
+    }
+
+    nsCOMPtr<nsPIDOMWindow> win(docShell->GetWindow());
     if (win) {
       nsCOMPtr<EventTarget> target = do_QueryInterface(win->GetFrameElementInternal());
       mPrt->mPPEventListeners = new nsPrintPreviewListener(target);
       mPrt->mPPEventListeners->AddListeners();
     }
   }
 }
 
@@ -1136,18 +1140,17 @@ nsPrintEngine::IsParentAFrameSet(nsIDocS
   // XXX we really need to search the frame tree, and not the content
   // but there is no way to distinguish between IFRAMEs and FRAMEs
   // with the GetFrameType call.
   // Bug 53459 has been files so we can eventually distinguish
   // between IFRAME frames and FRAME frames
   bool isFrameSet = false;
   // only check to see if there is a frameset if there is
   // NO parent doc for this doc. meaning this parent is the root doc
-  nsCOMPtr<nsIDOMDocument> domDoc = do_GetInterface(aParent);
-  nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
+  nsCOMPtr<nsIDocument> doc = aParent->GetDocument();
   if (doc) {
     nsIContent *rootElement = doc->GetRootElement();
     if (rootElement) {
       isFrameSet = HasFramesetChild(rootElement);
     }
   }
   return isFrameSet;
 }
@@ -1387,17 +1390,18 @@ nsPrintEngine::IsThereAnIFrameSelected(n
     // First, check to see if we are a frameset
     if (!aIsParentFrameSet) {
       // Check to see if there is a currenlt focused frame
       // if so, it means the selected frame is either the main docshell
       // or an IFRAME
       if (aDOMWin) {
         // Get the main docshell's DOMWin to see if it matches 
         // the frame that is selected
-        nsCOMPtr<nsIDOMWindow> domWin = do_GetInterface(aDocShell);
+        nsCOMPtr<nsIDOMWindow> domWin =
+         aDocShell ? aDocShell->GetWindow() : nullptr;
         if (domWin != aDOMWin) {
           iFrameIsSelected = true; // we have a selected IFRAME
         }
       }
     }
   }
 
   return iFrameIsSelected;
@@ -3295,17 +3299,17 @@ nsPrintEngine::EnablePOsForPrinting()
           PR_PL(("HowToEnableFrameUI: %s \n", gFrameHowToEnableStr[printHowEnable]));
           PR_PL(("PrintRange:         %s \n", gPrintRangeStr[printRangeType]));
           return NS_OK;
         }
       } else {
         for (uint32_t i=0;i<mPrt->mPrintDocList.Length();i++) {
           nsPrintObject* po = mPrt->mPrintDocList.ElementAt(i);
           NS_ASSERTION(po, "nsPrintObject can't be null!");
-          nsCOMPtr<nsIDOMWindow> domWin = do_GetInterface(po->mDocShell);
+          nsCOMPtr<nsIDOMWindow> domWin = po->mDocShell->GetWindow();
           if (IsThereARangeSelection(domWin)) {
             mPrt->mCurrentFocusWin = domWin;
             SetPrintPO(po, true);
             break;
           }
         }
         return NS_OK;
       }
--- a/layout/svg/nsSVGOuterSVGFrame.cpp
+++ b/layout/svg/nsSVGOuterSVGFrame.cpp
@@ -846,18 +846,22 @@ nsSVGOuterSVGFrame::GetCanvasTM(uint32_t
 //----------------------------------------------------------------------
 // Implementation helpers
 
 bool
 nsSVGOuterSVGFrame::IsRootOfReplacedElementSubDoc(nsIFrame **aEmbeddingFrame)
 {
   if (!mContent->GetParent()) {
     // Our content is the document element
-    nsCOMPtr<nsISupports> container = PresContext()->GetContainerWeak();
-    nsCOMPtr<nsIDOMWindow> window = do_GetInterface(container);
+    nsCOMPtr<nsIDocShell> docShell = PresContext()->GetDocShell();
+    nsCOMPtr<nsIDOMWindow> window;
+    if (docShell) {
+      window = docShell->GetWindow();
+    }
+
     if (window) {
       nsCOMPtr<nsIDOMElement> frameElement;
       window->GetFrameElement(getter_AddRefs(frameElement));
       nsCOMPtr<nsIObjectLoadingContent> olc = do_QueryInterface(frameElement);
       if (olc) {
         // Our document is inside an HTML 'object', 'embed' or 'applet' element
         if (aEmbeddingFrame) {
           nsCOMPtr<nsIContent> element = do_QueryInterface(frameElement);
--- a/layout/xul/nsXULPopupManager.cpp
+++ b/layout/xul/nsXULPopupManager.cpp
@@ -1567,17 +1567,21 @@ nsXULPopupManager::MayShowPopup(nsMenuPo
     return false;
 
   // chrome shells can always open popups, but other types of shells can only
   // open popups when they are focused and visible
   if (dsti->ItemType() != nsIDocShellTreeItem::typeChrome) {
     // only allow popups in active windows
     nsCOMPtr<nsIDocShellTreeItem> root;
     dsti->GetRootTreeItem(getter_AddRefs(root));
-    nsCOMPtr<nsIDOMWindow> rootWin = do_GetInterface(root);
+    if (!root) {
+      return false;
+    }
+
+    nsCOMPtr<nsIDOMWindow> rootWin = root->GetWindow();
 
     nsIFocusManager* fm = nsFocusManager::GetFocusManager();
     if (!fm || !rootWin)
       return false;
 
     nsCOMPtr<nsIDOMWindow> activeWindow;
     fm->GetActiveWindow(getter_AddRefs(activeWindow));
     if (activeWindow != rootWin)
--- a/toolkit/components/satchel/nsFormFillController.cpp
+++ b/toolkit/components/satchel/nsFormFillController.cpp
@@ -1143,24 +1143,23 @@ nsFormFillController::StopControllingInp
     mFocusedInput = nullptr;
   }
   mFocusedPopup = nullptr;
 }
 
 nsIDocShell *
 nsFormFillController::GetDocShellForInput(nsIDOMHTMLInputElement *aInput)
 {
-  nsCOMPtr<nsIDOMDocument> domDoc;
-  nsCOMPtr<nsIDOMElement> element = do_QueryInterface(aInput);
-  element->GetOwnerDocument(getter_AddRefs(domDoc));
-  nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
-  NS_ENSURE_TRUE(doc, nullptr);
-  nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(doc->GetWindow());
-  nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(webNav);
-  return docShell;
+  nsCOMPtr<nsINode> node = do_QueryInterface(aInput);
+  NS_ENSURE_TRUE(node, nullptr);
+
+  nsCOMPtr<nsPIDOMWindow> win = node->OwnerDoc()->GetWindow();
+  NS_ENSURE_TRUE(win, nullptr);
+
+  return win->GetDocShell();
 }
 
 nsIDOMWindow *
 nsFormFillController::GetWindowForDocShell(nsIDocShell *aDocShell)
 {
   nsCOMPtr<nsIContentViewer> contentViewer;
   aDocShell->GetContentViewer(getter_AddRefs(contentViewer));
   NS_ENSURE_TRUE(contentViewer, nullptr);
--- a/toolkit/xre/nsNativeAppSupportWin.cpp
+++ b/toolkit/xre/nsNativeAppSupportWin.cpp
@@ -1479,17 +1479,18 @@ nsNativeAppSupportWin::OpenBrowserWindow
 
         nsCOMPtr<nsIBrowserDOMWindow> bwin;
         { // scope a bunch of temporary cruft used to generate bwin
           nsCOMPtr<nsIWebNavigation> navNav( do_GetInterface( navWin ) );
           nsCOMPtr<nsIDocShellTreeItem> navItem( do_QueryInterface( navNav ) );
           if ( navItem ) {
             nsCOMPtr<nsIDocShellTreeItem> rootItem;
             navItem->GetRootTreeItem( getter_AddRefs( rootItem ) );
-            nsCOMPtr<nsIDOMWindow> rootWin( do_GetInterface( rootItem ) );
+            nsCOMPtr<nsIDOMWindow> rootWin =
+              rootItem ? rootItem->GetWindow() : nullptr;
             nsCOMPtr<nsIDOMChromeWindow> chromeWin(do_QueryInterface(rootWin));
             if ( chromeWin )
               chromeWin->GetBrowserDOMWindow( getter_AddRefs ( bwin ) );
           }
         }
         if ( bwin ) {
           nsCOMPtr<nsIURI> uri;
           NS_NewURI( getter_AddRefs( uri ), NS_LITERAL_CSTRING("about:blank"), 0, 0 );
--- a/xpfe/appshell/src/nsAppShellService.cpp
+++ b/xpfe/appshell/src/nsAppShellService.cpp
@@ -651,23 +651,21 @@ NS_IMETHODIMP
 nsAppShellService::GetHiddenDOMWindow(nsIDOMWindow **aWindow)
 {
   nsresult rv;
   nsCOMPtr<nsIDocShell> docShell;
   NS_ENSURE_TRUE(mHiddenWindow, NS_ERROR_FAILURE);
 
   rv = mHiddenWindow->GetDocShell(getter_AddRefs(docShell));
   NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCOMPtr<nsIDOMWindow> hiddenDOMWindow(do_GetInterface(docShell, &rv));
-  NS_ENSURE_SUCCESS(rv, rv);
+  NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
 
-  *aWindow = hiddenDOMWindow;
-  NS_IF_ADDREF(*aWindow);
-  return NS_OK;
+  nsCOMPtr<nsIDOMWindow> hiddenDOMWindow(docShell->GetWindow());
+  hiddenDOMWindow.forget(aWindow);
+  return *aWindow ? NS_OK : NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsAppShellService::GetHiddenPrivateWindow(nsIXULWindow **aWindow)
 {
   NS_ENSURE_ARG_POINTER(aWindow);
 
   EnsurePrivateHiddenWindow();
@@ -683,23 +681,21 @@ nsAppShellService::GetHiddenPrivateDOMWi
   EnsurePrivateHiddenWindow();
 
   nsresult rv;
   nsCOMPtr<nsIDocShell> docShell;
   NS_ENSURE_TRUE(mHiddenPrivateWindow, NS_ERROR_FAILURE);
 
   rv = mHiddenPrivateWindow->GetDocShell(getter_AddRefs(docShell));
   NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCOMPtr<nsIDOMWindow> hiddenPrivateDOMWindow(do_GetInterface(docShell, &rv));
-  NS_ENSURE_SUCCESS(rv, rv);
+  NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
 
-  *aWindow = hiddenPrivateDOMWindow;
-  NS_IF_ADDREF(*aWindow);
-  return NS_OK;
+  nsCOMPtr<nsIDOMWindow> hiddenPrivateDOMWindow(docShell->GetWindow());
+  hiddenPrivateDOMWindow.forget(aWindow);
+  return *aWindow ? NS_OK : NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsAppShellService::GetHasHiddenPrivateWindow(bool* aHasPrivateWindow)
 {
   NS_ENSURE_ARG_POINTER(aHasPrivateWindow);
 
   *aHasPrivateWindow = !!mHiddenPrivateWindow;
@@ -717,24 +713,26 @@ nsAppShellService::GetHiddenWindowAndJSC
 
         if ( mHiddenWindow ) {
             // Convert hidden window to nsIDOMWindow and extract its JSContext.
             do {
                 // 1. Get doc for hidden window.
                 nsCOMPtr<nsIDocShell> docShell;
                 rv = mHiddenWindow->GetDocShell(getter_AddRefs(docShell));
                 if (NS_FAILED(rv)) break;
+                if (!docShell) {
+                  break;
+                }
 
                 // 2. Convert that to an nsIDOMWindow.
-                nsCOMPtr<nsIDOMWindow> hiddenDOMWindow(do_GetInterface(docShell));
+                nsCOMPtr<nsIDOMWindow> hiddenDOMWindow(docShell->GetWindow());
                 if(!hiddenDOMWindow) break;
 
                 // 3. Get script global object for the window.
-                nsCOMPtr<nsIScriptGlobalObject> sgo;
-                sgo = do_QueryInterface( hiddenDOMWindow );
+                nsCOMPtr<nsIScriptGlobalObject> sgo = docShell->GetScriptGlobalObject();
                 if (!sgo) { rv = NS_ERROR_FAILURE; break; }
 
                 // 4. Get script context from that.
                 nsIScriptContext *scriptContext = sgo->GetContext();
                 if (!scriptContext) { rv = NS_ERROR_FAILURE; break; }
 
                 // 5. Get JSContext from the script context.
                 JSContext *jsContext = scriptContext->GetNativeContext();
@@ -766,17 +764,19 @@ nsAppShellService::GetApplicationProvide
  */
 NS_IMETHODIMP
 nsAppShellService::RegisterTopLevelWindow(nsIXULWindow* aWindow)
 {
   NS_ENSURE_ARG_POINTER(aWindow);
 
   nsCOMPtr<nsIDocShell> docShell;
   aWindow->GetDocShell(getter_AddRefs(docShell));
-  nsCOMPtr<nsPIDOMWindow> domWindow(do_GetInterface(docShell));
+  NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
+
+  nsCOMPtr<nsPIDOMWindow> domWindow(docShell->GetWindow());
   NS_ENSURE_TRUE(domWindow, NS_ERROR_FAILURE);
   domWindow->SetInitialPrincipalToSubject();
 
   // tell the window mediator about the new window
   nsCOMPtr<nsIWindowMediator> mediator
     ( do_GetService(NS_WINDOWMEDIATOR_CONTRACTID) );
   NS_ASSERTION(mediator, "Couldn't get window mediator.");
 
@@ -838,17 +838,17 @@ nsAppShellService::UnregisterTopLevelWin
 
   // tell the window watcher
   nsCOMPtr<nsPIWindowWatcher> wwatcher ( do_GetService(NS_WINDOWWATCHER_CONTRACTID) );
   NS_ASSERTION(wwatcher, "Couldn't get windowwatcher, doing xpcom shutdown?");
   if (wwatcher) {
     nsCOMPtr<nsIDocShell> docShell;
     aWindow->GetDocShell(getter_AddRefs(docShell));
     if (docShell) {
-      nsCOMPtr<nsIDOMWindow> domWindow(do_GetInterface(docShell));
+      nsCOMPtr<nsIDOMWindow> domWindow(docShell->GetWindow());
       if (domWindow)
         wwatcher->RemoveWindow(domWindow);
     }
   }
 
   return NS_OK;
 }
 
--- a/xpfe/appshell/src/nsContentTreeOwner.cpp
+++ b/xpfe/appshell/src/nsContentTreeOwner.cpp
@@ -749,18 +749,18 @@ NS_IMETHODIMP nsContentTreeOwner::SetTit
       //
       // location bar is turned off, find the browser location
       //
       // use the document's nsPrincipal to find the true owner
       // in case of javascript: or data: documents
       //
       nsCOMPtr<nsIDocShellTreeItem> dsitem;
       GetPrimaryContentShell(getter_AddRefs(dsitem));
-      nsCOMPtr<nsIDOMDocument> domdoc(do_GetInterface(dsitem));
-      nsCOMPtr<nsIScriptObjectPrincipal> doc(do_QueryInterface(domdoc));
+      nsCOMPtr<nsIScriptObjectPrincipal> doc =
+        do_QueryInterface(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
@@ -1073,19 +1073,21 @@ nsSiteWindow::SetFocus(void)
      nsGlobalWindow::Focus (providing a hook for MDI embedding apps)
      and it's better for our purposes to not pick a document and
      focus it, but allow nsGlobalWindow to carry on unhindered.
   */
   nsXULWindow *window = mAggregator->XULWindow();
   if (window) {
     nsCOMPtr<nsIDocShell> docshell;
     window->GetDocShell(getter_AddRefs(docshell));
-    nsCOMPtr<nsIDOMWindow> domWindow(do_GetInterface(docshell));
-    if (domWindow)
-      domWindow->Focus();
+    if (docShell) {
+      nsCOMPtr<nsIDOMWindow> domWindow(docShell->GetWindow());
+      if (domWindow)
+        domWindow->Focus();
+    }
   }
 #endif
   return NS_OK;
 }
 
 /* this implementation focuses another window. if there isn't another
    window to focus, we do nothing. */
 NS_IMETHODIMP
@@ -1135,17 +1137,21 @@ nsSiteWindow::Blur(void)
 
     windowEnumerator->HasMoreElements(&more);
   }
 
   // change focus to the window we just found
   if (xulWindow) {
     nsCOMPtr<nsIDocShell> docshell;
     xulWindow->GetDocShell(getter_AddRefs(docshell));
-    nsCOMPtr<nsIDOMWindow> domWindow(do_GetInterface(docshell));
+    if (!docshell) {
+      return NS_OK;
+    }
+
+    nsCOMPtr<nsIDOMWindow> domWindow(docshell->GetWindow());
     if (domWindow)
       domWindow->Focus();
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSiteWindow::GetVisibility(bool *aVisibility)
--- a/xpfe/appshell/src/nsWebShellWindow.cpp
+++ b/xpfe/appshell/src/nsWebShellWindow.cpp
@@ -207,17 +207,17 @@ nsresult nsWebShellWindow::Initialize(ns
   // Eagerly create an about:blank content viewer with the right principal here,
   // rather than letting it happening in the upcoming call to
   // SetInitialPrincipalToSubject. This avoids creating the about:blank document
   // and then blowing it away with a second one, which can cause problems for the
   // top-level chrome window case. See bug 789773.
   if (nsContentUtils::IsInitialized()) { // Sometimes this happens really early  See bug 793370.
     rv = mDocShell->CreateAboutBlankContentViewer(nsContentUtils::SubjectPrincipal());
     NS_ENSURE_SUCCESS(rv, rv);
-    nsCOMPtr<nsIDocument> doc = do_GetInterface(mDocShell);
+    nsCOMPtr<nsIDocument> doc = mDocShell ? mDocShell->GetDocument() : nullptr;
     NS_ENSURE_TRUE(!!doc, NS_ERROR_FAILURE);
     doc->SetIsInitialDocument(true);
   }
 
   if (nullptr != aUrl)  {
     nsCString tmpStr;
 
     rv = aUrl->GetSpec(tmpStr);
@@ -246,17 +246,18 @@ nsWebShellWindow::GetPresShell()
   return mDocShell->GetPresShell();
 }
 
 bool
 nsWebShellWindow::WindowMoved(nsIWidget* aWidget, int32_t x, int32_t y)
 {
   nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
   if (pm) {
-    nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(mDocShell);
+    nsCOMPtr<nsPIDOMWindow> window =
+      mDocShell ? mDocShell->GetWindow() : nullptr;
     pm->AdjustPopupsOnWindowChange(window);
   }
 
   // Persist position, but not immediately, in case this OS is firing
   // repeated move events as the user drags the window
   SetPersistenceTimer(PAD_POSITION);
   return false;
 }
@@ -276,21 +277,20 @@ nsWebShellWindow::WindowResized(nsIWidge
 }
 
 bool
 nsWebShellWindow::RequestWindowClose(nsIWidget* aWidget)
 {
   // Maintain a reference to this as it is about to get destroyed.
   nsCOMPtr<nsIXULWindow> xulWindow(this);
 
-  nsCOMPtr<nsPIDOMWindow> window(do_GetInterface(mDocShell));
+  nsCOMPtr<nsPIDOMWindow> window(mDocShell ? mDocShell->GetWindow() : nullptr);
   nsCOMPtr<EventTarget> eventTarget = do_QueryInterface(window);
 
   nsCOMPtr<nsIPresShell> presShell = mDocShell->GetPresShell();
-
   if (!presShell) {
     mozilla::DebugOnly<bool> dying;
     MOZ_ASSERT(NS_SUCCEEDED(mDocShell->IsBeingDestroyed(&dying)) && dying,
                "No presShell, but window is not being destroyed");
   } else if (eventTarget) {
     nsRefPtr<nsPresContext> presContext = presShell->GetPresContext();
 
     nsEventStatus status = nsEventStatus_eIgnore;
@@ -319,17 +319,18 @@ nsWebShellWindow::SizeModeChanged(nsSize
       SetZLevel(nsIXULWindow::normalZ);
   }
   mWindow->SetSizeMode(sizeMode);
 
   // Persist mode, but not immediately, because in many (all?)
   // cases this will merge with the similar call in NS_SIZE and
   // write the attribute values only once.
   SetPersistenceTimer(PAD_MISC);
-  nsCOMPtr<nsPIDOMWindow> ourWindow = do_GetInterface(mDocShell);
+  nsCOMPtr<nsPIDOMWindow> ourWindow =
+    mDocShell ? mDocShell->GetWindow() : nullptr;
   if (ourWindow) {
     // Let the application know if it's in fullscreen mode so it
     // can update its UI.
     if (sizeMode == nsSizeMode_Fullscreen) {
       ourWindow->SetFullScreen(true);
     }
     else if (sizeMode != nsSizeMode_Minimized) {
       ourWindow->SetFullScreen(false);
@@ -383,33 +384,34 @@ nsWebShellWindow::ZLevelChanged(bool aIm
 }
 
 void
 nsWebShellWindow::WindowActivated()
 {
   nsCOMPtr<nsIXULWindow> xulWindow(this);
 
   // focusing the window could cause it to close, so keep a reference to it
-  nsCOMPtr<nsIDOMWindow> window = do_GetInterface(mDocShell);
+  nsCOMPtr<nsIDOMWindow> window = mDocShell ? mDocShell->GetWindow() : nullptr;
   nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
   if (fm && window)
     fm->WindowRaised(window);
 
   if (mChromeLoaded) {
     PersistentAttributesDirty(PAD_POSITION | PAD_SIZE | PAD_MISC);
     SavePersistentAttributes();
    }
 }
 
 void
 nsWebShellWindow::WindowDeactivated()
 {
   nsCOMPtr<nsIXULWindow> xulWindow(this);
 
-  nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(mDocShell);
+  nsCOMPtr<nsPIDOMWindow> window =
+    mDocShell ? mDocShell->GetWindow() : nullptr;
   nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
   if (fm && window)
     fm->WindowLowered(window);
 }
 
 #ifdef USE_NATIVE_MENUS
 static void LoadNativeMenus(nsIDOMDocument *aDOMDoc, nsIWidget *aParentWindow)
 {
@@ -666,18 +668,20 @@ bool nsWebShellWindow::ExecuteCloseHandl
 {
   /* If the event handler closes this window -- a likely scenario --
      things get deleted out of order without this death grip.
      (The problem may be the death grip in nsWindow::windowProc,
      which forces this window's widget to remain alive longer
      than it otherwise would.) */
   nsCOMPtr<nsIXULWindow> kungFuDeathGrip(this);
 
-  nsCOMPtr<nsPIDOMWindow> window(do_GetInterface(mDocShell));
-  nsCOMPtr<EventTarget> eventTarget = do_QueryInterface(window);
+  nsCOMPtr<EventTarget> eventTarget;
+  if (mDocShell) {
+    eventTarget = do_QueryInterface(mDocShell->GetWindow());
+  }
 
   if (eventTarget) {
     nsCOMPtr<nsIContentViewer> contentViewer;
     mDocShell->GetContentViewer(getter_AddRefs(contentViewer));
     if (contentViewer) {
       nsRefPtr<nsPresContext> presContext;
       contentViewer->GetPresContext(getter_AddRefs(presContext));
 
--- a/xpfe/appshell/src/nsWindowMediator.cpp
+++ b/xpfe/appshell/src/nsWindowMediator.cpp
@@ -38,18 +38,21 @@ struct WindowTitleData {
 };
 
 nsresult
 nsWindowMediator::GetDOMWindow(nsIXULWindow* inWindow,
                                nsCOMPtr<nsIDOMWindow>& outDOMWindow)
 {
   nsCOMPtr<nsIDocShell> docShell;
 
+  outDOMWindow = nullptr;
   inWindow->GetDocShell(getter_AddRefs(docShell));
-  outDOMWindow = do_GetInterface(docShell);
+  NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
+
+  outDOMWindow = docShell->GetWindow();
   return outDOMWindow ? NS_OK : NS_ERROR_FAILURE;
 }
 
 nsWindowMediator::nsWindowMediator() :
   mEnumeratorList(), mOldestWindow(nullptr), mTopmostWindow(nullptr),
   mTimeStamp(0), mSortingZOrder(false), mReady(false),
   mListLock("nsWindowMediator.mListLock")
 {
--- a/xpfe/appshell/src/nsXULWindow.cpp
+++ b/xpfe/appshell/src/nsXULWindow.cpp
@@ -1542,17 +1542,17 @@ NS_IMETHODIMP nsXULWindow::SavePersisten
   return NS_OK;
 }
 
 NS_IMETHODIMP nsXULWindow::GetWindowDOMWindow(nsIDOMWindow** aDOMWindow)
 {
   NS_ENSURE_STATE(mDocShell);
 
   if (!mDOMWindow)
-    mDOMWindow = do_GetInterface(mDocShell);
+    mDOMWindow = mDocShell->GetWindow();
   NS_ENSURE_TRUE(mDOMWindow, NS_ERROR_FAILURE);
 
   *aDOMWindow = mDOMWindow;
   NS_ADDREF(*aDOMWindow);
   return NS_OK;
 }
 
 dom::Element*