Merge inbound to mozilla-central. a=merge
authorCiure Andrei <aciure@mozilla.com>
Mon, 03 Sep 2018 12:35:26 +0300
changeset 434453 2a4cf603095ae6c4dc01d9e2b4adc217cbfd2eaf
parent 434444 d263a0a200f57a5fc7ff845b279d46f9c801a211 (current diff)
parent 434452 1a30d6a8028642c7381686b14569b9dae9bc07f2 (diff)
child 434458 eb7bf7bd5b70241403e3c06b15447f98c06b144e
child 434467 868b50082f4fa23f81accd23b14cfc3c7f611e34
push id34559
push useraciure@mozilla.com
push dateMon, 03 Sep 2018 09:35:47 +0000
treeherdermozilla-central@2a4cf603095a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone63.0a1
first release with
nightly linux32
2a4cf603095a / 63.0a1 / 20180903100454 / files
nightly linux64
2a4cf603095a / 63.0a1 / 20180903100454 / files
nightly mac
2a4cf603095a / 63.0a1 / 20180903100454 / files
nightly win32
2a4cf603095a / 63.0a1 / 20180903100454 / files
nightly win64
2a4cf603095a / 63.0a1 / 20180903100454 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge inbound to mozilla-central. a=merge
docshell/shistory/nsISHistoryInternal.idl
--- a/browser/actors/NetErrorChild.jsm
+++ b/browser/actors/NetErrorChild.jsm
@@ -163,17 +163,17 @@ class NetErrorChild extends ActorChild {
       let subjectAltNames = input.data.certSubjectAltNames.split(",");
       let numSubjectAltNames = subjectAltNames.length;
       let msgPrefix = "";
       if (numSubjectAltNames != 0) {
         if (numSubjectAltNames == 1) {
           if (newErrorPagesEnabled) {
             technicalInfo.textContent = "";
             let brandName = gBrandBundle.GetStringFromName("brandShortName");
-            msgPrefix = gPipNSSBundle.formatStringFromName("certErrorMismatchSinglePrefix1", [brandName, hostString], 2);
+            msgPrefix = gPipNSSBundle.formatStringFromName("certErrorMismatchSinglePrefix1", [brandName, hostString], 2) + " ";
             msgPrefix += gPipNSSBundle.GetStringFromName("certErrorMismatchSinglePrefix");
           } else {
             msgPrefix = gPipNSSBundle.GetStringFromName("certErrorMismatchSinglePrefix");
           }
           // Let's check if we want to make this a link.
           let okHost = input.data.certSubjectAltNames;
           let href = "";
           let thisHost = doc.location.hostname;
--- a/browser/components/sessionstore/ContentRestore.jsm
+++ b/browser/components/sessionstore/ContentRestore.jsm
@@ -376,18 +376,16 @@ HistoryListener.prototype = {
 
   uninstall() {
     let shistory = this.webNavigation.sessionHistory.legacySHistory;
     if (shistory) {
       shistory.removeSHistoryListener(this);
     }
   },
 
-  OnHistoryGoBack(backURI) { return true; },
-  OnHistoryGoForward(forwardURI) { return true; },
   OnHistoryGotoIndex(index, gotoURI) { return true; },
   OnHistoryPurge(numEntries) { return true; },
   OnHistoryReplaceEntry(index) {},
 
   // This will be called for a pending tab when loadURI(uri) is called where
   // the given |uri| only differs in the fragment.
   OnHistoryNewEntry(newURI) {
     let currentURI = this.webNavigation.currentURI;
--- a/browser/components/sessionstore/ContentSessionStore.jsm
+++ b/browser/components/sessionstore/ContentSessionStore.jsm
@@ -293,28 +293,16 @@ class SessionHistoryListener extends Han
     this.collect();
   }
 
   OnHistoryNewEntry(newURI, oldIndex) {
     // We ought to collect the previously current entry as well, see bug 1350567.
     this.collectFrom(oldIndex);
   }
 
-  OnHistoryGoBack(backURI) {
-    // We ought to collect the previously current entry as well, see bug 1350567.
-    this.collectFrom(kLastIndex);
-    return true;
-  }
-
-  OnHistoryGoForward(forwardURI) {
-    // We ought to collect the previously current entry as well, see bug 1350567.
-    this.collectFrom(kLastIndex);
-    return true;
-  }
-
   OnHistoryGotoIndex(index, gotoURI) {
     // We ought to collect the previously current entry as well, see bug 1350567.
     this.collectFrom(kLastIndex);
     return true;
   }
 
   OnHistoryPurge(numEntries) {
     this.collect();
--- a/browser/components/sessionstore/test/content.js
+++ b/browser/components/sessionstore/test/content.js
@@ -12,26 +12,16 @@ function executeSoon(callback) {
   Services.tm.dispatchToMainThread(callback);
 }
 
 var historyListener = {
   OnHistoryNewEntry() {
     sendAsyncMessage("ss-test:OnHistoryNewEntry");
   },
 
-  OnHistoryGoBack() {
-    sendAsyncMessage("ss-test:OnHistoryGoBack");
-    return true;
-  },
-
-  OnHistoryGoForward() {
-    sendAsyncMessage("ss-test:OnHistoryGoForward");
-    return true;
-  },
-
   OnHistoryGotoIndex() {
     sendAsyncMessage("ss-test:OnHistoryGotoIndex");
     return true;
   },
 
   OnHistoryPurge() {
     sendAsyncMessage("ss-test:OnHistoryPurge");
     return true;
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -114,17 +114,16 @@
 #include "nsIScrollableFrame.h"
 #include "nsIScrollObserver.h"
 #include "nsISecureBrowserUI.h"
 #include "nsISecurityUITelemetry.h"
 #include "nsISeekableStream.h"
 #include "nsISelectionDisplay.h"
 #include "nsISHEntry.h"
 #include "nsISHistory.h"
-#include "nsISHistoryInternal.h"
 #include "nsISiteSecurityService.h"
 #include "nsISocketProvider.h"
 #include "nsIStringBundle.h"
 #include "nsIStructuredCloneContainer.h"
 #include "nsISupportsPrimitives.h"
 #include "nsITabChild.h"
 #include "nsITextToSubURI.h"
 #include "nsITimedChannel.h"
@@ -418,17 +417,17 @@ nsDocShell::~nsDocShell()
   MOZ_ASSERT(!mObserved);
 
   // Avoid notifying observers while we're in the dtor.
   mIsBeingDestroyed = true;
 
   Destroy();
 
   if (mSessionHistory) {
-    mSessionHistory->LegacySHistoryInternal()->SetRootDocShell(nullptr);
+    mSessionHistory->LegacySHistory()->SetRootDocShell(nullptr);
   }
 
   if (--gDocShellCount == 0) {
     NS_IF_RELEASE(sURIFixup);
   }
 
   MOZ_LOG(gDocShellLeakLog, LogLevel::Debug, ("DOCSHELL %p destroyed\n", this));
 
@@ -1065,17 +1064,17 @@ nsDocShell::FirePageHideNotificationInte
       }
     }
 
     // If the document is unloading, remove all dynamic subframe entries.
     if (aIsUnload && !aSkipCheckingDynEntries) {
       RefPtr<ChildSHistory> rootSH = GetRootSessionHistory();
       if (rootSH && mOSHE) {
         int32_t index = rootSH->Index();
-        rootSH->LegacySHistoryInternal()->RemoveDynEntries(index, mOSHE);
+        rootSH->LegacySHistory()->RemoveDynEntries(index, mOSHE);
       }
     }
 
     // Now make sure our editor, if any, is detached before we go
     // any farther.
     DetachEditorFromWindow();
   }
 }
@@ -3792,17 +3791,17 @@ nsDocShell::AddChildSHEntryInternal(nsIS
     if (currentEntry) {
       uint32_t cloneID = 0;
       nsCOMPtr<nsISHEntry> nextEntry;
       aCloneRef->GetID(&cloneID);
       rv = nsSHistory::CloneAndReplace(currentEntry, this, cloneID,
         aNewEntry, aCloneChildren, getter_AddRefs(nextEntry));
 
       if (NS_SUCCEEDED(rv)) {
-        rv = mSessionHistory->LegacySHistoryInternal()->AddEntry(nextEntry, true);
+        rv = mSessionHistory->LegacySHistory()->AddEntry(nextEntry, true);
       }
     }
   } else {
     /* Just pass this along */
     nsCOMPtr<nsIDocShell> parent =
       do_QueryInterface(GetAsSupports(mParent), &rv);
     if (parent) {
       rv = static_cast<nsDocShell*>(parent.get())->AddChildSHEntryInternal(
@@ -3877,17 +3876,17 @@ nsDocShell::RemoveFromSessionHistory()
     return NS_OK;
   }
   RefPtr<ChildSHistory> sessionHistory = rootAsWebnav->GetSessionHistory();
   if (!sessionHistory) {
     return NS_OK;
   }
   int32_t index = sessionHistory->Index();
   AutoTArray<nsID, 16> ids({mHistoryID});
-  sessionHistory->LegacySHistoryInternal()->RemoveEntries(ids, index);
+  sessionHistory->LegacySHistory()->RemoveEntries(ids, index);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocShell::SetCreatedDynamically(bool aDynamic)
 {
   mDynamicallyCreated = aDynamic;
   return NS_OK;
@@ -3999,17 +3998,17 @@ nsDocShell::ClearFrameHistory(nsISHEntry
   for (int32_t i = 0; i < count; ++i) {
     nsCOMPtr<nsISHEntry> child;
     aEntry->GetChildAt(i, getter_AddRefs(child));
     if (child) {
       ids.AppendElement(child->DocshellID());
     }
   }
   int32_t index = rootSH->Index();
-  rootSH->LegacySHistoryInternal()->RemoveEntries(ids, index);
+  rootSH->LegacySHistory()->RemoveEntries(ids, index);
 }
 
 //-------------------------------------
 //-- Helper Method for Print discovery
 //-------------------------------------
 bool
 nsDocShell::IsPrintingOrPP(bool aDisplayErrorDialog)
 {
@@ -4102,17 +4101,17 @@ nsDocShell::GoForward()
 NS_IMETHODIMP
 nsDocShell::GotoIndex(int32_t aIndex)
 {
   if (!IsNavigationAllowed()) {
     return NS_OK; // JS may not handle returning of an error code
   }
   RefPtr<ChildSHistory> rootSH = GetRootSessionHistory();
   NS_ENSURE_TRUE(rootSH, NS_ERROR_FAILURE);
-  return rootSH->LegacySHistoryWebNav()->GotoIndex(aIndex);
+  return rootSH->LegacySHistoryImpl()->GotoIndex(aIndex);
 }
 
 NS_IMETHODIMP
 nsDocShell::LoadURI(const char16_t* aURI,
                     uint32_t aLoadFlags,
                     nsIURI* aReferringURI,
                     nsIInputStream* aPostStream,
                     nsIInputStream* aHeaderStream,
@@ -4857,17 +4856,17 @@ nsDocShell::Reload(uint32_t aReloadFlags
   uint32_t loadType = MAKE_LOAD_TYPE(LOAD_RELOAD_NORMAL, aReloadFlags);
   NS_ENSURE_TRUE(IsValidLoadType(loadType), NS_ERROR_INVALID_ARG);
 
   // Send notifications to the HistoryListener if any, about the impending
   // reload
   RefPtr<ChildSHistory> rootSH = GetRootSessionHistory();
   bool canReload = true;
   if (rootSH) {
-    rootSH->LegacySHistoryInternal()
+    rootSH->LegacySHistory()
       ->NotifyOnHistoryReload(mCurrentURI, aReloadFlags, &canReload);
   }
 
   if (!canReload) {
     return NS_OK;
   }
 
   /* If you change this part of code, make sure bug 45297 does not re-occur */
@@ -8077,17 +8076,17 @@ nsDocShell::RestoreFromHistory()
   // Set mFiredUnloadEvent = false so that the unload handler for the
   // *new* document will fire.
   mFiredUnloadEvent = false;
 
   mURIResultedInDocument = true;
   RefPtr<ChildSHistory> rootSH = GetRootSessionHistory();
   if (rootSH) {
     mPreviousTransIndex = rootSH->Index();
-    rootSH->LegacySHistoryInternal()->UpdateIndex();
+    rootSH->LegacySHistory()->UpdateIndex();
     mLoadedTransIndex = rootSH->Index();
 #ifdef DEBUG_PAGE_CACHE
     printf("Previous index: %d, Loaded index: %d\n\n", mPreviousTransIndex,
            mLoadedTransIndex);
 #endif
   }
 
   // Rather than call Embed(), we will retrieve the viewer from the session
@@ -11531,17 +11530,17 @@ nsDocShell::OnNewURI(nsIURI* aURI, nsICh
     mSessionHistory->LegacySHistory()->GetRequestedIndex(&index);
     if (index == -1) {
       index = mSessionHistory->Index();
     }
     nsCOMPtr<nsISHEntry> currentSH;
     mSessionHistory->LegacySHistory()->GetEntryAtIndex(
       index, false, getter_AddRefs(currentSH));
     if (currentSH != mLSHE) {
-      mSessionHistory->LegacySHistoryInternal()->ReplaceEntry(index, mLSHE);
+      mSessionHistory->LegacySHistory()->ReplaceEntry(index, mLSHE);
     }
   }
 
   // If this is a POST request, we do not want to include this in global
   // history.
   if (updateGHistory && aAddToGlobalHistory && !ChannelIsPost(aChannel)) {
     nsCOMPtr<nsIURI> previousURI;
     uint32_t previousFlags = 0;
@@ -11564,17 +11563,17 @@ nsDocShell::OnNewURI(nsIURI* aURI, nsICh
 
   // If this was a history load or a refresh, or it was a history load but
   // later changed to LOAD_NORMAL_REPLACE due to redirection, update the index
   // in session history.
   if (rootSH &&
        ((mLoadType & (LOAD_CMD_HISTORY | LOAD_CMD_RELOAD)) ||
          mLoadType == LOAD_NORMAL_REPLACE)) {
     mPreviousTransIndex = rootSH->Index();
-    rootSH->LegacySHistoryInternal()->UpdateIndex();
+    rootSH->LegacySHistory()->UpdateIndex();
     mLoadedTransIndex = rootSH->Index();
 #ifdef DEBUG_PAGE_CACHE
     printf("Previous index: %d, Loaded index: %d\n\n",
            mPreviousTransIndex, mLoadedTransIndex);
 #endif
   }
 
   // aCloneSHChildren exactly means "we are not loading a new document".
@@ -11876,25 +11875,25 @@ nsDocShell::AddState(JS::Handle<JS::Valu
   // call ReplaceEntry so that we notify nsIHistoryListeners that an entry
   // was replaced.
   RefPtr<ChildSHistory> rootSH = GetRootSessionHistory();
   NS_ENSURE_TRUE(rootSH, NS_ERROR_UNEXPECTED);
 
   if (!aReplace) {
     int32_t curIndex = rootSH->Index();
     if (curIndex > -1) {
-      rootSH->LegacySHistoryInternal()->EvictOutOfRangeContentViewers(curIndex);
+      rootSH->LegacySHistory()->EvictOutOfRangeContentViewers(curIndex);
     }
   } else {
     nsCOMPtr<nsISHEntry> rootSHEntry = nsSHistory::GetRootSHEntry(newSHEntry);
 
     int32_t index = -1;
     rv = rootSH->LegacySHistory()->GetIndexOfEntry(rootSHEntry, &index);
     if (NS_SUCCEEDED(rv) && index > -1) {
-      rootSH->LegacySHistoryInternal()->ReplaceEntry(index, rootSHEntry);
+      rootSH->LegacySHistory()->ReplaceEntry(index, rootSHEntry);
     }
   }
 
   // Step 6: If the document's URI changed, update document's URI and update
   // global history.
   //
   // We need to call FireOnLocationChange so that the browser's address bar
   // gets updated and the back button is enabled, but we only need to
@@ -12201,31 +12200,29 @@ nsDocShell::AddToSessionHistory(nsIURI* 
       int32_t index = 0;
       mSessionHistory->LegacySHistory()->GetRequestedIndex(&index);
       if (index == -1) {
         index = mSessionHistory->Index();
       }
 
       // Replace the current entry with the new entry
       if (index >= 0) {
-        rv = mSessionHistory->LegacySHistoryInternal()->ReplaceEntry(index,
-                                                                     entry);
+        rv = mSessionHistory->LegacySHistory()->ReplaceEntry(index, entry);
       } else {
         // If we're trying to replace an inexistant shistory entry, append.
         addToSHistory = true;
       }
     }
 
     if (addToSHistory) {
       // Add to session history
       mPreviousTransIndex = mSessionHistory->Index();
 
       bool shouldPersist = ShouldAddToSessionHistory(aURI, aChannel);
-      rv = mSessionHistory->LegacySHistoryInternal()->AddEntry(
-        entry, shouldPersist);
+      rv = mSessionHistory->LegacySHistory()->AddEntry(entry, shouldPersist);
       mLoadedTransIndex = mSessionHistory->Index();
 #ifdef DEBUG_PAGE_CACHE
       printf("Previous index: %d, Loaded index: %d\n\n",
              mPreviousTransIndex, mLoadedTransIndex);
 #endif
     }
   } else {
     // This is a subframe.
--- a/docshell/shistory/ChildSHistory.cpp
+++ b/docshell/shistory/ChildSHistory.cpp
@@ -60,19 +60,16 @@ ChildSHistory::CanGo(int32_t aOffset)
     return false;
   }
   return index.value() < Count() && index.value() >= 0;
 }
 
 void
 ChildSHistory::Go(int32_t aOffset, ErrorResult& aRv)
 {
-  // XXX(nika): Should we turn Go(-1) and Go(1) to call GoForward and GoBack?
-  // They technically fire different change events but I couldn't find anyone
-  // who cares, so I'm inclined not to.
   CheckedInt<int32_t> index = Index();
   index += aOffset;
   if (!index.isValid()) {
     aRv.Throw(NS_ERROR_FAILURE);
     return;
   }
   aRv = mHistory->GotoIndex(index.value());
 }
@@ -84,24 +81,18 @@ ChildSHistory::EvictLocalContentViewers(
 }
 
 nsISHistory*
 ChildSHistory::LegacySHistory()
 {
   return mHistory;
 }
 
-nsISHistoryInternal*
-ChildSHistory::LegacySHistoryInternal()
-{
-  return mHistory;
-}
-
-nsIWebNavigation*
-ChildSHistory::LegacySHistoryWebNav()
+nsSHistory*
+ChildSHistory::LegacySHistoryImpl()
 {
   return mHistory;
 }
 
 ParentSHistory*
 ChildSHistory::GetParentIfSameProcess()
 {
   if (XRE_IsContentProcess()) {
--- a/docshell/shistory/ChildSHistory.h
+++ b/docshell/shistory/ChildSHistory.h
@@ -22,17 +22,16 @@
 
 #include "nsCOMPtr.h"
 #include "mozilla/ErrorResult.h"
 #include "nsWrapperCache.h"
 
 class nsSHistory;
 class nsDocShell;
 class nsISHistory;
-class nsISHistoryInternal;
 class nsIWebNavigation;
 class nsIGlobalObject;
 
 namespace mozilla {
 namespace dom {
 
 class ParentSHistory;
 
@@ -67,18 +66,17 @@ public:
   void Go(int32_t aOffset, ErrorResult& aRv);
 
   /**
    * Evicts all content viewers within the current process.
    */
   void EvictLocalContentViewers();
 
   nsISHistory* LegacySHistory();
-  nsISHistoryInternal* LegacySHistoryInternal();
-  nsIWebNavigation* LegacySHistoryWebNav();
+  nsSHistory* LegacySHistoryImpl();
 
   ParentSHistory* GetParentIfSameProcess();
 
 private:
   virtual ~ChildSHistory();
 
   RefPtr<nsDocShell> mDocShell;
   RefPtr<nsSHistory> mHistory;
--- a/docshell/shistory/moz.build
+++ b/docshell/shistory/moz.build
@@ -3,17 +3,16 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 XPIDL_SOURCES += [
     'nsIBFCacheEntry.idl',
     'nsISHEntry.idl',
     'nsISHistory.idl',
-    'nsISHistoryInternal.idl',
     'nsISHistoryListener.idl',
     'nsISHTransaction.idl',
 ]
 
 XPIDL_MODULE = 'shistory'
 
 EXPORTS += [
     'nsSHEntryShared.h',
--- a/docshell/shistory/nsISHistory.idl
+++ b/docshell/shistory/nsISHistory.idl
@@ -1,17 +1,27 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: IDL; 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 "nsISupports.idl"
 
+interface nsIBFCacheEntry;
+interface nsIDocShell;
 interface nsISHEntry;
 interface nsISHistoryListener;
+interface nsISHTransaction;
+interface nsIURI;
+
+%{C++
+#include "nsTArrayForwardDeclare.h"
+%}
+
+[ref] native nsDocshellIDArray(nsTArray<nsID>);
 
 /**
  * An interface to the primary properties of the Session History
  * component. In an embedded browser environment, the nsIWebBrowser
  * object creates an instance of session history for each open window.
  * A handle to the session history object can be obtained from
  * nsIWebNavigation. In a non-embedded situation, the  owner of the
  * session history component must create a instance of it and set
@@ -27,113 +37,232 @@ interface nsISHistory: nsISupports
    * bfcache around the currently active SHEntry.
    *
    * We try to keep viewers for SHEntries between index - VIEWER_WINDOW and
    * index + VIEWER_WINDOW alive.
    */
   const long VIEWER_WINDOW = 3;
 
   /**
-   * A readonly property of the interface that returns 
+   * A readonly property of the interface that returns
    * the number of toplevel documents currently available
    * in session history.
    */
-   readonly attribute long count;
+  readonly attribute long count;
 
   /**
    * A readonly property of the interface that returns
    * the index of the current document in session history.
    */
-   readonly attribute long index;
+  readonly attribute long index;
 
   /**
    * A readonly property of the interface that returns
    * the index of the last document that started to load and
    * didn't finished yet. When document finishes the loading
    * value -1 is returned.
    */
-   readonly attribute long requestedIndex;
+  readonly attribute long requestedIndex;
 
   /**
    * A read/write property of the interface, used to Get/Set
-   * the maximum number of toplevel documents, session history 
-   * can hold for each instance. 
+   * the maximum number of toplevel documents, session history
+   * can hold for each instance.
    */
-   attribute long maxLength;
+  attribute long maxLength;
 
   /**
    * Called to obtain handle to the history entry at a
    * given index.
    *
    * @param index             The index value whose entry is requested.
    *                          The oldest entry is located at index == 0.
    * @param modifyIndex       A boolean flag that indicates if the current
-   *                          index of session history should be modified 
+   *                          index of session history should be modified
    *                          to the parameter index.
    *
-   * @return                  <code>NS_OK</code> history entry for 
+   * @return                  <code>NS_OK</code> history entry for
    *                          the index is obtained successfully.
    *                          <code>NS_ERROR_FAILURE</code> Error in obtaining
    *                          history entry for the given index.
    */
-   nsISHEntry getEntryAtIndex(in long index, in boolean modifyIndex);
+  nsISHEntry getEntryAtIndex(in long aIndex, in boolean aModifyIndex);
 
   /**
    * Called to purge older documents from history.
-   * Documents can be removed from session history for various 
-   * reasons. For example to  control memory usage of the browser, to 
+   * Documents can be removed from session history for various
+   * reasons. For example to  control memory usage of the browser, to
    * prevent users from loading documents from history, to erase evidence of
    * prior page loads etc...
    *
    * @param numEntries        The number of toplevel documents to be
    *                          purged from history. During purge operation,
-   *                          the latest documents are maintained and older 
+   *                          the latest documents are maintained and older
    *                          'numEntries' documents are removed from history.
-   * @throws                  <code>NS_SUCCESS_LOSS_OF_INSIGNIFICANT_DATA</code> Purge was vetod.
+   * @throws                  <code>NS_SUCCESS_LOSS_OF_INSIGNIFICANT_DATA</code>
+   *                          Purge was vetod.
    * @throws                  <code>NS_ERROR_FAILURE</code> numEntries is
    *                          invalid or out of bounds with the size of history.
-   *                          
    */
-   void PurgeHistory(in long numEntries);
+  void PurgeHistory(in long aNumEntries);
 
   /**
    * Called to register a listener for the session history component.
    * Listeners are notified when pages are loaded or purged from history.
-   * 
+   *
    * @param aListener         Listener object to be notified for all
    *                          page loads that initiate in session history.
    *
-   * @note                    A listener object must implement 
+   * @note                    A listener object must implement
    *                          nsISHistoryListener and nsSupportsWeakReference
    *
    * @see nsISHistoryListener
    * @see nsSupportsWeakReference
    */
-   void addSHistoryListener(in nsISHistoryListener aListener);
+  void addSHistoryListener(in nsISHistoryListener aListener);
 
   /**
    * Called to remove a listener for the session history component.
    * Listeners are notified when pages are loaded from history.
-   * 
-   * @param aListener         Listener object to be removed from 
+   *
+   * @param aListener         Listener object to be removed from
    *                          session history.
    *
-   * @note                    A listener object must implement 
+   * @note                    A listener object must implement
    *                          nsISHistoryListener and nsSupportsWeakReference
    * @see nsISHistoryListener
    * @see nsSupportsWeakReference
-   */ 
-   void removeSHistoryListener(in nsISHistoryListener aListener);
+   */
+  void removeSHistoryListener(in nsISHistoryListener aListener);
 
-   void reloadCurrentEntry();
+  void reloadCurrentEntry();
 
-   /**
+  /**
    * Called to obtain the index to a given history entry.
    *
    * @param aEntry            The entry to obtain the index of.
    *
    * @return                  <code>NS_OK</code> index for the history entry
    *                          is obtained successfully.
    *                          <code>NS_ERROR_FAILURE</code> Error in obtaining
    *                          index for the given history entry.
    */
-   long getIndexOfEntry(in nsISHEntry aEntry);
+  long getIndexOfEntry(in nsISHEntry aEntry);
+
+  /**
+   * Add a new Entry to the History List.
+   *
+   * @param aEntry            The entry to add.
+   * @param aPersist          If true this specifies that the entry should
+   *                          persist in the list. If false, this means that
+   *                          when new entries are added this element will not
+   *                          appear in the session history list.
+   */
+  void addEntry(in nsISHEntry aEntry, in boolean aPersist);
+
+  /**
+   * Get the transaction at a particular index.
+   */
+  nsISHTransaction GetTransactionAtIndex(in int32_t aIndex);
+
+  /**
+   * Sets the toplevel docshell object to which this SHistory object belongs to.
+   */
+  void setRootDocShell(in nsIDocShell rootDocShell);
+
+  /**
+   * Update the index maintained by sessionHistory
+   */
+  void updateIndex();
+
+  /**
+   * Replace the nsISHEntry at a particular index
+   *
+   * @param aIndex            The index at which the entry should be replaced.
+   * @param aReplaceEntry     The replacement entry for the index.
+   */
+  void replaceEntry(in long aIndex, in nsISHEntry aReplaceEntry);
+
+  /**
+   * Notifies all registered session history listeners about an impending
+   * reload.
+   *
+   * @param aReloadURI        The URI of the document to be reloaded.
+   * @param aReloadFlags      Flags that indicate how the document is to be
+   *                          refreshed. See constants on the nsIWebNavigation
+   *                          interface.
+   *
+   * @return                  Whether the operation can proceed.
+   */
+  boolean notifyOnHistoryReload(in nsIURI aReloadURI,
+                                in unsigned long aReloadFlags);
+
+  /**
+   * Evict content viewers which don't lie in the "safe" range around aIndex.
+   * In practice, this should leave us with no more than gHistoryMaxViewers
+   * viewers associated with this SHistory object.
+   *
+   * Also make sure that the total number of content viewers in all windows is
+   * not greater than our global max; if it is, evict viewers as appropriate.
+   *
+   * @param aIndex           The index around which the "safe" range is
+   *                         centered.  In general, if you just navigated the
+   *                         history, aIndex should be the index history was
+   *                         navigated to.
+   */
+  void evictOutOfRangeContentViewers(in long aIndex);
+
+  /**
+   * Evict the content viewer associated with a bfcache entry that has timed
+   * out.
+   */
+  void evictExpiredContentViewerForEntry(in nsIBFCacheEntry aEntry);
+
+  /**
+   * Evict all the content viewers in this session history
+   */
+  void evictAllContentViewers();
+
+  /**
+   * Add a BFCache entry to expiration tracker so it gets evicted on
+   * expiration.
+   */
+  void addToExpirationTracker(in nsIBFCacheEntry aEntry);
+
+  /**
+   * Remove a BFCache entry from expiration tracker.
+   */
+  void removeFromExpirationTracker(in nsIBFCacheEntry aEntry);
+
+  /**
+   * Remove dynamic entries found at given index.
+   *
+   * @param aIndex           Index to remove dynamic entries from. It will be
+   *                         passed to RemoveEntries as aStartIndex.
+   * @param aEntry (optional)  The entry to start looking in for dynamic
+   *                         entries. Only the dynamic descendants of the
+   *                         entry will be removed. If not given, all dynamic
+   *                         entries at the index will be removed.
+   */
+  [noscript, notxpcom]
+  void RemoveDynEntries(in long aIndex, in nsISHEntry aEntry);
+
+  /**
+   * Similar to RemoveDynEntries, but instead of specifying an index, use the
+   * given BFCacheEntry to find the index and remove dynamic entries from the
+   * index.
+   *
+   * The method takes no effect if the bfcache entry is not or no longer hold
+   * by the SHistory instance.
+   *
+   * @param aEntry           The bfcache entry to look up for index to remove
+   *                         dynamic entries from.
+   */
+  [noscript, notxpcom]
+  void RemoveDynEntriesForBFCacheEntry(in nsIBFCacheEntry aEntry);
+
+  /**
+   * Removes entries from the history if their docshellID is in
+   * aIDs array.
+   */
+  [noscript, notxpcom]
+  void RemoveEntries(in nsDocshellIDArray aIDs, in long aStartIndex);
 };
deleted file mode 100644
--- a/docshell/shistory/nsISHistoryInternal.idl
+++ /dev/null
@@ -1,136 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* 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 nsIBFCacheEntry;
-interface nsISHEntry;
-interface nsISHistoryListener;
-interface nsISHTransaction;
-interface nsIDocShell;
-interface nsIURI;
-
-%{C++
-#include "nsTArrayForwardDeclare.h"
-%}
-
-[ref] native nsDocshellIDArray(nsTArray<nsID>);
-
-[scriptable, uuid(3dfb2f54-378d-4d3c-a9f9-95dd2673248c)]
-interface nsISHistoryInternal: nsISupports
-{
-  /**
-   * Add a new Entry to the History List
-   * @param aEntry - The entry to add
-   * @param aPersist - If true this specifies that the entry should persist
-   * in the list.  If false, this means that when new entries are added
-   * this element will not appear in the session history list.
-   */
-   void  addEntry(in nsISHEntry aEntry, in boolean aPersist);
-
-  /**
-   * Get the transaction at a particular index.
-   */
-  nsISHTransaction GetTransactionAtIndex(in int32_t aIndex);
-
-  /**
-   * Sets the toplevel docshell object to which this SHistory object belongs to.
-   */
-   void setRootDocShell(in nsIDocShell rootDocShell);
-
-  /**
-   * Update the index maintained by sessionHistory
-   */
-   void updateIndex();
-
-  /**
-   * Replace the nsISHEntry at a particular index
-   * @param aIndex - The index at which the entry should be replaced
-   * @param aReplaceEntry - The replacement entry for the index.
-   */
-   void replaceEntry(in long aIndex, in nsISHEntry aReplaceEntry);
-
-  /**
-   * Notifies all registered session history listeners about an impending
-   * reload.
-   *
-   * @param aReloadURI    The URI of the document to be reloaded.
-   * @param aReloadFlags  Flags that indicate how the document is to be
-   *                      refreshed. See constants on the nsIWebNavigation
-   *                      interface.
-   * @return              Whether the operation can proceed.
-   */
-   boolean notifyOnHistoryReload(in nsIURI aReloadURI, in unsigned long aReloadFlags);
-
-   /**
-    * Evict content viewers which don't lie in the "safe" range around aIndex.
-    * In practice, this should leave us with no more than gHistoryMaxViewers
-    * viewers associated with this SHistory object.
-    *
-    * Also make sure that the total number of content viewers in all windows is
-    * not greater than our global max; if it is, evict viewers as appropriate.
-    *
-    * @param aIndex - The index around which the "safe" range is centered.  In
-    *   general, if you just navigated the history, aIndex should be the index
-    *   history was navigated to.
-    */
-   void evictOutOfRangeContentViewers(in long aIndex);
-
-   /**
-    * Evict the content viewer associated with a bfcache entry
-    * that has timed out.
-    */
-   void evictExpiredContentViewerForEntry(in nsIBFCacheEntry aEntry);
-
-   /**
-    * Evict all the content viewers in this session history
-    */
-   void evictAllContentViewers();
-
-   /**
-    * Add a BFCache entry to expiration tracker so it gets evicted on expiration.
-    */
-   void addToExpirationTracker(in nsIBFCacheEntry aEntry);
-
-   /**
-    * Remove a BFCache entry from expiration tracker.
-    */
-   void removeFromExpirationTracker(in nsIBFCacheEntry aEntry);
-
-   /**
-    * Remove dynamic entries found at given index.
-    *
-    * @param aIndex
-    *        Index to remove dynamic entries from. It will be passed to
-    *        RemoveEntries as aStartIndex.
-    * @param aEntry (optional)
-    *        The entry to start looking in for dynamic entries. Only the
-    *        dynamic descendants of the entry will be removed. If not given,
-    *        all dynamic entries at the index will be removed.
-    */
-   [noscript, notxpcom] void RemoveDynEntries(in long aIndex,
-                                              in nsISHEntry aEntry);
-
-   /**
-    * Similar to RemoveDynEntries, but instead of specifying an index, use the
-    * given BFCacheEntry to find the index and remove dynamic entries from the
-    * index.
-    *
-    * The method takes no effect if the bfcache entry is not or no longer hold
-    * by the SHistory instance.
-    *
-    * @param aEntry
-    *        The bfcache entry to look up for index to remove dynamic entries
-    *        from.
-    */
-   [noscript, notxpcom] void RemoveDynEntriesForBFCacheEntry(in nsIBFCacheEntry aEntry);
-
-   /**
-    * Removes entries from the history if their docshellID is in
-    * aIDs array.
-    */
-   [noscript, notxpcom] void RemoveEntries(in nsDocshellIDArray aIDs,
-                                           in long aStartIndex);
-};
--- a/docshell/shistory/nsISHistoryListener.idl
+++ b/docshell/shistory/nsISHistoryListener.idl
@@ -29,40 +29,16 @@ interface nsISHistoryListener : nsISuppo
    * added to session history by docshell when new pages are loaded in a frame
    * or content area, for example via nsIWebNavigation::loadURI()
    *
    * @param aNewURI     The URI of the document to be added to session history.
    * @param aOldIndex   The index of the current history item before the operation.
    */
    void OnHistoryNewEntry(in nsIURI aNewURI, in long aOldIndex);
 
-  /**
-   * Called when navigating to a previous session history entry, for example
-   * due to a nsIWebNavigation::goBack() call.
-   *
-   * @param aBackURI    The URI of the session history entry being navigated to.
-   *                    It could be null in case of a grouped session history
-   *                    navigation since we have no URI information of entries
-   *                    existing in other partial histories.
-   * @return            Whether the operation can proceed.
-   */
-   boolean OnHistoryGoBack(in nsIURI aBackURI);
-
-  /**
-   * Called when navigating to a next session history entry, for example
-   * due to a nsIWebNavigation::goForward() call.
-   *
-   * @param aForwardURI   The URI of the session history entry being navigated to.
-   *                      It could be null in case of a grouped session history
-   *                      navigation since we have no URI information of entries
-   *                      existing in other partial histories.
-   * @return              Whether the operation can proceed.
-   */
-   boolean OnHistoryGoForward(in nsIURI aForwardURI);
-
   /** 
    * Called when the current document is reloaded, for example due to a
    * nsIWebNavigation::reload() call.
    *
    * @param aReloadURI    The URI of the document to be reloaded.
    * @param aReloadFlags  Flags that indicate how the document is to be 
    *                      refreshed. See constants on the nsIWebNavigation
    *                      interface.
--- a/docshell/shistory/nsSHEntryShared.cpp
+++ b/docshell/shistory/nsSHEntryShared.cpp
@@ -9,17 +9,16 @@
 #include "nsArray.h"
 #include "nsDocShellEditorData.h"
 #include "nsIContentViewer.h"
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsIDocument.h"
 #include "nsILayoutHistoryState.h"
 #include "nsISHistory.h"
-#include "nsISHistoryInternal.h"
 #include "nsIWebNavigation.h"
 #include "nsThreadUtils.h"
 
 #include "mozilla/Attributes.h"
 #include "mozilla/Preferences.h"
 
 namespace dom = mozilla::dom;
 
@@ -87,17 +86,17 @@ nsSHEntryShared::Duplicate(nsSHEntryShar
   newEntry->mLastTouched = aEntry->mLastTouched;
 
   return newEntry.forget();
 }
 
 void
 nsSHEntryShared::RemoveFromExpirationTracker()
 {
-  nsCOMPtr<nsISHistoryInternal> shistory = do_QueryReferent(mSHistory);
+  nsCOMPtr<nsISHistory> shistory = do_QueryReferent(mSHistory);
   if (shistory && GetExpirationState()->IsTracked()) {
     shistory->RemoveFromExpirationTracker(this);
   }
 }
 
 nsresult
 nsSHEntryShared::SyncPresentationState()
 {
@@ -150,17 +149,17 @@ nsSHEntryShared::SetContentViewer(nsICon
   // non-null content viewer, the entry shouldn't have been tracked either.
   MOZ_ASSERT(!GetExpirationState()->IsTracked());
   mContentViewer = aViewer;
 
   if (mContentViewer) {
     // mSHistory is only set for root entries, but in general bfcache only
     // applies to root entries as well. BFCache for subframe navigation has been
     // disabled since 2005 in bug 304860.
-    if (nsCOMPtr<nsISHistoryInternal> shistory = do_QueryReferent(mSHistory)) {
+    if (nsCOMPtr<nsISHistory> shistory = do_QueryReferent(mSHistory)) {
       shistory->AddToExpirationTracker(this);
     }
 
     // Store observed document in strong pointer in case it is removed from
     // the contentviewer
     mDocument = mContentViewer->GetDocument();
     if (mDocument) {
       mDocument->SetBFCacheEntry(this);
@@ -185,17 +184,17 @@ nsSHEntryShared::RemoveFromBFCacheSync()
   DropPresentationState();
 
   if (viewer) {
     viewer->Destroy();
   }
 
   // Now that we've dropped the viewer, we have to clear associated dynamic
   // subframe entries.
-  nsCOMPtr<nsISHistoryInternal> shistory = do_QueryReferent(mSHistory);
+  nsCOMPtr<nsISHistory> shistory = do_QueryReferent(mSHistory);
   if (shistory) {
     shistory->RemoveDynEntriesForBFCacheEntry(this);
   }
 
   return NS_OK;
 }
 
 nsresult
@@ -216,17 +215,17 @@ nsSHEntryShared::RemoveFromBFCacheAsync(
   RefPtr<nsSHEntryShared> self = this;
   nsresult rv = mDocument->Dispatch(mozilla::TaskCategory::Other,
     NS_NewRunnableFunction("nsSHEntryShared::RemoveFromBFCacheAsync",
     [self, viewer, document]() {
       if (viewer) {
         viewer->Destroy();
       }
 
-      nsCOMPtr<nsISHistoryInternal> shistory = do_QueryReferent(self->mSHistory);
+      nsCOMPtr<nsISHistory> shistory = do_QueryReferent(self->mSHistory);
       if (shistory) {
         shistory->RemoveDynEntriesForBFCacheEntry(self);
       }
     }));
 
   if (NS_FAILED(rv)) {
     NS_WARNING("Failed to dispatch RemoveFromBFCacheAsync runnable.");
   } else {
--- a/docshell/shistory/nsSHistory.cpp
+++ b/docshell/shistory/nsSHistory.cpp
@@ -135,18 +135,16 @@ static LazyLogModule gSHistoryLog("nsSHi
     if (canceled) {                                        \
       retval = false;                                      \
     }                                                      \
   }                                                        \
   PR_END_MACRO
 
 enum HistCmd
 {
-  HIST_CMD_BACK,
-  HIST_CMD_FORWARD,
   HIST_CMD_GOTOINDEX,
   HIST_CMD_RELOAD
 };
 
 class nsSHistoryObserver final : public nsIObserver
 {
 public:
   NS_DECL_ISUPPORTS
@@ -250,18 +248,16 @@ nsSHistory::~nsSHistory()
 }
 
 NS_IMPL_ADDREF(nsSHistory)
 NS_IMPL_RELEASE(nsSHistory)
 
 NS_INTERFACE_MAP_BEGIN(nsSHistory)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISHistory)
   NS_INTERFACE_MAP_ENTRY(nsISHistory)
-  NS_INTERFACE_MAP_ENTRY(nsIWebNavigation)
-  NS_INTERFACE_MAP_ENTRY(nsISHistoryInternal)
   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
 NS_INTERFACE_MAP_END
 
 // static
 uint32_t
 nsSHistory::CalcMaxTotalViewers()
 {
   // This value allows tweaking how fast the allowed amount of content viewers
@@ -958,76 +954,17 @@ nsSHistory::EvictAllContentViewers()
   // we might have viewers quite far from mIndex.  So just evict everything.
   for (int32_t i = 0; i < Length(); i++) {
     EvictContentViewerForTransaction(mTransactions[i]);
   }
 
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsSHistory::GetCanGoBack(bool* aCanGoBack)
-{
-  NS_ENSURE_ARG_POINTER(aCanGoBack);
-
-  int32_t index = -1;
-  NS_ENSURE_SUCCESS(GetIndex(&index), NS_ERROR_FAILURE);
-  if (index > 0) {
-    *aCanGoBack = true;
-    return NS_OK;
-  }
-
-  *aCanGoBack = false;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsSHistory::GetCanGoForward(bool* aCanGoForward)
-{
-  NS_ENSURE_ARG_POINTER(aCanGoForward);
-
-  int32_t index = -1;
-  int32_t count = -1;
-  NS_ENSURE_SUCCESS(GetIndex(&index), NS_ERROR_FAILURE);
-  NS_ENSURE_SUCCESS(GetCount(&count), NS_ERROR_FAILURE);
-  if (index >= 0 && index < (count - 1)) {
-    *aCanGoForward = true;
-    return NS_OK;
-  }
-
-  *aCanGoForward = false;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsSHistory::GoBack()
-{
-  bool canGoBack = false;
-
-  GetCanGoBack(&canGoBack);
-  if (!canGoBack) {
-    return NS_ERROR_UNEXPECTED;
-  }
-  return LoadEntry(mIndex - 1, LOAD_HISTORY, HIST_CMD_BACK);
-}
-
-NS_IMETHODIMP
-nsSHistory::GoForward()
-{
-  bool canGoForward = false;
-
-  GetCanGoForward(&canGoForward);
-  if (!canGoForward) {
-    return NS_ERROR_UNEXPECTED;
-  }
-  return LoadEntry(mIndex + 1, LOAD_HISTORY,
-                   HIST_CMD_FORWARD);
-}
-
-NS_IMETHODIMP
+nsresult
 nsSHistory::Reload(uint32_t aReloadFlags)
 {
   uint32_t loadType;
   if (aReloadFlags & nsIWebNavigation::LOAD_FLAGS_BYPASS_PROXY &&
       aReloadFlags & nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE) {
     loadType = LOAD_RELOAD_BYPASS_PROXY_AND_CACHE;
   } else if (aReloadFlags & nsIWebNavigation::LOAD_FLAGS_BYPASS_PROXY) {
     loadType = LOAD_RELOAD_BYPASS_PROXY;
@@ -1571,93 +1508,32 @@ nsSHistory::UpdateIndex()
     mIndex = mRequestedIndex;
     NOTIFY_LISTENERS(OnIndexChanged, (mIndex))
   }
 
   mRequestedIndex = -1;
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsSHistory::Stop(uint32_t aStopFlags)
-{
-  // Not implemented
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsSHistory::GetDocument(nsIDocument** aDocument)
-{
-  // Not implemented
-  return NS_OK;
-}
-
-NS_IMETHODIMP
+nsresult
 nsSHistory::GetCurrentURI(nsIURI** aResultURI)
 {
   NS_ENSURE_ARG_POINTER(aResultURI);
   nsresult rv;
 
   nsCOMPtr<nsISHEntry> currentEntry;
   rv = GetEntryAtIndex(mIndex, false, getter_AddRefs(currentEntry));
   if (NS_FAILED(rv) && !currentEntry) {
     return rv;
   }
   rv = currentEntry->GetURI(aResultURI);
   return rv;
 }
 
-NS_IMETHODIMP
-nsSHistory::GetReferringURI(nsIURI** aURI)
-{
-  *aURI = nullptr;
-  // Not implemented
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsSHistory::GetSessionHistoryXPCOM(nsISupports** aSessionHistory)
-{
-  *aSessionHistory = nullptr;
-  // Not implemented
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsSHistory::LoadURIWithOptions(const char16_t* aURI,
-                               uint32_t aLoadFlags,
-                               nsIURI* aReferringURI,
-                               uint32_t aReferrerPolicy,
-                               nsIInputStream* aPostStream,
-                               nsIInputStream* aExtraHeaderStream,
-                               nsIURI* aBaseURI,
-                               nsIPrincipal* aTriggeringPrincipal)
-{
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsSHistory::SetOriginAttributesBeforeLoading(JS::HandleValue aOriginAttributes,
-                                             JSContext* aCx)
-{
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsSHistory::LoadURI(const char16_t* aURI,
-                    uint32_t aLoadFlags,
-                    nsIURI* aReferringURI,
-                    nsIInputStream* aPostStream,
-                    nsIInputStream* aExtraHeaderStream,
-                    nsIPrincipal* aTriggeringPrincipal)
-{
-  return NS_OK;
-}
-
-NS_IMETHODIMP
+nsresult
 nsSHistory::GotoIndex(int32_t aIndex)
 {
   return LoadEntry(aIndex, LOAD_HISTORY, HIST_CMD_GOTOINDEX);
 }
 
 nsresult
 nsSHistory::LoadNextPossibleEntry(int32_t aNewIndex, long aLoadType,
                                   uint32_t aHistCmd)
@@ -1704,25 +1580,17 @@ nsSHistory::LoadEntry(int32_t aIndex, lo
 
   // Get the uri for the entry we are about to visit
   nextEntry->GetURI(getter_AddRefs(nextURI));
 
   MOZ_ASSERT((prevEntry && nextEntry && nextURI), "prevEntry, nextEntry and nextURI can't be null");
 
   // Send appropriate listener notifications.
   bool canNavigate = true;
-  if (aHistCmd == HIST_CMD_BACK) {
-    // We are going back one entry. Send GoBack notifications
-    NOTIFY_LISTENERS_CANCELABLE(OnHistoryGoBack, canNavigate,
-                                (nextURI, &canNavigate));
-  } else if (aHistCmd == HIST_CMD_FORWARD) {
-    // We are going forward. Send GoForward notification
-    NOTIFY_LISTENERS_CANCELABLE(OnHistoryGoForward, canNavigate,
-                                (nextURI, &canNavigate));
-  } else if (aHistCmd == HIST_CMD_GOTOINDEX) {
+  if (aHistCmd == HIST_CMD_GOTOINDEX) {
     // We are going somewhere else. This is not reload either
     NOTIFY_LISTENERS_CANCELABLE(OnHistoryGotoIndex, canNavigate,
                                 (aIndex, nextURI, &canNavigate));
   }
 
   if (!canNavigate) {
     // If the listener asked us not to proceed with
     // the operation, simply return.
--- a/docshell/shistory/nsSHistory.h
+++ b/docshell/shistory/nsSHistory.h
@@ -5,36 +5,32 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsSHistory_h
 #define nsSHistory_h
 
 #include "nsCOMPtr.h"
 #include "nsExpirationTracker.h"
 #include "nsISHistory.h"
-#include "nsISHistoryInternal.h"
-#include "nsIWebNavigation.h"
 #include "nsSHEntryShared.h"
 #include "nsSimpleEnumerator.h"
 #include "nsTObserverArray.h"
 #include "nsWeakReference.h"
 
 #include "mozilla/LinkedList.h"
 #include "mozilla/UniquePtr.h"
 
 class nsIDocShell;
 class nsDocShell;
 class nsSHistoryObserver;
 class nsISHEntry;
 class nsISHTransaction;
 
 class nsSHistory final : public mozilla::LinkedListElement<nsSHistory>,
                          public nsISHistory,
-                         public nsISHistoryInternal,
-                         public nsIWebNavigation,
                          public nsSupportsWeakReference
 {
 public:
 
   // The timer based history tracker is used to evict bfcache on expiration.
   class HistoryTracker final : public nsExpirationTracker<nsSHEntryShared, 3>
   {
   public:
@@ -67,18 +63,20 @@ public:
     nsISHEntry* destTreeRoot;    // constant; the root of the dest tree
     nsISHEntry* destTreeParent;  // constant; the node under destTreeRoot
                                  // whose children will correspond to aEntry
   };
 
   nsSHistory();
   NS_DECL_ISUPPORTS
   NS_DECL_NSISHISTORY
-  NS_DECL_NSISHISTORYINTERNAL
-  NS_DECL_NSIWEBNAVIGATION
+
+  nsresult GotoIndex(int32_t aIndex);
+  nsresult Reload(uint32_t aReloadFlags);
+  nsresult GetCurrentURI(nsIURI** aResultURI);
 
   // One time initialization method called upon docshell module construction
   static nsresult Startup();
   static void Shutdown();
   static void UpdatePrefs();
 
   // Max number of total cached content viewers.  If the pref
   // browser.sessionhistory.max_total_viewers is negative, then
--- a/docshell/test/browser/browser_bug422543.js
+++ b/docshell/test/browser/browser_bug422543.js
@@ -21,17 +21,17 @@ add_task(async function runTests() {
   await checkListeners("gotoindex", "forward to the second shentry");
 
   await whenPageShown(browser, () => browser.reload());
   await checkListeners("reload", "current shentry reloaded");
 
   await whenPageShown(browser, () => browser.gotoIndex(0));
   await checkListeners("gotoindex", "back to the first index");
 
-  // Check nsISHistoryInternal.notifyOnHistoryReload
+  // Check nsISHistory.notifyOnHistoryReload
   info("# part 2");
   ok((await notifyReload()), "reloading has not been canceled");
   await checkListeners("reload", "saw the reload notification");
 
   // Let the first listener cancel the reload action.
   info("# part 3");
   await resetListeners();
   await setListenerRetval(0, false);
--- a/docshell/test/browser/browser_bug670318.js
+++ b/docshell/test/browser/browser_bug670318.js
@@ -34,18 +34,16 @@ add_task(async function test() {
             delete content._testListener;
             content.setTimeout(() => { content.location.reload(); }, 0);
           }
 
           return true;
         },
 
         OnHistoryReload: () => true,
-        OnHistoryGoBack: () => true,
-        OnHistoryGoForward: () => true,
         OnHistoryGotoIndex: () => true,
         OnHistoryPurge: () => true,
         OnHistoryReplaceEntry: () => {
           // The initial load of about:blank causes a transient entry to be
           // created, so our first navigation to a real page is a replace
           // instead of a new entry.
           ++count;
           return true;
--- a/docshell/test/browser/file_bug422543_script.js
+++ b/docshell/test/browser/file_bug422543_script.js
@@ -6,26 +6,16 @@ function SHistoryListener() {
 SHistoryListener.prototype = {
   retval: true,
   last: "initial",
 
   OnHistoryNewEntry: function (aNewURI) {
     this.last = "newentry";
   },
 
-  OnHistoryGoBack: function (aBackURI) {
-    this.last = "goback";
-    return this.retval;
-  },
-
-  OnHistoryGoForward: function (aForwardURI) {
-    this.last = "goforward";
-    return this.retval;
-  },
-
   OnHistoryGotoIndex: function (aIndex, aGotoURI) {
     this.last = "gotoindex";
     return this.retval;
   },
 
   OnHistoryPurge: function (aNumEntries) {
     this.last = "purge";
     return this.retval;
@@ -71,19 +61,19 @@ let testAPI = {
     for (let listener of this.listeners) {
       listener.last = "initial";
     }
 
     sendAsyncMessage("bug422543:resetListeners:return", {});
   },
 
   notifyReload() {
-    let internal = this.shistory.legacySHistory.QueryInterface(Ci.nsISHistoryInternal);
+    let history = this.shistory.legacySHistory;
     let rval =
-      internal.notifyOnHistoryReload(content.document.documentURIObject, 0);
+      history.notifyOnHistoryReload(content.document.documentURIObject, 0);
     sendAsyncMessage("bug422543:notifyReload:return", { rval });
   },
 
   setRetval({ num, val }) {
     this.listeners[num].retval = val;
     sendAsyncMessage("bug422543:setRetval:return", {});
   },
 };
--- a/docshell/test/chrome/bug662200_window.xul
+++ b/docshell/test/chrome/bug662200_window.xul
@@ -83,35 +83,33 @@
                           {type: "pageshow", 
                            title: "B"} ],
         onNavComplete: nextTest
       };
       doPageNavigation(navData);
       yield undefined;
 
       var docshell = TestWindow.getWindow().docShell;
-      var shistory = docshell.QueryInterface(Ci.nsIWebNavigation)
-                             .sessionHistory
-                             .legacySHistory
-                             .QueryInterface(Ci.nsIWebNavigation);
+      var shistory = docshell.sessionHistory.legacySHistory;
 
       // Reload.
       navData = {
         eventsToListenFor: ["pageshow", "pagehide"],
         expectedEvents: [ {type: "pagehide", 
                            title: "B"},
                           {type: "pageshow", 
                            title: "B"} ],
         onNavComplete: nextTest
       };
       // Asking the docshell harness to reload for us will call reload on
       // nsDocShell which has different behavior than the reload on nsSHistory
-      // so we call reload explicitly here
+      // so we call reloadCurrentEntry() (which is equivalent to reload(0) and
+      // visible from JS) explicitly here.
       waitForPageEvents(navData);
-      shistory.reload(0);
+      shistory.reloadCurrentEntry();
       yield undefined;
 
       // After this sequence of events, we should be able to go back and forward
       is(TestWindow.getBrowser().canGoBack, true, "Should be able to go back!");
       is(TestWindow.getBrowser().canGoForward, true, "Should be able to go forward!");
       is(shistory.requestedIndex, -1, "Requested index should be cleared!");
 
       // Tell the framework the test is finished.
--- a/docshell/test/navigation/file_bug1326251_evict_cache.html
+++ b/docshell/test/navigation/file_bug1326251_evict_cache.html
@@ -7,17 +7,16 @@
     SpecialPowers.Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
 
     // Evict bfcache and then go back.
     async function evictCache() {
       let shistory = SpecialPowers.wrap(window)
                        .docShell
                        .QueryInterface(SpecialPowers.Ci.nsIWebNavigation)
                        .sessionHistory;
-      let shPrivate = shistory.legacySHistory.QueryInterface(SpecialPowers.Ci.nsISHistoryInternal);
-      shPrivate.evictAllContentViewers();
+      shistory.legacySHistory.evictAllContentViewers();
       history.back();
     }
     </script>
   </head>
   <body onload="setTimeout(evictCache, 0);">
   </body>
 </html>
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -35,17 +35,16 @@
 #include "nsIScriptSecurityManager.h"
 #include "nsIScrollable.h"
 #include "nsFrameLoader.h"
 #include "nsIFrame.h"
 #include "nsIScrollableFrame.h"
 #include "nsSubDocumentFrame.h"
 #include "nsError.h"
 #include "nsISHistory.h"
-#include "nsISHistoryInternal.h"
 #include "nsIXULWindow.h"
 #include "nsIMozBrowserFrame.h"
 #include "nsISHistory.h"
 #include "nsIScriptError.h"
 #include "nsGlobalWindow.h"
 #include "nsHTMLDocument.h"
 #include "nsPIWindowRoot.h"
 #include "nsLayoutUtils.h"
--- a/dom/base/nsFrameMessageManager.cpp
+++ b/dom/base/nsFrameMessageManager.cpp
@@ -50,16 +50,17 @@
 #include "mozilla/dom/ResolveSystemBinding.h"
 #include "mozilla/dom/SameProcessMessageQueue.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/dom/ToJSValue.h"
 #include "mozilla/dom/ipc/SharedMap.h"
 #include "mozilla/dom/ipc/StructuredCloneData.h"
 #include "mozilla/dom/DOMStringList.h"
 #include "mozilla/jsipc/CrossProcessObjectWrappers.h"
+#include "mozilla/recordreplay/ParentIPC.h"
 #include "nsPrintfCString.h"
 #include "nsXULAppAPI.h"
 #include "nsQueryObject.h"
 #include "xpcprivate.h"
 #include <algorithm>
 #include "chrome/common/ipc_channel.h" // for IPC::Channel::kMaximumMessageSize
 
 #ifdef XP_WIN
@@ -658,17 +659,18 @@ public:
 // When recording or replaying, return whether a message should be received in
 // the middleman process instead of the recording/replaying process.
 static bool
 DirectMessageToMiddleman(const nsAString& aMessage)
 {
   // Middleman processes run developer tools server code and need to receive
   // debugger related messages. The session store flush message needs to be
   // received in order to cleanly shutdown the process.
-  return StringBeginsWith(aMessage, NS_LITERAL_STRING("debug:"))
+  return (StringBeginsWith(aMessage, NS_LITERAL_STRING("debug:")) &&
+          recordreplay::parent::DebuggerRunsInMiddleman())
       || aMessage.EqualsLiteral("SessionStore:flush");
 }
 
 void
 nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
                                       nsFrameLoader* aTargetFrameLoader,
                                       bool aTargetClosed,
                                       const nsAString& aMessage,
--- a/dom/base/nsHistory.cpp
+++ b/dom/base/nsHistory.cpp
@@ -14,17 +14,16 @@
 #include "nsPresContext.h"
 #include "nsIDocShell.h"
 #include "nsIWebNavigation.h"
 #include "nsIURI.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsReadableUtils.h"
 #include "nsContentUtils.h"
 #include "nsISHistory.h"
-#include "nsISHistoryInternal.h"
 #include "mozilla/Preferences.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 //
 //  History class implementation
 //
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -2297,17 +2297,18 @@ TabChild::RecvActivateFrameEvent(const n
 }
 
 // Return whether a remote script should be loaded in middleman processes in
 // addition to any child recording process they have.
 static bool
 LoadScriptInMiddleman(const nsString& aURL)
 {
   return // Middleman processes run devtools server side scripts.
-         StringBeginsWith(aURL, NS_LITERAL_STRING("resource://devtools/"))
+         (StringBeginsWith(aURL, NS_LITERAL_STRING("resource://devtools/")) &&
+          recordreplay::parent::DebuggerRunsInMiddleman())
          // This script includes event listeners needed to propagate document
          // title changes.
       || aURL.EqualsLiteral("chrome://global/content/browser-child.js")
          // This script is needed to respond to session store requests from the
          // UI process.
       || aURL.EqualsLiteral("chrome://browser/content/content-sessionStore.js");
 }
 
--- a/layout/base/nsDocumentViewer.cpp
+++ b/layout/base/nsDocumentViewer.cpp
@@ -105,17 +105,16 @@
 
 //focus
 #include "nsIDOMEventListener.h"
 #include "nsISelectionController.h"
 
 #include "mozilla/EventDispatcher.h"
 #include "nsISHEntry.h"
 #include "nsISHistory.h"
-#include "nsISHistoryInternal.h"
 #include "nsIWebNavigation.h"
 #include "mozilla/dom/XMLHttpRequestMainThread.h"
 
 //paint forcing
 #include <stdio.h>
 
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/Event.h"
@@ -2249,18 +2248,17 @@ nsDocumentViewer::Show(void)
         int32_t prevIndex,loadedIndex;
         nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(treeItem);
         docShell->GetPreviousTransIndex(&prevIndex);
         docShell->GetLoadedTransIndex(&loadedIndex);
 #ifdef DEBUG_PAGE_CACHE
         printf("About to evict content viewers: prev=%d, loaded=%d\n",
                prevIndex, loadedIndex);
 #endif
-        history->LegacySHistoryInternal()->
-          EvictOutOfRangeContentViewers(loadedIndex);
+        history->LegacySHistory()->EvictOutOfRangeContentViewers(loadedIndex);
       }
     }
   }
 
   if (mWindow) {
     // When attached to a top level xul window, we do not need to call
     // Show on the widget. Underlying window management code handles
     // this when the window is initialized.
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -4665,26 +4665,16 @@ Tab.prototype = {
 
     GlobalEventDispatcher.sendRequest(message);
   },
 
   OnHistoryNewEntry: function(newURI, oldIndex) {
     Services.obs.notifyObservers(this.browser, "Content:HistoryChange");
   },
 
-  OnHistoryGoBack: function(backURI) {
-    Services.obs.notifyObservers(this.browser, "Content:HistoryChange");
-    return true;
-  },
-
-  OnHistoryGoForward: function(forwardURI) {
-    Services.obs.notifyObservers(this.browser, "Content:HistoryChange");
-    return true;
-  },
-
   OnHistoryReload: function(reloadURI, reloadFlags) {
     Services.obs.notifyObservers(this.browser, "Content:HistoryChange");
     return true;
   },
 
   OnHistoryGotoIndex: function(index, gotoURI) {
     Services.obs.notifyObservers(this.browser, "Content:HistoryChange");
     return true;
--- a/toolkit/actors/PurgeSessionHistoryChild.jsm
+++ b/toolkit/actors/PurgeSessionHistoryChild.jsm
@@ -16,17 +16,16 @@ class PurgeSessionHistoryChild extends A
     let sessionHistory = this.docShell.QueryInterface(Ci.nsIWebNavigation).sessionHistory;
     if (!sessionHistory) {
       return;
     }
 
     // place the entry at current index at the end of the history list, so it won't get removed
     if (sessionHistory.index < sessionHistory.count - 1) {
       let legacy = sessionHistory.legacySHistory;
-      legacy.QueryInterface(Ci.nsISHistoryInternal);
       let indexEntry = legacy.getEntryAtIndex(sessionHistory.index, false);
       indexEntry.QueryInterface(Ci.nsISHEntry);
       legacy.addEntry(indexEntry, true);
     }
 
     let purge = sessionHistory.count;
     if (this.content.location.href != "about:blank") {
       --purge; // Don't remove the page the user's staring at from shistory
--- a/toolkit/components/viewsource/content/viewSource-content.js
+++ b/toolkit/components/viewsource/content/viewSource-content.js
@@ -264,17 +264,16 @@ var ViewSourceContent = {
     shEntry.setTitle(viewSrcURL);
     let systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
     shEntry.triggeringPrincipal = systemPrincipal;
     shEntry.setAsHistoryLoad();
     shEntry.cacheKey = shEntrySource.cacheKey;
     docShell.QueryInterface(Ci.nsIWebNavigation)
             .sessionHistory
             .legacySHistory
-            .QueryInterface(Ci.nsISHistoryInternal)
             .addEntry(shEntry, true);
   },
 
   /**
    * Load some URL in the browser.
    *
    * @param URL
    *        The URL string to load.
--- a/toolkit/modules/sessionstore/SessionHistory.jsm
+++ b/toolkit/modules/sessionstore/SessionHistory.jsm
@@ -79,20 +79,19 @@ var SessionHistoryInternal = {
     // how many we skipped, so we can sanitiy-check the current history index
     // and also determine whether we need to get any fallback data or not.
     let skippedCount = 0, entryCount = 0;
 
     if (history && history.count > 0) {
       // Loop over the transactions so we can get the persist property for each
       // one.
       let shistory = history.legacySHistory.QueryInterface(Ci.nsISHistory);
-      let shistoryInternal = history.legacySHistory.QueryInterface(Ci.nsISHistoryInternal);
       let count = shistory.count;
       for ( ; entryCount < count; entryCount++) {
-        let txn = shistoryInternal.GetTransactionAtIndex(entryCount);
+        let txn = shistory.GetTransactionAtIndex(entryCount);
         if (entryCount <= aFromIdx) {
           skippedCount++;
           continue;
         }
         let entry = this.serializeEntry(txn.sHEntry);
         entry.persist = txn.persist;
         data.entries.push(entry);
       }
@@ -288,25 +287,24 @@ var SessionHistoryInternal = {
 
   /**
    * Restores session history data for a given docShell.
    *
    * @param docShell
    *        The docShell that owns the session history.
    * @param tabData
    *        The tabdata including all history entries.
-   * @return A reference to the docShell's nsISHistoryInternal interface.
+   * @return A reference to the docShell's nsISHistory interface.
    */
   restore(docShell, tabData) {
     let webNavigation = docShell.QueryInterface(Ci.nsIWebNavigation);
     let history = webNavigation.sessionHistory.legacySHistory;
     if (history.count > 0) {
       history.PurgeHistory(history.count);
     }
-    history.QueryInterface(Ci.nsISHistoryInternal);
 
     let idMap = { used: {} };
     let docIdentMap = {};
     for (let i = 0; i < tabData.entries.length; i++) {
       let entry = tabData.entries[i];
       // XXXzpao Wallpaper patch for bug 514751
       if (!entry.url)
         continue;
--- a/toolkit/recordreplay/ipc/Channel.h
+++ b/toolkit/recordreplay/ipc/Channel.h
@@ -49,16 +49,20 @@ namespace recordreplay {
 // flushing a new index to the file.
 
 #define ForEachMessageType(_Macro)                             \
   /* Messages sent from the middleman to the child process. */ \
                                                                \
   /* Sent at startup. */                                       \
   _Macro(Introduction)                                         \
                                                                \
+  /* Sent to recording processes to indicate that the middleman will be running */ \
+  /* developer tools server-side code instead of the recording process itself. */ \
+  _Macro(SetDebuggerRunsInMiddleman)                           \
+                                                               \
   /* Sent to recording processes when exiting, or to force a hanged replaying */ \
   /* process to crash. */                                      \
   _Macro(Terminate)                                            \
                                                                \
   /* Flush the current recording to disk. */                   \
   _Macro(FlushRecording)                                       \
                                                                \
   /* Poke a child that is recording to create an artificial checkpoint, rather than */ \
@@ -150,16 +154,24 @@ public:
     switch (mType) {
 #define EnumToString(Kind) case MessageType::Kind: return #Kind;
   ForEachMessageType(EnumToString)
 #undef EnumToString
     default: return "Unknown";
     }
   }
 
+  // Return whether this is a middleman->child message that can be sent while
+  // the child is unpaused.
+  bool CanBeSentWhileUnpaused() const {
+    return mType == MessageType::CreateCheckpoint
+        || mType == MessageType::SetDebuggerRunsInMiddleman
+        || mType == MessageType::Terminate;
+  }
+
 protected:
   template <typename T, typename Elem>
   Elem* Data() { return (Elem*) (sizeof(T) + (char*) this); }
 
   template <typename T, typename Elem>
   const Elem* Data() const { return (const Elem*) (sizeof(T) + (const char*) this); }
 
   template <typename T, typename Elem>
@@ -220,16 +232,17 @@ struct IntroductionMessage : public Mess
 template <MessageType Type>
 struct EmptyMessage : public Message
 {
   EmptyMessage()
     : Message(Type, sizeof(*this))
   {}
 };
 
+typedef EmptyMessage<MessageType::SetDebuggerRunsInMiddleman> SetDebuggerRunsInMiddlemanMessage;
 typedef EmptyMessage<MessageType::Terminate> TerminateMessage;
 typedef EmptyMessage<MessageType::CreateCheckpoint> CreateCheckpointMessage;
 typedef EmptyMessage<MessageType::FlushRecording> FlushRecordingMessage;
 
 template <MessageType Type>
 struct JSONMessage : public Message
 {
   explicit JSONMessage(uint32_t aSize)
--- a/toolkit/recordreplay/ipc/ChildIPC.cpp
+++ b/toolkit/recordreplay/ipc/ChildIPC.cpp
@@ -55,23 +55,24 @@ static StaticInfallibleVector<char*> gPa
 // parent process.
 static FileHandle gCheckpointWriteFd;
 static FileHandle gCheckpointReadFd;
 
 // Copy of the introduction message we got from the middleman. This is saved on
 // receipt and then processed during InitRecordingOrReplayingProcess.
 static IntroductionMessage* gIntroductionMessage;
 
+// When recording, whether developer tools server code runs in the middleman.
+static bool gDebuggerRunsInMiddleman;
+
 // Processing routine for incoming channel messages.
 static void
 ChannelMessageHandler(Message* aMsg)
 {
-  MOZ_RELEASE_ASSERT(MainThreadShouldPause() ||
-                     aMsg->mType == MessageType::CreateCheckpoint ||
-                     aMsg->mType == MessageType::Terminate);
+  MOZ_RELEASE_ASSERT(MainThreadShouldPause() || aMsg->CanBeSentWhileUnpaused());
 
   switch (aMsg->mType) {
   case MessageType::Introduction: {
     MOZ_RELEASE_ASSERT(!gIntroductionMessage);
     gIntroductionMessage = (IntroductionMessage*) aMsg->Clone();
     break;
   }
   case MessageType::CreateCheckpoint: {
@@ -80,16 +81,21 @@ ChannelMessageHandler(Message* aMsg)
     // Ignore requests to create checkpoints before we have reached the first
     // paint and finished initializing.
     if (navigation::IsInitialized()) {
       uint8_t data = 0;
       DirectWrite(gCheckpointWriteFd, &data, 1);
     }
     break;
   }
+  case MessageType::SetDebuggerRunsInMiddleman: {
+    MOZ_RELEASE_ASSERT(IsRecording());
+    PauseMainThreadAndInvokeCallback([=]() { gDebuggerRunsInMiddleman = true; });
+    break;
+  }
   case MessageType::Terminate: {
     // Terminate messages behave differently in recording vs. replaying
     // processes. When sent to a recording process (which the middleman manages
     // directly) they signal that a clean shutdown is needed, while when sent
     // to a replaying process (which the UI process manages) they signal that
     // the process should crash, since it seems to be hanged.
     if (IsRecording()) {
       PrintSpew("Terminate message received, exiting...\n");
@@ -303,16 +309,22 @@ MiddlemanProcessId()
 }
 
 base::ProcessId
 ParentProcessId()
 {
   return gParentPid;
 }
 
+bool
+DebuggerRunsInMiddleman()
+{
+  return RecordReplayValue(gDebuggerRunsInMiddleman);
+}
+
 void
 MaybeCreateInitialCheckpoint()
 {
   NewCheckpoint(/* aTemporary = */ false);
 }
 
 void
 ReportFatalError(const Maybe<MinidumpInfo>& aMinidump, const char* aFormat, ...)
--- a/toolkit/recordreplay/ipc/ChildInternal.h
+++ b/toolkit/recordreplay/ipc/ChildInternal.h
@@ -108,14 +108,17 @@ void NotifyAlwaysMarkMajorCheckpoints();
 
 // Report a fatal error to the middleman process.
 void ReportFatalError(const char* aFormat, ...);
 
 // Mark a time span when the main thread is idle.
 void BeginIdleTime();
 void EndIdleTime();
 
+// Whether the middleman runs developer tools server code.
+bool DebuggerRunsInMiddleman();
+
 } // namespace child
 
 } // namespace recordreplay
 } // namespace mozilla
 
 #endif // mozilla_recordreplay_ChildInternal_h
--- a/toolkit/recordreplay/ipc/ChildProcess.cpp
+++ b/toolkit/recordreplay/ipc/ChildProcess.cpp
@@ -272,19 +272,17 @@ ChildProcessInfo::OnIncomingMessage(size
 
 void
 ChildProcessInfo::SendMessage(const Message& aMsg)
 {
   MOZ_RELEASE_ASSERT(!IsRecovering());
   MOZ_RELEASE_ASSERT(NS_IsMainThread());
 
   // Update paused state.
-  MOZ_RELEASE_ASSERT(IsPaused() ||
-                     aMsg.mType == MessageType::CreateCheckpoint ||
-                     aMsg.mType == MessageType::Terminate);
+  MOZ_RELEASE_ASSERT(IsPaused() || aMsg.CanBeSentWhileUnpaused());
   switch (aMsg.mType) {
   case MessageType::Resume:
   case MessageType::RestoreCheckpoint:
   case MessageType::RunToPoint:
     free(mPausedMessage);
     mPausedMessage = nullptr;
     MOZ_FALLTHROUGH;
   case MessageType::DebuggerRequest:
--- a/toolkit/recordreplay/ipc/DisabledIPC.cpp
+++ b/toolkit/recordreplay/ipc/DisabledIPC.cpp
@@ -147,12 +147,18 @@ ParentProcessId()
 }
 
 bool
 IsMiddlemanWithRecordingChild()
 {
   return false;
 }
 
+bool
+DebuggerRunsInMiddleman()
+{
+  MOZ_CRASH();
+}
+
 } // namespace parent
 
 } // namespace recordreplay
 } // namespace mozilla
--- a/toolkit/recordreplay/ipc/ParentIPC.cpp
+++ b/toolkit/recordreplay/ipc/ParentIPC.cpp
@@ -623,34 +623,56 @@ PreferencesLoaded()
 
   gRewindingEnabled = Preferences::GetBool("devtools.recordreplay.enableRewinding");
 
   // Force-disable rewinding and saving checkpoints with an env var for testing.
   if (getenv("NO_REWIND")) {
     gRewindingEnabled = false;
   }
 
-  // If there is no recording child, we have now initialized enough state
-  // that we can start spawning replaying children.
-  if (!gRecordingChild) {
+  if (gRecordingChild) {
+    // Inform the recording child if we will be running devtools server code in
+    // this process.
+    if (DebuggerRunsInMiddleman()) {
+      gRecordingChild->SendMessage(SetDebuggerRunsInMiddlemanMessage());
+    }
+  } else {
+    // If there is no recording child, we have now initialized enough state
+    // that we can start spawning replaying children.
     if (CanRewind()) {
       SpawnReplayingChildren();
     } else {
       SpawnSingleReplayingChild();
     }
   }
 }
 
 bool
 CanRewind()
 {
   MOZ_RELEASE_ASSERT(gPreferencesLoaded);
   return gRewindingEnabled;
 }
 
+bool
+DebuggerRunsInMiddleman()
+{
+  if (IsRecordingOrReplaying()) {
+    // This can be called in recording/replaying processes as well as the
+    // middleman. Fetch the value which the middleman informed us of.
+    return child::DebuggerRunsInMiddleman();
+  }
+
+  // Middleman processes which are recording and can't rewind do not run
+  // developer tools server code. This will run in the recording process
+  // instead.
+  MOZ_RELEASE_ASSERT(IsMiddleman());
+  return !gRecordingChild || CanRewind();
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 // Saving Recordings
 ///////////////////////////////////////////////////////////////////////////////
 
 static void
 FlushRecording()
 {
   MOZ_RELEASE_ASSERT(NS_IsMainThread());
--- a/toolkit/recordreplay/ipc/ParentIPC.h
+++ b/toolkit/recordreplay/ipc/ParentIPC.h
@@ -61,13 +61,16 @@ void OpenChannel(base::ProcessId aMiddle
                  ipc::FileDescriptor* aConnection);
 
 // Get the command line arguments to use when spawning a recording or replaying
 // child process.
 void GetArgumentsForChildProcess(base::ProcessId aMiddlemanPid, uint32_t aChannelId,
                                  const char* aRecordingFile, bool aRecording,
                                  std::vector<std::string>& aExtraArgs);
 
+// Return whether the middleman will be running developer tools server code.
+bool DebuggerRunsInMiddleman();
+
 } // namespace parent
 } // namespace recordreplay
 } // namespace mozilla
 
 #endif // mozilla_recordreplay_ParentIPC_h
--- a/widget/windows/nsNativeThemeWin.cpp
+++ b/widget/windows/nsNativeThemeWin.cpp
@@ -4219,27 +4219,27 @@ GetScrollbarButtonColor(nscolor aTrackCo
 
   bool isActive = aStates.HasState(NS_EVENT_STATE_ACTIVE);
   bool isHover = aStates.HasState(NS_EVENT_STATE_HOVER);
   if (!isActive && !isHover) {
     return aTrackColor;
   }
   float luminance = RelativeLuminanceUtils::Compute(aTrackColor);
   if (isActive) {
-    if (luminance >= 0.18) {
-      luminance *= 0.134;
+    if (luminance >= 0.18f) {
+      luminance *= 0.134f;
     } else {
-      luminance /= 0.134;
+      luminance /= 0.134f;
       luminance = std::min(luminance, 1.0f);
     }
   } else {
-    if (luminance >= 0.18) {
-      luminance *= 0.805;
+    if (luminance >= 0.18f) {
+      luminance *= 0.805f;
     } else {
-      luminance /= 0.805;
+      luminance /= 0.805f;
     }
   }
   return RelativeLuminanceUtils::Adjust(aTrackColor, luminance);
 }
 
 static nscolor
 GetScrollbarArrowColor(nscolor aButtonColor)
 {
@@ -4290,26 +4290,26 @@ AdjustScrollbarFaceColor(nscolor aFaceCo
 
   bool isActive = aStates.HasState(NS_EVENT_STATE_ACTIVE);
   bool isHover = aStates.HasState(NS_EVENT_STATE_HOVER);
   if (!isActive && !isHover) {
     return aFaceColor;
   }
   float luminance = RelativeLuminanceUtils::Compute(aFaceColor);
   if (isActive) {
-    if (luminance >= 0.18) {
-      luminance *= 0.192;
+    if (luminance >= 0.18f) {
+      luminance *= 0.192f;
     } else {
-      luminance /= 0.192;
+      luminance /= 0.192f;
     }
   } else {
-    if (luminance >= 0.18) {
-      luminance *= 0.625;
+    if (luminance >= 0.18f) {
+      luminance *= 0.625f;
     } else {
-      luminance /= 0.625;
+      luminance /= 0.625f;
     }
   }
   return RelativeLuminanceUtils::Adjust(aFaceColor, luminance);
 }
 
 // This tries to draw a Windows 10 style scrollbar with given colors.
 nsresult
 nsNativeThemeWin::DrawCustomScrollbarPart(gfxContext* aContext,