bug 939049 - staticly type nsIDocument::mDocumentContainer and nsDocumentViewerContainer::mContainer r=smaug
authorTrevor Saunders <trev.saunders@gmail.com>
Fri, 15 Nov 2013 02:12:43 -0500
changeset 156382 ad287f78608abe2cd17bad739ba99e322a1bd616
parent 156289 9c5256d1d8a74aefc9c72c8a4452358dbe7cc671
child 156383 babac1cc07414db229df0842376d93e6b03d2f90
push idunknown
push userunknown
push dateunknown
reviewerssmaug
bugs939049
milestone28.0a1
bug 939049 - staticly type nsIDocument::mDocumentContainer and nsDocumentViewerContainer::mContainer r=smaug
content/base/public/nsIDocument.h
content/base/src/moz.build
content/base/src/nsDocument.cpp
content/html/document/src/ImageDocument.cpp
content/html/document/src/moz.build
content/html/document/src/nsHTMLDocument.cpp
content/xul/document/src/XULDocument.cpp
content/xul/document/src/moz.build
docshell/base/nsDocShell.cpp
docshell/base/nsDocShell.h
docshell/base/nsIContentViewer.idl
docshell/base/nsIDocumentLoaderFactory.idl
docshell/shistory/src/nsSHEntryShared.cpp
layout/base/moz.build
layout/base/nsDocumentViewer.cpp
layout/build/moz.build
layout/build/nsContentDLF.cpp
layout/build/nsContentDLF.h
layout/printing/nsPrintEngine.cpp
layout/printing/nsPrintEngine.h
uriloader/prefetch/nsOfflineCacheUpdateService.cpp
xpfe/components/directory/nsDirectoryViewer.cpp
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -15,24 +15,27 @@
 #include "nsIDocumentObserver.h"         // for typedef (nsUpdateType)
 #include "nsILoadGroup.h"                // for member (in nsCOMPtr)
 #include "nsINode.h"                     // for base class
 #include "nsIScriptGlobalObject.h"       // for member (in nsCOMPtr)
 #include "nsPIDOMWindow.h"               // for use in inline functions
 #include "nsPropertyTable.h"             // for member
 #include "nsTHashtable.h"                // for member
 #include "mozilla/dom/DocumentBinding.h"
+#include "mozilla/WeakPtr.h"
 #include "Units.h"
 #include "nsExpirationTracker.h"
 #include "nsClassHashtable.h"
 
 class imgIRequest;
 class nsAString;
 class nsBindingManager;
 class nsCSSStyleSheet;
+class nsIDocShell;
+class nsDocShell;
 class nsDOMNavigationTiming;
 class nsDOMTouchList;
 class nsEventStates;
 class nsFrameLoader;
 class nsHTMLCSSStyleSheet;
 class nsHTMLDocument;
 class nsHTMLStyleSheet;
 class nsIAtom;
@@ -1145,26 +1148,22 @@ public:
    */
   virtual void ResetToURI(nsIURI *aURI, nsILoadGroup* aLoadGroup,
                           nsIPrincipal* aPrincipal) = 0;
 
   /**
    * Set the container (docshell) for this document. Virtual so that
    * docshell can call it.
    */
-  virtual void SetContainer(nsISupports *aContainer);
+  virtual void SetContainer(nsDocShell* aContainer);
 
   /**
    * Get the container (docshell) for this document.
    */
-  already_AddRefed<nsISupports> GetContainer() const
-  {
-    nsCOMPtr<nsISupports> container = do_QueryReferent(mDocumentContainer);
-    return container.forget();
-  }
+  nsISupports* GetContainer() const;
 
   /**
    * Get the container's load context for this document.
    */
   nsILoadContext* GetLoadContext() const;
 
   /**
    * Set and get XML declaration. If aVersion is null there is no declaration.
@@ -1691,17 +1690,17 @@ public:
    */
   bool IsStaticDocument() { return mIsStaticDocument; }
 
   /**
    * Clones the document and subdocuments and stylesheet etc.
    * @param aCloneContainer The container for the clone document.
    */
   virtual already_AddRefed<nsIDocument>
-  CreateStaticClone(nsISupports* aCloneContainer);
+  CreateStaticClone(nsIDocShell* aCloneContainer);
 
   /**
    * If this document is a static clone, this returns the original
    * document.
    */
   nsIDocument* GetOriginalDocument()
   {
     MOZ_ASSERT(!mOriginalDocument || !mOriginalDocument->GetOriginalDocument());
@@ -2222,17 +2221,17 @@ protected:
   nsString mLastModified;
 
   nsCOMPtr<nsIURI> mDocumentURI;
   nsCOMPtr<nsIURI> mOriginalURI;
   nsCOMPtr<nsIURI> mDocumentBaseURI;
 
   nsWeakPtr mDocumentLoadGroup;
 
-  nsWeakPtr mDocumentContainer;
+  mozilla::WeakPtr<nsDocShell> mDocumentContainer;
 
   nsCString mCharacterSet;
   int32_t mCharacterSetSource;
 
   // This is just a weak pointer; the parent document owns its children.
   nsIDocument* mParentDocument;
 
   // A reference to the element last returned from GetRootElement().
--- a/content/base/src/moz.build
+++ b/content/base/src/moz.build
@@ -188,16 +188,17 @@ LOCAL_INCLUDES += [
     '/content/html/content/src',
     '/content/html/document/src',
     '/content/xbl/src',
     '/content/xml/content/src',
     '/content/xml/document/src',
     '/content/xslt/src/xpath',
     '/content/xul/content/src',
     '/content/xul/document/src',
+    '/docshell/base',
     '/dom/base',
     '/dom/ipc',
     '/dom/workers',
     '/image/src',
     '/js/ipc',
     '/js/xpconnect/src',
     '/js/xpconnect/wrappers',
     '/layout/base',
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -28,17 +28,17 @@
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsUnicharUtils.h"
 #include "nsContentList.h"
 #include "nsIObserver.h"
 #include "nsIBaseWindow.h"
 #include "mozilla/css/Loader.h"
 #include "mozilla/css/ImageLoader.h"
-#include "nsIDocShell.h"
+#include "nsDocShell.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsCOMArray.h"
 #include "nsDOMClassInfo.h"
 #include "nsCxPusher.h"
 
 #include "mozilla/BasicEvents.h"
 #include "nsAsyncDOMEvent.h"
 #include "nsIDOMNodeFilter.h"
@@ -2198,17 +2198,17 @@ nsDocument::ResetToURI(nsIURI *aURI, nsI
 
   // Now get our new principal
   if (aPrincipal) {
     SetPrincipal(aPrincipal);
   } else {
     nsIScriptSecurityManager *securityManager =
       nsContentUtils::GetSecurityManager();
     if (securityManager) {
-      nsCOMPtr<nsIDocShell> docShell = do_QueryReferent(mDocumentContainer);
+      nsCOMPtr<nsIDocShell> docShell(mDocumentContainer);
 
       if (!docShell && aLoadGroup) {
         nsCOMPtr<nsIInterfaceRequestor> cbs;
         aLoadGroup->GetNotificationCallbacks(getter_AddRefs(cbs));
         docShell = do_GetInterface(cbs);
       }
 
       MOZ_ASSERT(docShell,
@@ -2694,17 +2694,17 @@ nsDocument::InitCSP(nsIChannel* aChannel
     rv = AppendCSPFromHeader(csp, cspROHeaderValue, selfURI, true, true);
     NS_ENSURE_SUCCESS(rv, rv);
   } else if (!cspOldROHeaderValue.IsEmpty()) {
     rv = AppendCSPFromHeader(csp, cspOldROHeaderValue, selfURI, true, false);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   // ----- Enforce frame-ancestor policy on any applied policies
-  nsCOMPtr<nsIDocShell> docShell = do_QueryReferent(mDocumentContainer);
+  nsCOMPtr<nsIDocShell> docShell(mDocumentContainer);
   if (docShell) {
     bool safeAncestry = false;
 
     // PermitsAncestry sends violation reports when necessary
     rv = csp->PermitsAncestry(docShell, &safeAncestry);
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (!safeAncestry) {
@@ -2925,17 +2925,17 @@ nsDocument::SetContentType(const nsAStri
 
   SetContentTypeInternal(NS_ConvertUTF16toUTF8(aContentType));
 }
 
 nsresult
 nsDocument::GetAllowPlugins(bool * aAllowPlugins)
 {
   // First, we ask our docshell if it allows plugins.
-  nsCOMPtr<nsIDocShell> docShell = do_QueryReferent(mDocumentContainer);
+  nsCOMPtr<nsIDocShell> docShell(mDocumentContainer);
 
   if (docShell) {
     docShell->GetAllowPlugins(aAllowPlugins);
 
     // If the docshell allows plugins, we check whether
     // we are sandboxed and plugins should not be allowed.
     if (*aAllowPlugins)
       *aAllowPlugins = !(mSandboxFlags & SANDBOXED_PLUGINS);
@@ -3393,17 +3393,17 @@ nsDocument::SetHeaderData(nsIAtom* aHead
       // to worry about null strings.
       EnableStyleSheetsForSetInternal(aData, true);
     }
   }
 
   if (aHeaderField == nsGkAtoms::refresh) {
     // We get into this code before we have a script global yet, so get to
     // our container via mDocumentContainer.
-    nsCOMPtr<nsIRefreshURI> refresher = do_QueryReferent(mDocumentContainer);
+    nsCOMPtr<nsIRefreshURI> refresher(mDocumentContainer);
     if (refresher) {
       // Note: using mDocumentURI instead of mBaseURI here, for consistency
       // (used to just use the current URI of our webnavigation, but that
       // should really be the same thing).  Note that this code can run
       // before the current URI of the webnavigation has been updated, so we
       // can't assert equality here.
       refresher->SetupRefreshURIFromHeader(mDocumentURI, NodePrincipal(),
                                            NS_ConvertUTF16toUTF8(aData));
@@ -3474,17 +3474,17 @@ nsDocument::doCreateShell(nsPresContext*
 
   nsRefPtr<PresShell> shell = new PresShell;
   shell->Init(this, aContext, aViewManager, aStyleSet, aCompatMode);
 
   // Note: we don't hold a ref to the shell (it holds a ref to us)
   mPresShell = shell;
 
   // Make sure to never paint if we belong to an invisible DocShell.
-  nsCOMPtr<nsIDocShell> docShell = do_QueryReferent(mDocumentContainer);
+  nsCOMPtr<nsIDocShell> docShell(mDocumentContainer);
   if (docShell && docShell->IsInvisible())
     shell->SetNeverPainting(true);
 
   mExternalResourceMap.ShowViewers();
 
   MaybeRescheduleAnimationFrameNotifications();
 
   return shell.forget();
@@ -4187,37 +4187,49 @@ NotifyActivityChanged(nsIContent *aConte
   nsCOMPtr<nsIObjectLoadingContent> objectLoadingContent(do_QueryInterface(aContent));
   if (objectLoadingContent) {
     nsObjectLoadingContent* olc = static_cast<nsObjectLoadingContent*>(objectLoadingContent.get());
     olc->NotifyOwnerDocumentActivityChanged();
   }
 }
 
 void
-nsIDocument::SetContainer(nsISupports* aContainer)
-{
-  mDocumentContainer = do_GetWeakReference(aContainer);
+nsIDocument::SetContainer(nsDocShell* aContainer)
+{
+  if (aContainer) {
+    mDocumentContainer = aContainer->asWeakPtr();
+  } else {
+    mDocumentContainer = WeakPtr<nsDocShell>();
+  }
+
   EnumerateFreezableElements(NotifyActivityChanged, nullptr);
+  if (!aContainer) {
+    return;
+  }
+
   // Get the Docshell
-  nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(aContainer);
-  if (docShell) {
-    int32_t itemType;
-    docShell->GetItemType(&itemType);
-    // check itemtype
-    if (itemType == nsIDocShellTreeItem::typeContent) {
-      // check if same type root
-      nsCOMPtr<nsIDocShellTreeItem> sameTypeRoot;
-      docShell->GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRoot));
-      NS_ASSERTION(sameTypeRoot, "No document shell root tree item from document shell tree item!");
-
-      if (sameTypeRoot == docShell) {
-        static_cast<nsDocument*>(this)->SetIsTopLevelContentDocument(true);
-      }
-    }
-  }
+  int32_t itemType;
+  aContainer->GetItemType(&itemType);
+  // check itemtype
+  if (itemType == nsIDocShellTreeItem::typeContent) {
+    // check if same type root
+    nsCOMPtr<nsIDocShellTreeItem> sameTypeRoot;
+    aContainer->GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRoot));
+    NS_ASSERTION(sameTypeRoot, "No document shell root tree item from document shell tree item!");
+
+    if (sameTypeRoot == aContainer) {
+      static_cast<nsDocument*>(this)->SetIsTopLevelContentDocument(true);
+    }
+  }
+}
+
+nsISupports*
+nsIDocument::GetContainer() const
+{
+  return static_cast<nsIDocShell*>(mDocumentContainer);
 }
 
 void
 nsDocument::SetScriptGlobalObject(nsIScriptGlobalObject *aScriptGlobalObject)
 {
 #ifdef DEBUG
   {
     nsCOMPtr<nsPIDOMWindow> win(do_QueryInterface(aScriptGlobalObject));
@@ -4267,17 +4279,17 @@ nsDocument::SetScriptGlobalObject(nsIScr
         JSObject *newScope = aScriptGlobalObject->GetGlobalJSObject();
         NS_ASSERTION(js::GetGlobalForObjectCrossCompartment(obj) == newScope,
                      "Wrong scope, this is really bad!");
       }
     }
 #endif
 
     if (mAllowDNSPrefetch) {
-      nsCOMPtr<nsIDocShell> docShell = do_QueryReferent(mDocumentContainer);
+      nsCOMPtr<nsIDocShell> docShell(mDocumentContainer);
       if (docShell) {
 #ifdef DEBUG
         nsCOMPtr<nsIWebNavigation> webNav =
           do_GetInterface(aScriptGlobalObject);
         NS_ASSERTION(SameCOMIdentity(webNav, docShell),
                      "Unexpected container or script global?");
 #endif
         bool allowDNSPrefetch;
@@ -4366,18 +4378,17 @@ 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 =
-      do_QueryReferent(mDocumentContainer);
+    nsCOMPtr<nsIInterfaceRequestor> requestor(mDocumentContainer);
     if (requestor) {
       // The docshell returns the outer window we are done.
       win = do_GetInterface(requestor);
     }
   } else {
     win = do_QueryInterface(mScriptGlobalObject);
     if (win) {
       // mScriptGlobalObject is always the inner window, let's get the outer.
@@ -7794,17 +7805,17 @@ nsDocument::RemovedFromDocShell()
 
 already_AddRefed<nsILayoutHistoryState>
 nsDocument::GetLayoutHistoryState() const
 {
   nsCOMPtr<nsILayoutHistoryState> state;
   if (!mScriptGlobalObject) {
     state = mLayoutHistoryState;
   } else {
-    nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mDocumentContainer));
+    nsCOMPtr<nsIDocShell> docShell(mDocumentContainer);
     if (docShell) {
       docShell->GetLayoutHistoryState(getter_AddRefs(state));
     }
   }
 
   return state.forget();
 }
 
@@ -8315,31 +8326,30 @@ nsDocument::CloneDocHelper(nsDocument* c
   clone->SetPrincipal(NodePrincipal());
   clone->mDocumentBaseURI = mDocumentBaseURI;
 
   if (mCreatingStaticClone) {
     nsCOMPtr<nsILoadGroup> loadGroup;
 
     // |mDocumentContainer| is the container of the document that is being
     // created and not the original container. See CreateStaticClone function().
-    nsCOMPtr<nsIDocumentLoader> docLoader = do_QueryReferent(mDocumentContainer);
+    nsCOMPtr<nsIDocumentLoader> docLoader(mDocumentContainer);
     if (docLoader) {
       docLoader->GetLoadGroup(getter_AddRefs(loadGroup));
     }
     nsCOMPtr<nsIChannel> channel = GetChannel();
     if (channel && loadGroup) {
       clone->Reset(channel, loadGroup);
     } else {
       nsIURI* uri = static_cast<const nsIDocument*>(this)->GetDocumentURI();
       if (uri) {
         clone->ResetToURI(uri, loadGroup, NodePrincipal());
       }
     }
-    nsCOMPtr<nsISupports> container = GetContainer();
-    clone->SetContainer(container);
+    clone->SetContainer(mDocumentContainer);
   }
 
   // Set scripting object
   bool hasHadScriptObject = true;
   nsIScriptGlobalObject* scriptObject =
     GetScriptHandlingObject(hasHadScriptObject);
   NS_ENSURE_STATE(scriptObject || !hasHadScriptObject);
   if (scriptObject) {
@@ -8840,28 +8850,29 @@ nsIDocument::FlushPendingLinkUpdates()
 
   nsAutoScriptBlocker scriptBlocker;
   mLinksToUpdate.EnumerateEntries(EnumeratePendingLinkUpdates, nullptr);
   mLinksToUpdate.Clear();
   mHasLinksToUpdate = false;
 }
 
 already_AddRefed<nsIDocument>
-nsIDocument::CreateStaticClone(nsISupports* aCloneContainer)
+nsIDocument::CreateStaticClone(nsIDocShell* aCloneContainer)
 {
   nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(this);
   NS_ENSURE_TRUE(domDoc, nullptr);
   mCreatingStaticClone = true;
 
   // Make document use different container during cloning.
   nsCOMPtr<nsISupports> originalContainer = GetContainer();
-  SetContainer(aCloneContainer);
+  nsCOMPtr<nsIDocShell> originalShell = do_QueryInterface(originalContainer);
+  SetContainer(static_cast<nsDocShell*>(aCloneContainer));
   nsCOMPtr<nsIDOMNode> clonedNode;
   nsresult rv = domDoc->CloneNode(true, 1, getter_AddRefs(clonedNode));
-  SetContainer(originalContainer);
+  SetContainer(static_cast<nsDocShell*>(originalShell.get()));
 
   nsCOMPtr<nsIDocument> clonedDoc;
   if (NS_SUCCEEDED(rv)) {
     clonedDoc = do_QueryInterface(clonedNode);
     if (clonedDoc) {
       if (IsStaticDocument()) {
         clonedDoc->mOriginalDocument = mOriginalDocument;
       } else {
@@ -10519,17 +10530,17 @@ nsDocument::IsFullScreenEnabled(bool aCa
   }
   if (HasFullScreenSubDocument(this)) {
     LogFullScreenDenied(aLogFailure, "FullScreenDeniedSubDocFullScreen", this);
     return false;
   }
 
   // Ensure that all ancestor <iframe> elements have the allowfullscreen
   // boolean attribute set.
-  nsCOMPtr<nsIDocShell> docShell = do_QueryReferent(mDocumentContainer);
+  nsCOMPtr<nsIDocShell> docShell(mDocumentContainer);
   bool allowed = false;
   if (docShell) {
     docShell->GetFullscreenAllowed(&allowed);
   }
   if (!allowed) {
     LogFullScreenDenied(aLogFailure, "FullScreenDeniedIframeNotAllowed", this);
   }
 
--- a/content/html/document/src/ImageDocument.cpp
+++ b/content/html/document/src/ImageDocument.cpp
@@ -3,16 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ImageDocument.h"
 #include "mozilla/dom/ImageDocumentBinding.h"
 #include "nsRect.h"
 #include "nsIImageLoadingContent.h"
 #include "nsGenericHTMLElement.h"
+#include "nsDocShell.h"
 #include "nsIDocumentInlines.h"
 #include "nsDOMTokenList.h"
 #include "nsIDOMHTMLImageElement.h"
 #include "nsIDOMEvent.h"
 #include "nsIDOMKeyEvent.h"
 #include "nsIDOMMouseEvent.h"
 #include "nsIDOMEventListener.h"
 #include "nsGkAtoms.h"
@@ -719,17 +720,17 @@ ImageDocument::UpdateTitleAndCharset()
 
   MediaDocument::UpdateTitleAndCharset(typeStr, formatNames,
                                        mImageWidth, mImageHeight, status);
 }
 
 void
 ImageDocument::ResetZoomLevel()
 {
-  nsCOMPtr<nsIDocShell> docShell = do_QueryReferent(mDocumentContainer);
+  nsCOMPtr<nsIDocShell> docShell(mDocumentContainer);
   if (docShell) {
     if (nsContentUtils::IsChildOfSameType(this)) {
       return;
     }
 
     nsCOMPtr<nsIContentViewer> cv;
     docShell->GetContentViewer(getter_AddRefs(cv));
     nsCOMPtr<nsIMarkupDocumentViewer> mdv = do_QueryInterface(cv);
@@ -738,17 +739,17 @@ ImageDocument::ResetZoomLevel()
     }
   }
 }
 
 float
 ImageDocument::GetZoomLevel()
 {
   float zoomLevel = mOriginalZoomLevel;
-  nsCOMPtr<nsIDocShell> docShell = do_QueryReferent(mDocumentContainer);
+  nsCOMPtr<nsIDocShell> docShell(mDocumentContainer);
   if (docShell) {
     nsCOMPtr<nsIContentViewer> cv;
     docShell->GetContentViewer(getter_AddRefs(cv));
     nsCOMPtr<nsIMarkupDocumentViewer> mdv = do_QueryInterface(cv);
     if (mdv) {
       mdv->GetFullZoom(&zoomLevel);
     }
   }
--- a/content/html/document/src/moz.build
+++ b/content/html/document/src/moz.build
@@ -27,14 +27,15 @@ FAIL_ON_WARNINGS = True
 
 MSVC_ENABLE_PGO = True
 
 LOCAL_INCLUDES += [
     '../../content/src',
     '/caps/include',
     '/content/base/src',
     '/content/events/src',
+    '/docshell/base',
     '/dom/base',
     '/layout/style',
     '/xpcom/ds',
 ]
 
 FINAL_LIBRARY = 'gklayout'
--- a/content/html/document/src/nsHTMLDocument.cpp
+++ b/content/html/document/src/nsHTMLDocument.cpp
@@ -27,17 +27,17 @@
 #include "nsDOMString.h"
 #include "nsIStreamListener.h"
 #include "nsIURI.h"
 #include "nsIIOService.h"
 #include "nsNetUtil.h"
 #include "nsIContentViewerContainer.h"
 #include "nsIContentViewer.h"
 #include "nsIMarkupDocumentViewer.h"
-#include "nsIDocShell.h"
+#include "nsDocShell.h"
 #include "nsDocShellLoadTypes.h"
 #include "nsIWebNavigation.h"
 #include "nsIBaseWindow.h"
 #include "nsIWebShellServices.h"
 #include "nsIScriptContext.h"
 #include "nsIXPConnect.h"
 #include "nsContentList.h"
 #include "nsError.h"
@@ -1357,17 +1357,17 @@ nsHTMLDocument::Open(JSContext* cx,
 
   nsPIDOMWindow* outer = GetWindow();
   if (!outer || (GetInnerWindow() != outer->GetCurrentInnerWindow())) {
     nsCOMPtr<nsIDocument> ret = this;
     return ret.forget();
   }
 
   // check whether we're in the middle of unload.  If so, ignore this call.
-  nsCOMPtr<nsIDocShell> shell = do_QueryReferent(mDocumentContainer);
+  nsCOMPtr<nsIDocShell> shell(mDocumentContainer);
   if (!shell) {
     // We won't be able to create a parser anyway.
     nsCOMPtr<nsIDocument> ret = this;
     return ret.forget();
   }
 
   bool inUnload;
   shell->GetIsInUnload(&inUnload);
--- a/content/xul/document/src/XULDocument.cpp
+++ b/content/xul/document/src/XULDocument.cpp
@@ -33,17 +33,17 @@
 #include "nsViewManager.h"
 #include "nsIContentViewer.h"
 #include "nsIDOMXULElement.h"
 #include "nsIRDFNode.h"
 #include "nsIRDFRemoteDataSource.h"
 #include "nsIRDFService.h"
 #include "nsIStreamListener.h"
 #include "nsITimer.h"
-#include "nsIDocShell.h"
+#include "nsDocShell.h"
 #include "nsGkAtoms.h"
 #include "nsXMLContentSink.h"
 #include "nsXULContentSink.h"
 #include "nsXULContentUtils.h"
 #include "nsIXULOverlayProvider.h"
 #include "nsNetUtil.h"
 #include "nsParserCIID.h"
 #include "nsPIBoxObject.h"
@@ -4662,17 +4662,17 @@ XULDocument::ParserObserver::OnStopReque
     mDocument = nullptr;
 
     return rv;
 }
 
 already_AddRefed<nsPIWindowRoot>
 XULDocument::GetWindowRoot()
 {
-    nsCOMPtr<nsIInterfaceRequestor> ir = do_QueryReferent(mDocumentContainer);
+    nsCOMPtr<nsIInterfaceRequestor> ir(mDocumentContainer);
     nsCOMPtr<nsIDOMWindow> window(do_GetInterface(ir));
     nsCOMPtr<nsPIDOMWindow> piWin(do_QueryInterface(window));
     return piWin ? piWin->GetTopWindowRoot() : nullptr;
 }
 
 bool
 XULDocument::IsDocumentRightToLeft()
 {
--- a/content/xul/document/src/moz.build
+++ b/content/xul/document/src/moz.build
@@ -23,16 +23,17 @@ MSVC_ENABLE_PGO = True
 
 LOCAL_INCLUDES += [
     '/content/base/src',
     '/content/events/src',
     '/content/xbl/src',
     '/content/xml/document/src',
     '/content/xul/content/src',
     '/content/xul/templates/src',
+    '/docshell/base',
     '/dom/base',
     '/layout/base',
     '/layout/generic',
     '/layout/style',
     '/layout/xul/base/src',
     '/xpcom/ds',
 ]
 
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -7254,29 +7254,29 @@ nsDocShell::CreateAboutBlankContentViewe
     // generate (about:blank) document to load
     docFactory->CreateBlankDocument(mLoadGroup, principal,
                                     getter_AddRefs(blankDoc));
     if (blankDoc) {
       // Hack: set the base URI manually, since this document never
       // got Reset() with a channel.
       blankDoc->SetBaseURI(aBaseURI);
 
-      blankDoc->SetContainer(static_cast<nsIDocShell *>(this));
+      blankDoc->SetContainer(this);
 
       // Copy our sandbox flags to the document. These are immutable
       // after being set here.
       blankDoc->SetSandboxFlags(mSandboxFlags);
 
       // create a content viewer for us and the new document
       docFactory->CreateInstanceForDocument(NS_ISUPPORTS_CAST(nsIDocShell *, this),
                     blankDoc, "view", getter_AddRefs(viewer));
 
       // hook 'em up
       if (viewer) {
-        viewer->SetContainer(static_cast<nsIContentViewerContainer *>(this));
+        viewer->SetContainer(this);
         Embed(viewer, "", 0);
 
         SetCurrentURI(blankDoc->GetDocumentURI(), nullptr, true, 0);
         rv = mIsBeingDestroyed ? NS_ERROR_NOT_AVAILABLE : NS_OK;
       }
     }
   }
   mCreatingDocument = false;
@@ -7602,17 +7602,17 @@ nsDocShell::RestorePresentation(nsISHEnt
     }
 
     // We need to make sure the content viewer's container is this docshell.
     // In subframe navigation, it's possible for the docshell that the
     // content viewer was originally loaded into to be replaced with a
     // different one.  We don't currently support restoring the presentation
     // in that case.
 
-    nsCOMPtr<nsISupports> container;
+    nsCOMPtr<nsIDocShell> container;
     viewer->GetContainer(getter_AddRefs(container));
     if (!::SameCOMIdentity(container, GetAsSupports(this))) {
 #ifdef DEBUG_PAGE_CACHE
         printf("No valid container, clearing presentation\n");
 #endif
         aSHEntry->SetContentViewer(nullptr);
         return NS_ERROR_FAILURE;
     }
@@ -8328,23 +8328,23 @@ nsDocShell::NewContentViewerObj(const ch
         return NS_ERROR_FAILURE;
     }
 
     // Now create an instance of the content viewer
     // nsLayoutDLF makes the determination if it should be a "view-source" instead of "view"
     nsresult rv = docLoaderFactory->CreateInstance("view",
                                                    aOpenedChannel,
                                                    aLoadGroup, aContentType,
-                                                   static_cast<nsIContentViewerContainer*>(this),
+                                                   this,
                                                    nullptr,
                                                    aContentHandler,
                                                    aViewer);
     NS_ENSURE_SUCCESS(rv, rv);
 
-    (*aViewer)->SetContainer(static_cast<nsIContentViewerContainer *>(this));
+    (*aViewer)->SetContainer(this);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocShell::SetupNewViewer(nsIContentViewer * aNewViewer)
 {
     //
     // Copy content viewer state from previous or parent content viewer.
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -13,16 +13,17 @@
 #include "nsIDocShellTreeItem.h"
 #include "nsIDocShellTreeNode.h"
 #include "nsIBaseWindow.h"
 #include "nsIScrollable.h"
 #include "nsITextScroll.h"
 #include "nsIContentViewerContainer.h"
 #include "nsIDOMStorageManager.h"
 #include "nsDocLoader.h"
+#include "mozilla/WeakPtr.h"
 
 // Helper Classes
 #include "nsCOMPtr.h"
 #include "nsPoint.h" // mCurrent/mDefaultScrollbarPreferences
 #include "nsString.h"
 #include "nsAutoPtr.h"
 #include "nsThreadUtils.h"
 
@@ -132,17 +133,18 @@ class nsDocShell : public nsDocLoader,
                    public nsIRefreshURI,
                    public nsIWebProgressListener,
                    public nsIWebPageDescriptor,
                    public nsIAuthPromptProvider,
                    public nsILoadContext,
                    public nsIWebShellServices,
                    public nsILinkHandler,
                    public nsIClipboardCommands,
-                   public nsIDOMStorageManager
+                   public nsIDOMStorageManager,
+                   public mozilla::SupportsWeakPtr<nsDocShell>
 {
     friend class nsDSURIContentListener;
 
 public:
     // Object Management
     nsDocShell();
 
     NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
--- a/docshell/base/nsIContentViewer.idl
+++ b/docshell/base/nsIContentViewer.idl
@@ -1,14 +1,15 @@
 /* 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 nsIDocShell;
 interface nsIDOMDocument;
 interface nsISHEntry;
 interface nsIPrintSettings;
 
 
 %{ C++
 class nsIWidget;
 class nsIDocument;
@@ -29,17 +30,17 @@ class nsDOMNavigationTiming;
 
 [scriptable, builtinclass, uuid(b9d92b8b-5623-4079-ae11-36bb341f322e)]
 interface nsIContentViewer : nsISupports
 {
 
   [noscript] void init(in nsIWidgetPtr aParentWidget,
                        [const] in nsIntRectRef aBounds);
 
-  attribute nsISupports container;
+  attribute nsIDocShell container;
 
   void loadStart(in nsISupports aDoc);
   void loadComplete(in nsresult aStatus);
 
   /**
    * Checks if the document wants to prevent unloading by firing beforeunload on
    * the document, and if it does, prompts the user. The result is returned.
    *
--- a/docshell/base/nsIDocumentLoaderFactory.idl
+++ b/docshell/base/nsIDocumentLoaderFactory.idl
@@ -4,35 +4,36 @@
  * 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 nsIChannel;
 interface nsIContentViewer;
 interface nsIStreamListener;
+interface nsIDocShell;
 interface nsIDocument;
 interface nsILoadGroup;
 interface nsIPrincipal;
 
 /**
  * To get a component that implements nsIDocumentLoaderFactory
  * for a given mimetype, use nsICategoryManager to find an entry
  * with the mimetype as its name in the category "Gecko-Content-Viewers".
  * The value of the entry is the contractid of the component.
  * The component is a service, so use GetService, not CreateInstance to get it.
  */
 
-[scriptable, uuid(5e7d2967-5a07-444f-95d5-25b533252d38)]
+[scriptable, uuid(70905274-8494-4e39-b011-d559adde3733)]
 interface nsIDocumentLoaderFactory : nsISupports {
     nsIContentViewer createInstance(in string aCommand,
                               in nsIChannel aChannel,
                               in nsILoadGroup aLoadGroup,
                               in string aContentType, 
-                              in nsISupports aContainer,
+                              in nsIDocShell aContainer,
                               in nsISupports aExtraInfo,
                               out nsIStreamListener aDocListenerResult);
 
     nsIContentViewer createInstanceForDocument(in nsISupports aContainer,
                                          in nsIDocument aDocument,
                                          in string aCommand);
 
     /**
--- a/docshell/shistory/src/nsSHEntryShared.cpp
+++ b/docshell/shistory/src/nsSHEntryShared.cpp
@@ -5,16 +5,17 @@
 #include "nsSHEntryShared.h"
 
 #include "nsIDOMDocument.h"
 #include "nsISHistory.h"
 #include "nsISHistoryInternal.h"
 #include "nsIDocument.h"
 #include "nsIWebNavigation.h"
 #include "nsIContentViewer.h"
+#include "nsIDocShell.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsDocShellEditorData.h"
 #include "nsThreadUtils.h"
 #include "nsILayoutHistoryState.h"
 #include "mozilla/Attributes.h"
 #include "nsISupportsArray.h"
 
 namespace dom = mozilla::dom;
@@ -162,17 +163,17 @@ nsSHEntryShared::DropPresentationState()
 void
 nsSHEntryShared::Expire()
 {
   // This entry has timed out. If we still have a content viewer, we need to
   // evict it.
   if (!mContentViewer) {
     return;
   }
-  nsCOMPtr<nsISupports> container;
+  nsCOMPtr<nsIDocShell> container;
   mContentViewer->GetContainer(getter_AddRefs(container));
   nsCOMPtr<nsIDocShellTreeItem> treeItem = do_QueryInterface(container);
   if (!treeItem) {
     return;
   }
   // We need to find the root DocShell since only that object has an
   // SHistory and we need the SHistory to evict content viewers
   nsCOMPtr<nsIDocShellTreeItem> root;
--- a/layout/base/moz.build
+++ b/layout/base/moz.build
@@ -106,9 +106,12 @@ SOURCES += [
 ]
 
 FAIL_ON_WARNINGS = True
 
 MSVC_ENABLE_PGO = True
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
+LOCAL_INCLUDES += [
+    '/docshell/base',
+]
 FINAL_LIBRARY = 'gklayout'
--- a/layout/base/nsDocumentViewer.cpp
+++ b/layout/base/nsDocumentViewer.cpp
@@ -31,29 +31,30 @@
 #include "nsISelectionPrivate.h"
 #include "nsIDOMHTMLDocument.h"
 #include "nsIDOMHTMLElement.h"
 #include "nsContentUtils.h"
 #include "nsLayoutStylesheetCache.h"
 #include "mozilla/BasicEvents.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/dom/EncodingUtils.h"
+#include "mozilla/WeakPtr.h"
 
 #include "nsViewManager.h"
 #include "nsView.h"
 
 #include "nsIPageSequenceFrame.h"
 #include "nsNetUtil.h"
 #include "nsIContentViewerEdit.h"
 #include "nsIContentViewerFile.h"
 #include "mozilla/css/Loader.h"
 #include "nsIMarkupDocumentViewer.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
-#include "nsIDocShell.h"
+#include "nsDocShell.h"
 #include "nsIBaseWindow.h"
 #include "nsILayoutHistoryState.h"
 #include "nsCharsetSource.h"
 #include "nsHTMLReflowState.h"
 #include "nsIImageLoadingContent.h"
 #include "nsCopySupport.h"
 #include "nsIDOMHTMLFrameSetElement.h"
 #ifdef MOZ_XUL
@@ -343,17 +344,17 @@ protected:
   void DetachFromTopLevelWidget();
 
   // IMPORTANT: The ownership implicit in the following member
   // variables has been explicitly checked and set using nsCOMPtr
   // for owning pointers and raw COM interface pointers for weak
   // (ie, non owning) references. If you add any members to this
   // class, please make the ownership explicit (pinkerton, scc).
 
-  nsWeakPtr mContainer; // it owns me!
+  WeakPtr<nsDocShell> mContainer; // it owns me!
   nsWeakPtr mTopContainerWhilePrinting;
   nsRefPtr<nsDeviceContext> mDeviceContext;  // We create and own this baby
 
   // the following six items are explicitly in this order
   // so they will be destroyed in the reverse order (pinkerton, scc)
   nsCOMPtr<nsIDocument>    mDocument;
   nsCOMPtr<nsIWidget>      mWindow;      // may be null
   nsRefPtr<nsViewManager> mViewManager;
@@ -571,17 +572,17 @@ nsDocumentViewer::LoadStart(nsISupports 
   }
 
   return rv;
 }
 
 nsresult
 nsDocumentViewer::SyncParentSubDocMap()
 {
-  nsCOMPtr<nsIDocShellTreeItem> item(do_QueryReferent(mContainer));
+  nsCOMPtr<nsIDocShellTreeItem> item(mContainer);
   nsCOMPtr<nsPIDOMWindow> pwin(do_GetInterface(item));
   nsCOMPtr<nsIContent> content;
 
   if (mDocument && pwin) {
     content = do_QueryInterface(pwin->GetFrameElementInternal());
   }
 
   if (content) {
@@ -605,37 +606,36 @@ nsDocumentViewer::SyncParentSubDocMap()
       }
     }
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDocumentViewer::SetContainer(nsISupports* aContainer)
+nsDocumentViewer::SetContainer(nsIDocShell* aContainer)
 {
-  mContainer = do_GetWeakReference(aContainer);
+  mContainer = static_cast<nsDocShell*>(aContainer)->asWeakPtr();
   if (mPresContext) {
     mPresContext->SetContainer(aContainer);
   }
 
   // We're loading a new document into the window where this document
   // viewer lives, sync the parent document's frame element -> sub
   // document map
 
   return SyncParentSubDocMap();
 }
 
 NS_IMETHODIMP
-nsDocumentViewer::GetContainer(nsISupports** aResult)
+nsDocumentViewer::GetContainer(nsIDocShell** aResult)
 {
    NS_ENSURE_ARG_POINTER(aResult);
 
-   *aResult = nullptr;
-   nsCOMPtr<nsISupports> container = do_QueryReferent(mContainer);
+   nsCOMPtr<nsIDocShell> container(mContainer);
    container.swap(*aResult);
    return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocumentViewer::Init(nsIWidget* aParentWidget,
                          const nsIntRect& aBounds)
 {
@@ -868,17 +868,17 @@ nsDocumentViewer::InitInternal(nsIWidget
       // Avoid leaking the old viewer.
       if (mPreviousViewer) {
         mPreviousViewer->Destroy();
         mPreviousViewer = nullptr;
       }
     }
   }
 
-  nsCOMPtr<nsIInterfaceRequestor> requestor(do_QueryReferent(mContainer));
+  nsCOMPtr<nsIInterfaceRequestor> requestor(mContainer);
   if (requestor) {
     if (mPresContext) {
       nsCOMPtr<nsILinkHandler> linkHandler;
       requestor->GetInterface(NS_GET_IID(nsILinkHandler),
                               getter_AddRefs(linkHandler));
 
       mPresContext->SetContainer(requestor);
       mPresContext->SetLinkHandler(linkHandler);
@@ -1102,17 +1102,17 @@ nsDocumentViewer::PermitUnload(bool aCal
     nsEventDispatcher::DispatchDOMEvent(window, nullptr, event, mPresContext,
                                         nullptr);
     mInPermitUnload = false;
     if (dialogsWereEnabled) {
       utils->EnableDialogs();
     }
   }
 
-  nsCOMPtr<nsIDocShellTreeNode> docShellNode(do_QueryReferent(mContainer));
+  nsCOMPtr<nsIDocShellTreeNode> docShellNode(mContainer);
   nsAutoString text;
   beforeUnload->GetReturnValue(text);
   if (event->GetInternalNSEvent()->mFlags.mDefaultPrevented ||
       !text.IsEmpty()) {
     // Ask the user if it's ok to unload the current page
 
     nsCOMPtr<nsIPrompt> prompt = do_GetInterface(docShellNode);
 
@@ -1193,17 +1193,17 @@ nsDocumentViewer::PermitUnload(bool aCal
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocumentViewer::ResetCloseWindow()
 {
   mCallerIsClosingWindow = false;
 
-  nsCOMPtr<nsIDocShellTreeNode> docShellNode(do_QueryReferent(mContainer));
+  nsCOMPtr<nsIDocShellTreeNode> docShellNode(mContainer);
   if (docShellNode) {
     int32_t childCount;
     docShellNode->GetChildCount(&childCount);
 
     for (int32_t i = 0; i < childCount; ++i) {
       nsCOMPtr<nsIDocShellTreeItem> item;
       docShellNode->GetChildAt(i, getter_AddRefs(item));
 
@@ -1281,17 +1281,17 @@ nsDocumentViewer::PageHide(bool aIsUnloa
 static void
 AttachContainerRecurse(nsIDocShell* aShell)
 {
   nsCOMPtr<nsIContentViewer> viewer;
   aShell->GetContentViewer(getter_AddRefs(viewer));
   if (viewer) {
     nsIDocument* doc = viewer->GetDocument();
     if (doc) {
-      doc->SetContainer(aShell);
+      doc->SetContainer(static_cast<nsDocShell*>(aShell));
     }
     nsRefPtr<nsPresContext> pc;
     viewer->GetPresContext(getter_AddRefs(pc));
     if (pc) {
       pc->SetContainer(aShell);
       pc->SetLinkHandler(nsCOMPtr<nsILinkHandler>(do_QueryInterface(aShell)));
     }
     nsCOMPtr<nsIPresShell> presShell;
@@ -1312,17 +1312,17 @@ AttachContainerRecurse(nsIDocShell* aShe
 }
 
 NS_IMETHODIMP
 nsDocumentViewer::Open(nsISupports *aState, nsISHEntry *aSHEntry)
 {
   NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_INITIALIZED);
 
   if (mDocument)
-    mDocument->SetContainer(nsCOMPtr<nsISupports>(do_QueryReferent(mContainer)));
+    mDocument->SetContainer(mContainer);
 
   nsresult rv = InitInternal(mParentWidget, aState, mBounds, false);
   NS_ENSURE_SUCCESS(rv, rv);
 
   mHidden = false;
 
   if (mPresShell)
     mPresShell->SetForwardingContainer(nullptr);
@@ -1556,18 +1556,21 @@ nsDocumentViewer::Destroy()
 
     if (mDocument) {
       mDocument->SetContainer(nullptr);
     }
     if (mPresContext) {
       mPresContext->SetLinkHandler(nullptr);
       mPresContext->SetContainer(nullptr);
     }
-    if (mPresShell)
-      mPresShell->SetForwardingContainer(mContainer);
+    if (mPresShell) {
+      nsWeakPtr container =
+        do_GetWeakReference(static_cast<nsIDocShell*>(mContainer));
+      mPresShell->SetForwardingContainer(container);
+    }
 
     // Do the same for our children.  Note that we need to get the child
     // docshells from the SHEntry now; the docshell will have cleared them.
     nsCOMPtr<nsIDocShellTreeItem> item;
     int32_t itemIndex = 0;
     while (NS_SUCCEEDED(shEntry->ChildShellAt(itemIndex++,
                                               getter_AddRefs(item))) && item) {
       DetachContainerRecurse(nsCOMPtr<nsIDocShell>(do_QueryInterface(item)));
@@ -1615,17 +1618,17 @@ nsDocumentViewer::Destroy()
   mDeviceContext = nullptr;
 
   if (mPresContext) {
     DestroyPresContext();
   }
 
   mWindow = nullptr;
   mViewManager = nullptr;
-  mContainer = nullptr;
+  mContainer = WeakPtr<nsDocShell>();
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocumentViewer::Stop(void)
 {
   NS_ASSERTION(mDocument, "Stop called too early or too late");
@@ -1686,38 +1689,38 @@ nsDocumentViewer::SetDOMDocument(nsIDOMD
 
 NS_IMETHODIMP
 nsDocumentViewer::SetDocumentInternal(nsIDocument* aDocument,
                                         bool aForceReuseInnerWindow)
 {
   MOZ_ASSERT(aDocument);
 
   // Set new container
-  nsCOMPtr<nsISupports> container = do_QueryReferent(mContainer);
-  aDocument->SetContainer(container);
+  aDocument->SetContainer(mContainer);
 
   if (mDocument != aDocument) {
     if (mDocument->IsStaticDocument()) {
       mDocument->SetScriptGlobalObject(nullptr);
       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(container);
+    nsCOMPtr<nsPIDOMWindow> window =
+      do_GetInterface(static_cast<nsIDocShell*>(mContainer.get()));
     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<nsIDocShellTreeNode> node = do_QueryInterface(container);
+      nsCOMPtr<nsIDocShellTreeNode> node(mContainer);
       if (node) {
         int32_t count;
         node->GetChildCount(&count);
         for (int32_t i = 0; i < count; ++i) {
           nsCOMPtr<nsIDocShellTreeItem> child;
           node->GetChildAt(0, getter_AddRefs(child));
           node->RemoveChild(child);
         }
@@ -1883,17 +1886,17 @@ nsDocumentViewer::Show(void)
   if (mPreviousViewer) {
     // This little dance *may* only be to keep
     // PresShell::EndObservingDocument happy, but I'm not sure.
     nsCOMPtr<nsIContentViewer> prevViewer(mPreviousViewer);
     mPreviousViewer = nullptr;
     prevViewer->Destroy();
 
     // Make sure we don't have too many cached ContentViewers
-    nsCOMPtr<nsIDocShellTreeItem> treeItem = do_QueryReferent(mContainer);
+    nsCOMPtr<nsIDocShellTreeItem> treeItem(mContainer);
     if (treeItem) {
       // We need to find the root DocShell since only that object has an
       // SHistory and we need the SHistory to evict content viewers
       nsCOMPtr<nsIDocShellTreeItem> root;
       treeItem->GetSameTypeRootTreeItem(getter_AddRefs(root));
       nsCOMPtr<nsIWebNavigation> webNav = do_QueryInterface(root);
       nsCOMPtr<nsISHistory> history;
       webNav->GetSessionHistory(getter_AddRefs(history));
@@ -1919,17 +1922,17 @@ nsDocumentViewer::Show(void)
     if (!mAttachedToParent) {
       mWindow->Show(true);
     }
   }
 
   if (mDocument && !mPresShell) {
     NS_ASSERTION(!mWindow, "Window already created but no presshell?");
 
-    nsCOMPtr<nsIBaseWindow> base_win(do_QueryReferent(mContainer));
+    nsCOMPtr<nsIBaseWindow> base_win(mContainer);
     if (base_win) {
       base_win->GetParentWidget(&mParentWidget);
       if (mParentWidget) {
         mParentWidget->Release(); // GetParentWidget AddRefs, but mParentWidget is weak
       }
     }
 
     nsView* containerView = FindContainerView();
@@ -2009,32 +2012,32 @@ nsDocumentViewer::Hide(void)
   if (mIsSticky) {
     // This window is sticky, that means that it might be shown again
     // and we don't want the presshell n' all that to be thrown away
     // just because the window is hidden.
 
     return NS_OK;
   }
 
-  nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mContainer));
+  nsCOMPtr<nsIDocShell> docShell(mContainer);
   if (docShell) {
     nsCOMPtr<nsILayoutHistoryState> layoutState;
     mPresShell->CaptureHistoryState(getter_AddRefs(layoutState));
   }
 
   DestroyPresShell();
 
   DestroyPresContext();
 
   mViewManager   = nullptr;
   mWindow        = nullptr;
   mDeviceContext = nullptr;
   mParentWidget  = nullptr;
 
-  nsCOMPtr<nsIBaseWindow> base_win(do_QueryReferent(mContainer));
+  nsCOMPtr<nsIBaseWindow> base_win(mContainer);
 
   if (base_win && !mAttachedToParent) {
     base_win->SetParentWidget(nullptr);
   }
 
   return NS_OK;
 }
 
@@ -2109,17 +2112,17 @@ nsDocumentViewer::CreateStyleSet(nsIDocu
 
   if (sheet)
     styleSet->AppendStyleSheet(nsStyleSet::eUserSheet, sheet);
 
   // Append chrome sheets (scrollbars + forms).
   bool shouldOverride = false;
   // We don't want a docshell here for external resource docs, so just
   // look at mContainer.
-  nsCOMPtr<nsIDocShell> ds(do_QueryReferent(mContainer));
+  nsCOMPtr<nsIDocShell> ds(mContainer);
   nsCOMPtr<nsIDOMEventTarget> chromeHandler;
   nsCOMPtr<nsIURI> uri;
   nsRefPtr<nsCSSStyleSheet> csssheet;
 
   if (ds) {
     ds->GetChromeEventHandler(getter_AddRefs(chromeHandler));
   }
   if (chromeHandler) {
@@ -2298,17 +2301,17 @@ nsDocumentViewer::DetachFromTopLevelWidg
 }
 
 nsView*
 nsDocumentViewer::FindContainerView()
 {
   nsView* containerView = nullptr;
 
   if (mContainer) {
-    nsCOMPtr<nsIDocShellTreeItem> docShellItem = do_QueryReferent(mContainer);
+    nsCOMPtr<nsIDocShellTreeItem> docShellItem(mContainer);
     nsCOMPtr<nsPIDOMWindow> pwin(do_GetInterface(docShellItem));
     if (pwin) {
       nsCOMPtr<nsIContent> containerElement = do_QueryInterface(pwin->GetFrameElementInternal());
       if (!containerElement) {
         return nullptr;
       }
       nsCOMPtr<nsIPresShell> parentPresShell;
       if (docShellItem) {
@@ -2495,17 +2498,17 @@ NS_IMETHODIMP nsDocumentViewer::CopyLink
 NS_IMETHODIMP nsDocumentViewer::CopyImage(int32_t aCopyFlags)
 {
   NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_INITIALIZED);
   nsCOMPtr<nsIImageLoadingContent> node;
   GetPopupImageNode(getter_AddRefs(node));
   // make noise if we're not in an image
   NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);
 
-  nsCOMPtr<nsILoadContext> loadContext(do_QueryReferent(mContainer));
+  nsCOMPtr<nsILoadContext> loadContext(mContainer);
   return nsCopySupport::ImageCopy(node, loadContext, aCopyFlags);
 }
 
 
 NS_IMETHODIMP nsDocumentViewer::GetCopyable(bool *aCopyable)
 {
   NS_ENSURE_ARG_POINTER(aCopyable);
   *aCopyable = nsCopySupport::CanCopy(mDocument);
@@ -2627,17 +2630,17 @@ NS_IMETHODIMP nsDocumentViewer::ScrollTo
                                      nsIPresShell::SCROLL_OVERFLOW_HIDDEN),
     NS_ERROR_FAILURE);
   return NS_OK;
 }
 
 void
 nsDocumentViewer::CallChildren(CallChildFunc aFunc, void* aClosure)
 {
-  nsCOMPtr<nsIDocShellTreeNode> docShellNode(do_QueryReferent(mContainer));
+  nsCOMPtr<nsIDocShellTreeNode> docShellNode(mContainer);
   if (docShellNode)
   {
     int32_t i;
     int32_t n;
     docShellNode->GetChildCount(&n);
     for (i=0; i < n; i++)
     {
       nsCOMPtr<nsIDocShellTreeItem> child;
@@ -3221,17 +3224,17 @@ NS_IMETHODIMP nsDocumentViewer::ChangeMa
 }
 
 NS_IMETHODIMP
 nsDocumentViewer::GetContentSize(int32_t* aWidth, int32_t* aHeight)
 {
    NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
 
    // Skip doing this on docshell-less documents for now
-   nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryReferent(mContainer));
+   nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(mContainer);
    NS_ENSURE_TRUE(docShellAsItem, NS_ERROR_NOT_AVAILABLE);
    
    nsCOMPtr<nsIDocShellTreeItem> docShellParent;
    docShellAsItem->GetSameTypeParent(getter_AddRefs(docShellParent));
 
    // It's only valid to access this from a top frame.  Doesn't work from
    // sub-frames.
    NS_ENSURE_TRUE(!docShellParent, NS_ERROR_FAILURE);
@@ -3549,17 +3552,17 @@ nsDocumentViewer::Print(nsIPrintSettings
   }
 #endif
 
   if (!mContainer) {
     PR_PL(("Container was destroyed yet we are still trying to use it!"));
     return NS_ERROR_FAILURE;
   }
 
-  nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mContainer));
+  nsCOMPtr<nsIDocShell> docShell(mContainer);
   NS_ENSURE_STATE(docShell);
 
   // Check to see if this document is still busy
   // If it is busy and we aren't already "queued" up to print then
   // Indicate there is a print pending and cache the args for later
   uint32_t busyFlags = nsIDocShell::BUSY_FLAGS_NONE;
   if ((NS_FAILED(docShell->GetBusyFlags(&busyFlags)) ||
        (busyFlags != nsIDocShell::BUSY_FLAGS_NONE && busyFlags & nsIDocShell::BUSY_FLAGS_PAGE_LOADING)) && 
@@ -3659,17 +3662,17 @@ nsDocumentViewer::PrintPreview(nsIPrintS
   nsCOMPtr<nsIXULDocument> xulDoc(do_QueryInterface(mDocument));
   if (xulDoc) {
     nsPrintEngine::CloseProgressDialog(aWebProgressListener);
     nsPrintEngine::ShowPrintErrorDialog(NS_ERROR_GFX_PRINTER_NO_XUL, false);
     return NS_ERROR_FAILURE;
   }
 #endif
 
-  nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mContainer));
+  nsCOMPtr<nsIDocShell> docShell(mContainer);
   if (!docShell || !mDeviceContext) {
     PR_PL(("Can't Print Preview without device context and docshell"));
     return NS_ERROR_FAILURE;
   }
 
   nsCOMPtr<nsIDOMDocument> domDoc;
   aChildDOMWin->GetDocument(getter_AddRefs(domDoc));
   nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
@@ -4025,17 +4028,17 @@ nsDocumentViewer::SetIsPrintingInDocShel
 #endif // NS_PRINTING
 
 bool
 nsDocumentViewer::ShouldAttachToTopLevel()
 {
   if (!mParentWidget)
     return false;
 
-  nsCOMPtr<nsIDocShellTreeItem> containerItem = do_QueryReferent(mContainer);
+  nsCOMPtr<nsIDocShellTreeItem> containerItem(mContainer);
   if (!containerItem)
     return false;
 
   // We always attach when using puppet widgets
   if (nsIWidget::UsePuppetWidgets())
     return true;
 
 #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
@@ -4093,17 +4096,17 @@ nsDocumentViewer::GetIsPrinting()
 //------------------------------------------------------------
 // Notification from the PrintEngine of the current Printing status
 void
 nsDocumentViewer::SetIsPrinting(bool aIsPrinting)
 {
 #ifdef NS_PRINTING
   // Set all the docShells in the docshell tree to be printing.
   // that way if anyone of them tries to "navigate" it can't
-  nsCOMPtr<nsIDocShellTreeNode> docShellTreeNode(do_QueryReferent(mContainer));
+  nsCOMPtr<nsIDocShellTreeNode> docShellTreeNode(mContainer);
   if (docShellTreeNode || !aIsPrinting) {
     SetIsPrintingInDocShellTree(docShellTreeNode, aIsPrinting, true);
   } else {
     NS_WARNING("Did you close a window before printing?");
   }
 
   if (!aIsPrinting) {
     mBeforeAndAfterPrint = nullptr;
@@ -4129,17 +4132,17 @@ nsDocumentViewer::GetIsPrintPreview()
 //------------------------------------------------------------
 // Notification from the PrintEngine of the current PP status
 void
 nsDocumentViewer::SetIsPrintPreview(bool aIsPrintPreview)
 {
 #ifdef NS_PRINTING
   // Set all the docShells in the docshell tree to be printing.
   // that way if anyone of them tries to "navigate" it can't
-  nsCOMPtr<nsIDocShellTreeNode> docShellTreeNode(do_QueryReferent(mContainer));
+  nsCOMPtr<nsIDocShellTreeNode> docShellTreeNode(mContainer);
   if (docShellTreeNode || !aIsPrintPreview) {
     SetIsPrintingInDocShellTree(docShellTreeNode, aIsPrintPreview, true);
   }
   if (!aIsPrintPreview) {
     mBeforeAndAfterPrint = nullptr;
   }
 #endif
   if (!aIsPrintPreview) {
@@ -4203,17 +4206,17 @@ nsDocumentViewer::ReturnToGalleyPresenta
   }
 
   SetIsPrintPreview(false);
 
   mPrintEngine->TurnScriptingOn(true);
   mPrintEngine->Destroy();
   mPrintEngine = nullptr;
 
-  nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mContainer));
+  nsCOMPtr<nsIDocShell> docShell(mContainer);
   ResetFocusState(docShell);
 
   SetTextZoom(mTextZoom);
   SetFullZoom(mPageZoom);
   SetMinFontSize(mMinFontSize);
   Show();
 
 #endif // NS_PRINTING && NS_PRINT_PREVIEW
@@ -4242,18 +4245,18 @@ nsDocumentViewer::OnDonePrinting()
     } else {
       mPrintEngine = nullptr;
       pe->Destroy();
     }
 
     // We are done printing, now cleanup 
     if (mDeferredWindowClose) {
       mDeferredWindowClose = false;
-      nsCOMPtr<nsISupports> container = do_QueryReferent(mContainer);
-      nsCOMPtr<nsIDOMWindow> win = do_GetInterface(container);
+      nsCOMPtr<nsIDOMWindow> win =
+        do_GetInterface(static_cast<nsIDocShell*>(mContainer));
       if (win)
         win->Close();
     } else if (mClosingWhilePrinting) {
       if (mDocument) {
         mDocument->SetScriptGlobalObject(nullptr);
         mDocument->Destroy();
         mDocument = nullptr;
       }
--- a/layout/build/moz.build
+++ b/layout/build/moz.build
@@ -24,9 +24,12 @@ if CONFIG['MOZ_NFC']:
 FAIL_ON_WARNINGS = True
 
 MSVC_ENABLE_PGO = True
 
 LIBRARY_NAME = 'gklayout'
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
+LOCAL_INCLUDES += [
+    '/docshell/base',
+]
 FINAL_LIBRARY = 'xul'
--- a/layout/build/nsContentDLF.cpp
+++ b/layout/build/nsContentDLF.cpp
@@ -1,15 +1,16 @@
 /* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=2 sw=2 et tw=78: */
 /* 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 "nsCOMPtr.h"
 #include "nsContentDLF.h"
+#include "nsDocShell.h"
 #include "nsGenericHTMLElement.h"
 #include "nsGkAtoms.h"
 #include "nsIComponentManager.h"
 #include "nsIComponentRegistrar.h"
 #include "nsIContentViewer.h"
 #include "nsICategoryManager.h"
 #include "nsIDocumentLoaderFactory.h"
 #include "nsIDocument.h"
@@ -130,17 +131,17 @@ MayUseXULXBL(nsIChannel* aChannel)
   return nsContentUtils::AllowXULXBLForPrincipal(principal);
 }
 
 NS_IMETHODIMP
 nsContentDLF::CreateInstance(const char* aCommand,
                              nsIChannel* aChannel,
                              nsILoadGroup* aLoadGroup,
                              const char* aContentType, 
-                             nsISupports* aContainer,
+                             nsIDocShell* aContainer,
                              nsISupports* aExtraInfo,
                              nsIStreamListener** aDocListener,
                              nsIContentViewer** aDocViewer)
 {
   // Declare "type" here.  This is because although the variable itself only
   // needs limited scope, we need to use the raw string memory -- as returned
   // by "type.get()" farther down in the function.
   nsAutoCString type;
@@ -365,17 +366,17 @@ nsContentDLF::CreateBlankDocument(nsILoa
   return rv;
 }
 
 
 nsresult
 nsContentDLF::CreateDocument(const char* aCommand,
                              nsIChannel* aChannel,
                              nsILoadGroup* aLoadGroup,
-                             nsISupports* aContainer,
+                             nsIDocShell* aContainer,
                              const nsCID& aDocumentCID,
                              nsIStreamListener** aDocListener,
                              nsIContentViewer** aContentViewer)
 {
   nsresult rv = NS_ERROR_FAILURE;
 
   nsCOMPtr<nsIURI> aURL;
   rv = aChannel->GetURI(getter_AddRefs(aURL));
@@ -394,17 +395,17 @@ nsContentDLF::CreateDocument(const char*
   nsCOMPtr<nsIDocument> doc = do_CreateInstance(aDocumentCID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Create the content viewer  XXX: could reuse content viewer here!
   nsCOMPtr<nsIContentViewer> contentViewer;
   rv = NS_NewContentViewer(getter_AddRefs(contentViewer));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  doc->SetContainer(aContainer);
+  doc->SetContainer(static_cast<nsDocShell*>(aContainer));
 
   // Initialize the document to begin loading the data.  An
   // nsIStreamListener connected to the parser is returned in
   // aDocListener.
   rv = doc->StartDocumentLoad(aCommand, aChannel, aLoadGroup, aContainer, aDocListener, true);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Bind the document to the Content Viewer
@@ -413,17 +414,17 @@ nsContentDLF::CreateDocument(const char*
   return rv;
 }
 
 nsresult
 nsContentDLF::CreateXULDocument(const char* aCommand,
                                 nsIChannel* aChannel,
                                 nsILoadGroup* aLoadGroup,
                                 const char* aContentType,
-                                nsISupports* aContainer,
+                                nsIDocShell* aContainer,
                                 nsISupports* aExtraInfo,
                                 nsIStreamListener** aDocListener,
                                 nsIContentViewer** aContentViewer)
 {
   nsresult rv;
   nsCOMPtr<nsIDocument> doc = do_CreateInstance(kXULDocumentCID, &rv);
   if (NS_FAILED(rv)) return rv;
 
@@ -437,17 +438,17 @@ nsContentDLF::CreateXULDocument(const ch
 
   /* 
    * Initialize the document to begin loading the data...
    *
    * An nsIStreamListener connected to the parser is returned in
    * aDocListener.
    */
 
-  doc->SetContainer(aContainer);
+  doc->SetContainer(static_cast<nsDocShell*>(aContainer));
 
   rv = doc->StartDocumentLoad(aCommand, aChannel, aLoadGroup, aContainer, aDocListener, true);
   if (NS_FAILED(rv)) return rv;
 
   /*
    * Bind the document to the Content Viewer...
    */
   rv = contentViewer->LoadStart(doc);
--- a/layout/build/nsContentDLF.h
+++ b/layout/build/nsContentDLF.h
@@ -28,26 +28,26 @@ public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIDOCUMENTLOADERFACTORY
 
   nsresult InitUAStyleSheet();
 
   nsresult CreateDocument(const char* aCommand,
                           nsIChannel* aChannel,
                           nsILoadGroup* aLoadGroup,
-                          nsISupports* aContainer,
+                          nsIDocShell* aContainer,
                           const nsCID& aDocumentCID,
                           nsIStreamListener** aDocListener,
                           nsIContentViewer** aContentViewer);
 
   nsresult CreateXULDocument(const char* aCommand,
                              nsIChannel* aChannel,
                              nsILoadGroup* aLoadGroup,
                              const char* aContentType,
-                             nsISupports* aContainer,
+                             nsIDocShell* aContainer,
                              nsISupports* aExtraInfo,
                              nsIStreamListener** aDocListener,
                              nsIContentViewer** aContentViewer);
 
 private:
   static nsresult EnsureUAStyleSheet();
   static bool IsImageContentType(const char* aContentType);
 };
--- a/layout/printing/nsPrintEngine.cpp
+++ b/layout/printing/nsPrintEngine.cpp
@@ -288,27 +288,27 @@ void nsPrintEngine::DestroyPrintingData(
 }
 
 //---------------------------------------------------------------------------------
 //-- Section: Methods needed by the DocViewer
 //---------------------------------------------------------------------------------
 
 //--------------------------------------------------------
 nsresult nsPrintEngine::Initialize(nsIDocumentViewerPrint* aDocViewerPrint, 
-                                   nsIWeakReference*       aContainer,
+                                   nsIDocShell*            aContainer,
                                    nsIDocument*            aDocument,
                                    float                   aScreenDPI,
                                    FILE*                   aDebugFile)
 {
   NS_ENSURE_ARG_POINTER(aDocViewerPrint);
   NS_ENSURE_ARG_POINTER(aContainer);
   NS_ENSURE_ARG_POINTER(aDocument);
 
   mDocViewerPrint = aDocViewerPrint;
-  mContainer      = aContainer;
+  mContainer      = do_GetWeakReference(aContainer);
   mDocument       = aDocument;
   mScreenDPI      = aScreenDPI;
 
   mDebugFile      = aDebugFile;      // ok to be nullptr
 
   return NS_OK;
 }
 
--- a/layout/printing/nsPrintEngine.h
+++ b/layout/printing/nsPrintEngine.h
@@ -77,17 +77,17 @@ public:
 
   nsPrintEngine();
   ~nsPrintEngine();
 
   void Destroy();
   void DestroyPrintingData();
 
   nsresult Initialize(nsIDocumentViewerPrint* aDocViewerPrint, 
-                      nsIWeakReference*       aContainer,
+                      nsIDocShell*            aContainer,
                       nsIDocument*            aDocument,
                       float                   aScreenDPI,
                       FILE*                   aDebugFile);
 
   nsresult GetSeqFrameAndCountPages(nsIFrame*& aSeqFrame, int32_t& aCount);
 
   //
   // The following three methods are used for printing...
--- a/uriloader/prefetch/nsOfflineCacheUpdateService.cpp
+++ b/uriloader/prefetch/nsOfflineCacheUpdateService.cpp
@@ -18,16 +18,17 @@
 #include "nsIApplicationCacheContainer.h"
 #include "nsIApplicationCacheChannel.h"
 #include "nsIApplicationCacheService.h"
 #include "nsICache.h"
 #include "nsICacheService.h"
 #include "nsICacheSession.h"
 #include "nsICachingChannel.h"
 #include "nsIContent.h"
+#include "nsIDocShell.h"
 #include "nsIDocumentLoader.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMWindow.h"
 #include "nsIDOMOfflineResourceList.h"
 #include "nsIDocument.h"
 #include "nsIObserverService.h"
 #include "nsIURL.h"
 #include "nsIWebProgress.h"
@@ -373,18 +374,17 @@ NS_IMETHODIMP
 nsOfflineCacheUpdateService::ScheduleOnDocumentStop(nsIURI *aManifestURI,
                                                     nsIURI *aDocumentURI,
                                                     nsIDOMDocument *aDocument)
 {
     LOG(("nsOfflineCacheUpdateService::ScheduleOnDocumentStop [%p, manifestURI=%p, documentURI=%p doc=%p]",
          this, aManifestURI, aDocumentURI, aDocument));
 
     nsCOMPtr<nsIDocument> doc = do_QueryInterface(aDocument);
-    nsCOMPtr<nsISupports> container = doc->GetContainer();
-    nsCOMPtr<nsIWebProgress> progress = do_QueryInterface(container);
+    nsCOMPtr<nsIWebProgress> progress = do_QueryInterface(doc->GetContainer());
     NS_ENSURE_TRUE(progress, NS_ERROR_INVALID_ARG);
 
     // Proceed with cache update
     nsRefPtr<nsOfflineCachePendingUpdate> update =
         new nsOfflineCachePendingUpdate(this, aManifestURI,
                                         aDocumentURI, aDocument);
     NS_ENSURE_TRUE(update, NS_ERROR_OUT_OF_MEMORY);
 
--- a/xpfe/components/directory/nsDirectoryViewer.cpp
+++ b/xpfe/components/directory/nsDirectoryViewer.cpp
@@ -12,16 +12,17 @@
 
   One added change is for a description entry, for when the
   target does not match the filename
 
 */
 
 #include "nsDirectoryViewer.h"
 #include "nsIDirIndex.h"
+#include "nsIDocShell.h"
 #include "jsapi.h"
 #include "nsCOMPtr.h"
 #include "nsCRT.h"
 #include "nsEnumeratorUtils.h"
 #include "nsEscape.h"
 #include "nsIRDFService.h"
 #include "nsRDFCID.h"
 #include "rdf.h"
@@ -1260,17 +1261,17 @@ NS_IMPL_ISUPPORTS1(nsDirectoryViewerFact
 
 
 
 NS_IMETHODIMP
 nsDirectoryViewerFactory::CreateInstance(const char *aCommand,
                                          nsIChannel* aChannel,
                                          nsILoadGroup* aLoadGroup,
                                          const char* aContentType, 
-                                         nsISupports* aContainer,
+                                         nsIDocShell* aContainer,
                                          nsISupports* aExtraInfo,
                                          nsIStreamListener** aDocListenerResult,
                                          nsIContentViewer** aDocViewerResult)
 {
   nsresult rv;
 
   bool viewSource = (PL_strstr(aContentType,"view-source") != 0);