Bug 1434768 - Part 4: Create a ParentSHistory in nsFrameLoader, r=bz
authorNika Layzell <nika@thelayzells.com>
Thu, 01 Feb 2018 17:56:54 -0500
changeset 412756 0171a483cd7b062b797b1773812c8ce0a0e0ae3c
parent 412755 3bc418e5727e0f682909f0543db3c92376840d7c
child 412757 7ae896b5ad633c584e7f2ad56013605c813adf72
push id33818
push userapavel@mozilla.com
push dateWed, 11 Apr 2018 14:36:40 +0000
treeherdermozilla-central@cfe6399e142c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1434768
milestone61.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 1434768 - Part 4: Create a ParentSHistory in nsFrameLoader, r=bz
docshell/shistory/ParentSHistory.cpp
dom/base/nsFrameLoader.cpp
dom/base/nsFrameLoader.h
dom/webidl/FrameLoader.webidl
--- a/docshell/shistory/ParentSHistory.cpp
+++ b/docshell/shistory/ParentSHistory.cpp
@@ -61,13 +61,13 @@ JSObject*
 ParentSHistory::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
 {
   return ParentSHistoryBinding::Wrap(cx, this, aGivenProto);
 }
 
 nsISupports*
 ParentSHistory::GetParentObject() const
 {
-  return static_cast<nsIFrameLoader*>(mFrameLoader);
+  return mFrameLoader;
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -143,17 +143,18 @@ typedef FrameMetrics::ViewID ViewID;
 // of shells can rapidly become huge and run us out of memory.  To solve that,
 // we'd need to re-institute a fixed version of bug 98158.
 #define MAX_DEPTH_CONTENT_FRAMES 10
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsFrameLoader,
                                       mDocShell,
                                       mMessageManager,
                                       mChildMessageManager,
-                                      mOpener)
+                                      mOpener,
+                                      mParentSHistory)
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsFrameLoader)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsFrameLoader)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsFrameLoader)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   if (aIID.Equals(NS_GET_IID(nsFrameLoader))) {
       // We want to end up with a pointer that can then be reinterpret_cast
       // from nsISupports* to nsFrameLoader* and end up with |this|.
@@ -2098,22 +2099,26 @@ nsFrameLoader::MaybeCreateDocShell()
   // but it must be called to make sure things are properly
   // initialized.
   if (NS_FAILED(base_win->Create()) || !win_private) {
     // Do not call Destroy() here. See bug 472312.
     NS_WARNING("Something wrong when creating the docshell for a frameloader!");
     return NS_ERROR_FAILURE;
   }
 
+  // If we are an in-process browser, we want to set up our session history. We
+  // do this by creating both the child SHistory (which is in the nsDocShell),
+  // and creating the corresponding in-process ParentSHistory.
   if (mIsTopLevelContent &&
       mOwnerContent->IsXULElement(nsGkAtoms::browser) &&
       !mOwnerContent->HasAttr(kNameSpaceID_None, nsGkAtoms::disablehistory)) {
     // XXX(nika): Set this up more explicitly?
     nsresult rv = mDocShell->InitSessionHistory();
     NS_ENSURE_SUCCESS(rv, rv);
+    mParentSHistory = new ParentSHistory(this);
   }
 
   OriginAttributes attrs;
   if (parentDocShell->ItemType() == mDocShell->ItemType()) {
     attrs = nsDocShell::Cast(parentDocShell)->GetOriginAttributes();
   }
 
   // Inherit origin attributes from parent document if
@@ -2667,16 +2672,24 @@ nsFrameLoader::TryRemoteBrowser()
   nsCOMPtr<nsIDOMChromeWindow> rootChromeWin = do_QueryInterface(rootWin);
 
   if (rootChromeWin) {
     nsCOMPtr<nsIBrowserDOMWindow> browserDOMWin;
     rootChromeWin->GetBrowserDOMWindow(getter_AddRefs(browserDOMWin));
     mRemoteBrowser->SetBrowserDOMWindow(browserDOMWin);
   }
 
+  // Set up a parent SHistory
+  if (XRE_IsParentProcess()) {
+    // XXX(nika): Once we get out of process iframes we won't want to
+    // unconditionally set this up. What do we do for iframes in a chrome loaded
+    // document for example?
+    mParentSHistory = new ParentSHistory(this);
+  }
+
   // Send down the name of the browser through mRemoteBrowser if it is set.
   // Only do this on xul:browsers for now.
   if (mOwnerContent->IsXULElement()) {
     nsAutoString frameName;
     mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::name, frameName);
     if (nsContentUtils::IsOverridingWindowName(frameName)) {
       Unused << mRemoteBrowser->SendSetWindowName(frameName);
     }
--- a/dom/base/nsFrameLoader.h
+++ b/dom/base/nsFrameLoader.h
@@ -17,16 +17,17 @@
 #include "nsIFrameLoaderOwner.h"
 #include "nsPoint.h"
 #include "nsSize.h"
 #include "nsWrapperCache.h"
 #include "nsIURI.h"
 #include "nsFrameMessageManager.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/Element.h"
+#include "mozilla/dom/ParentSHistory.h"
 #include "mozilla/Attributes.h"
 #include "nsStubMutationObserver.h"
 #include "Units.h"
 #include "nsIFrame.h"
 #include "nsPluginTags.h"
 
 class nsIURI;
 class nsSubDocumentFrame;
@@ -279,16 +280,18 @@ public:
 
   mozilla::dom::ChromeMessageSender* GetFrameMessageManager() { return mMessageManager; }
 
   mozilla::dom::Element* GetOwnerContent() { return mOwnerContent; }
   bool ShouldClipSubdocument() { return mClipSubdocument; }
 
   bool ShouldClampScrollPosition() { return mClampScrollPosition; }
 
+  mozilla::dom::ParentSHistory* GetParentSHistory() { return mParentSHistory; }
+
   /**
    * Tell this FrameLoader to use a particular remote browser.
    *
    * This will assert if mRemoteBrowser is non-null.  In practice,
    * this means you can't have successfully run TryRemoteBrowser() on
    * this object, which means you can't have called ShowRemoteFrame()
    * or ReallyStartLoading().
    */
@@ -474,16 +477,18 @@ private:
 
   // Holds the last known size of the frame.
   mozilla::ScreenIntSize mLazySize;
 
   // A stack-maintained reference to an array of promises which are blocking
   // grouped history navigation
   nsTArray<RefPtr<mozilla::dom::Promise>>* mBrowserChangingProcessBlockers;
 
+  RefPtr<mozilla::dom::ParentSHistory> mParentSHistory;
+
   bool mDepthTooGreat : 1;
   bool mIsTopLevelContent : 1;
   bool mDestroyCalled : 1;
   bool mNeedsAsyncDestroy : 1;
   bool mInSwap : 1;
   bool mInShow : 1;
   bool mHideCalled : 1;
   // True when the object is created for an element which the parser has
--- a/dom/webidl/FrameLoader.webidl
+++ b/dom/webidl/FrameLoader.webidl
@@ -29,16 +29,22 @@ interface FrameLoader {
   /**
    * Get an nsILoadContext for the top-level docshell. For remote
    * frames, a shim is returned that contains private browsing and app
    * information.
    */
   readonly attribute LoadContext loadContext;
 
   /**
+   * Get the ParentSHistory for the nsFrameLoader. May return null if this
+   * frameloader is not for a toplevel frame.
+   */
+  readonly attribute ParentSHistory? parentSHistory;
+
+  /**
    * Adds a blocking promise for the current cross process navigation.
    * This method can only be called while the "BrowserWillChangeProcess" event
    * is being fired.
    */
   [Throws]
   void addProcessChangeBlockingPromise(Promise<any> aPromise);
 
   /**