Bug 1416384 - Part 2e: Eliminate duplicate declarations, and get gecko building again, r=smaug
authorNika Layzell <nika@thelayzells.com>
Wed, 15 Nov 2017 11:33:58 -0500
changeset 392030 862355bc5c589cc22420526d5bbf10e7f6f7ba78
parent 392029 d1fc9865c5574cecc72270dde1822c9344bc137e
child 392031 ba47537d18440f8d9df9351d3461d734beb9e867
push id32909
push usercbrindusan@mozilla.com
push dateWed, 15 Nov 2017 22:25:14 +0000
treeherdermozilla-central@f41930a869a8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1416384
milestone59.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 1416384 - Part 2e: Eliminate duplicate declarations, and get gecko building again, r=smaug There are many helper methods and structs in nsGlobalWindow.cpp. Many of these are used by only the inner or only the outer window, while some are used by both. In the case of the items used by both, I extracted them into nsGlobalWindow.cpp, which includes nsGlobalWindowInner.cpp and nsGlobalWindowOuter.cpp as the compilation unit entry point. In the case of items used by just one or the other, I removed them from the other file, and deleted the bodies of functions which used them, replacing them, with a MOZ_CRASH. This gets gecko building again, so that we can make further incremental improvements. MozReview-Commit-ID: 8QnJ1PX6TAO
dom/base/moz.build
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindowInner.cpp
dom/base/nsGlobalWindowInner.h
dom/base/nsGlobalWindowOuter.cpp
layout/build/nsLayoutStatics.cpp
--- a/dom/base/moz.build
+++ b/dom/base/moz.build
@@ -384,19 +384,20 @@ SOURCES += [
     'DOMIntersectionObserver.cpp',
     # Because of OS X headers.
     'nsContentUtils.cpp',
     # this file doesn't like windows.h
     'nsDOMWindowUtils.cpp',
     # Conflicts with windows.h's definition of SendMessage.
     'nsFrameMessageManager.cpp',
     # This file has a #error "Never include windows.h in this file!"
-    # 'nsGlobalWindow.cpp',
-    'nsGlobalWindowInner.cpp',
-    'nsGlobalWindowOuter.cpp',
+    'nsGlobalWindow.cpp',
+    # These files are included by nsGlobalWindow.cpp
+    # 'nsGlobalWindowInner.cpp',
+    # 'nsGlobalWindowOuter.cpp',
     # Conflicts with windows.h's definition of LoadImage.
     'nsImageLoadingContent.cpp',
     # Because of OS X headers.
     'nsObjectLoadingContent.cpp',
     # nsPluginArray.cpp includes npapi.h indirectly, and that includes a lot of system headers
     'nsPluginArray.cpp',
 ]
 
new file mode 100644
--- /dev/null
+++ b/dom/base/nsGlobalWindow.cpp
@@ -0,0 +1,960 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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 "nsGlobalWindow.h"
+
+#include <algorithm>
+
+#include "mozilla/MemoryReporting.h"
+
+// Local Includes
+#include "Navigator.h"
+#include "nsContentSecurityManager.h"
+#include "nsScreen.h"
+#include "nsHistory.h"
+#include "nsDOMNavigationTiming.h"
+#include "nsIDOMStorageManager.h"
+#include "mozilla/dom/LocalStorage.h"
+#include "mozilla/dom/Storage.h"
+#include "mozilla/dom/IdleRequest.h"
+#include "mozilla/dom/Performance.h"
+#include "mozilla/dom/StorageEvent.h"
+#include "mozilla/dom/StorageEventBinding.h"
+#include "mozilla/dom/StorageNotifierService.h"
+#include "mozilla/dom/StorageUtils.h"
+#include "mozilla/dom/Timeout.h"
+#include "mozilla/dom/TimeoutHandler.h"
+#include "mozilla/dom/TimeoutManager.h"
+#include "mozilla/IntegerPrintfMacros.h"
+#if defined(MOZ_WIDGET_ANDROID)
+#include "mozilla/dom/WindowOrientationObserver.h"
+#endif
+#include "nsDOMOfflineResourceList.h"
+#include "nsError.h"
+#include "nsIIdleService.h"
+#include "nsISizeOfEventTarget.h"
+#include "nsDOMJSUtils.h"
+#include "nsArrayUtils.h"
+#include "nsIDOMWindowCollection.h"
+#include "nsDOMWindowList.h"
+#include "mozilla/dom/WakeLock.h"
+#include "mozilla/dom/power/PowerManagerService.h"
+#include "nsIDocShellTreeOwner.h"
+#include "nsIInterfaceRequestorUtils.h"
+#include "nsIPermissionManager.h"
+#include "nsIScriptContext.h"
+#include "nsIScriptTimeoutHandler.h"
+#include "nsITimeoutHandler.h"
+#include "nsIController.h"
+#include "nsScriptNameSpaceManager.h"
+#include "nsISlowScriptDebug.h"
+#include "nsWindowMemoryReporter.h"
+#include "nsWindowSizes.h"
+#include "WindowNamedPropertiesHandler.h"
+#include "nsFrameSelection.h"
+#include "nsNetUtil.h"
+#include "nsVariant.h"
+#include "nsPrintfCString.h"
+#include "mozilla/intl/LocaleService.h"
+
+// Helper Classes
+#include "nsJSUtils.h"
+#include "jsapi.h"              // for JSAutoRequest
+#include "jswrapper.h"
+#include "nsCharSeparatedTokenizer.h"
+#include "nsReadableUtils.h"
+#include "nsDOMClassInfo.h"
+#include "nsJSEnvironment.h"
+#include "mozilla/dom/ScriptSettings.h"
+#include "mozilla/Preferences.h"
+#include "mozilla/Likely.h"
+#include "mozilla/Sprintf.h"
+#include "mozilla/Unused.h"
+
+// Other Classes
+#include "mozilla/dom/BarProps.h"
+#include "nsContentCID.h"
+#include "nsLayoutStatics.h"
+#include "nsCCUncollectableMarker.h"
+#include "mozilla/dom/workers/Workers.h"
+#include "mozilla/dom/ToJSValue.h"
+#include "nsJSPrincipals.h"
+#include "mozilla/Attributes.h"
+#include "mozilla/Debug.h"
+#include "mozilla/EventListenerManager.h"
+#include "mozilla/EventStates.h"
+#include "mozilla/MouseEvents.h"
+#include "mozilla/ProcessHangMonitor.h"
+#include "mozilla/ThrottledEventQueue.h"
+#include "AudioChannelService.h"
+#include "nsAboutProtocolUtils.h"
+#include "nsCharTraits.h" // NS_IS_HIGH/LOW_SURROGATE
+#include "PostMessageEvent.h"
+#include "mozilla/dom/DocGroup.h"
+#include "mozilla/dom/TabGroup.h"
+
+// Interfaces Needed
+#include "nsIFrame.h"
+#include "nsCanvasFrame.h"
+#include "nsIWidget.h"
+#include "nsIWidgetListener.h"
+#include "nsIBaseWindow.h"
+#include "nsIDeviceSensors.h"
+#include "nsIContent.h"
+#include "nsIDocShell.h"
+#include "nsIDocCharset.h"
+#include "nsIDocument.h"
+#include "Crypto.h"
+#include "nsIDOMDocument.h"
+#include "nsIDOMElement.h"
+#include "nsIDOMEvent.h"
+#include "nsIDOMOfflineResourceList.h"
+#include "nsDOMString.h"
+#include "nsIEmbeddingSiteWindow.h"
+#include "nsThreadUtils.h"
+#include "nsILoadContext.h"
+#include "nsIPresShell.h"
+#include "nsIScrollableFrame.h"
+#include "nsView.h"
+#include "nsViewManager.h"
+#include "nsISelectionController.h"
+#include "nsISelection.h"
+#include "nsIPrompt.h"
+#include "nsIPromptService.h"
+#include "nsIPromptFactory.h"
+#include "nsIAddonPolicyService.h"
+#include "nsIWritablePropertyBag2.h"
+#include "nsIWebNavigation.h"
+#include "nsIWebBrowserChrome.h"
+#include "nsIWebBrowserFind.h"  // For window.find()
+#include "nsIWindowMediator.h"  // For window.find()
+#include "nsComputedDOMStyle.h"
+#include "nsDOMCID.h"
+#include "nsDOMWindowUtils.h"
+#include "nsIWindowWatcher.h"
+#include "nsPIWindowWatcher.h"
+#include "nsIContentViewer.h"
+#include "nsIScriptError.h"
+#include "nsIControllers.h"
+#include "nsIControllerContext.h"
+#include "nsGlobalWindowCommands.h"
+#include "nsQueryObject.h"
+#include "nsContentUtils.h"
+#include "nsCSSProps.h"
+#include "nsIDOMFileList.h"
+#include "nsIURIFixup.h"
+#ifndef DEBUG
+#include "nsIAppStartup.h"
+#include "nsToolkitCompsCID.h"
+#endif
+#include "nsCDefaultURIFixup.h"
+#include "mozilla/EventDispatcher.h"
+#include "mozilla/EventStateManager.h"
+#include "nsIObserverService.h"
+#include "nsFocusManager.h"
+#include "nsIXULWindow.h"
+#include "nsITimedChannel.h"
+#include "nsServiceManagerUtils.h"
+#ifdef MOZ_XUL
+#include "nsIDOMXULControlElement.h"
+#include "nsMenuPopupFrame.h"
+#endif
+#include "mozilla/dom/CustomEvent.h"
+#include "nsIJARChannel.h"
+#include "nsIScreenManager.h"
+#include "nsIEffectiveTLDService.h"
+
+#include "xpcprivate.h"
+
+#ifdef NS_PRINTING
+#include "nsIPrintSettings.h"
+#include "nsIPrintSettingsService.h"
+#include "nsIWebBrowserPrint.h"
+#endif
+
+#include "nsWindowRoot.h"
+#include "nsNetCID.h"
+#include "nsIArray.h"
+
+// XXX An unfortunate dependency exists here (two XUL files).
+#include "nsIDOMXULDocument.h"
+#include "nsIDOMXULCommandDispatcher.h"
+
+#include "nsBindingManager.h"
+#include "nsXBLService.h"
+
+// used for popup blocking, needs to be converted to something
+// belonging to the back-end like nsIContentPolicy
+#include "nsIPopupWindowManager.h"
+
+#include "nsIDragService.h"
+#include "mozilla/dom/Element.h"
+#include "mozilla/dom/Selection.h"
+#include "nsFrameLoader.h"
+#include "nsISupportsPrimitives.h"
+#include "nsXPCOMCID.h"
+#include "mozilla/Logging.h"
+#include "prenv.h"
+
+#include "mozilla/dom/IDBFactory.h"
+#include "mozilla/dom/MessageChannel.h"
+#include "mozilla/dom/Promise.h"
+
+#include "mozilla/dom/Gamepad.h"
+#include "mozilla/dom/GamepadManager.h"
+
+#include "gfxVR.h"
+#include "mozilla/dom/VRDisplay.h"
+#include "mozilla/dom/VRDisplayEvent.h"
+#include "mozilla/dom/VRDisplayEventBinding.h"
+#include "mozilla/dom/VREventObserver.h"
+
+#include "nsRefreshDriver.h"
+#include "Layers.h"
+
+#include "mozilla/AddonPathService.h"
+#include "mozilla/BasePrincipal.h"
+#include "mozilla/Services.h"
+#include "mozilla/Telemetry.h"
+#include "mozilla/dom/Location.h"
+#include "nsHTMLDocument.h"
+#include "nsWrapperCacheInlines.h"
+#include "mozilla/DOMEventTargetHelper.h"
+#include "prrng.h"
+#include "nsSandboxFlags.h"
+#include "TimeChangeObserver.h"
+#include "mozilla/dom/AudioContext.h"
+#include "mozilla/dom/BrowserElementDictionariesBinding.h"
+#include "mozilla/dom/cache/CacheStorage.h"
+#include "mozilla/dom/Console.h"
+#include "mozilla/dom/Fetch.h"
+#include "mozilla/dom/FunctionBinding.h"
+#include "mozilla/dom/HashChangeEvent.h"
+#include "mozilla/dom/IntlUtils.h"
+#include "mozilla/dom/MozSelfSupportBinding.h"
+#include "mozilla/dom/PopStateEvent.h"
+#include "mozilla/dom/PopupBlockedEvent.h"
+#include "mozilla/dom/PrimitiveConversions.h"
+#include "mozilla/dom/WindowBinding.h"
+#include "nsITabChild.h"
+#include "mozilla/dom/MediaQueryList.h"
+#include "mozilla/dom/ScriptSettings.h"
+#include "mozilla/dom/NavigatorBinding.h"
+#include "mozilla/dom/ImageBitmap.h"
+#include "mozilla/dom/ImageBitmapBinding.h"
+#include "mozilla/dom/ServiceWorkerRegistration.h"
+#include "mozilla/dom/U2F.h"
+#include "mozilla/dom/WebIDLGlobalNameHash.h"
+#include "mozilla/dom/Worklet.h"
+#ifdef HAVE_SIDEBAR
+#include "mozilla/dom/ExternalBinding.h"
+#endif
+
+#ifdef MOZ_WEBSPEECH
+#include "mozilla/dom/SpeechSynthesis.h"
+#endif
+
+// Apple system headers seem to have a check() macro.  <sigh>
+#ifdef check
+class nsIScriptTimeoutHandler;
+#undef check
+#endif // check
+#include "AccessCheck.h"
+
+#ifdef ANDROID
+#include <android/log.h>
+#endif
+
+#ifdef XP_WIN
+#include <process.h>
+#define getpid _getpid
+#else
+#include <unistd.h> // for getpid()
+#endif
+
+static const char kStorageEnabled[] = "dom.storage.enabled";
+
+using namespace mozilla;
+using namespace mozilla::dom;
+using namespace mozilla::dom::ipc;
+using mozilla::BasePrincipal;
+using mozilla::OriginAttributes;
+using mozilla::TimeStamp;
+using mozilla::TimeDuration;
+using mozilla::dom::cache::CacheStorage;
+
+static LazyLogModule gDOMLeakPRLog("DOMLeak");
+
+static int32_t              gRefCnt                           = 0;
+static int32_t              gOpenPopupSpamCount               = 0;
+static PopupControlState    gPopupControlState                = openAbused;
+static bool                 gMouseDown                        = false;
+static bool                 gDragServiceDisabled              = false;
+static FILE                *gDumpFile                         = nullptr;
+static uint32_t             gSerialCounter                    = 0;
+static bool                 gIdleObserversAPIFuzzTimeDisabled = false;
+
+#ifdef DEBUG_jst
+int32_t gTimeoutCnt                                    = 0;
+#endif
+
+#if defined(DEBUG_bryner) || defined(DEBUG_chb)
+#define DEBUG_PAGE_CACHE
+#endif
+
+#define DOM_TOUCH_LISTENER_ADDED "dom-touch-listener-added"
+
+#define MEMORY_PRESSURE_OBSERVER_TOPIC "memory-pressure"
+
+// The interval at which we execute idle callbacks
+static uint32_t gThrottledIdlePeriodLength;
+
+#define DEFAULT_THROTTLED_IDLE_PERIOD_LENGTH 10000
+
+#define FORWARD_TO_OUTER(method, args, err_rval)                              \
+  PR_BEGIN_MACRO                                                              \
+  if (IsInnerWindow()) {                                                      \
+    nsGlobalWindowOuter *outer = GetOuterWindowInternal();                    \
+    if (!AsInner()->HasActiveDocument()) {                                    \
+      NS_WARNING(outer ?                                                      \
+                 "Inner window does not have active document." :              \
+                 "No outer window available!");                               \
+      return err_rval;                                                        \
+    }                                                                         \
+    return outer->method args;                                                \
+  }                                                                           \
+  PR_END_MACRO
+
+#define FORWARD_TO_OUTER_OR_THROW(method, args, errorresult, err_rval)        \
+  PR_BEGIN_MACRO                                                              \
+  MOZ_RELEASE_ASSERT(IsInnerWindow());                                        \
+  nsGlobalWindowOuter *outer = GetOuterWindowInternal();                      \
+  if (MOZ_LIKELY(AsInner()->HasActiveDocument())) {                           \
+    return outer->method args;                                                \
+  }                                                                           \
+  if (!outer) {                                                               \
+    NS_WARNING("No outer window available!");                                 \
+    errorresult.Throw(NS_ERROR_NOT_INITIALIZED);                              \
+  } else {                                                                    \
+    errorresult.Throw(NS_ERROR_XPC_SECURITY_MANAGER_VETO);                    \
+  }                                                                           \
+  return err_rval;                                                            \
+  PR_END_MACRO
+
+#define FORWARD_TO_OUTER_VOID(method, args)                                   \
+  PR_BEGIN_MACRO                                                              \
+  if (IsInnerWindow()) {                                                      \
+    nsGlobalWindowOuter *outer = GetOuterWindowInternal();                    \
+    if (!AsInner()->HasActiveDocument()) {                                    \
+      NS_WARNING(outer ?                                                      \
+                 "Inner window does not have active document." :              \
+                 "No outer window available!");                               \
+      return;                                                                 \
+    }                                                                         \
+    outer->method args;                                                       \
+    return;                                                                   \
+  }                                                                           \
+  PR_END_MACRO
+
+#define FORWARD_TO_OUTER_MODAL_CONTENT_WINDOW(method, args, err_rval)         \
+  PR_BEGIN_MACRO                                                              \
+  if (IsInnerWindow()) {                                                      \
+    nsGlobalWindowOuter *outer = GetOuterWindowInternal();                    \
+    if (!AsInner()->HasActiveDocument()) {                                    \
+      NS_WARNING(outer ?                                                      \
+                 "Inner window does not have active document." :              \
+                 "No outer window available!");                               \
+      return err_rval;                                                        \
+    }                                                                         \
+    return ((nsGlobalModalWindow *)outer)->method args;                       \
+  }                                                                           \
+  PR_END_MACRO
+
+#define FORWARD_TO_INNER(method, args, err_rval)                              \
+  PR_BEGIN_MACRO                                                              \
+  if (IsOuterWindow()) {                                                      \
+    if (!mInnerWindow) {                                                      \
+      NS_WARNING("No inner window available!");                               \
+      return err_rval;                                                        \
+    }                                                                         \
+    return GetCurrentInnerWindowInternal()->method args;                      \
+  }                                                                           \
+  PR_END_MACRO
+
+#define FORWARD_TO_INNER_MODAL_CONTENT_WINDOW(method, args, err_rval)         \
+  PR_BEGIN_MACRO                                                              \
+  if (IsOuterWindow()) {                                                      \
+    if (!mInnerWindow) {                                                      \
+      NS_WARNING("No inner window available!");                               \
+      return err_rval;                                                        \
+    }                                                                         \
+    return ((nsGlobalModalWindow*)GetCurrentInnerWindowInternal())->method args; \
+  }                                                                           \
+  PR_END_MACRO
+
+#define FORWARD_TO_INNER_VOID(method, args)                                   \
+  PR_BEGIN_MACRO                                                              \
+  if (IsOuterWindow()) {                                                      \
+    if (!mInnerWindow) {                                                      \
+      NS_WARNING("No inner window available!");                               \
+      return;                                                                 \
+    }                                                                         \
+    GetCurrentInnerWindowInternal()->method args;                             \
+    return;                                                                   \
+  }                                                                           \
+  PR_END_MACRO
+
+// Same as FORWARD_TO_INNER, but this will create a fresh inner if an
+// inner doesn't already exists.
+#define FORWARD_TO_INNER_CREATE(method, args, err_rval)                       \
+  PR_BEGIN_MACRO                                                              \
+  if (IsOuterWindow()) {                                                      \
+    if (!mInnerWindow) {                                                      \
+      if (mIsClosed) {                                                        \
+        return err_rval;                                                      \
+      }                                                                       \
+      nsCOMPtr<nsIDocument> kungFuDeathGrip = GetDoc();                       \
+      ::mozilla::Unused << kungFuDeathGrip;                                   \
+      if (!mInnerWindow) {                                                    \
+        return err_rval;                                                      \
+      }                                                                       \
+    }                                                                         \
+    return GetCurrentInnerWindowInternal()->method args;                      \
+  }                                                                           \
+  PR_END_MACRO
+
+// CIDs
+static NS_DEFINE_CID(kXULControllersCID, NS_XULCONTROLLERS_CID);
+
+#define NETWORK_UPLOAD_EVENT_NAME     NS_LITERAL_STRING("moznetworkupload")
+#define NETWORK_DOWNLOAD_EVENT_NAME   NS_LITERAL_STRING("moznetworkdownload")
+
+namespace mozilla {
+namespace dom {
+extern uint64_t
+NextWindowID();
+} // namespace dom
+} // namespace mozilla
+
+template<class T>
+nsPIDOMWindow<T>::nsPIDOMWindow(nsPIDOMWindowOuter *aOuterWindow)
+: mFrameElement(nullptr), mDocShell(nullptr), mModalStateDepth(0),
+  mMutationBits(0), mActivePeerConnections(0), mIsDocumentLoaded(false),
+  mIsHandlingResizeEvent(false), mIsInnerWindow(aOuterWindow != nullptr),
+  mMayHavePaintEventListener(false), mMayHaveTouchEventListener(false),
+  mMayHaveSelectionChangeEventListener(false),
+  mMayHaveMouseEnterLeaveEventListener(false),
+  mMayHavePointerEnterLeaveEventListener(false),
+  mInnerObjectsFreed(false),
+  mIsActive(false), mIsBackground(false),
+  mMediaSuspend(Preferences::GetBool("media.block-autoplay-until-in-foreground", true) ?
+    nsISuspendedTypes::SUSPENDED_BLOCK : nsISuspendedTypes::NONE_SUSPENDED),
+  mAudioMuted(false), mAudioVolume(1.0), mAudioCaptured(false),
+  mDesktopModeViewport(false), mIsRootOuterWindow(false), mInnerWindow(nullptr),
+  mOuterWindow(aOuterWindow),
+  // Make sure no actual window ends up with mWindowID == 0
+  mWindowID(NextWindowID()), mHasNotifiedGlobalCreated(false),
+  mMarkedCCGeneration(0), mServiceWorkersTestingEnabled(false),
+  mLargeAllocStatus(LargeAllocStatus::NONE),
+  mHasTriedToCacheTopInnerWindow(false),
+  mNumOfIndexedDBDatabases(0),
+  mNumOfOpenWebSockets(0)
+{
+  if (aOuterWindow) {
+    mTimeoutManager =
+      MakeUnique<mozilla::dom::TimeoutManager>(*nsGlobalWindowInner::Cast(AsInner()));
+  }
+}
+
+template<class T>
+nsPIDOMWindow<T>::~nsPIDOMWindow() {}
+
+PopupControlState
+PushPopupControlState(PopupControlState aState, bool aForce)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  PopupControlState oldState = gPopupControlState;
+
+  if (aState < gPopupControlState || aForce) {
+    gPopupControlState = aState;
+  }
+
+  return oldState;
+}
+
+void
+PopPopupControlState(PopupControlState aState)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  gPopupControlState = aState;
+}
+
+// We need certain special behavior for remote XUL whitelisted domains, but we
+// don't want that behavior to take effect in automation, because we whitelist
+// all the mochitest domains. So we need to check a pref here.
+static bool
+TreatAsRemoteXUL(nsIPrincipal* aPrincipal)
+{
+  MOZ_ASSERT(!nsContentUtils::IsSystemPrincipal(aPrincipal));
+  return nsContentUtils::AllowXULXBLForPrincipal(aPrincipal) &&
+         !Preferences::GetBool("dom.use_xbl_scopes_for_remote_xul", false);
+}
+
+static bool
+EnablePrivilege(JSContext* cx, unsigned argc, JS::Value* vp)
+{
+  Telemetry::Accumulate(Telemetry::ENABLE_PRIVILEGE_EVER_CALLED, true);
+  return xpc::EnableUniversalXPConnect(cx);
+}
+
+static const JSFunctionSpec EnablePrivilegeSpec[] = {
+  JS_FN("enablePrivilege", EnablePrivilege, 1, 0),
+  JS_FS_END
+};
+
+static bool
+InitializeLegacyNetscapeObject(JSContext* aCx, JS::Handle<JSObject*> aGlobal)
+{
+  JSAutoCompartment ac(aCx, aGlobal);
+
+  // Note: MathJax depends on window.netscape being exposed. See bug 791526.
+  JS::Rooted<JSObject*> obj(aCx);
+  obj = JS_DefineObject(aCx, aGlobal, "netscape", nullptr);
+  NS_ENSURE_TRUE(obj, false);
+
+  obj = JS_DefineObject(aCx, obj, "security", nullptr);
+  NS_ENSURE_TRUE(obj, false);
+
+  // We hide enablePrivilege behind a pref because it has been altered in a
+  // way that makes it fundamentally insecure to use in production. Mozilla
+  // uses this pref during automated testing to support legacy test code that
+  // uses enablePrivilege. If you're not doing test automation, you _must_ not
+  // flip this pref, or you will be exposing all your users to security
+  // vulnerabilities.
+  if (!xpc::IsInAutomation()) {
+    return true;
+  }
+
+  /* Define PrivilegeManager object with the necessary "static" methods. */
+  obj = JS_DefineObject(aCx, obj, "PrivilegeManager", nullptr);
+  NS_ENSURE_TRUE(obj, false);
+
+  return JS_DefineFunctions(aCx, obj, EnablePrivilegeSpec);
+}
+
+static JS::CompartmentCreationOptions&
+SelectZoneGroup(nsGlobalWindowInner* aNewInner,
+                JS::CompartmentCreationOptions& aOptions)
+{
+  JS::CompartmentCreationOptions options;
+
+  if (aNewInner->GetOuterWindow()) {
+    nsGlobalWindowOuter *top = aNewInner->GetTopInternal();
+
+    // If we have a top-level window, use its zone (and zone group).
+    if (top && top->GetGlobalJSObject()) {
+      return aOptions.setExistingZone(top->GetGlobalJSObject());
+    }
+  }
+
+  // If we're in the parent process, don't bother with zone groups.
+  if (XRE_IsParentProcess()) {
+    return aOptions.setNewZoneInSystemZoneGroup();
+  }
+
+  // Otherwise, find a zone group from the TabGroup. Typically we only have to
+  // go through one iteration of this loop.
+  RefPtr<TabGroup> tabGroup = aNewInner->TabGroup();
+  for (nsPIDOMWindowOuter* outer : tabGroup->GetWindows()) {
+    nsGlobalWindowOuter* window = nsGlobalWindowOuter::Cast(outer);
+    if (JSObject* global = window->GetGlobalJSObject()) {
+      return aOptions.setNewZoneInExistingZoneGroup(global);
+    }
+  }
+
+  return aOptions.setNewZoneInNewZoneGroup();
+}
+
+/**
+ * Create a new global object that will be used for an inner window.
+ * Return the native global and an nsISupports 'holder' that can be used
+ * to manage the lifetime of it.
+ */
+static nsresult
+CreateNativeGlobalForInner(JSContext* aCx,
+                           nsGlobalWindowInner* aNewInner,
+                           nsIURI* aURI,
+                           nsIPrincipal* aPrincipal,
+                           JS::MutableHandle<JSObject*> aGlobal,
+                           bool aIsSecureContext)
+{
+  MOZ_ASSERT(aCx);
+  MOZ_ASSERT(aNewInner);
+  MOZ_ASSERT(aNewInner->IsInnerWindow());
+  MOZ_ASSERT(aPrincipal);
+
+  // DOMWindow with nsEP is not supported, we have to make sure
+  // no one creates one accidentally.
+  nsCOMPtr<nsIExpandedPrincipal> nsEP = do_QueryInterface(aPrincipal);
+  MOZ_RELEASE_ASSERT(!nsEP, "DOMWindow with nsEP is not supported");
+
+  JS::CompartmentOptions options;
+
+  SelectZoneGroup(aNewInner, options.creationOptions());
+
+  // Sometimes add-ons load their own XUL windows, either as separate top-level
+  // windows or inside a browser element. In such cases we want to tag the
+  // window's compartment with the add-on ID. See bug 1092156.
+  if (nsContentUtils::IsSystemPrincipal(aPrincipal)) {
+    options.creationOptions().setAddonId(MapURIToAddonID(aURI));
+  }
+
+  options.creationOptions().setSecureContext(aIsSecureContext);
+
+  xpc::InitGlobalObjectOptions(options, aPrincipal);
+
+  // Determine if we need the Components object.
+  bool needComponents = nsContentUtils::IsSystemPrincipal(aPrincipal) ||
+                        TreatAsRemoteXUL(aPrincipal);
+  uint32_t flags = needComponents ? 0 : xpc::OMIT_COMPONENTS_OBJECT;
+  flags |= xpc::DONT_FIRE_ONNEWGLOBALHOOK;
+
+  if (!WindowBinding::Wrap(aCx, aNewInner, aNewInner, options,
+                           nsJSPrincipals::get(aPrincipal), false, aGlobal) ||
+      !xpc::InitGlobalObject(aCx, aGlobal, flags)) {
+    return NS_ERROR_FAILURE;
+  }
+
+  MOZ_ASSERT(aNewInner->GetWrapperPreserveColor() == aGlobal);
+
+  // Set the location information for the new global, so that tools like
+  // about:memory may use that information
+  xpc::SetLocationForGlobal(aGlobal, aURI);
+
+  if (!InitializeLegacyNetscapeObject(aCx, aGlobal)) {
+    return NS_ERROR_FAILURE;
+  }
+
+  return NS_OK;
+}
+
+static
+already_AddRefed<EventTarget>
+TryGetTabChildGlobalAsEventTarget(nsISupports *aFrom)
+{
+  nsCOMPtr<nsIFrameLoaderOwner> frameLoaderOwner = do_QueryInterface(aFrom);
+  if (!frameLoaderOwner) {
+    return nullptr;
+  }
+
+  RefPtr<nsFrameLoader> frameLoader = frameLoaderOwner->GetFrameLoader();
+  if (!frameLoader) {
+    return nullptr;
+  }
+
+  nsCOMPtr<EventTarget> target = frameLoader->GetTabChildGlobalAsEventTarget();
+  return target.forget();
+}
+
+template <class T>
+nsIURI*
+nsPIDOMWindow<T>::GetDocumentURI() const
+{
+  return mDoc ? mDoc->GetDocumentURI() : mDocumentURI.get();
+}
+
+template <class T>
+nsIURI*
+nsPIDOMWindow<T>::GetDocBaseURI() const
+{
+  return mDoc ? mDoc->GetDocBaseURI() : mDocBaseURI.get();
+}
+
+template <class T>
+void
+nsPIDOMWindow<T>::MaybeCreateDoc()
+{
+  MOZ_ASSERT(!mDoc);
+  if (nsIDocShell* docShell = GetDocShell()) {
+    // Note that |document| here is the same thing as our mDoc, but we
+    // don't have to explicitly set the member variable because the docshell
+    // has already called SetNewDocument().
+    nsCOMPtr<nsIDocument> document = docShell->GetDocument();
+    Unused << document;
+  }
+}
+
+// Try to match compartments that are not web content by matching compartments
+// with principals that are either the system principal or an expanded principal.
+// This may not return true for all non-web-content compartments.
+struct BrowserCompartmentMatcher : public js::CompartmentFilter {
+  bool match(JSCompartment* aC) const override
+    {
+      nsCOMPtr<nsIPrincipal> pc = nsJSPrincipals::get(JS_GetCompartmentPrincipals(aC));
+      return nsContentUtils::IsSystemOrExpandedPrincipal(pc);
+    }
+};
+
+class WindowDestroyedEvent final : public Runnable
+{
+public:
+  WindowDestroyedEvent(nsGlobalWindowInner* aWindow, uint64_t aID, const char* aTopic)
+    : mozilla::Runnable("WindowDestroyedEvent")
+    , mID(aID)
+    , mPhase(Phase::Destroying)
+    , mTopic(aTopic)
+    , mIsInnerWindow(true)
+  {
+    mWindow = do_GetWeakReference(aWindow);
+  }
+  WindowDestroyedEvent(nsGlobalWindowOuter* aWindow, uint64_t aID, const char* aTopic)
+    : mozilla::Runnable("WindowDestroyedEvent")
+    , mID(aID)
+    , mPhase(Phase::Destroying)
+    , mTopic(aTopic)
+    , mIsInnerWindow(false)
+  {
+    mWindow = do_GetWeakReference(aWindow);
+  }
+
+  enum class Phase
+  {
+    Destroying,
+    Nuking
+  };
+
+  NS_IMETHOD Run() override
+  {
+    AUTO_PROFILER_LABEL("WindowDestroyedEvent::Run", OTHER);
+
+    nsCOMPtr<nsIObserverService> observerService =
+      services::GetObserverService();
+    if (!observerService) {
+      return NS_OK;
+    }
+
+    nsCOMPtr<nsISupportsPRUint64> wrapper =
+      do_CreateInstance(NS_SUPPORTS_PRUINT64_CONTRACTID);
+    if (wrapper) {
+      wrapper->SetData(mID);
+      observerService->NotifyObservers(wrapper, mTopic.get(), nullptr);
+    }
+
+    switch (mPhase) {
+      case Phase::Destroying:
+      {
+        bool skipNukeCrossCompartment = false;
+#ifndef DEBUG
+        nsCOMPtr<nsIAppStartup> appStartup =
+          do_GetService(NS_APPSTARTUP_CONTRACTID);
+
+        if (appStartup) {
+          appStartup->GetShuttingDown(&skipNukeCrossCompartment);
+        }
+#endif
+
+        if (!skipNukeCrossCompartment) {
+          // The compartment nuking phase might be too expensive, so do that
+          // part off of idle dispatch.
+
+          // For the compartment nuking phase, we dispatch either an
+          // inner-window-nuked or an outer-window-nuked notification.
+          // This will allow tests to wait for compartment nuking to happen.
+          if (mTopic.EqualsLiteral("inner-window-destroyed")) {
+            mTopic.AssignLiteral("inner-window-nuked");
+          } else if (mTopic.EqualsLiteral("outer-window-destroyed")) {
+            mTopic.AssignLiteral("outer-window-nuked");
+          }
+          mPhase = Phase::Nuking;
+
+          nsCOMPtr<nsIRunnable> copy(this);
+          NS_IdleDispatchToCurrentThread(copy.forget(), 1000);
+        }
+      }
+      break;
+
+      case Phase::Nuking:
+      {
+        nsCOMPtr<nsISupports> window = do_QueryReferent(mWindow);
+        if (window) {
+          nsGlobalWindowInner* currentInner;
+          if (mIsInnerWindow) {
+            currentInner = nsGlobalWindowInner::FromSupports(window);
+          } else {
+            nsGlobalWindowOuter* outer = nsGlobalWindowOuter::FromSupports(window);
+            currentInner = outer->GetCurrentInnerWindowInternal();
+          }
+          NS_ENSURE_TRUE(currentInner, NS_OK);
+
+          AutoSafeJSContext cx;
+          JS::Rooted<JSObject*> obj(cx, currentInner->FastGetGlobalJSObject());
+          if (obj && !js::IsSystemCompartment(js::GetObjectCompartment(obj))) {
+            JSCompartment* cpt = js::GetObjectCompartment(obj);
+            nsCOMPtr<nsIPrincipal> pc = nsJSPrincipals::get(JS_GetCompartmentPrincipals(cpt));
+
+            if (BasePrincipal::Cast(pc)->AddonPolicy()) {
+              // We want to nuke all references to the add-on compartment.
+              xpc::NukeAllWrappersForCompartment(cx, cpt,
+                                                 mIsInnerWindow ? js::DontNukeWindowReferences
+                                                                : js::NukeWindowReferences);
+            } else {
+              // We only want to nuke wrappers for the chrome->content case
+              js::NukeCrossCompartmentWrappers(cx, BrowserCompartmentMatcher(), cpt,
+                                               mIsInnerWindow ? js::DontNukeWindowReferences
+                                                              : js::NukeWindowReferences,
+                                               js::NukeIncomingReferences);
+            }
+          }
+        }
+      }
+      break;
+    }
+
+    return NS_OK;
+  }
+
+private:
+  uint64_t mID;
+  Phase mPhase;
+  nsCString mTopic;
+  nsWeakPtr mWindow;
+  bool mIsInnerWindow;
+};
+
+class ChildCommandDispatcher : public Runnable
+{
+public:
+  ChildCommandDispatcher(nsPIWindowRoot* aRoot,
+                         nsITabChild* aTabChild,
+                         const nsAString& aAction)
+    : mozilla::Runnable("ChildCommandDispatcher")
+    , mRoot(aRoot)
+    , mTabChild(aTabChild)
+    , mAction(aAction)
+  {
+  }
+
+  NS_IMETHOD Run() override
+  {
+    nsTArray<nsCString> enabledCommands, disabledCommands;
+    mRoot->GetEnabledDisabledCommands(enabledCommands, disabledCommands);
+    if (enabledCommands.Length() || disabledCommands.Length()) {
+      mTabChild->EnableDisableCommands(mAction, enabledCommands, disabledCommands);
+    }
+
+    return NS_OK;
+  }
+
+private:
+  nsCOMPtr<nsPIWindowRoot>             mRoot;
+  nsCOMPtr<nsITabChild>                mTabChild;
+  nsString                             mAction;
+};
+
+class CommandDispatcher : public Runnable
+{
+public:
+  CommandDispatcher(nsIDOMXULCommandDispatcher* aDispatcher,
+                    const nsAString& aAction)
+    : mozilla::Runnable("CommandDispatcher")
+    , mDispatcher(aDispatcher)
+    , mAction(aAction)
+  {
+  }
+
+  NS_IMETHOD Run() override
+  {
+    return mDispatcher->UpdateCommands(mAction);
+  }
+
+  nsCOMPtr<nsIDOMXULCommandDispatcher> mDispatcher;
+  nsString                             mAction;
+};
+
+static bool IsLink(nsIContent* aContent)
+{
+  return aContent && (aContent->IsHTMLElement(nsGkAtoms::a) ||
+                      aContent->AttrValueIs(kNameSpaceID_XLink, nsGkAtoms::type,
+                                            nsGkAtoms::simple, eCaseMatters));
+}
+
+static bool ShouldShowFocusRingIfFocusedByMouse(nsIContent* aNode)
+{
+  if (!aNode) {
+    return true;
+  }
+  return !IsLink(aNode) &&
+    !aNode->IsAnyOfHTMLElements(nsGkAtoms::video, nsGkAtoms::audio);
+}
+
+static bool
+IsInterval(const Optional<int32_t>& aTimeout, int32_t& aResultTimeout)
+{
+  if (aTimeout.WasPassed()) {
+    aResultTimeout = aTimeout.Value();
+    return true;
+  }
+
+  // If no interval was specified, treat this like a timeout, to avoid setting
+  // an interval of 0 milliseconds.
+  aResultTimeout = 0;
+  return false;
+}
+
+template<typename T>
+mozilla::dom::TabGroup*
+nsPIDOMWindow<T>::TabGroup()
+{
+  if (IsInnerWindow()) {
+    nsGlobalWindowInner* globalWindow =
+      static_cast<nsGlobalWindowInner*>(
+        reinterpret_cast<nsPIDOMWindow<nsISupports>*>(this));
+    return globalWindow->TabGroupInner();
+  } else {
+    nsGlobalWindowOuter* globalWindow =
+      static_cast<nsGlobalWindowOuter*>(
+        reinterpret_cast<nsPIDOMWindow<nsISupports>*>(this));
+    return globalWindow->TabGroupOuter();
+  }
+}
+
+template<typename T>
+mozilla::dom::DocGroup*
+nsPIDOMWindow<T>::GetDocGroup() const
+{
+  nsIDocument* doc = GetExtantDoc();
+  if (doc) {
+    return doc->GetDocGroup();
+  }
+  return nullptr;
+}
+
+static void
+EnsurePrefCaches()
+{
+  static bool sFirstTime = true;
+  if (sFirstTime) {
+    TimeoutManager::Initialize();
+    Preferences::AddBoolVarCache(&gIdleObserversAPIFuzzTimeDisabled,
+                                 "dom.idle-observers-api.fuzz_time.disabled",
+                                 false);
+
+    Preferences::AddUintVarCache(&gThrottledIdlePeriodLength,
+                                 "dom.idle_period.throttled_length",
+                                 DEFAULT_THROTTLED_IDLE_PERIOD_LENGTH);
+    sFirstTime = false;
+  }
+}
+
+// Include the implementations for the inner and outer windows respectively.
+#include "nsGlobalWindowOuter.cpp"
+#include "nsGlobalWindowInner.cpp"
+
+template class nsPIDOMWindow<mozIDOMWindowProxy>;
+template class nsPIDOMWindow<mozIDOMWindow>;
+template class nsPIDOMWindow<nsISupports>;
--- a/dom/base/nsGlobalWindowInner.cpp
+++ b/dom/base/nsGlobalWindowInner.cpp
@@ -1,444 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 "nsGlobalWindow.h"
-
-#include <algorithm>
-
-#include "mozilla/MemoryReporting.h"
-
-// Local Includes
-#include "Navigator.h"
-#include "nsContentSecurityManager.h"
-#include "nsScreen.h"
-#include "nsHistory.h"
-#include "nsDOMNavigationTiming.h"
-#include "nsIDOMStorageManager.h"
-#include "mozilla/dom/LocalStorage.h"
-#include "mozilla/dom/Storage.h"
-#include "mozilla/dom/IdleRequest.h"
-#include "mozilla/dom/Performance.h"
-#include "mozilla/dom/StorageEvent.h"
-#include "mozilla/dom/StorageEventBinding.h"
-#include "mozilla/dom/StorageNotifierService.h"
-#include "mozilla/dom/StorageUtils.h"
-#include "mozilla/dom/Timeout.h"
-#include "mozilla/dom/TimeoutHandler.h"
-#include "mozilla/dom/TimeoutManager.h"
-#include "mozilla/IntegerPrintfMacros.h"
-#if defined(MOZ_WIDGET_ANDROID)
-#include "mozilla/dom/WindowOrientationObserver.h"
-#endif
-#include "nsDOMOfflineResourceList.h"
-#include "nsError.h"
-#include "nsIIdleService.h"
-#include "nsISizeOfEventTarget.h"
-#include "nsDOMJSUtils.h"
-#include "nsArrayUtils.h"
-#include "nsIDOMWindowCollection.h"
-#include "nsDOMWindowList.h"
-#include "mozilla/dom/WakeLock.h"
-#include "mozilla/dom/power/PowerManagerService.h"
-#include "nsIDocShellTreeOwner.h"
-#include "nsIInterfaceRequestorUtils.h"
-#include "nsIPermissionManager.h"
-#include "nsIScriptContext.h"
-#include "nsIScriptTimeoutHandler.h"
-#include "nsITimeoutHandler.h"
-#include "nsIController.h"
-#include "nsScriptNameSpaceManager.h"
-#include "nsISlowScriptDebug.h"
-#include "nsWindowMemoryReporter.h"
-#include "nsWindowSizes.h"
-#include "WindowNamedPropertiesHandler.h"
-#include "nsFrameSelection.h"
-#include "nsNetUtil.h"
-#include "nsVariant.h"
-#include "nsPrintfCString.h"
-#include "mozilla/intl/LocaleService.h"
-
-// Helper Classes
-#include "nsJSUtils.h"
-#include "jsapi.h"              // for JSAutoRequest
-#include "jswrapper.h"
-#include "nsCharSeparatedTokenizer.h"
-#include "nsReadableUtils.h"
-#include "nsDOMClassInfo.h"
-#include "nsJSEnvironment.h"
-#include "mozilla/dom/ScriptSettings.h"
-#include "mozilla/Preferences.h"
-#include "mozilla/Likely.h"
-#include "mozilla/Sprintf.h"
-#include "mozilla/Unused.h"
-
-// Other Classes
-#include "mozilla/dom/BarProps.h"
-#include "nsContentCID.h"
-#include "nsLayoutStatics.h"
-#include "nsCCUncollectableMarker.h"
-#include "mozilla/dom/workers/Workers.h"
-#include "mozilla/dom/ToJSValue.h"
-#include "nsJSPrincipals.h"
-#include "mozilla/Attributes.h"
-#include "mozilla/Debug.h"
-#include "mozilla/EventListenerManager.h"
-#include "mozilla/EventStates.h"
-#include "mozilla/MouseEvents.h"
-#include "mozilla/ProcessHangMonitor.h"
-#include "mozilla/ThrottledEventQueue.h"
-#include "AudioChannelService.h"
-#include "nsAboutProtocolUtils.h"
-#include "nsCharTraits.h" // NS_IS_HIGH/LOW_SURROGATE
-#include "PostMessageEvent.h"
-#include "mozilla/dom/DocGroup.h"
-#include "mozilla/dom/TabGroup.h"
-
-// Interfaces Needed
-#include "nsIFrame.h"
-#include "nsCanvasFrame.h"
-#include "nsIWidget.h"
-#include "nsIWidgetListener.h"
-#include "nsIBaseWindow.h"
-#include "nsIDeviceSensors.h"
-#include "nsIContent.h"
-#include "nsIDocShell.h"
-#include "nsIDocCharset.h"
-#include "nsIDocument.h"
-#include "Crypto.h"
-#include "nsIDOMDocument.h"
-#include "nsIDOMElement.h"
-#include "nsIDOMEvent.h"
-#include "nsIDOMOfflineResourceList.h"
-#include "nsDOMString.h"
-#include "nsIEmbeddingSiteWindow.h"
-#include "nsThreadUtils.h"
-#include "nsILoadContext.h"
-#include "nsIPresShell.h"
-#include "nsIScrollableFrame.h"
-#include "nsView.h"
-#include "nsViewManager.h"
-#include "nsISelectionController.h"
-#include "nsISelection.h"
-#include "nsIPrompt.h"
-#include "nsIPromptService.h"
-#include "nsIPromptFactory.h"
-#include "nsIAddonPolicyService.h"
-#include "nsIWritablePropertyBag2.h"
-#include "nsIWebNavigation.h"
-#include "nsIWebBrowserChrome.h"
-#include "nsIWebBrowserFind.h"  // For window.find()
-#include "nsIWindowMediator.h"  // For window.find()
-#include "nsComputedDOMStyle.h"
-#include "nsDOMCID.h"
-#include "nsDOMWindowUtils.h"
-#include "nsIWindowWatcher.h"
-#include "nsPIWindowWatcher.h"
-#include "nsIContentViewer.h"
-#include "nsIScriptError.h"
-#include "nsIControllers.h"
-#include "nsIControllerContext.h"
-#include "nsGlobalWindowCommands.h"
-#include "nsQueryObject.h"
-#include "nsContentUtils.h"
-#include "nsCSSProps.h"
-#include "nsIDOMFileList.h"
-#include "nsIURIFixup.h"
-#ifndef DEBUG
-#include "nsIAppStartup.h"
-#include "nsToolkitCompsCID.h"
-#endif
-#include "nsCDefaultURIFixup.h"
-#include "mozilla/EventDispatcher.h"
-#include "mozilla/EventStateManager.h"
-#include "nsIObserverService.h"
-#include "nsFocusManager.h"
-#include "nsIXULWindow.h"
-#include "nsITimedChannel.h"
-#include "nsServiceManagerUtils.h"
-#ifdef MOZ_XUL
-#include "nsIDOMXULControlElement.h"
-#include "nsMenuPopupFrame.h"
-#endif
-#include "mozilla/dom/CustomEvent.h"
-#include "nsIJARChannel.h"
-#include "nsIScreenManager.h"
-#include "nsIEffectiveTLDService.h"
-
-#include "xpcprivate.h"
-
-#ifdef NS_PRINTING
-#include "nsIPrintSettings.h"
-#include "nsIPrintSettingsService.h"
-#include "nsIWebBrowserPrint.h"
-#endif
-
-#include "nsWindowRoot.h"
-#include "nsNetCID.h"
-#include "nsIArray.h"
-
-// XXX An unfortunate dependency exists here (two XUL files).
-#include "nsIDOMXULDocument.h"
-#include "nsIDOMXULCommandDispatcher.h"
-
-#include "nsBindingManager.h"
-#include "nsXBLService.h"
-
-// used for popup blocking, needs to be converted to something
-// belonging to the back-end like nsIContentPolicy
-#include "nsIPopupWindowManager.h"
-
-#include "nsIDragService.h"
-#include "mozilla/dom/Element.h"
-#include "mozilla/dom/Selection.h"
-#include "nsFrameLoader.h"
-#include "nsISupportsPrimitives.h"
-#include "nsXPCOMCID.h"
-#include "mozilla/Logging.h"
-#include "prenv.h"
-
-#include "mozilla/dom/IDBFactory.h"
-#include "mozilla/dom/MessageChannel.h"
-#include "mozilla/dom/Promise.h"
-
-#include "mozilla/dom/Gamepad.h"
-#include "mozilla/dom/GamepadManager.h"
-
-#include "gfxVR.h"
-#include "mozilla/dom/VRDisplay.h"
-#include "mozilla/dom/VRDisplayEvent.h"
-#include "mozilla/dom/VRDisplayEventBinding.h"
-#include "mozilla/dom/VREventObserver.h"
-
-#include "nsRefreshDriver.h"
-#include "Layers.h"
-
-#include "mozilla/AddonPathService.h"
-#include "mozilla/BasePrincipal.h"
-#include "mozilla/Services.h"
-#include "mozilla/Telemetry.h"
-#include "mozilla/dom/Location.h"
-#include "nsHTMLDocument.h"
-#include "nsWrapperCacheInlines.h"
-#include "mozilla/DOMEventTargetHelper.h"
-#include "prrng.h"
-#include "nsSandboxFlags.h"
-#include "TimeChangeObserver.h"
-#include "mozilla/dom/AudioContext.h"
-#include "mozilla/dom/BrowserElementDictionariesBinding.h"
-#include "mozilla/dom/cache/CacheStorage.h"
-#include "mozilla/dom/Console.h"
-#include "mozilla/dom/Fetch.h"
-#include "mozilla/dom/FunctionBinding.h"
-#include "mozilla/dom/HashChangeEvent.h"
-#include "mozilla/dom/IntlUtils.h"
-#include "mozilla/dom/MozSelfSupportBinding.h"
-#include "mozilla/dom/PopStateEvent.h"
-#include "mozilla/dom/PopupBlockedEvent.h"
-#include "mozilla/dom/PrimitiveConversions.h"
-#include "mozilla/dom/WindowBinding.h"
-#include "nsITabChild.h"
-#include "mozilla/dom/MediaQueryList.h"
-#include "mozilla/dom/ScriptSettings.h"
-#include "mozilla/dom/NavigatorBinding.h"
-#include "mozilla/dom/ImageBitmap.h"
-#include "mozilla/dom/ImageBitmapBinding.h"
-#include "mozilla/dom/ServiceWorkerRegistration.h"
-#include "mozilla/dom/U2F.h"
-#include "mozilla/dom/WebIDLGlobalNameHash.h"
-#include "mozilla/dom/Worklet.h"
-#ifdef HAVE_SIDEBAR
-#include "mozilla/dom/ExternalBinding.h"
-#endif
-
-#ifdef MOZ_WEBSPEECH
-#include "mozilla/dom/SpeechSynthesis.h"
-#endif
-
-// Apple system headers seem to have a check() macro.  <sigh>
-#ifdef check
-class nsIScriptTimeoutHandler;
-#undef check
-#endif // check
-#include "AccessCheck.h"
-
-#ifdef ANDROID
-#include <android/log.h>
-#endif
-
-#ifdef XP_WIN
-#include <process.h>
-#define getpid _getpid
-#else
-#include <unistd.h> // for getpid()
-#endif
-
-static const char kStorageEnabled[] = "dom.storage.enabled";
-
-using namespace mozilla;
-using namespace mozilla::dom;
-using namespace mozilla::dom::ipc;
-using mozilla::BasePrincipal;
-using mozilla::OriginAttributes;
-using mozilla::TimeStamp;
-using mozilla::TimeDuration;
-using mozilla::dom::cache::CacheStorage;
-
-static LazyLogModule gDOMLeakPRLog("DOMLeak");
-
 nsGlobalWindowInner::InnerWindowByIdTable *nsGlobalWindowInner::sInnerWindowsById = nullptr;
 
-static int32_t              gRefCnt                           = 0;
-static int32_t              gOpenPopupSpamCount               = 0;
-static PopupControlState    gPopupControlState                = openAbused;
-static bool                 gMouseDown                        = false;
-static bool                 gDragServiceDisabled              = false;
-static FILE                *gDumpFile                         = nullptr;
-static uint32_t             gSerialCounter                    = 0;
-static bool                 gIdleObserversAPIFuzzTimeDisabled = false;
-
-#ifdef DEBUG_jst
-int32_t gTimeoutCnt                                    = 0;
-#endif
-
-#if defined(DEBUG_bryner) || defined(DEBUG_chb)
-#define DEBUG_PAGE_CACHE
-#endif
-
-#define DOM_TOUCH_LISTENER_ADDED "dom-touch-listener-added"
-
-#define MEMORY_PRESSURE_OBSERVER_TOPIC "memory-pressure"
-
-// The interval at which we execute idle callbacks
-static uint32_t gThrottledIdlePeriodLength;
-
-#define DEFAULT_THROTTLED_IDLE_PERIOD_LENGTH 10000
-
-#define FORWARD_TO_OUTER(method, args, err_rval)                              \
-  PR_BEGIN_MACRO                                                              \
-  if (IsInnerWindow()) {                                                      \
-    nsGlobalWindowOuter *outer = GetOuterWindowInternal();                    \
-    if (!AsInner()->HasActiveDocument()) {                                    \
-      NS_WARNING(outer ?                                                      \
-                 "Inner window does not have active document." :              \
-                 "No outer window available!");                               \
-      return err_rval;                                                        \
-    }                                                                         \
-    return outer->method args;                                                \
-  }                                                                           \
-  PR_END_MACRO
-
-#define FORWARD_TO_OUTER_OR_THROW(method, args, errorresult, err_rval)        \
-  PR_BEGIN_MACRO                                                              \
-  MOZ_RELEASE_ASSERT(IsInnerWindow());                                        \
-  nsGlobalWindowOuter *outer = GetOuterWindowInternal();                      \
-  if (MOZ_LIKELY(AsInner()->HasActiveDocument())) {                           \
-    return outer->method args;                                                \
-  }                                                                           \
-  if (!outer) {                                                               \
-    NS_WARNING("No outer window available!");                                 \
-    errorresult.Throw(NS_ERROR_NOT_INITIALIZED);                              \
-  } else {                                                                    \
-    errorresult.Throw(NS_ERROR_XPC_SECURITY_MANAGER_VETO);                    \
-  }                                                                           \
-  return err_rval;                                                            \
-  PR_END_MACRO
-
-#define FORWARD_TO_OUTER_VOID(method, args)                                   \
-  PR_BEGIN_MACRO                                                              \
-  if (IsInnerWindow()) {                                                      \
-    nsGlobalWindowOuter *outer = GetOuterWindowInternal();                    \
-    if (!AsInner()->HasActiveDocument()) {                                    \
-      NS_WARNING(outer ?                                                      \
-                 "Inner window does not have active document." :              \
-                 "No outer window available!");                               \
-      return;                                                                 \
-    }                                                                         \
-    outer->method args;                                                       \
-    return;                                                                   \
-  }                                                                           \
-  PR_END_MACRO
-
-#define FORWARD_TO_OUTER_MODAL_CONTENT_WINDOW(method, args, err_rval)         \
-  PR_BEGIN_MACRO                                                              \
-  if (IsInnerWindow()) {                                                      \
-    nsGlobalWindowOuter *outer = GetOuterWindowInternal();                    \
-    if (!AsInner()->HasActiveDocument()) {                                    \
-      NS_WARNING(outer ?                                                      \
-                 "Inner window does not have active document." :              \
-                 "No outer window available!");                               \
-      return err_rval;                                                        \
-    }                                                                         \
-    return ((nsGlobalModalWindow *)outer)->method args;                       \
-  }                                                                           \
-  PR_END_MACRO
-
-#define FORWARD_TO_INNER(method, args, err_rval)                              \
-  PR_BEGIN_MACRO                                                              \
-  if (IsOuterWindow()) {                                                      \
-    if (!mInnerWindow) {                                                      \
-      NS_WARNING("No inner window available!");                               \
-      return err_rval;                                                        \
-    }                                                                         \
-    return GetCurrentInnerWindowInternal()->method args;                      \
-  }                                                                           \
-  PR_END_MACRO
-
-#define FORWARD_TO_INNER_MODAL_CONTENT_WINDOW(method, args, err_rval)         \
-  PR_BEGIN_MACRO                                                              \
-  if (IsOuterWindow()) {                                                      \
-    if (!mInnerWindow) {                                                      \
-      NS_WARNING("No inner window available!");                               \
-      return err_rval;                                                        \
-    }                                                                         \
-    return ((nsGlobalModalWindow*)GetCurrentInnerWindowInternal())->method args; \
-  }                                                                           \
-  PR_END_MACRO
-
-#define FORWARD_TO_INNER_VOID(method, args)                                   \
-  PR_BEGIN_MACRO                                                              \
-  if (IsOuterWindow()) {                                                      \
-    if (!mInnerWindow) {                                                      \
-      NS_WARNING("No inner window available!");                               \
-      return;                                                                 \
-    }                                                                         \
-    GetCurrentInnerWindowInternal()->method args;                             \
-    return;                                                                   \
-  }                                                                           \
-  PR_END_MACRO
-
-// Same as FORWARD_TO_INNER, but this will create a fresh inner if an
-// inner doesn't already exists.
-#define FORWARD_TO_INNER_CREATE(method, args, err_rval)                       \
-  PR_BEGIN_MACRO                                                              \
-  if (IsOuterWindow()) {                                                      \
-    if (!mInnerWindow) {                                                      \
-      if (mIsClosed) {                                                        \
-        return err_rval;                                                      \
-      }                                                                       \
-      nsCOMPtr<nsIDocument> kungFuDeathGrip = GetDoc();                       \
-      ::mozilla::Unused << kungFuDeathGrip;                                   \
-      if (!mInnerWindow) {                                                    \
-        return err_rval;                                                      \
-      }                                                                       \
-    }                                                                         \
-    return GetCurrentInnerWindowInternal()->method args;                      \
-  }                                                                           \
-  PR_END_MACRO
-
-// CIDs
-static NS_DEFINE_CID(kXULControllersCID, NS_XULCONTROLLERS_CID);
-
-#define NETWORK_UPLOAD_EVENT_NAME     NS_LITERAL_STRING("moznetworkupload")
-#define NETWORK_DOWNLOAD_EVENT_NAME   NS_LITERAL_STRING("moznetworkdownload")
-
 /**
  * An indirect observer object that means we don't have to implement nsIObserver
  * on nsGlobalWindow, where any script could see it.
  */
 class nsGlobalWindowObserver final : public nsIObserver
                                    , public nsIInterfaceRequestor
                                    , public StorageNotificationObserver
 {
@@ -494,51 +66,16 @@ private:
 
   // This reference is non-owning and safe because it's cleared by
   // nsGlobalWindowInner::CleanUp().
   nsGlobalWindowInner* MOZ_NON_OWNING_REF mWindow;
 };
 
 NS_IMPL_ISUPPORTS(nsGlobalWindowObserver, nsIObserver, nsIInterfaceRequestor)
 
-static already_AddRefed<nsIVariant>
-CreateVoidVariant()
-{
-  RefPtr<nsVariantCC> writable = new nsVariantCC();
-  writable->SetAsVoid();
-  return writable.forget();
-}
-
-nsresult
-DialogValueHolder::Get(nsIPrincipal* aSubject, nsIVariant** aResult)
-{
-  nsCOMPtr<nsIVariant> result;
-  if (aSubject->SubsumesConsideringDomain(mOrigin)) {
-    result = mValue;
-  } else {
-    result = CreateVoidVariant();
-  }
-  result.forget(aResult);
-  return NS_OK;
-}
-
-void
-DialogValueHolder::Get(JSContext* aCx, JS::Handle<JSObject*> aScope,
-                       nsIPrincipal* aSubject,
-                       JS::MutableHandle<JS::Value> aResult,
-                       mozilla::ErrorResult& aError)
-{
-  if (aSubject->Subsumes(mOrigin)) {
-    aError = nsContentUtils::XPConnect()->VariantToJS(aCx, aScope,
-                                                      mValue, aResult);
-  } else {
-    aResult.setUndefined();
-  }
-}
-
 class IdleRequestExecutor;
 
 class IdleRequestExecutorTimeoutHandler final : public TimeoutHandler
 {
 public:
   explicit IdleRequestExecutorTimeoutHandler(IdleRequestExecutor* aExecutor)
     : mExecutor(aExecutor)
   {
@@ -978,557 +515,16 @@ nsGlobalWindowInner::DisableIdleCallback
   }
 }
 
 bool
 nsGlobalWindowInner::IsBackgroundInternal() const
 {
   return !mOuterWindow || mOuterWindow->IsBackground();
 }
-namespace mozilla {
-namespace dom {
-extern uint64_t
-NextWindowID();
-} // namespace dom
-} // namespace mozilla
-
-template<class T>
-nsPIDOMWindow<T>::nsPIDOMWindow(nsPIDOMWindowOuter *aOuterWindow)
-: mFrameElement(nullptr), mDocShell(nullptr), mModalStateDepth(0),
-  mMutationBits(0), mActivePeerConnections(0), mIsDocumentLoaded(false),
-  mIsHandlingResizeEvent(false), mIsInnerWindow(aOuterWindow != nullptr),
-  mMayHavePaintEventListener(false), mMayHaveTouchEventListener(false),
-  mMayHaveSelectionChangeEventListener(false),
-  mMayHaveMouseEnterLeaveEventListener(false),
-  mMayHavePointerEnterLeaveEventListener(false),
-  mInnerObjectsFreed(false),
-  mIsActive(false), mIsBackground(false),
-  mMediaSuspend(Preferences::GetBool("media.block-autoplay-until-in-foreground", true) ?
-    nsISuspendedTypes::SUSPENDED_BLOCK : nsISuspendedTypes::NONE_SUSPENDED),
-  mAudioMuted(false), mAudioVolume(1.0), mAudioCaptured(false),
-  mDesktopModeViewport(false), mIsRootOuterWindow(false), mInnerWindow(nullptr),
-  mOuterWindow(aOuterWindow),
-  // Make sure no actual window ends up with mWindowID == 0
-  mWindowID(NextWindowID()), mHasNotifiedGlobalCreated(false),
-  mMarkedCCGeneration(0), mServiceWorkersTestingEnabled(false),
-  mLargeAllocStatus(LargeAllocStatus::NONE),
-  mHasTriedToCacheTopInnerWindow(false),
-  mNumOfIndexedDBDatabases(0),
-  mNumOfOpenWebSockets(0)
-{
-  if (aOuterWindow) {
-    mTimeoutManager =
-      MakeUnique<mozilla::dom::TimeoutManager>(*nsGlobalWindowInner::Cast(AsInner()));
-  }
-}
-
-template<class T>
-nsPIDOMWindow<T>::~nsPIDOMWindow() {}
-
-/* static */
-nsPIDOMWindowOuter*
-nsPIDOMWindowOuter::GetFromCurrentInner(nsPIDOMWindowInner* aInner)
-{
-  if (!aInner) {
-    return nullptr;
-  }
-
-  nsPIDOMWindowOuter* outer = aInner->GetOuterWindow();
-  if (!outer || outer->GetCurrentInnerWindow() != aInner) {
-    return nullptr;
-  }
-
-  return outer;
-}
-
-// DialogValueHolder CC goop.
-NS_IMPL_CYCLE_COLLECTION(DialogValueHolder, mValue)
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DialogValueHolder)
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
-NS_INTERFACE_MAP_END
-
-NS_IMPL_CYCLE_COLLECTING_ADDREF(DialogValueHolder)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(DialogValueHolder)
-
-//*****************************************************************************
-// nsOuterWindowProxy: Outer Window Proxy
-//*****************************************************************************
-
-class nsOuterWindowProxy : public js::Wrapper
-{
-public:
-  constexpr nsOuterWindowProxy() : js::Wrapper(0) { }
-
-  bool finalizeInBackground(const JS::Value& priv) const override {
-    return false;
-  }
-
-  // Standard internal methods
-  bool getOwnPropertyDescriptor(JSContext* cx,
-                                JS::Handle<JSObject*> proxy,
-                                JS::Handle<jsid> id,
-                                JS::MutableHandle<JS::PropertyDescriptor> desc)
-                                const override;
-  bool defineProperty(JSContext* cx,
-                      JS::Handle<JSObject*> proxy,
-                      JS::Handle<jsid> id,
-                      JS::Handle<JS::PropertyDescriptor> desc,
-                      JS::ObjectOpResult &result) const override;
-  bool ownPropertyKeys(JSContext *cx,
-                       JS::Handle<JSObject*> proxy,
-                       JS::AutoIdVector &props) const override;
-  bool delete_(JSContext *cx, JS::Handle<JSObject*> proxy,
-                       JS::Handle<jsid> id,
-                       JS::ObjectOpResult &result) const override;
-
-  bool getPrototypeIfOrdinary(JSContext* cx,
-                              JS::Handle<JSObject*> proxy,
-                              bool* isOrdinary,
-                              JS::MutableHandle<JSObject*> protop) const override;
-
-  JSObject* enumerate(JSContext *cx, JS::Handle<JSObject*> proxy) const override;
-  bool preventExtensions(JSContext* cx,
-                         JS::Handle<JSObject*> proxy,
-                         JS::ObjectOpResult& result) const override;
-  bool isExtensible(JSContext *cx, JS::Handle<JSObject*> proxy, bool *extensible)
-                    const override;
-  bool has(JSContext *cx, JS::Handle<JSObject*> proxy,
-           JS::Handle<jsid> id, bool *bp) const override;
-  bool get(JSContext *cx, JS::Handle<JSObject*> proxy,
-           JS::Handle<JS::Value> receiver,
-           JS::Handle<jsid> id,
-           JS::MutableHandle<JS::Value> vp) const override;
-  bool set(JSContext *cx, JS::Handle<JSObject*> proxy,
-           JS::Handle<jsid> id, JS::Handle<JS::Value> v,
-           JS::Handle<JS::Value> receiver,
-           JS::ObjectOpResult &result) const override;
-
-  // SpiderMonkey extensions
-  bool getPropertyDescriptor(JSContext* cx,
-                             JS::Handle<JSObject*> proxy,
-                             JS::Handle<jsid> id,
-                             JS::MutableHandle<JS::PropertyDescriptor> desc)
-                             const override;
-  bool hasOwn(JSContext *cx, JS::Handle<JSObject*> proxy,
-              JS::Handle<jsid> id, bool *bp) const override;
-  bool getOwnEnumerablePropertyKeys(JSContext *cx, JS::Handle<JSObject*> proxy,
-                                    JS::AutoIdVector &props) const override;
-  const char *className(JSContext *cx,
-                        JS::Handle<JSObject*> wrapper) const override;
-
-  void finalize(JSFreeOp *fop, JSObject *proxy) const override;
-  size_t objectMoved(JSObject* proxy, JSObject* old) const override;
-
-  bool isCallable(JSObject *obj) const override {
-    return false;
-  }
-  bool isConstructor(JSObject *obj) const override {
-    return false;
-  }
-
-  static const nsOuterWindowProxy singleton;
-
-protected:
-  static nsGlobalWindowOuter* GetOuterWindow(JSObject *proxy)
-  {
-    nsGlobalWindowOuter* outerWindow = nsGlobalWindowOuter::FromSupports(
-      static_cast<nsISupports*>(js::GetProxyReservedSlot(proxy, 0).toPrivate()));
-    MOZ_ASSERT_IF(outerWindow, outerWindow->IsOuterWindow());
-    return outerWindow;
-  }
-
-  // False return value means we threw an exception.  True return value
-  // but false "found" means we didn't have a subframe at that index.
-  bool GetSubframeWindow(JSContext *cx, JS::Handle<JSObject*> proxy,
-                         JS::Handle<jsid> id,
-                         JS::MutableHandle<JS::Value> vp,
-                         bool &found) const;
-
-  // Returns a non-null window only if id is an index and we have a
-  // window at that index.
-  already_AddRefed<nsPIDOMWindowOuter>
-  GetSubframeWindow(JSContext *cx,
-                    JS::Handle<JSObject*> proxy,
-                    JS::Handle<jsid> id) const;
-
-  bool AppendIndexedPropertyNames(JSContext *cx, JSObject *proxy,
-                                  JS::AutoIdVector &props) const;
-};
-
-// Give OuterWindowProxyClass 2 reserved slots, like the other wrappers, so
-// JSObject::swap can swap it with CrossCompartmentWrappers without requiring
-// malloc.
-const js::Class OuterWindowProxyClass = PROXY_CLASS_DEF(
-    "Proxy",
-    JSCLASS_HAS_RESERVED_SLOTS(2)); /* additional class flags */
-
-const char *
-nsOuterWindowProxy::className(JSContext *cx, JS::Handle<JSObject*> proxy) const
-{
-    MOZ_ASSERT(js::IsProxy(proxy));
-
-    return "Window";
-}
-
-void
-nsOuterWindowProxy::finalize(JSFreeOp *fop, JSObject *proxy) const
-{
-  nsGlobalWindowOuter* outerWindow = GetOuterWindow(proxy);
-  if (outerWindow) {
-    outerWindow->ClearWrapper(proxy);
-
-    // Ideally we would use OnFinalize here, but it's possible that
-    // EnsureScriptEnvironment will later be called on the window, and we don't
-    // want to create a new script object in that case. Therefore, we need to
-    // write a non-null value that will reliably crash when dereferenced.
-    outerWindow->PoisonOuterWindowProxy(proxy);
-  }
-}
-
-bool
-nsOuterWindowProxy::getPropertyDescriptor(JSContext* cx,
-                                          JS::Handle<JSObject*> proxy,
-                                          JS::Handle<jsid> id,
-                                          JS::MutableHandle<JS::PropertyDescriptor> desc) const
-{
-  // The only thing we can do differently from js::Wrapper is shadow stuff with
-  // our indexed properties, so we can just try getOwnPropertyDescriptor and if
-  // that gives us nothing call on through to js::Wrapper.
-  desc.object().set(nullptr);
-  if (!getOwnPropertyDescriptor(cx, proxy, id, desc)) {
-    return false;
-  }
-
-  if (desc.object()) {
-    return true;
-  }
-
-  return js::Wrapper::getPropertyDescriptor(cx, proxy, id, desc);
-}
-
-bool
-nsOuterWindowProxy::getOwnPropertyDescriptor(JSContext* cx,
-                                             JS::Handle<JSObject*> proxy,
-                                             JS::Handle<jsid> id,
-                                             JS::MutableHandle<JS::PropertyDescriptor> desc)
-                                             const
-{
-  bool found;
-  if (!GetSubframeWindow(cx, proxy, id, desc.value(), found)) {
-    return false;
-  }
-  if (found) {
-    FillPropertyDescriptor(desc, proxy, true);
-    return true;
-  }
-  // else fall through to js::Wrapper
-
-  return js::Wrapper::getOwnPropertyDescriptor(cx, proxy, id, desc);
-}
-
-bool
-nsOuterWindowProxy::defineProperty(JSContext* cx,
-                                   JS::Handle<JSObject*> proxy,
-                                   JS::Handle<jsid> id,
-                                   JS::Handle<JS::PropertyDescriptor> desc,
-                                   JS::ObjectOpResult &result) const
-{
-  if (IsArrayIndex(GetArrayIndexFromId(cx, id))) {
-    // Spec says to Reject whether this is a supported index or not,
-    // since we have no indexed setter or indexed creator.  It is up
-    // to the caller to decide whether to throw a TypeError.
-    return result.failCantDefineWindowElement();
-  }
-
-  return js::Wrapper::defineProperty(cx, proxy, id, desc, result);
-}
-
-bool
-nsOuterWindowProxy::ownPropertyKeys(JSContext *cx,
-                                    JS::Handle<JSObject*> proxy,
-                                    JS::AutoIdVector &props) const
-{
-  // Just our indexed stuff followed by our "normal" own property names.
-  if (!AppendIndexedPropertyNames(cx, proxy, props)) {
-    return false;
-  }
-
-  JS::AutoIdVector innerProps(cx);
-  if (!js::Wrapper::ownPropertyKeys(cx, proxy, innerProps)) {
-    return false;
-  }
-  return js::AppendUnique(cx, props, innerProps);
-}
-
-bool
-nsOuterWindowProxy::delete_(JSContext *cx, JS::Handle<JSObject*> proxy,
-                            JS::Handle<jsid> id, JS::ObjectOpResult &result) const
-{
-  if (nsCOMPtr<nsPIDOMWindowOuter> frame = GetSubframeWindow(cx, proxy, id)) {
-    // Fail (which means throw if strict, else return false).
-    return result.failCantDeleteWindowElement();
-  }
-
-  if (IsArrayIndex(GetArrayIndexFromId(cx, id))) {
-    // Indexed, but not supported.  Spec says return true.
-    return result.succeed();
-  }
-
-  return js::Wrapper::delete_(cx, proxy, id, result);
-}
-
-bool
-nsOuterWindowProxy::getPrototypeIfOrdinary(JSContext* cx,
-                                           JS::Handle<JSObject*> proxy,
-                                           bool* isOrdinary,
-                                           JS::MutableHandle<JSObject*> protop) const
-{
-  // Window's [[GetPrototypeOf]] trap isn't the ordinary definition:
-  //
-  //   https://html.spec.whatwg.org/multipage/browsers.html#windowproxy-getprototypeof
-  //
-  // We nonetheless can implement it with a static [[Prototype]], because
-  // wrapper-class handlers (particularly, XOW in FilteringWrapper.cpp) supply
-  // all non-ordinary behavior.
-  //
-  // But from a spec point of view, it's the exact same object in both cases --
-  // only the observer's changed.  So this getPrototypeIfOrdinary trap on the
-  // non-wrapper object *must* report non-ordinary, even if static [[Prototype]]
-  // usually means ordinary.
-  *isOrdinary = false;
-  return true;
-}
-
-bool
-nsOuterWindowProxy::preventExtensions(JSContext* cx,
-                                      JS::Handle<JSObject*> proxy,
-                                      JS::ObjectOpResult& result) const
-{
-  // If [[Extensible]] could be false, then navigating a window could navigate
-  // to a window that's [[Extensible]] after being at one that wasn't: an
-  // invariant violation.  So never change a window's extensibility.
-  return result.failCantPreventExtensions();
-}
-
-bool
-nsOuterWindowProxy::isExtensible(JSContext *cx, JS::Handle<JSObject*> proxy,
-                                 bool *extensible) const
-{
-  // See above.
-  *extensible = true;
-  return true;
-}
-
-bool
-nsOuterWindowProxy::has(JSContext *cx, JS::Handle<JSObject*> proxy,
-                        JS::Handle<jsid> id, bool *bp) const
-{
-  if (nsCOMPtr<nsPIDOMWindowOuter> frame = GetSubframeWindow(cx, proxy, id)) {
-    *bp = true;
-    return true;
-  }
-
-  return js::Wrapper::has(cx, proxy, id, bp);
-}
-
-bool
-nsOuterWindowProxy::hasOwn(JSContext *cx, JS::Handle<JSObject*> proxy,
-                           JS::Handle<jsid> id, bool *bp) const
-{
-  if (nsCOMPtr<nsPIDOMWindowOuter> frame = GetSubframeWindow(cx, proxy, id)) {
-    *bp = true;
-    return true;
-  }
-
-  return js::Wrapper::hasOwn(cx, proxy, id, bp);
-}
-
-bool
-nsOuterWindowProxy::get(JSContext *cx, JS::Handle<JSObject*> proxy,
-                        JS::Handle<JS::Value> receiver,
-                        JS::Handle<jsid> id,
-                        JS::MutableHandle<JS::Value> vp) const
-{
-  if (id == nsDOMClassInfo::sWrappedJSObject_id &&
-      xpc::AccessCheck::isChrome(js::GetContextCompartment(cx))) {
-    vp.set(JS::ObjectValue(*proxy));
-    return true;
-  }
-
-  bool found;
-  if (!GetSubframeWindow(cx, proxy, id, vp, found)) {
-    return false;
-  }
-  if (found) {
-    return true;
-  }
-  // Else fall through to js::Wrapper
-
-  return js::Wrapper::get(cx, proxy, receiver, id, vp);
-}
-
-bool
-nsOuterWindowProxy::set(JSContext *cx, JS::Handle<JSObject*> proxy,
-                        JS::Handle<jsid> id,
-                        JS::Handle<JS::Value> v,
-                        JS::Handle<JS::Value> receiver,
-                        JS::ObjectOpResult &result) const
-{
-  if (IsArrayIndex(GetArrayIndexFromId(cx, id))) {
-    // Reject the set.  It's up to the caller to decide whether to throw a
-    // TypeError.  If the caller is strict mode JS code, it'll throw.
-    return result.failReadOnly();
-  }
-
-  return js::Wrapper::set(cx, proxy, id, v, receiver, result);
-}
-
-bool
-nsOuterWindowProxy::getOwnEnumerablePropertyKeys(JSContext *cx, JS::Handle<JSObject*> proxy,
-                                                 JS::AutoIdVector &props) const
-{
-  // Like ownPropertyKeys, our indexed stuff followed by our "normal" enumerable
-  // own property names.
-  //
-  // Note that this does not match current spec per
-  // https://github.com/whatwg/html/issues/2753 but as that issue says I believe
-  // the spec is wrong.
-  if (!AppendIndexedPropertyNames(cx, proxy, props)) {
-    return false;
-  }
-
-  JS::AutoIdVector innerProps(cx);
-  if (!js::Wrapper::getOwnEnumerablePropertyKeys(cx, proxy, innerProps)) {
-    return false;
-  }
-  return js::AppendUnique(cx, props, innerProps);
-}
-
-JSObject*
-nsOuterWindowProxy::enumerate(JSContext *cx, JS::Handle<JSObject*> proxy) const
-{
-  // BaseProxyHandler::enumerate seems to do what we want here: fall
-  // back on the property names returned from js::GetPropertyKeys()
-  return js::BaseProxyHandler::enumerate(cx, proxy);
-}
-
-bool
-nsOuterWindowProxy::GetSubframeWindow(JSContext *cx,
-                                      JS::Handle<JSObject*> proxy,
-                                      JS::Handle<jsid> id,
-                                      JS::MutableHandle<JS::Value> vp,
-                                      bool& found) const
-{
-  nsCOMPtr<nsPIDOMWindowOuter> frame = GetSubframeWindow(cx, proxy, id);
-  if (!frame) {
-    found = false;
-    return true;
-  }
-
-  found = true;
-  // Just return the window's global
-  nsGlobalWindowOuter* global = nsGlobalWindowOuter::Cast(frame);
-  frame->EnsureInnerWindow();
-  JSObject* obj = global->FastGetGlobalJSObject();
-  // This null check fixes a hard-to-reproduce crash that occurs when we
-  // get here when we're mid-call to nsDocShell::Destroy. See bug 640904
-  // comment 105.
-  if (MOZ_UNLIKELY(!obj)) {
-    return xpc::Throw(cx, NS_ERROR_FAILURE);
-  }
-  JS::ExposeObjectToActiveJS(obj);
-  vp.setObject(*obj);
-  return JS_WrapValue(cx, vp);
-}
-
-already_AddRefed<nsPIDOMWindowOuter>
-nsOuterWindowProxy::GetSubframeWindow(JSContext *cx,
-                                      JS::Handle<JSObject*> proxy,
-                                      JS::Handle<jsid> id) const
-{
-  uint32_t index = GetArrayIndexFromId(cx, id);
-  if (!IsArrayIndex(index)) {
-    return nullptr;
-  }
-
-  nsGlobalWindowOuter* win = GetOuterWindow(proxy);
-  MOZ_ASSERT(win->IsOuterWindow());
-  return win->IndexedGetterOuter(index);
-}
-
-bool
-nsOuterWindowProxy::AppendIndexedPropertyNames(JSContext *cx, JSObject *proxy,
-                                               JS::AutoIdVector &props) const
-{
-  uint32_t length = GetOuterWindow(proxy)->Length();
-  MOZ_ASSERT(int32_t(length) >= 0);
-  if (!props.reserve(props.length() + length)) {
-    return false;
-  }
-  for (int32_t i = 0; i < int32_t(length); ++i) {
-    if (!props.append(INT_TO_JSID(i))) {
-      return false;
-    }
-  }
-
-  return true;
-}
-
-size_t
-nsOuterWindowProxy::objectMoved(JSObject *obj, JSObject *old) const
-{
-  nsGlobalWindowOuter* outerWindow = GetOuterWindow(obj);
-  if (outerWindow) {
-    outerWindow->UpdateWrapper(obj, old);
-  }
-  return 0;
-}
-
-const nsOuterWindowProxy
-nsOuterWindowProxy::singleton;
-
-class nsChromeOuterWindowProxy : public nsOuterWindowProxy
-{
-public:
-  constexpr nsChromeOuterWindowProxy() : nsOuterWindowProxy() { }
-
-  const char *className(JSContext *cx, JS::Handle<JSObject*> wrapper) const override;
-
-  static const nsChromeOuterWindowProxy singleton;
-};
-
-const char *
-nsChromeOuterWindowProxy::className(JSContext *cx,
-                                    JS::Handle<JSObject*> proxy) const
-{
-    MOZ_ASSERT(js::IsProxy(proxy));
-
-    return "ChromeWindow";
-}
-
-const nsChromeOuterWindowProxy
-nsChromeOuterWindowProxy::singleton;
-
-static JSObject*
-NewOuterWindowProxy(JSContext *cx, JS::Handle<JSObject*> global, bool isChrome)
-{
-  JSAutoCompartment ac(cx, global);
-  MOZ_ASSERT(js::GetGlobalForObjectCrossCompartment(global) == global);
-
-  js::WrapperOptions options;
-  options.setClass(&OuterWindowProxyClass);
-  options.setSingleton(true);
-  JSObject *obj = js::Wrapper::New(cx, global,
-                                   isChrome ? &nsChromeOuterWindowProxy::singleton
-                                            : &nsOuterWindowProxy::singleton,
-                                   options);
-  MOZ_ASSERT_IF(obj, js::IsWindowProxy(obj));
-  return obj;
-}
 
 //*****************************************************************************
 //***    nsGlobalWindowInner: Object Management
 //*****************************************************************************
 
 nsGlobalWindowInner::nsGlobalWindowInner(nsGlobalWindowOuter *aOuterWindow)
   : nsPIDOMWindow<nsISupports>(aOuterWindow->AsOuter()),
     mIdleFuzzFactor(0),
@@ -1628,28 +624,17 @@ nsGlobalWindowInner::nsGlobalWindowInner
   }
 
   // We could have failed the first time through trying
   // to create the entropy collector, so we should
   // try to get one until we succeed.
 
   gRefCnt++;
 
-  static bool sFirstTime = true;
-  if (sFirstTime) {
-    TimeoutManager::Initialize();
-    Preferences::AddBoolVarCache(&gIdleObserversAPIFuzzTimeDisabled,
-                                 "dom.idle-observers-api.fuzz_time.disabled",
-                                 false);
-
-    Preferences::AddUintVarCache(&gThrottledIdlePeriodLength,
-                                 "dom.idle_period.throttled_length",
-                                 DEFAULT_THROTTLED_IDLE_PERIOD_LENGTH);
-    sFirstTime = false;
-  }
+  EnsurePrefCaches();
 
   if (gDumpFile == nullptr) {
     nsAutoCString fname;
     Preferences::GetCString("browser.dom.window.dump.file", fname);
     if (!fname.IsEmpty()) {
       // If this fails to open, Dump() knows to just go to stdout on null.
       gDumpFile = fopen(fname.get(), "wb+");
     } else {
@@ -1697,20 +682,17 @@ nsGlobalWindowInner::AssertIsOnMainThrea
 /* static */
 void
 nsGlobalWindowInner::Init()
 {
   AssertIsOnMainThread();
 
   NS_ASSERTION(gDOMLeakPRLog, "gDOMLeakPRLog should have been initialized!");
 
-  nsGlobalWindowOuter::sOuterWindowsById =
-    new nsGlobalWindowOuter::OuterWindowByIdTable();
-  nsGlobalWindowInner::sInnerWindowsById =
-    new nsGlobalWindowInner::InnerWindowByIdTable();
+  sInnerWindowsById = new InnerWindowByIdTable();
 }
 
 nsGlobalWindowInner::~nsGlobalWindowInner()
 {
   AssertIsOnMainThread();
 
   if (IsChromeWindow()) {
     MOZ_ASSERT(mCleanMessageManager,
@@ -1862,25 +844,19 @@ nsGlobalWindowInner::DisconnectEventTarg
 }
 
 // static
 void
 nsGlobalWindowInner::ShutDown()
 {
   AssertIsOnMainThread();
 
-  if (gDumpFile && gDumpFile != stdout) {
-    fclose(gDumpFile);
-  }
-  gDumpFile = nullptr;
-
-  delete nsGlobalWindowInner::sInnerWindowsById;
-  nsGlobalWindowInner::sInnerWindowsById = nullptr;
-  delete nsGlobalWindowOuter::sOuterWindowsById;
-  nsGlobalWindowOuter::sOuterWindowsById = nullptr;
+  // nsGlobalWindowOuter::ShutDown() handles closing gDumpFile.
+  delete sInnerWindowsById;
+  sInnerWindowsById = nullptr;
 }
 
 // static
 void
 nsGlobalWindowInner::CleanupCachedXBLHandlers()
 {
   if (mCachedXBLPrototypeHandlers &&
       mCachedXBLPrototypeHandlers->Count() > 0) {
@@ -2236,25 +1212,16 @@ NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(nsGlobalWindowInner)
   return tmp->IsBlackForCC(true);
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END
 
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(nsGlobalWindowInner)
   return tmp->IsBlackForCC(false);
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
 
-inline void
-ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
-                            IdleObserverHolder& aField,
-                            const char* aName,
-                            unsigned aFlags)
-{
-  CycleCollectionNoteChild(aCallback, aField.mIdleObserver.get(), aName, aFlags);
-}
-
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsGlobalWindowInner)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGlobalWindowInner)
   if (MOZ_UNLIKELY(cb.WantDebugInfo())) {
     char name[512];
     nsAutoCString uri;
     if (tmp->mDoc && tmp->mDoc->GetDocumentURI()) {
       uri = tmp->mDoc->GetDocumentURI()->GetSpecOrDefault();
@@ -2635,38 +1602,16 @@ nsGlobalWindowInner::SetInitialPrincipal
     // Ensure that if someone plays with this document they will get
     // layout happening.
     nsRect r = shell->GetPresContext()->GetVisibleArea();
     shell->Initialize(r.Width(), r.Height());
   }
 }
 
 PopupControlState
-PushPopupControlState(PopupControlState aState, bool aForce)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  PopupControlState oldState = gPopupControlState;
-
-  if (aState < gPopupControlState || aForce) {
-    gPopupControlState = aState;
-  }
-
-  return oldState;
-}
-
-void
-PopPopupControlState(PopupControlState aState)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  gPopupControlState = aState;
-}
-
-PopupControlState
 nsGlobalWindowInner::PushPopupControlState(PopupControlState aState,
                                       bool aForce) const
 {
   return ::PushPopupControlState(aState, aForce);
 }
 
 void
 nsGlobalWindowInner::PopPopupControlState(PopupControlState aState) const
@@ -2676,638 +1621,43 @@ nsGlobalWindowInner::PopPopupControlStat
 
 PopupControlState
 nsGlobalWindowInner::GetPopupControlState() const
 {
   MOZ_ASSERT(NS_IsMainThread());
   return gPopupControlState;
 }
 
-#define WINDOWSTATEHOLDER_IID \
-{0x0b917c3e, 0xbd50, 0x4683, {0xaf, 0xc9, 0xc7, 0x81, 0x07, 0xae, 0x33, 0x26}}
-
-class WindowStateHolder final : public nsISupports
-{
-public:
-  NS_DECLARE_STATIC_IID_ACCESSOR(WINDOWSTATEHOLDER_IID)
-  NS_DECL_ISUPPORTS
-
-  explicit WindowStateHolder(nsGlobalWindowInner *aWindow);
-
-  nsGlobalWindowInner* GetInnerWindow() { return mInnerWindow; }
-
-  void DidRestoreWindow()
-  {
-    mInnerWindow = nullptr;
-    mInnerWindowReflector = nullptr;
-  }
-
-protected:
-  ~WindowStateHolder();
-
-  nsGlobalWindowInner *mInnerWindow;
-  // We hold onto this to make sure the inner window doesn't go away. The outer
-  // window ends up recalculating it anyway.
-  JS::PersistentRooted<JSObject*> mInnerWindowReflector;
-};
-
-NS_DEFINE_STATIC_IID_ACCESSOR(WindowStateHolder, WINDOWSTATEHOLDER_IID)
-
-WindowStateHolder::WindowStateHolder(nsGlobalWindowInner* aWindow)
-  : mInnerWindow(aWindow),
-    mInnerWindowReflector(RootingCx(), aWindow->GetWrapper())
-{
-  NS_PRECONDITION(aWindow, "null window");
-  NS_PRECONDITION(aWindow->IsInnerWindow(), "Saving an outer window");
-
-  aWindow->Suspend();
-
-  // When a global goes into the bfcache, we disable script.
-  xpc::Scriptability::Get(mInnerWindowReflector).SetDocShellAllowsScript(false);
-}
-
-WindowStateHolder::~WindowStateHolder()
-{
-  if (mInnerWindow) {
-    // This window was left in the bfcache and is now going away. We need to
-    // free it up.
-    // Note that FreeInnerObjects may already have been called on the
-    // inner window if its outer has already had SetDocShell(null)
-    // called.
-    mInnerWindow->FreeInnerObjects();
-  }
-}
-
-NS_IMPL_ISUPPORTS(WindowStateHolder, WindowStateHolder)
-
-// We need certain special behavior for remote XUL whitelisted domains, but we
-// don't want that behavior to take effect in automation, because we whitelist
-// all the mochitest domains. So we need to check a pref here.
-static bool
-TreatAsRemoteXUL(nsIPrincipal* aPrincipal)
-{
-  MOZ_ASSERT(!nsContentUtils::IsSystemPrincipal(aPrincipal));
-  return nsContentUtils::AllowXULXBLForPrincipal(aPrincipal) &&
-         !Preferences::GetBool("dom.use_xbl_scopes_for_remote_xul", false);
-}
-
-static bool
-EnablePrivilege(JSContext* cx, unsigned argc, JS::Value* vp)
-{
-  Telemetry::Accumulate(Telemetry::ENABLE_PRIVILEGE_EVER_CALLED, true);
-  return xpc::EnableUniversalXPConnect(cx);
-}
-
-static const JSFunctionSpec EnablePrivilegeSpec[] = {
-  JS_FN("enablePrivilege", EnablePrivilege, 1, 0),
-  JS_FS_END
-};
-
-static bool
-InitializeLegacyNetscapeObject(JSContext* aCx, JS::Handle<JSObject*> aGlobal)
-{
-  JSAutoCompartment ac(aCx, aGlobal);
-
-  // Note: MathJax depends on window.netscape being exposed. See bug 791526.
-  JS::Rooted<JSObject*> obj(aCx);
-  obj = JS_DefineObject(aCx, aGlobal, "netscape", nullptr);
-  NS_ENSURE_TRUE(obj, false);
-
-  obj = JS_DefineObject(aCx, obj, "security", nullptr);
-  NS_ENSURE_TRUE(obj, false);
-
-  // We hide enablePrivilege behind a pref because it has been altered in a
-  // way that makes it fundamentally insecure to use in production. Mozilla
-  // uses this pref during automated testing to support legacy test code that
-  // uses enablePrivilege. If you're not doing test automation, you _must_ not
-  // flip this pref, or you will be exposing all your users to security
-  // vulnerabilities.
-  if (!xpc::IsInAutomation()) {
-    return true;
-  }
-
-  /* Define PrivilegeManager object with the necessary "static" methods. */
-  obj = JS_DefineObject(aCx, obj, "PrivilegeManager", nullptr);
-  NS_ENSURE_TRUE(obj, false);
-
-  return JS_DefineFunctions(aCx, obj, EnablePrivilegeSpec);
-}
-
 bool
 nsGlobalWindowInner::ComputeIsSecureContext(nsIDocument* aDocument, SecureContextFlags aFlags)
 {
   MOZ_CRASH("Outer Window Only - notbuilding");
 }
 
-static JS::CompartmentCreationOptions&
-SelectZoneGroup(nsGlobalWindowInner* aNewInner,
-                JS::CompartmentCreationOptions& aOptions)
-{
-  JS::CompartmentCreationOptions options;
-
-  if (aNewInner->GetOuterWindow()) {
-    nsGlobalWindowOuter *top = aNewInner->GetTopInternal();
-
-    // If we have a top-level window, use its zone (and zone group).
-    if (top && top->GetGlobalJSObject()) {
-      return aOptions.setExistingZone(top->GetGlobalJSObject());
-    }
-  }
-
-  // If we're in the parent process, don't bother with zone groups.
-  if (XRE_IsParentProcess()) {
-    return aOptions.setNewZoneInSystemZoneGroup();
-  }
-
-  // Otherwise, find a zone group from the TabGroup. Typically we only have to
-  // go through one iteration of this loop.
-  RefPtr<TabGroup> tabGroup = aNewInner->TabGroup();
-  for (nsPIDOMWindowOuter* outer : tabGroup->GetWindows()) {
-    nsGlobalWindowOuter* window = nsGlobalWindowOuter::Cast(outer);
-    if (JSObject* global = window->GetGlobalJSObject()) {
-      return aOptions.setNewZoneInExistingZoneGroup(global);
-    }
-  }
-
-  return aOptions.setNewZoneInNewZoneGroup();
-}
-
-/**
- * Create a new global object that will be used for an inner window.
- * Return the native global and an nsISupports 'holder' that can be used
- * to manage the lifetime of it.
- */
-static nsresult
-CreateNativeGlobalForInner(JSContext* aCx,
-                           nsGlobalWindowInner* aNewInner,
-                           nsIURI* aURI,
-                           nsIPrincipal* aPrincipal,
-                           JS::MutableHandle<JSObject*> aGlobal,
-                           bool aIsSecureContext)
-{
-  MOZ_ASSERT(aCx);
-  MOZ_ASSERT(aNewInner);
-  MOZ_ASSERT(aNewInner->IsInnerWindow());
-  MOZ_ASSERT(aPrincipal);
-
-  // DOMWindow with nsEP is not supported, we have to make sure
-  // no one creates one accidentally.
-  nsCOMPtr<nsIExpandedPrincipal> nsEP = do_QueryInterface(aPrincipal);
-  MOZ_RELEASE_ASSERT(!nsEP, "DOMWindow with nsEP is not supported");
-
-  JS::CompartmentOptions options;
-
-  SelectZoneGroup(aNewInner, options.creationOptions());
-
-  // Sometimes add-ons load their own XUL windows, either as separate top-level
-  // windows or inside a browser element. In such cases we want to tag the
-  // window's compartment with the add-on ID. See bug 1092156.
-  if (nsContentUtils::IsSystemPrincipal(aPrincipal)) {
-    options.creationOptions().setAddonId(MapURIToAddonID(aURI));
-  }
-
-  options.creationOptions().setSecureContext(aIsSecureContext);
-
-  xpc::InitGlobalObjectOptions(options, aPrincipal);
-
-  // Determine if we need the Components object.
-  bool needComponents = nsContentUtils::IsSystemPrincipal(aPrincipal) ||
-                        TreatAsRemoteXUL(aPrincipal);
-  uint32_t flags = needComponents ? 0 : xpc::OMIT_COMPONENTS_OBJECT;
-  flags |= xpc::DONT_FIRE_ONNEWGLOBALHOOK;
-
-  if (!WindowBinding::Wrap(aCx, aNewInner, aNewInner, options,
-                           nsJSPrincipals::get(aPrincipal), false, aGlobal) ||
-      !xpc::InitGlobalObject(aCx, aGlobal, flags)) {
-    return NS_ERROR_FAILURE;
-  }
-
-  MOZ_ASSERT(aNewInner->GetWrapperPreserveColor() == aGlobal);
-
-  // Set the location information for the new global, so that tools like
-  // about:memory may use that information
-  xpc::SetLocationForGlobal(aGlobal, aURI);
-
-  if (!InitializeLegacyNetscapeObject(aCx, aGlobal)) {
-    return NS_ERROR_FAILURE;
-  }
-
-  return NS_OK;
-}
-
 nsresult
 nsGlobalWindowInner::SetNewDocument(nsIDocument* aDocument,
                                nsISupports* aState,
                                bool aForceReuseInnerWindow)
 {
   NS_PRECONDITION(mDocumentPrincipal == nullptr,
                   "mDocumentPrincipal prematurely set!");
   MOZ_ASSERT(aDocument);
 
-  if (IsInnerWindow()) {
-    if (!mOuterWindow) {
-      return NS_ERROR_NOT_INITIALIZED;
-    }
-
-    // Refuse to set a new document if the call came from an inner
-    // window that's not the current inner window.
-    if (mOuterWindow->GetCurrentInnerWindow() != AsInner()) {
-      return NS_ERROR_NOT_AVAILABLE;
-    }
-
-    return GetOuterWindowInternal()->SetNewDocument(aDocument, aState,
-                                                    aForceReuseInnerWindow);
-  }
-
-  NS_PRECONDITION(IsOuterWindow(), "Must only be called on outer windows");
-
-  // Bail out early if we're in process of closing down the window.
-  NS_ENSURE_STATE(!mCleanedUp);
-
-  NS_ASSERTION(!AsOuter()->GetCurrentInnerWindow() ||
-               AsOuter()->GetCurrentInnerWindow()->GetExtantDoc() == mDoc,
-               "Uh, mDoc doesn't match the current inner window "
-               "document!");
-
-  bool wouldReuseInnerWindow = WouldReuseInnerWindow(aDocument);
-  if (aForceReuseInnerWindow &&
-      !wouldReuseInnerWindow &&
-      mDoc &&
-      mDoc->NodePrincipal() != aDocument->NodePrincipal()) {
-    NS_ERROR("Attempted forced inner window reuse while changing principal");
-    return NS_ERROR_UNEXPECTED;
-  }
-
-  nsCOMPtr<nsIDocument> oldDoc = mDoc;
-
-  AutoJSAPI jsapi;
-  jsapi.Init();
-  JSContext *cx = jsapi.cx();
-
-  // Check if we're anywhere near the stack limit before we reach the
-  // transplanting code, since it has no good way to handle errors. This uses
-  // the untrusted script limit, which is not strictly necessary since no
-  // actual script should run.
-  if (!js::CheckRecursionLimitConservativeDontReport(cx)) {
-    NS_WARNING("Overrecursion in SetNewDocument");
-    return NS_ERROR_FAILURE;
-  }
-
-  if (!mDoc) {
-    // First document load.
-
-    // Get our private root. If it is equal to us, then we need to
-    // attach our global key bindings that handles browser scrolling
-    // and other browser commands.
-    nsPIDOMWindowOuter* privateRoot = GetPrivateRoot();
-
-    if (privateRoot == AsOuter()) {
-      nsXBLService::AttachGlobalKeyHandler(mChromeEventHandler);
-    }
-  }
-
-  /* No mDocShell means we're already been partially closed down.  When that
-     happens, setting status isn't a big requirement, so don't. (Doesn't happen
-     under normal circumstances, but bug 49615 describes a case.) */
-
-  nsContentUtils::AddScriptRunner(NewRunnableMethod(
-    "nsGlobalWindowInner::ClearStatus", this, &nsGlobalWindowInner::ClearStatus));
-
-  // Sometimes, WouldReuseInnerWindow() returns true even if there's no inner
-  // window (see bug 776497). Be safe.
-  bool reUseInnerWindow = (aForceReuseInnerWindow || wouldReuseInnerWindow) &&
-                          GetCurrentInnerWindowInternal();
-
-  nsresult rv = NS_OK;
-
-  // We set mDoc even though this is an outer window to avoid
-  // having to *always* reach into the inner window to find the
-  // document.
-  mDoc = aDocument;
-
-  // Take this opportunity to clear mSuspendedDoc. Our old inner window is now
-  // responsible for unsuspending it.
-  mSuspendedDoc = nullptr;
-
-#ifdef DEBUG
-  mLastOpenedURI = aDocument->GetDocumentURI();
-#endif
-
-  mContext->WillInitializeContext();
-
-  nsGlobalWindowInner *currentInner = GetCurrentInnerWindowInternal();
-
-  if (currentInner && currentInner->mNavigator) {
-    currentInner->mNavigator->OnNavigation();
-  }
-
-  RefPtr<nsGlobalWindowInner> newInnerWindow;
-  bool createdInnerWindow = false;
-
-  bool thisChrome = IsChromeWindow();
-
-  nsCOMPtr<WindowStateHolder> wsh = do_QueryInterface(aState);
-  NS_ASSERTION(!aState || wsh, "What kind of weird state are you giving me here?");
-
-  JS::Rooted<JSObject*> newInnerGlobal(cx);
-  if (reUseInnerWindow) {
-    // We're reusing the current inner window.
-    NS_ASSERTION(!currentInner->IsFrozen(),
-                 "We should never be reusing a shared inner window");
-    newInnerWindow = currentInner;
-    newInnerGlobal = currentInner->GetWrapperPreserveColor();
-
-    if (aDocument != oldDoc) {
-      JS::ExposeObjectToActiveJS(newInnerGlobal);
-    }
-
-    // We're reusing the inner window, but this still counts as a navigation,
-    // so all expandos and such defined on the outer window should go away. Force
-    // all Xray wrappers to be recomputed.
-    JS::Rooted<JSObject*> rootedObject(cx, GetWrapper());
-    if (!JS_RefreshCrossCompartmentWrappers(cx, rootedObject)) {
-      return NS_ERROR_FAILURE;
-    }
-
-    // Inner windows are only reused for same-origin principals, but the principals
-    // don't necessarily match exactly. Update the principal on the compartment to
-    // match the new document.
-    // NB: We don't just call currentInner->RefreshCompartmentPrincipals() here
-    // because we haven't yet set its mDoc to aDocument.
-    JSCompartment *compartment = js::GetObjectCompartment(newInnerGlobal);
-#ifdef DEBUG
-    bool sameOrigin = false;
-    nsIPrincipal *existing =
-      nsJSPrincipals::get(JS_GetCompartmentPrincipals(compartment));
-    aDocument->NodePrincipal()->Equals(existing, &sameOrigin);
-    MOZ_ASSERT(sameOrigin);
-#endif
-    MOZ_ASSERT_IF(aDocument == oldDoc,
-                  xpc::GetCompartmentPrincipal(compartment) ==
-                  aDocument->NodePrincipal());
-    if (aDocument != oldDoc) {
-      JS_SetCompartmentPrincipals(compartment,
-                                  nsJSPrincipals::get(aDocument->NodePrincipal()));
-      // Make sure we clear out the old content XBL scope, so the new one will
-      // get created with a principal that subsumes our new principal.
-      xpc::ClearContentXBLScope(newInnerGlobal);
-    }
-  } else {
-    if (aState) {
-      newInnerWindow = wsh->GetInnerWindow();
-      newInnerGlobal = newInnerWindow->GetWrapperPreserveColor();
-    } else {
-      newInnerWindow = nsGlobalWindowInner::Create(AssertOuter(), thisChrome);
-
-      // The outer window is automatically treated as frozen when we
-      // null out the inner window. As a result, initializing classes
-      // on the new inner won't end up reaching into the old inner
-      // window for classes etc.
-      //
-      // [This happens with Object.prototype when XPConnect creates
-      // a temporary global while initializing classes; the reason
-      // being that xpconnect creates the temp global w/o a parent
-      // and proto, which makes the JS engine look up classes in
-      // cx->globalObject, i.e. this outer window].
-
-      mInnerWindow = nullptr;
-
-      mCreatingInnerWindow = true;
-      // Every script context we are initialized with must create a
-      // new global.
-      rv = CreateNativeGlobalForInner(cx, newInnerWindow,
-                                      aDocument->GetDocumentURI(),
-                                      aDocument->NodePrincipal(),
-                                      &newInnerGlobal,
-                                      ComputeIsSecureContext(aDocument));
-      NS_ASSERTION(NS_SUCCEEDED(rv) && newInnerGlobal &&
-                   newInnerWindow->GetWrapperPreserveColor() == newInnerGlobal,
-                   "Failed to get script global");
-      newInnerWindow->mIsSecureContextIfOpenerIgnored =
-        ComputeIsSecureContext(aDocument, SecureContextFlags::eIgnoreOpener);
-
-      mCreatingInnerWindow = false;
-      createdInnerWindow = true;
-
-      NS_ENSURE_SUCCESS(rv, rv);
-    }
-
-    if (currentInner && currentInner->GetWrapperPreserveColor()) {
-      if (oldDoc == aDocument) {
-        // Make a copy of the old window's performance object on document.open.
-        // Note that we have to force eager creation of it here, because we need
-        // to grab the current document channel and whatnot before that changes.
-        currentInner->AsInner()->CreatePerformanceObjectIfNeeded();
-        if (currentInner->mPerformance) {
-          newInnerWindow->mPerformance =
-            Performance::CreateForMainThread(newInnerWindow->AsInner(),
-                                             currentInner->mPerformance->GetDOMTiming(),
-                                             currentInner->mPerformance->GetChannel());
-        }
-      }
-
-      // Don't free objects on our current inner window if it's going to be
-      // held in the bfcache.
-      if (!currentInner->IsFrozen()) {
-        currentInner->FreeInnerObjects();
-      }
-    }
-
-    mInnerWindow = newInnerWindow->AsInner();
-    MOZ_ASSERT(mInnerWindow);
-    mInnerWindow->TryToCacheTopInnerWindow();
-
-    if (!GetWrapperPreserveColor()) {
-      JS::Rooted<JSObject*> outer(cx,
-        NewOuterWindowProxy(cx, newInnerGlobal, thisChrome));
-      NS_ENSURE_TRUE(outer, NS_ERROR_FAILURE);
-
-      js::SetProxyReservedSlot(outer, 0, js::PrivateValue(ToSupports(this)));
-
-      // Inform the nsJSContext, which is the canonical holder of the outer.
-      mContext->SetWindowProxy(outer);
-      mContext->DidInitializeContext();
-
-      SetWrapper(mContext->GetWindowProxy());
-    } else {
-      JS::ExposeObjectToActiveJS(newInnerGlobal);
-      JS::Rooted<JSObject*> outerObject(cx,
-        NewOuterWindowProxy(cx, newInnerGlobal, thisChrome));
-      if (!outerObject) {
-        NS_ERROR("out of memory");
-        return NS_ERROR_FAILURE;
-      }
-
-      JS::Rooted<JSObject*> obj(cx, GetWrapperPreserveColor());
-
-      js::SetProxyReservedSlot(obj, 0, js::PrivateValue(nullptr));
-      js::SetProxyReservedSlot(outerObject, 0, js::PrivateValue(nullptr));
-
-      outerObject = xpc::TransplantObject(cx, obj, outerObject);
-      if (!outerObject) {
-        NS_ERROR("unable to transplant wrappers, probably OOM");
-        return NS_ERROR_FAILURE;
-      }
-
-      js::SetProxyReservedSlot(outerObject, 0, js::PrivateValue(ToSupports(this)));
-
-      SetWrapper(outerObject);
-
-      MOZ_ASSERT(js::GetGlobalForObjectCrossCompartment(outerObject) == newInnerGlobal);
-
-      // Inform the nsJSContext, which is the canonical holder of the outer.
-      mContext->SetWindowProxy(outerObject);
-    }
-
-    // Enter the new global's compartment.
-    JSAutoCompartment ac(cx, GetWrapperPreserveColor());
-
-    {
-      JS::Rooted<JSObject*> outer(cx, GetWrapperPreserveColor());
-      js::SetWindowProxy(cx, newInnerGlobal, outer);
-    }
-
-    // Set scriptability based on the state of the docshell.
-    bool allow = GetDocShell()->GetCanExecuteScripts();
-    xpc::Scriptability::Get(GetWrapperPreserveColor()).SetDocShellAllowsScript(allow);
-
-    if (!aState) {
-      // Get the "window" property once so it will be cached on our inner.  We
-      // have to do this here, not in binding code, because this has to happen
-      // after we've created the outer window proxy and stashed it in the outer
-      // nsGlobalWindowInner, so GetWrapperPreserveColor() on that outer
-      // nsGlobalWindowInner doesn't return null and nsGlobalWindowInner::OuterObject
-      // works correctly.
-      JS::Rooted<JS::Value> unused(cx);
-      if (!JS_GetProperty(cx, newInnerGlobal, "window", &unused)) {
-        NS_ERROR("can't create the 'window' property");
-        return NS_ERROR_FAILURE;
-      }
-
-      // And same thing for the "self" property.
-      if (!JS_GetProperty(cx, newInnerGlobal, "self", &unused)) {
-        NS_ERROR("can't create the 'self' property");
-        return NS_ERROR_FAILURE;
-      }
-    }
-  }
-
-  JSAutoCompartment ac(cx, GetWrapperPreserveColor());
-
-  if (!aState && !reUseInnerWindow) {
-    // Loading a new page and creating a new inner window, *not*
-    // restoring from session history.
-
-    // Now that both the the inner and outer windows are initialized
-    // let the script context do its magic to hook them together.
-    MOZ_ASSERT(mContext->GetWindowProxy() == GetWrapperPreserveColor());
-#ifdef DEBUG
-    JS::Rooted<JSObject*> rootedJSObject(cx, GetWrapperPreserveColor());
-    JS::Rooted<JSObject*> proto1(cx), proto2(cx);
-    JS_GetPrototype(cx, rootedJSObject, &proto1);
-    JS_GetPrototype(cx, newInnerGlobal, &proto2);
-    NS_ASSERTION(proto1 == proto2,
-                 "outer and inner globals should have the same prototype");
-#endif
-
-    mInnerWindow->SyncStateFromParentWindow();
-  }
-
-  // Add an extra ref in case we release mContext during GC.
-  nsCOMPtr<nsIScriptContext> kungFuDeathGrip(mContext);
-
-  aDocument->SetScriptGlobalObject(newInnerWindow);
-  MOZ_ASSERT(newInnerWindow->mTabGroup,
-             "We must have a TabGroup cached at this point");
-
-  if (!aState) {
-    if (reUseInnerWindow) {
-
-      if (newInnerWindow->mDoc != aDocument) {
-        newInnerWindow->mDoc = aDocument;
-
-        // The storage objects contain the URL of the window. We have to
-        // recreate them when the innerWindow is reused.
-        newInnerWindow->mLocalStorage = nullptr;
-        newInnerWindow->mSessionStorage = nullptr;
-
-        newInnerWindow->ClearDocumentDependentSlots(cx);
-      }
-    } else {
-      newInnerWindow->InnerSetNewDocument(cx, aDocument);
-
-      // Initialize DOM classes etc on the inner window.
-      JS::Rooted<JSObject*> obj(cx, newInnerGlobal);
-      rv = kungFuDeathGrip->InitClasses(obj);
-      NS_ENSURE_SUCCESS(rv, rv);
-    }
-
-    // If the document comes from a JAR, check if the channel was determined
-    // to be unsafe. If so, permanently disable script on the compartment by
-    // calling Block() and throwing away the key.
-    nsCOMPtr<nsIJARChannel> jarChannel = do_QueryInterface(aDocument->GetChannel());
-    if (jarChannel && jarChannel->GetIsUnsafe()) {
-      xpc::Scriptability::Get(newInnerGlobal).Block();
-    }
-
-    if (mArguments) {
-      newInnerWindow->DefineArgumentsProperty(mArguments);
-      mArguments = nullptr;
-    }
-
-    // Give the new inner window our chrome event handler (since it
-    // doesn't have one).
-    newInnerWindow->mChromeEventHandler = mChromeEventHandler;
-  }
-
-  // Ask the JS engine to assert that it's valid to access our DocGroup whenever
-  // it runs JS code for this compartment. We skip the check if this window is
-  // for chrome JS or an add-on.
-  nsCOMPtr<nsIPrincipal> principal = mDoc->NodePrincipal();
-  if (GetDocGroup() && !nsContentUtils::IsSystemPrincipal(principal) &&
-      !BasePrincipal::Cast(principal)->AddonPolicy()) {
-    js::SetCompartmentValidAccessPtr(cx, newInnerGlobal,
-                                     newInnerWindow->GetDocGroup()->GetValidAccessPtr());
-  }
-
-  kungFuDeathGrip->DidInitializeContext();
-
-  // We wait to fire the debugger hook until the window is all set up and hooked
-  // up with the outer. See bug 969156.
-  if (createdInnerWindow) {
-    nsContentUtils::AddScriptRunner(
-      NewRunnableMethod("nsGlobalWindowInner::FireOnNewGlobalObject",
-                        newInnerWindow,
-                        &nsGlobalWindowInner::FireOnNewGlobalObject));
-  }
-
-  if (newInnerWindow && !newInnerWindow->mHasNotifiedGlobalCreated && mDoc) {
-    // We should probably notify. However if this is the, arguably bad,
-    // situation when we're creating a temporary non-chrome-about-blank
-    // document in a chrome docshell, don't notify just yet. Instead wait
-    // until we have a real chrome doc.
-    if (!mDocShell ||
-        mDocShell->ItemType() != nsIDocShellTreeItem::typeChrome ||
-        nsContentUtils::IsSystemPrincipal(mDoc->NodePrincipal())) {
-      newInnerWindow->mHasNotifiedGlobalCreated = true;
-      nsContentUtils::AddScriptRunner(
-        NewRunnableMethod("nsGlobalWindowInner::DispatchDOMWindowCreated",
-                          this,
-                          &nsGlobalWindowInner::DispatchDOMWindowCreated));
-    }
-  }
-
-  PreloadLocalStorage();
-
-  // If we have a recorded interesting Large-Allocation header status, report it
-  // to the newly attached document.
-  ReportLargeAllocStatus();
-  mLargeAllocStatus = LargeAllocStatus::NONE;
-
-  return NS_OK;
+  if (!mOuterWindow) {
+    return NS_ERROR_NOT_INITIALIZED;
+  }
+
+  // Refuse to set a new document if the call came from an inner
+  // window that's not the current inner window.
+  if (mOuterWindow->GetCurrentInnerWindow() != AsInner()) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+
+  return GetOuterWindowInternal()->SetNewDocument(aDocument, aState,
+                                                  aForceReuseInnerWindow);
 }
 
 void
 nsGlobalWindowInner::PreloadLocalStorage()
 {
   MOZ_ASSERT(IsOuterWindow());
 
   if (!Preferences::GetBool(kStorageEnabled)) {
@@ -3525,34 +1875,16 @@ nsGlobalWindowInner::SetOpenerWindow(nsP
       aOpener->GetCurrentInnerWindow()->IsSecureContext();
   }
 
 #ifdef DEBUG
   mSetOpenerWindowCalled = true;
 #endif
 }
 
-static
-already_AddRefed<EventTarget>
-TryGetTabChildGlobalAsEventTarget(nsISupports *aFrom)
-{
-  nsCOMPtr<nsIFrameLoaderOwner> frameLoaderOwner = do_QueryInterface(aFrom);
-  if (!frameLoaderOwner) {
-    return nullptr;
-  }
-
-  RefPtr<nsFrameLoader> frameLoader = frameLoaderOwner->GetFrameLoader();
-  if (!frameLoader) {
-    return nullptr;
-  }
-
-  nsCOMPtr<EventTarget> target = frameLoader->GetTabChildGlobalAsEventTarget();
-  return target.forget();
-}
-
 void
 nsGlobalWindowInner::UpdateParentTarget()
 {
   // Try to get our frame element's tab child global (its in-process message
   // manager).  If that fails, fall back to the chrome event handler's tab
   // child global, and if it doesn't have one, just use the chrome event
   // handler itself.
 
@@ -3973,90 +2305,16 @@ nsGlobalWindowInner::GetPrincipal()
 
   return nullptr;
 }
 
 //*****************************************************************************
 // nsGlobalWindowInner::nsIDOMWindow
 //*****************************************************************************
 
-template <class T>
-nsIURI*
-nsPIDOMWindow<T>::GetDocumentURI() const
-{
-  return mDoc ? mDoc->GetDocumentURI() : mDocumentURI.get();
-}
-
-template <class T>
-nsIURI*
-nsPIDOMWindow<T>::GetDocBaseURI() const
-{
-  return mDoc ? mDoc->GetDocBaseURI() : mDocBaseURI.get();
-}
-
-template <class T>
-void
-nsPIDOMWindow<T>::MaybeCreateDoc()
-{
-  MOZ_ASSERT(!mDoc);
-  if (nsIDocShell* docShell = GetDocShell()) {
-    // Note that |document| here is the same thing as our mDoc, but we
-    // don't have to explicitly set the member variable because the docshell
-    // has already called SetNewDocument().
-    nsCOMPtr<nsIDocument> document = docShell->GetDocument();
-    Unused << document;
-  }
-}
-
-void
-nsPIDOMWindowOuter::SetInitialKeyboardIndicators(
-  UIStateChangeType aShowAccelerators, UIStateChangeType aShowFocusRings)
-{
-  MOZ_ASSERT(IsOuterWindow());
-  MOZ_ASSERT(!GetCurrentInnerWindow());
-
-  nsPIDOMWindowOuter* piWin = GetPrivateRoot();
-  if (!piWin) {
-    return;
-  }
-
-  MOZ_ASSERT(piWin == AsOuter());
-
-  // only change the flags that have been modified
-  nsCOMPtr<nsPIWindowRoot> windowRoot = do_QueryInterface(mChromeEventHandler);
-  if (!windowRoot) {
-    return;
-  }
-
-  if (aShowAccelerators != UIStateChangeType_NoChange) {
-    windowRoot->SetShowAccelerators(aShowAccelerators == UIStateChangeType_Set);
-  }
-  if (aShowFocusRings != UIStateChangeType_NoChange) {
-    windowRoot->SetShowFocusRings(aShowFocusRings == UIStateChangeType_Set);
-  }
-
-  nsContentUtils::SetKeyboardIndicatorsOnRemoteChildren(GetOuterWindow(),
-                                                        aShowAccelerators,
-                                                        aShowFocusRings);
-}
-
-Element*
-nsPIDOMWindowOuter::GetFrameElementInternal() const
-{
-  MOZ_ASSERT(IsOuterWindow());
-  return mFrameElement;
-}
-
-void
-nsPIDOMWindowOuter::SetFrameElementInternal(Element* aFrameElement)
-{
-  MOZ_ASSERT(IsOuterWindow());
-  mFrameElement = aFrameElement;
-}
-
 bool
 nsPIDOMWindowInner::AddAudioContext(AudioContext* aAudioContext)
 {
   MOZ_ASSERT(IsInnerWindow());
 
   mAudioContexts.AppendElement(aAudioContext);
 
   // Return true if the context should be muted and false if not.
@@ -4419,178 +2677,16 @@ bool
 nsPIDOMWindowInner::HasOpenWebSockets() const
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   return mNumOfOpenWebSockets ||
          (mTopInnerWindow && mTopInnerWindow->mNumOfOpenWebSockets);
 }
 
-void
-nsPIDOMWindowOuter::MaybeActiveMediaComponents()
-{
-  if (IsInnerWindow()) {
-    return mOuterWindow->MaybeActiveMediaComponents();
-  }
-
-  if (mMediaSuspend != nsISuspendedTypes::SUSPENDED_BLOCK) {
-    return;
-  }
-
-  MOZ_LOG(AudioChannelService::GetAudioChannelLog(), LogLevel::Debug,
-         ("nsPIDOMWindowOuter, MaybeActiveMediaComponents, "
-          "resume the window from blocked, this = %p\n", this));
-
-  SetMediaSuspend(nsISuspendedTypes::NONE_SUSPENDED);
-}
-
-SuspendTypes
-nsPIDOMWindowOuter::GetMediaSuspend() const
-{
-  if (IsInnerWindow()) {
-    return mOuterWindow->GetMediaSuspend();
-  }
-
-  return mMediaSuspend;
-}
-
-void
-nsPIDOMWindowOuter::SetMediaSuspend(SuspendTypes aSuspend)
-{
-  if (IsInnerWindow()) {
-    mOuterWindow->SetMediaSuspend(aSuspend);
-    return;
-  }
-
-  if (!IsDisposableSuspend(aSuspend)) {
-    MaybeNotifyMediaResumedFromBlock(aSuspend);
-    mMediaSuspend = aSuspend;
-  }
-
-  RefreshMediaElementsSuspend(aSuspend);
-}
-
-void
-nsPIDOMWindowOuter::MaybeNotifyMediaResumedFromBlock(SuspendTypes aSuspend)
-{
-  if (mMediaSuspend == nsISuspendedTypes::SUSPENDED_BLOCK &&
-      aSuspend == nsISuspendedTypes::NONE_SUSPENDED) {
-    RefPtr<AudioChannelService> service = AudioChannelService::GetOrCreate();
-    if (service) {
-      service->NotifyMediaResumedFromBlock(GetOuterWindow());
-    }
-  }
-}
-
-bool
-nsPIDOMWindowOuter::GetAudioMuted() const
-{
-  if (IsInnerWindow()) {
-    return mOuterWindow->GetAudioMuted();
-  }
-
-  return mAudioMuted;
-}
-
-void
-nsPIDOMWindowOuter::SetAudioMuted(bool aMuted)
-{
-  if (IsInnerWindow()) {
-    mOuterWindow->SetAudioMuted(aMuted);
-    return;
-  }
-
-  if (mAudioMuted == aMuted) {
-    return;
-  }
-
-  mAudioMuted = aMuted;
-  RefreshMediaElementsVolume();
-}
-
-float
-nsPIDOMWindowOuter::GetAudioVolume() const
-{
-  if (IsInnerWindow()) {
-    return mOuterWindow->GetAudioVolume();
-  }
-
-  return mAudioVolume;
-}
-
-nsresult
-nsPIDOMWindowOuter::SetAudioVolume(float aVolume)
-{
-  if (IsInnerWindow()) {
-    return mOuterWindow->SetAudioVolume(aVolume);
-  }
-
-  if (aVolume < 0.0) {
-    return NS_ERROR_DOM_INDEX_SIZE_ERR;
-  }
-
-  if (mAudioVolume == aVolume) {
-    return NS_OK;
-  }
-
-  mAudioVolume = aVolume;
-  RefreshMediaElementsVolume();
-  return NS_OK;
-}
-
-void
-nsPIDOMWindowOuter::RefreshMediaElementsVolume()
-{
-  RefPtr<AudioChannelService> service = AudioChannelService::GetOrCreate();
-  if (service) {
-    service->RefreshAgentsVolume(GetOuterWindow());
-  }
-}
-
-void
-nsPIDOMWindowOuter::RefreshMediaElementsSuspend(SuspendTypes aSuspend)
-{
-  RefPtr<AudioChannelService> service = AudioChannelService::GetOrCreate();
-  if (service) {
-    service->RefreshAgentsSuspend(GetOuterWindow(), aSuspend);
-  }
-}
-
-bool
-nsPIDOMWindowOuter::IsDisposableSuspend(SuspendTypes aSuspend) const
-{
-  return (aSuspend == nsISuspendedTypes::SUSPENDED_PAUSE_DISPOSABLE ||
-          aSuspend == nsISuspendedTypes::SUSPENDED_STOP_DISPOSABLE);
-}
-
-void
-nsPIDOMWindowOuter::SetServiceWorkersTestingEnabled(bool aEnabled)
-{
-  // Devtools should only be setting this on the top level window.  Its
-  // ok if devtools clears the flag on clean up of nested windows, though.
-  // It will have no affect.
-#ifdef DEBUG
-  nsCOMPtr<nsPIDOMWindowOuter> topWindow = GetScriptableTop();
-  MOZ_ASSERT_IF(aEnabled, this == topWindow);
-#endif
-  mServiceWorkersTestingEnabled = aEnabled;
-}
-
-bool
-nsPIDOMWindowOuter::GetServiceWorkersTestingEnabled()
-{
-  // Automatically get this setting from the top level window so that nested
-  // iframes get the correct devtools setting.
-  nsCOMPtr<nsPIDOMWindowOuter> topWindow = GetScriptableTop();
-  if (!topWindow) {
-    return false;
-  }
-  return topWindow->mServiceWorkersTestingEnabled;
-}
-
 bool
 nsPIDOMWindowInner::GetAudioCaptured() const
 {
   MOZ_ASSERT(IsInnerWindow());
   return mAudioCaptured;
 }
 
 nsresult
@@ -4710,74 +2806,34 @@ nsGlobalWindowInner::GetParent()
     nsCOMPtr<nsPIDOMWindowOuter> win = parent->GetWindow();
     return win.forget();
   }
 
   nsCOMPtr<nsPIDOMWindowOuter> win(AsOuter());
   return win.forget();
 }
 
-static nsresult
-GetTopImpl(nsGlobalWindowOuter* aWin, nsPIDOMWindowOuter** aTop, bool aScriptable)
-{
-  *aTop = nullptr;
-
-  // Walk up the parent chain.
-
-  nsCOMPtr<nsPIDOMWindowOuter> prevParent = aWin->AsOuter();
-  nsCOMPtr<nsPIDOMWindowOuter> parent = aWin->AsOuter();
-  do {
-    if (!parent) {
-      break;
-    }
-
-    prevParent = parent;
-
-    nsCOMPtr<nsPIDOMWindowOuter> newParent;
-    if (aScriptable) {
-      newParent = parent->GetScriptableParent();
-    }
-    else {
-      newParent = parent->GetParent();
-    }
-
-    parent = newParent;
-
-  } while (parent != prevParent);
-
-  if (parent) {
-    parent.swap(*aTop);
-  }
-
-  return NS_OK;
-}
-
 /**
  * GetScriptableTop is called when script reads window.top.
  *
  * In contrast to GetRealTop, GetScriptableTop respects <iframe mozbrowser>
  * boundaries.  If we encounter a window owned by an <iframe mozbrowser> while
  * walking up the window hierarchy, we'll stop and return that window.
  */
 nsPIDOMWindowOuter*
 nsGlobalWindowInner::GetScriptableTop()
 {
   FORWARD_TO_OUTER(GetScriptableTop, (), nullptr);
-  nsCOMPtr<nsPIDOMWindowOuter> window;
-  GetTopImpl(AssertOuter(), getter_AddRefs(window), /* aScriptable = */ true);
-  return window.get();
+  MOZ_CRASH("Outer window expected!");
 }
 
 already_AddRefed<nsPIDOMWindowOuter>
 nsGlobalWindowInner::GetTop()
 {
-  MOZ_ASSERT(IsOuterWindow());
-  nsCOMPtr<nsPIDOMWindowOuter> window;
-  GetTopImpl(AssertOuter(), getter_AddRefs(window), /* aScriptable = */ false);
-  return window.forget();
+  MOZ_CRASH("Outer window only");
 }
 
 void
 nsGlobalWindowInner::GetContentOuter(JSContext* aCx,
                                 JS::MutableHandle<JSObject*> aRetval,
                                 CallerType aCallerType,
                                 ErrorResult& aError)
 {
@@ -6153,22 +4209,16 @@ nsGlobalWindowInner::GetDevicePixelRatio
 }
 
 double
 nsGlobalWindowInner::GetDevicePixelRatio(CallerType aCallerType, ErrorResult& aError)
 {
   FORWARD_TO_OUTER_OR_THROW(GetDevicePixelRatioOuter, (aCallerType), aError, 0.0);
 }
 
-float
-nsPIDOMWindowOuter::GetDevicePixelRatio(CallerType aCallerType)
-{
-  return nsGlobalWindowOuter::Cast(this)->GetDevicePixelRatioOuter(aCallerType);
-}
-
 uint64_t
 nsGlobalWindowInner::GetMozPaintCountOuter()
 {
   MOZ_RELEASE_ASSERT(IsOuterWindow());
 
   if (!mDocShell) {
     return 0;
   }
@@ -6694,53 +4744,22 @@ void
 nsGlobalWindowInner::RefreshCompartmentPrincipal()
 {
   MOZ_ASSERT(IsInnerWindow());
 
   JS_SetCompartmentPrincipals(js::GetObjectCompartment(GetWrapperPreserveColor()),
                               nsJSPrincipals::get(mDoc->NodePrincipal()));
 }
 
-static already_AddRefed<nsIDocShellTreeItem>
-GetCallerDocShellTreeItem()
-{
-  nsCOMPtr<nsIWebNavigation> callerWebNav = do_GetInterface(GetEntryGlobal());
-  nsCOMPtr<nsIDocShellTreeItem> callerItem = do_QueryInterface(callerWebNav);
-
-  return callerItem.forget();
-}
-
 bool
 nsGlobalWindowInner::WindowExists(const nsAString& aName,
                              bool aForceNoOpener,
                              bool aLookForCallerOnJSStack)
 {
-  NS_PRECONDITION(IsOuterWindow(), "Must be outer window");
-  NS_PRECONDITION(mDocShell, "Must have docshell");
-
-  if (aForceNoOpener) {
-    return aName.LowerCaseEqualsLiteral("_self") ||
-           aName.LowerCaseEqualsLiteral("_top") ||
-           aName.LowerCaseEqualsLiteral("_parent");
-  }
-
-  nsCOMPtr<nsIDocShellTreeItem> caller;
-  if (aLookForCallerOnJSStack) {
-    caller = GetCallerDocShellTreeItem();
-  }
-
-  if (!caller) {
-    caller = mDocShell;
-  }
-
-  nsCOMPtr<nsIDocShellTreeItem> namedItem;
-  mDocShell->FindItemWithName(aName, nullptr, caller,
-                              /* aSkipTabGroup = */ false,
-                              getter_AddRefs(namedItem));
-  return namedItem != nullptr;
+  MOZ_CRASH("Outer window only");
 }
 
 already_AddRefed<nsIWidget>
 nsGlobalWindowInner::GetMainWidget()
 {
   FORWARD_TO_OUTER(GetMainWidget, (), nullptr);
 
   nsCOMPtr<nsIBaseWindow> treeOwnerAsWin = GetTreeOwnerWindow();
@@ -6783,465 +4802,44 @@ nsGlobalWindowInner::SetFullScreen(bool 
 nsresult
 nsGlobalWindowInner::SetFullScreen(bool aFullScreen)
 {
   FORWARD_TO_OUTER(SetFullScreen, (aFullScreen), NS_ERROR_NOT_INITIALIZED);
 
   return SetFullscreenInternal(FullscreenReason::ForFullscreenMode, aFullScreen);
 }
 
-static void
-FinishDOMFullscreenChange(nsIDocument* aDoc, bool aInDOMFullscreen)
-{
-  if (aInDOMFullscreen) {
-    // Ask the document to handle any pending DOM fullscreen change.
-    if (!nsIDocument::HandlePendingFullscreenRequests(aDoc)) {
-      // If we don't end up having anything in fullscreen,
-      // async request exiting fullscreen.
-      nsIDocument::AsyncExitFullscreen(aDoc);
-    }
-  } else {
-    // If the window is leaving fullscreen state, also ask the document
-    // to exit from DOM Fullscreen.
-    nsIDocument::ExitFullscreenInDocTree(aDoc);
-  }
-}
-
-struct FullscreenTransitionDuration
-{
-  // The unit of the durations is millisecond
-  uint16_t mFadeIn = 0;
-  uint16_t mFadeOut = 0;
-  bool IsSuppressed() const
-  {
-    return mFadeIn == 0 && mFadeOut == 0;
-  }
-};
-
-static void
-GetFullscreenTransitionDuration(bool aEnterFullscreen,
-                                FullscreenTransitionDuration* aDuration)
-{
-  const char* pref = aEnterFullscreen ?
-    "full-screen-api.transition-duration.enter" :
-    "full-screen-api.transition-duration.leave";
-  nsAutoCString prefValue;
-  Preferences::GetCString(pref, prefValue);
-  if (!prefValue.IsEmpty()) {
-    sscanf(prefValue.get(), "%hu%hu",
-           &aDuration->mFadeIn, &aDuration->mFadeOut);
-  }
-}
-
-class FullscreenTransitionTask : public Runnable
-{
-public:
-  FullscreenTransitionTask(const FullscreenTransitionDuration& aDuration,
-                           nsGlobalWindowOuter* aWindow,
-                           bool aFullscreen,
-                           nsIWidget* aWidget,
-                           nsIScreen* aScreen,
-                           nsISupports* aTransitionData)
-    : mozilla::Runnable("FullscreenTransitionTask")
-    , mWindow(aWindow)
-    , mWidget(aWidget)
-    , mScreen(aScreen)
-    , mTransitionData(aTransitionData)
-    , mDuration(aDuration)
-    , mStage(eBeforeToggle)
-    , mFullscreen(aFullscreen)
-  {
-  }
-
-  NS_IMETHOD Run() override;
-
-private:
-  ~FullscreenTransitionTask() override
-  {
-  }
-
-  /**
-   * The flow of fullscreen transition:
-   *
-   *         parent process         |         child process
-   * ----------------------------------------------------------------
-   *
-   *                                    | request/exit fullscreen
-   *                              <-----|
-   *         BeforeToggle stage |
-   *                            |
-   *  ToggleFullscreen stage *1 |----->
-   *                                    | HandleFullscreenRequests
-   *                                    |
-   *                              <-----| MozAfterPaint event
-   *       AfterToggle stage *2 |
-   *                            |
-   *                  End stage |
-   *
-   * Note we also start a timer at *1 so that if we don't get MozAfterPaint
-   * from the child process in time, we continue going to *2.
-   */
-  enum Stage {
-    // BeforeToggle stage happens before we enter or leave fullscreen
-    // state. In this stage, the task triggers the pre-toggle fullscreen
-    // transition on the widget.
-    eBeforeToggle,
-    // ToggleFullscreen stage actually executes the fullscreen toggle,
-    // and wait for the next paint on the content to continue.
-    eToggleFullscreen,
-    // AfterToggle stage happens after we toggle the fullscreen state.
-    // In this stage, the task triggers the post-toggle fullscreen
-    // transition on the widget.
-    eAfterToggle,
-    // End stage is triggered after the final transition finishes.
-    eEnd
-  };
-
-  class Observer final : public nsIObserver
-  {
-  public:
-    NS_DECL_ISUPPORTS
-    NS_DECL_NSIOBSERVER
-
-    explicit Observer(FullscreenTransitionTask* aTask)
-      : mTask(aTask) { }
-
-  private:
-    ~Observer() = default;
-
-    RefPtr<FullscreenTransitionTask> mTask;
-  };
-
-  static const char* const kPaintedTopic;
-
-  RefPtr<nsGlobalWindowOuter> mWindow;
-  nsCOMPtr<nsIWidget> mWidget;
-  nsCOMPtr<nsIScreen> mScreen;
-  nsCOMPtr<nsITimer> mTimer;
-  nsCOMPtr<nsISupports> mTransitionData;
-
-  TimeStamp mFullscreenChangeStartTime;
-  FullscreenTransitionDuration mDuration;
-  Stage mStage;
-  bool mFullscreen;
-};
-
-const char* const
-FullscreenTransitionTask::kPaintedTopic = "fullscreen-painted";
-
-NS_IMETHODIMP
-FullscreenTransitionTask::Run()
-{
-  Stage stage = mStage;
-  mStage = Stage(mStage + 1);
-  if (MOZ_UNLIKELY(mWidget->Destroyed())) {
-    // If the widget has been destroyed before we get here, don't try to
-    // do anything more. Just let it go and release ourselves.
-    NS_WARNING("The widget to fullscreen has been destroyed");
-    return NS_OK;
-  }
-  if (stage == eBeforeToggle) {
-    PROFILER_ADD_MARKER("Fullscreen transition start");
-    mWidget->PerformFullscreenTransition(nsIWidget::eBeforeFullscreenToggle,
-                                         mDuration.mFadeIn, mTransitionData,
-                                         this);
-  } else if (stage == eToggleFullscreen) {
-    PROFILER_ADD_MARKER("Fullscreen toggle start");
-    mFullscreenChangeStartTime = TimeStamp::Now();
-    if (MOZ_UNLIKELY(mWindow->mFullScreen != mFullscreen)) {
-      // This could happen in theory if several fullscreen requests in
-      // different direction happen continuously in a short time. We
-      // need to ensure the fullscreen state matches our target here,
-      // otherwise the widget would change the window state as if we
-      // toggle for Fullscreen Mode instead of Fullscreen API.
-      NS_WARNING("The fullscreen state of the window does not match");
-      mWindow->mFullScreen = mFullscreen;
-    }
-    // Toggle the fullscreen state on the widget
-    if (!mWindow->SetWidgetFullscreen(FullscreenReason::ForFullscreenAPI,
-                                      mFullscreen, mWidget, mScreen)) {
-      // Fail to setup the widget, call FinishFullscreenChange to
-      // complete fullscreen change directly.
-      mWindow->FinishFullscreenChange(mFullscreen);
-    }
-    // Set observer for the next content paint.
-    nsCOMPtr<nsIObserver> observer = new Observer(this);
-    nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
-    obs->AddObserver(observer, kPaintedTopic, false);
-    // There are several edge cases where we may never get the paint
-    // notification, including:
-    // 1. the window/tab is closed before the next paint;
-    // 2. the user has switched to another tab before we get here.
-    // Completely fixing those cases seems to be tricky, and since they
-    // should rarely happen, it probably isn't worth to fix. Hence we
-    // simply add a timeout here to ensure we never hang forever.
-    // In addition, if the page is complicated or the machine is less
-    // powerful, layout could take a long time, in which case, staying
-    // in black screen for that long could hurt user experience even
-    // more than exposing an intermediate state.
-    uint32_t timeout =
-      Preferences::GetUint("full-screen-api.transition.timeout", 1000);
-    NS_NewTimerWithObserver(getter_AddRefs(mTimer),
-                            observer, timeout, nsITimer::TYPE_ONE_SHOT);
-  } else if (stage == eAfterToggle) {
-    Telemetry::AccumulateTimeDelta(Telemetry::FULLSCREEN_TRANSITION_BLACK_MS,
-                                   mFullscreenChangeStartTime);
-    mWidget->PerformFullscreenTransition(nsIWidget::eAfterFullscreenToggle,
-                                         mDuration.mFadeOut, mTransitionData,
-                                         this);
-  } else if (stage == eEnd) {
-    PROFILER_ADD_MARKER("Fullscreen transition end");
-  }
-  return NS_OK;
-}
-
-NS_IMPL_ISUPPORTS(FullscreenTransitionTask::Observer, nsIObserver)
-
-NS_IMETHODIMP
-FullscreenTransitionTask::Observer::Observe(nsISupports* aSubject,
-                                            const char* aTopic,
-                                            const char16_t* aData)
-{
-  bool shouldContinue = false;
-  if (strcmp(aTopic, FullscreenTransitionTask::kPaintedTopic) == 0) {
-    nsCOMPtr<nsPIDOMWindowInner> win(do_QueryInterface(aSubject));
-    nsCOMPtr<nsIWidget> widget = win ?
-      nsGlobalWindowInner::Cast(win)->GetMainWidget() : nullptr;
-    if (widget == mTask->mWidget) {
-      // The paint notification arrives first. Cancel the timer.
-      mTask->mTimer->Cancel();
-      shouldContinue = true;
-      PROFILER_ADD_MARKER("Fullscreen toggle end");
-    }
-  } else {
-#ifdef DEBUG
-    MOZ_ASSERT(strcmp(aTopic, NS_TIMER_CALLBACK_TOPIC) == 0,
-               "Should only get fullscreen-painted or timer-callback");
-    nsCOMPtr<nsITimer> timer(do_QueryInterface(aSubject));
-    MOZ_ASSERT(timer && timer == mTask->mTimer,
-               "Should only trigger this with the timer the task created");
-#endif
-    shouldContinue = true;
-    PROFILER_ADD_MARKER("Fullscreen toggle timeout");
-  }
-  if (shouldContinue) {
-    nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
-    obs->RemoveObserver(this, kPaintedTopic);
-    mTask->mTimer = nullptr;
-    mTask->Run();
-  }
-  return NS_OK;
-}
-
-static bool
-MakeWidgetFullscreen(nsGlobalWindowOuter* aWindow, FullscreenReason aReason,
-                     bool aFullscreen)
-{
-  nsCOMPtr<nsIWidget> widget = aWindow->GetMainWidget();
-  if (!widget) {
-    return false;
-  }
-
-  FullscreenTransitionDuration duration;
-  bool performTransition = false;
-  nsCOMPtr<nsISupports> transitionData;
-  if (aReason == FullscreenReason::ForFullscreenAPI) {
-    GetFullscreenTransitionDuration(aFullscreen, &duration);
-    if (!duration.IsSuppressed()) {
-      performTransition = widget->
-        PrepareForFullscreenTransition(getter_AddRefs(transitionData));
-    }
-  }
-  // We pass nullptr as the screen to SetWidgetFullscreen
-  // and FullscreenTransitionTask, as we do not wish to override
-  // the default screen selection behavior.  The screen containing
-  // most of the widget will be selected.
-  if (!performTransition) {
-    return aWindow->SetWidgetFullscreen(aReason, aFullscreen, widget, nullptr);
-  }
-  nsCOMPtr<nsIRunnable> task =
-    new FullscreenTransitionTask(duration, aWindow, aFullscreen,
-                                 widget, nullptr, transitionData);
-  task->Run();
-  return true;
-}
-
 nsresult
 nsGlobalWindowInner::SetFullscreenInternal(FullscreenReason aReason,
                                       bool aFullScreen)
 {
-  MOZ_ASSERT(IsOuterWindow());
-  MOZ_ASSERT(nsContentUtils::IsSafeToRunScript(),
-             "Requires safe to run script as it "
-             "may call FinishDOMFullscreenChange");
-
-  NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);
-
-  MOZ_ASSERT(aReason != FullscreenReason::ForForceExitFullscreen || !aFullScreen,
-             "FullscreenReason::ForForceExitFullscreen can "
-             "only be used with exiting fullscreen");
-
-  // Only chrome can change our fullscreen mode. Otherwise, the state
-  // can only be changed for DOM fullscreen.
-  if (aReason == FullscreenReason::ForFullscreenMode &&
-      !nsContentUtils::LegacyIsCallerChromeOrNativeCode()) {
-    return NS_OK;
-  }
-
-  // SetFullScreen needs to be called on the root window, so get that
-  // via the DocShell tree, and if we are not already the root,
-  // call SetFullScreen on that window instead.
-  nsCOMPtr<nsIDocShellTreeItem> rootItem;
-  mDocShell->GetRootTreeItem(getter_AddRefs(rootItem));
-  nsCOMPtr<nsPIDOMWindowOuter> window = rootItem ? rootItem->GetWindow() : nullptr;
-  if (!window)
-    return NS_ERROR_FAILURE;
-  if (rootItem != mDocShell)
-    return window->SetFullscreenInternal(aReason, aFullScreen);
-
-  // make sure we don't try to set full screen on a non-chrome window,
-  // which might happen in embedding world
-  if (mDocShell->ItemType() != nsIDocShellTreeItem::typeChrome)
-    return NS_ERROR_FAILURE;
-
-  // If we are already in full screen mode, just return.
-  if (mFullScreen == aFullScreen)
-    return NS_OK;
-
-  // Note that although entering DOM fullscreen could also cause
-  // consequential calls to this method, those calls will be skipped
-  // at the condition above.
-  if (aReason == FullscreenReason::ForFullscreenMode) {
-    if (!aFullScreen && !mFullscreenMode) {
-      // If we are exiting fullscreen mode, but we actually didn't
-      // entered fullscreen mode, the fullscreen state was only for
-      // the Fullscreen API. Change the reason here so that we can
-      // perform transition for it.
-      aReason = FullscreenReason::ForFullscreenAPI;
-    } else {
-      mFullscreenMode = aFullScreen;
-    }
-  } else {
-    // If we are exiting from DOM fullscreen while we initially make
-    // the window fullscreen because of fullscreen mode, don't restore
-    // the window. But we still need to exit the DOM fullscreen state.
-    if (!aFullScreen && mFullscreenMode) {
-      FinishDOMFullscreenChange(mDoc, false);
-      return NS_OK;
-    }
-  }
-
-  // Prevent chrome documents which are still loading from resizing
-  // the window after we set fullscreen mode.
-  nsCOMPtr<nsIBaseWindow> treeOwnerAsWin = GetTreeOwnerWindow();
-  nsCOMPtr<nsIXULWindow> xulWin(do_GetInterface(treeOwnerAsWin));
-  if (aFullScreen && xulWin) {
-    xulWin->SetIntrinsicallySized(false);
-  }
-
-  // Set this before so if widget sends an event indicating its
-  // gone full screen, the state trap above works.
-  mFullScreen = aFullScreen;
-
-  // Sometimes we don't want the top-level widget to actually go fullscreen,
-  // for example in the B2G desktop client, we don't want the emulated screen
-  // dimensions to appear to increase when entering fullscreen mode; we just
-  // want the content to fill the entire client area of the emulator window.
-  if (!Preferences::GetBool("full-screen-api.ignore-widgets", false)) {
-    if (MakeWidgetFullscreen(AssertOuter(), aReason, aFullScreen)) {
-      // The rest of code for switching fullscreen is in nsGlobalWindowInner::
-      // FinishFullscreenChange() which will be called after sizemodechange
-      // event is dispatched.
-      return NS_OK;
-    }
-  }
-
-  FinishFullscreenChange(aFullScreen);
-  return NS_OK;
+  MOZ_CRASH("Outer window only");
 }
 
 bool
 nsGlobalWindowInner::SetWidgetFullscreen(FullscreenReason aReason, bool aIsFullscreen,
                                     nsIWidget* aWidget, nsIScreen* aScreen)
 {
   MOZ_CRASH("Only callable on the outer window");
 }
 
-
 /* virtual */ void
 nsGlobalWindowInner::FullscreenWillChange(bool aIsFullscreen)
 {
   if (aIsFullscreen) {
     DispatchCustomEvent(NS_LITERAL_STRING("willenterfullscreen"));
   } else {
     DispatchCustomEvent(NS_LITERAL_STRING("willexitfullscreen"));
   }
 }
 
 /* virtual */ void
 nsGlobalWindowInner::FinishFullscreenChange(bool aIsFullscreen)
 {
-  MOZ_ASSERT(IsOuterWindow());
-
-  if (aIsFullscreen != mFullScreen) {
-    NS_WARNING("Failed to toggle fullscreen state of the widget");
-    // We failed to make the widget enter fullscreen.
-    // Stop further changes and restore the state.
-    if (!aIsFullscreen) {
-      mFullScreen = false;
-      mFullscreenMode = false;
-    } else {
-      MOZ_ASSERT_UNREACHABLE("Failed to exit fullscreen?");
-      mFullScreen = true;
-      // We don't know how code can reach here. Not sure
-      // what value should be set for fullscreen mode.
-      mFullscreenMode = false;
-    }
-    return;
-  }
-
-  // Note that we must call this to toggle the DOM fullscreen state
-  // of the document before dispatching the "fullscreen" event, so
-  // that the chrome can distinguish between browser fullscreen mode
-  // and DOM fullscreen.
-  FinishDOMFullscreenChange(mDoc, mFullScreen);
-
-  // dispatch a "fullscreen" DOM event so that XUL apps can
-  // respond visually if we are kicked into full screen mode
-  DispatchCustomEvent(NS_LITERAL_STRING("fullscreen"));
-
-  if (!NS_WARN_IF(!IsChromeWindow())) {
-    if (nsCOMPtr<nsIPresShell> shell =
-        do_QueryReferent(mChromeFields.mFullscreenPresShell)) {
-      if (nsRefreshDriver* rd = shell->GetRefreshDriver()) {
-        rd->Thaw();
-      }
-      mChromeFields.mFullscreenPresShell = nullptr;
-    }
-  }
-
-  if (!mWakeLock && mFullScreen) {
-    RefPtr<power::PowerManagerService> pmService =
-      power::PowerManagerService::GetInstance();
-    if (!pmService) {
-      return;
-    }
-
-    // XXXkhuey using the inner here, do we need to do something if it changes?
-    ErrorResult rv;
-    mWakeLock = pmService->NewWakeLock(NS_LITERAL_STRING("DOM_Fullscreen"),
-                                       AsOuter()->GetCurrentInnerWindow(), rv);
-    NS_WARNING_ASSERTION(!rv.Failed(), "Failed to lock the wakelock");
-    rv.SuppressException();
-  } else if (mWakeLock && !mFullScreen) {
-    ErrorResult rv;
-    mWakeLock->Unlock(rv);
-    mWakeLock = nullptr;
-    rv.SuppressException();
-  }
+  MOZ_CRASH("Outer window only");
 }
 
 bool
 nsGlobalWindowInner::FullScreen() const
 {
   MOZ_ASSERT(IsOuterWindow());
 
   NS_ENSURE_TRUE(mDocShell, mFullScreen);
@@ -8635,35 +6233,16 @@ nsGlobalWindowInner::CaptureEvents()
 void
 nsGlobalWindowInner::ReleaseEvents()
 {
   if (mDoc) {
     mDoc->WarnOnceAbout(nsIDocument::eUseOfReleaseEvents);
   }
 }
 
-static
-bool IsPopupBlocked(nsIDocument* aDoc)
-{
-  nsCOMPtr<nsIPopupWindowManager> pm =
-    do_GetService(NS_POPUPWINDOWMANAGER_CONTRACTID);
-
-  if (!pm) {
-    return false;
-  }
-
-  if (!aDoc) {
-    return true;
-  }
-
-  uint32_t permission = nsIPopupWindowManager::ALLOW_POPUP;
-  pm->TestPermission(aDoc->NodePrincipal(), &permission);
-  return permission == nsIPopupWindowManager::DENY_POPUP;
-}
-
 void
 nsGlobalWindowInner::FirePopupBlockedEvent(nsIDocument* aDoc,
                                       nsIURI* aPopupURI,
                                       const nsAString& aPopupWindowName,
                                       const nsAString& aPopupWindowFeatures)
 {
   MOZ_ASSERT(IsOuterWindow(), "All callers seem to assume we're an outer window?");
   MOZ_ASSERT(aDoc);
@@ -8703,73 +6282,29 @@ nsGlobalWindowInner::CanSetProperty(cons
   // If the pref is set to true, we can not set the property
   // and vice versa.
   return !Preferences::GetBool(aPrefName, true);
 }
 
 bool
 nsGlobalWindowInner::PopupWhitelisted()
 {
-  if (!IsPopupBlocked(mDoc))
-    return true;
-
-  nsCOMPtr<nsPIDOMWindowOuter> parent = GetParent();
-  if (parent == AsOuter())
-  {
-    return false;
-  }
-
-  return nsGlobalWindowOuter::Cast(parent)->PopupWhitelisted();
+  MOZ_CRASH("Outer Window only");
 }
 
 /*
  * Examine the current document state to see if we're in a way that is
  * typically abused by web designers. The window.open code uses this
  * routine to determine whether to allow the new window.
  * Returns a value from the PopupControlState enum.
  */
 PopupControlState
 nsGlobalWindowInner::RevisePopupAbuseLevel(PopupControlState aControl)
 {
-  MOZ_ASSERT(IsOuterWindow());
-
-  NS_ASSERTION(mDocShell, "Must have docshell");
-
-  if (mDocShell->ItemType() != nsIDocShellTreeItem::typeContent) {
-    return openAllowed;
-  }
-
-  PopupControlState abuse = aControl;
-  switch (abuse) {
-  case openControlled:
-  case openBlocked:
-  case openOverridden:
-    if (PopupWhitelisted())
-      abuse = PopupControlState(abuse - 1);
-    break;
-  case openAbused:
-    if (PopupWhitelisted())
-      //Skip openBlocked
-      abuse = openControlled;
-    break;
-  case openAllowed: break;
-  default:
-    NS_WARNING("Strange PopupControlState!");
-  }
-
-  // limit the number of simultaneously open popups
-  if (abuse == openAbused ||
-      abuse == openBlocked ||
-      abuse == openControlled) {
-    int32_t popupMax = Preferences::GetInt("dom.popup_maximum", -1);
-    if (popupMax >= 0 && gOpenPopupSpamCount >= popupMax)
-      abuse = openOverridden;
-  }
-
-  return abuse;
+  MOZ_CRASH("Outer window only");
 }
 
 /* If a window open is blocked, fire the appropriate DOM events. */
 void
 nsGlobalWindowInner::FireAbuseEvents(const nsAString &aPopupURL,
                                 const nsAString &aPopupWindowName,
                                 const nsAString &aPopupWindowFeatures)
 {
@@ -9173,51 +6708,16 @@ nsGlobalWindowInner::PostMessageMoz(JSCo
   if (NS_WARN_IF(aRv.Failed())) {
     return;
   }
 
   PostMessageMoz(aCx, aMessage, aTargetOrigin, transferArray,
                  aSubjectPrincipal, aRv);
 }
 
-class nsCloseEvent : public Runnable {
-
-  RefPtr<nsGlobalWindowOuter> mWindow;
-  bool mIndirect;
-
-  nsCloseEvent(nsGlobalWindowOuter* aWindow, bool aIndirect)
-    : mozilla::Runnable("nsCloseEvent")
-    , mWindow(aWindow)
-    , mIndirect(aIndirect)
-  {}
-
-public:
-
-  static nsresult
-  PostCloseEvent(nsGlobalWindowOuter* aWindow, bool aIndirect) {
-    nsCOMPtr<nsIRunnable> ev = new nsCloseEvent(aWindow, aIndirect);
-    nsresult rv =
-      aWindow->Dispatch(TaskCategory::Other, ev.forget());
-    if (NS_SUCCEEDED(rv))
-      aWindow->MaybeForgiveSpamCount();
-    return rv;
-  }
-
-  NS_IMETHOD Run() override {
-    if (mWindow) {
-      if (mIndirect) {
-        return PostCloseEvent(mWindow, false);
-      }
-      mWindow->ReallyCloseWindow();
-    }
-    return NS_OK;
-  }
-
-};
-
 bool
 nsGlobalWindowInner::CanClose()
 {
   MOZ_ASSERT(IsOuterWindow());
 
   if (mIsChrome) {
     nsCOMPtr<nsIBrowserDOMWindow> bwin;
     GetBrowserDOMWindow(getter_AddRefs(bwin));
@@ -9365,48 +6865,17 @@ nsGlobalWindowInner::ForceClose()
   DispatchCustomEvent(NS_LITERAL_STRING("DOMWindowClose"));
 
   FinalClose();
 }
 
 void
 nsGlobalWindowInner::FinalClose()
 {
-  MOZ_ASSERT(IsOuterWindow());
-
-  // Flag that we were closed.
-  mIsClosed = true;
-
-  // If we get here from CloseOuter then it means that the parent process is
-  // going to close our window for us. It's just important to set mIsClosed.
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
-    return;
-  }
-
-  // This stuff is non-sensical but incredibly fragile. The reasons for the
-  // behavior here don't make sense today and may not have ever made sense,
-  // but various bits of frontend code break when you change them. If you need
-  // to fix up this behavior, feel free to. It's a righteous task, but involves
-  // wrestling with various download manager tests, frontend code, and possible
-  // broken addons. The chrome tests in toolkit/mozapps/downloads are a good
-  // testing ground.
-  //
-  // In particular, if some inner of |win| is the entry global, we must
-  // complete _two_ round-trips to the event loop before the call to
-  // ReallyCloseWindow. This allows setTimeout handlers that are set after
-  // FinalClose() is called to run before the window is torn down.
-  nsCOMPtr<nsPIDOMWindowInner> entryWindow =
-    do_QueryInterface(GetEntryGlobal());
-  bool indirect =
-    entryWindow && entryWindow->GetOuterWindow() == this->AsOuter();
-  if (NS_FAILED(nsCloseEvent::PostCloseEvent(AssertOuter(), indirect))) {
-    ReallyCloseWindow();
-  } else {
-    mHavePendingClose = true;
-  }
+  MOZ_CRASH("Outer window only");
 }
 
 
 void
 nsGlobalWindowInner::ReallyCloseWindow()
 {
   FORWARD_TO_OUTER_VOID(ReallyCloseWindow, ());
 
@@ -9593,154 +7062,16 @@ nsGlobalWindowInner::NotifyDOMWindowDest
     services::GetObserverService();
   if (observerService) {
     observerService->
       NotifyObservers(ToSupports(aWindow),
                       DOM_WINDOW_DESTROYED_TOPIC, nullptr);
   }
 }
 
-// Try to match compartments that are not web content by matching compartments
-// with principals that are either the system principal or an expanded principal.
-// This may not return true for all non-web-content compartments.
-struct BrowserCompartmentMatcher : public js::CompartmentFilter {
-  bool match(JSCompartment* aC) const override
-  {
-    nsCOMPtr<nsIPrincipal> pc = nsJSPrincipals::get(JS_GetCompartmentPrincipals(aC));
-    return nsContentUtils::IsSystemOrExpandedPrincipal(pc);
-  }
-};
-
-
-class WindowDestroyedEvent final : public Runnable
-{
-public:
-  WindowDestroyedEvent(nsGlobalWindowInner* aWindow, uint64_t aID, const char* aTopic)
-    : mozilla::Runnable("WindowDestroyedEvent")
-    , mID(aID)
-    , mPhase(Phase::Destroying)
-    , mTopic(aTopic)
-    , mIsInnerWindow(true)
-  {
-    mWindow = do_GetWeakReference(aWindow);
-  }
-  WindowDestroyedEvent(nsGlobalWindowOuter* aWindow, uint64_t aID, const char* aTopic)
-    : mozilla::Runnable("WindowDestroyedEvent")
-    , mID(aID)
-    , mPhase(Phase::Destroying)
-    , mTopic(aTopic)
-    , mIsInnerWindow(false)
-  {
-    mWindow = do_GetWeakReference(aWindow);
-  }
-
-  enum class Phase
-  {
-    Destroying,
-    Nuking
-  };
-
-  NS_IMETHOD Run() override
-  {
-    AUTO_PROFILER_LABEL("WindowDestroyedEvent::Run", OTHER);
-
-    nsCOMPtr<nsIObserverService> observerService =
-      services::GetObserverService();
-    if (!observerService) {
-      return NS_OK;
-    }
-
-    nsCOMPtr<nsISupportsPRUint64> wrapper =
-      do_CreateInstance(NS_SUPPORTS_PRUINT64_CONTRACTID);
-    if (wrapper) {
-      wrapper->SetData(mID);
-      observerService->NotifyObservers(wrapper, mTopic.get(), nullptr);
-    }
-
-    switch (mPhase) {
-      case Phase::Destroying:
-      {
-        bool skipNukeCrossCompartment = false;
-#ifndef DEBUG
-        nsCOMPtr<nsIAppStartup> appStartup =
-          do_GetService(NS_APPSTARTUP_CONTRACTID);
-
-        if (appStartup) {
-          appStartup->GetShuttingDown(&skipNukeCrossCompartment);
-        }
-#endif
-
-        if (!skipNukeCrossCompartment) {
-          // The compartment nuking phase might be too expensive, so do that
-          // part off of idle dispatch.
-
-          // For the compartment nuking phase, we dispatch either an
-          // inner-window-nuked or an outer-window-nuked notification.
-          // This will allow tests to wait for compartment nuking to happen.
-          if (mTopic.EqualsLiteral("inner-window-destroyed")) {
-            mTopic.AssignLiteral("inner-window-nuked");
-          } else if (mTopic.EqualsLiteral("outer-window-destroyed")) {
-            mTopic.AssignLiteral("outer-window-nuked");
-          }
-          mPhase = Phase::Nuking;
-
-          nsCOMPtr<nsIRunnable> copy(this);
-          NS_IdleDispatchToCurrentThread(copy.forget(), 1000);
-        }
-      }
-      break;
-
-      case Phase::Nuking:
-      {
-        nsCOMPtr<nsISupports> window = do_QueryReferent(mWindow);
-        if (window) {
-          nsGlobalWindowInner* currentInner;
-          if (mIsInnerWindow) {
-            currentInner = nsGlobalWindowInner::FromSupports(window);
-          } else {
-            nsGlobalWindowOuter* outer = nsGlobalWindowOuter::FromSupports(window);
-            currentInner = outer->GetCurrentInnerWindowInternal();
-          }
-          NS_ENSURE_TRUE(currentInner, NS_OK);
-
-          AutoSafeJSContext cx;
-          JS::Rooted<JSObject*> obj(cx, currentInner->FastGetGlobalJSObject());
-          if (obj && !js::IsSystemCompartment(js::GetObjectCompartment(obj))) {
-            JSCompartment* cpt = js::GetObjectCompartment(obj);
-            nsCOMPtr<nsIPrincipal> pc = nsJSPrincipals::get(JS_GetCompartmentPrincipals(cpt));
-
-            if (BasePrincipal::Cast(pc)->AddonPolicy()) {
-              // We want to nuke all references to the add-on compartment.
-              xpc::NukeAllWrappersForCompartment(cx, cpt,
-                                                 mIsInnerWindow ? js::DontNukeWindowReferences
-                                                                : js::NukeWindowReferences);
-            } else {
-              // We only want to nuke wrappers for the chrome->content case
-              js::NukeCrossCompartmentWrappers(cx, BrowserCompartmentMatcher(), cpt,
-                                               mIsInnerWindow ? js::DontNukeWindowReferences
-                                                              : js::NukeWindowReferences,
-                                               js::NukeIncomingReferences);
-            }
-          }
-        }
-      }
-      break;
-    }
-
-    return NS_OK;
-  }
-
-private:
-  uint64_t mID;
-  Phase mPhase;
-  nsCString mTopic;
-  nsWeakPtr mWindow;
-  bool mIsInnerWindow;
-};
-
 void
 nsGlobalWindowInner::NotifyWindowIDDestroyed(const char* aTopic)
 {
   nsCOMPtr<nsIRunnable> runnable;
   if (IsInnerWindow()) {
     runnable = new WindowDestroyedEvent(AssertInner(), mWindowID, aTopic);
   } else {
     runnable = new WindowDestroyedEvent(AssertOuter(), mWindowID, aTopic);
@@ -9994,66 +7325,16 @@ nsGlobalWindowInner::ConvertDialogOption
     if (iter == end ||
         !TokenizeDialogOptions(token, iter, end) ||
         !token.EqualsLiteral(";")) {
       break;
     }
   }
 }
 
-class ChildCommandDispatcher : public Runnable
-{
-public:
-  ChildCommandDispatcher(nsPIWindowRoot* aRoot,
-                         nsITabChild* aTabChild,
-                         const nsAString& aAction)
-    : mozilla::Runnable("ChildCommandDispatcher")
-    , mRoot(aRoot)
-    , mTabChild(aTabChild)
-    , mAction(aAction)
-  {
-  }
-
-  NS_IMETHOD Run() override
-  {
-    nsTArray<nsCString> enabledCommands, disabledCommands;
-    mRoot->GetEnabledDisabledCommands(enabledCommands, disabledCommands);
-    if (enabledCommands.Length() || disabledCommands.Length()) {
-      mTabChild->EnableDisableCommands(mAction, enabledCommands, disabledCommands);
-    }
-
-    return NS_OK;
-  }
-
-private:
-  nsCOMPtr<nsPIWindowRoot>             mRoot;
-  nsCOMPtr<nsITabChild>                mTabChild;
-  nsString                             mAction;
-};
-
-class CommandDispatcher : public Runnable
-{
-public:
-  CommandDispatcher(nsIDOMXULCommandDispatcher* aDispatcher,
-                    const nsAString& aAction)
-    : mozilla::Runnable("CommandDispatcher")
-    , mDispatcher(aDispatcher)
-    , mAction(aAction)
-  {
-  }
-
-  NS_IMETHOD Run() override
-  {
-    return mDispatcher->UpdateCommands(mAction);
-  }
-
-  nsCOMPtr<nsIDOMXULCommandDispatcher> mDispatcher;
-  nsString                             mAction;
-};
-
 nsresult
 nsGlobalWindowInner::UpdateCommands(const nsAString& anAction, nsISelection* aSel, int16_t aReason)
 {
   // If this is a child process, redirect to the parent process.
   if (nsIDocShell* docShell = GetDocShell()) {
     if (nsCOMPtr<nsITabChild> child = docShell->GetTabChild()) {
       nsCOMPtr<nsPIWindowRoot> root = GetTopWindowRoot();
       if (root) {
@@ -10487,31 +7768,20 @@ nsGlobalWindowInner::ActivateOrDeactivat
     }
 
     if (topLevelWindow) {
       topLevelWindow->SetActive(aActivate);
     }
   }
 }
 
-static bool
-NotifyDocumentTree(nsIDocument* aDocument, void* aData)
-{
-  aDocument->EnumerateSubDocuments(NotifyDocumentTree, nullptr);
-  aDocument->DocumentStatesChanged(NS_DOCUMENT_STATE_WINDOW_INACTIVE);
-  return true;
-}
-
 void
 nsGlobalWindowInner::SetActive(bool aActive)
 {
-  nsPIDOMWindow::SetActive(aActive);
-  if (mDoc) {
-    NotifyDocumentTree(mDoc, nullptr);
-  }
+  MOZ_CRASH("Outer window only");
 }
 
 bool
 nsGlobalWindowInner::IsTopLevelWindowActive()
 {
    nsCOMPtr<nsIDocShellTreeItem> treeItem(GetDocShell());
    if (!treeItem) {
      return false;
@@ -10522,17 +7792,18 @@ nsGlobalWindowInner::IsTopLevelWindowAct
    if (!rootItem) {
      return false;
    }
 
    nsCOMPtr<nsPIDOMWindowOuter> domWindow = rootItem->GetWindow();
    return domWindow && domWindow->IsActive();
 }
 
-void nsGlobalWindowInner::SetIsBackground(bool aIsBackground)
+void
+nsGlobalWindowInner::SetIsBackground(bool aIsBackground)
 {
   MOZ_ASSERT(IsOuterWindow());
 
   bool changed = aIsBackground != AsOuter()->IsBackground();
   SetIsBackgroundInternal(aIsBackground);
 
   nsGlobalWindowInner* inner = GetCurrentInnerWindowInternal();
 
@@ -10566,17 +7837,18 @@ void
 nsGlobalWindowInner::SetIsBackgroundInternal(bool aIsBackground)
 {
   if (mIsBackground != aIsBackground) {
     TabGroup()->WindowChangedBackgroundStatus(aIsBackground);
   }
   mIsBackground = aIsBackground;
 }
 
-void nsGlobalWindowInner::MaybeUpdateTouchState()
+void
+nsGlobalWindowInner::MaybeUpdateTouchState()
 {
   FORWARD_TO_INNER_VOID(MaybeUpdateTouchState, ());
 
   if (mMayHaveTouchEventListener) {
     nsCOMPtr<nsIObserverService> observerService =
       services::GetObserverService();
 
     if (observerService) {
@@ -10656,32 +7928,16 @@ nsGlobalWindowInner::SetChromeEventHandl
     // in the list.
     inner = static_cast<nsGlobalWindowInner*>(node);
     NS_ASSERTION(!inner->mOuterWindow || inner->mOuterWindow == AsOuter(),
                  "bad outer window pointer");
     inner->SetChromeEventHandlerInternal(aChromeEventHandler);
   }
 }
 
-static bool IsLink(nsIContent* aContent)
-{
-  return aContent && (aContent->IsHTMLElement(nsGkAtoms::a) ||
-                      aContent->AttrValueIs(kNameSpaceID_XLink, nsGkAtoms::type,
-                                            nsGkAtoms::simple, eCaseMatters));
-}
-
-static bool ShouldShowFocusRingIfFocusedByMouse(nsIContent* aNode)
-{
-  if (!aNode) {
-    return true;
-  }
-  return !IsLink(aNode) &&
-         !aNode->IsAnyOfHTMLElements(nsGkAtoms::video, nsGkAtoms::audio);
-}
-
 void
 nsGlobalWindowInner::SetFocusedNode(nsIContent* aNode,
                                uint32_t aFocusMethod,
                                bool aNeedsFocus)
 {
   FORWARD_TO_INNER_VOID(SetFocusedNode, (aNode, aFocusMethod, aNeedsFocus));
 
   if (aNode && aNode->GetComposedDoc() != mDoc) {
@@ -12674,239 +9930,28 @@ nsGlobalWindowInner::GetParentInternal()
 
 void
 nsGlobalWindowInner::UnblockScriptedClosing()
 {
   MOZ_ASSERT(IsOuterWindow());
   mBlockScriptedClosingFlag = false;
 }
 
-class AutoUnblockScriptClosing
-{
-private:
-  RefPtr<nsGlobalWindowOuter> mWin;
-public:
-  explicit AutoUnblockScriptClosing(nsGlobalWindowOuter* aWin)
-    : mWin(aWin)
-  {
-    MOZ_ASSERT(mWin);
-    MOZ_ASSERT(mWin->IsOuterWindow());
-  }
-  ~AutoUnblockScriptClosing()
-  {
-    void (nsGlobalWindowOuter::*run)() = &nsGlobalWindowOuter::UnblockScriptedClosing;
-    nsCOMPtr<nsIRunnable> caller = NewRunnableMethod(
-      "AutoUnblockScriptClosing::~AutoUnblockScriptClosing", mWin, run);
-    mWin->Dispatch(TaskCategory::Other, caller.forget());
-  }
-};
-
 nsresult
 nsGlobalWindowInner::OpenInternal(const nsAString& aUrl, const nsAString& aName,
                              const nsAString& aOptions, bool aDialog,
                              bool aContentModal, bool aCalledNoScript,
                              bool aDoJSFixups, bool aNavigate,
                              nsIArray *argv,
                              nsISupports *aExtraArgument,
                              nsIDocShellLoadInfo* aLoadInfo,
                              bool aForceNoOpener,
                              nsPIDOMWindowOuter **aReturn)
 {
-  MOZ_ASSERT(IsOuterWindow());
-
-#ifdef DEBUG
-  uint32_t argc = 0;
-  if (argv)
-      argv->GetLength(&argc);
-#endif
-  NS_PRECONDITION(!aExtraArgument || (!argv && argc == 0),
-                  "Can't pass in arguments both ways");
-  NS_PRECONDITION(!aCalledNoScript || (!argv && argc == 0),
-                  "Can't pass JS args when called via the noscript methods");
-
-  mozilla::Maybe<AutoUnblockScriptClosing> closeUnblocker;
-
-  // Calls to window.open from script should navigate.
-  MOZ_ASSERT(aCalledNoScript || aNavigate);
-
-  *aReturn = nullptr;
-
-  nsCOMPtr<nsIWebBrowserChrome> chrome = GetWebBrowserChrome();
-  if (!chrome) {
-    // No chrome means we don't want to go through with this open call
-    // -- see nsIWindowWatcher.idl
-    return NS_ERROR_NOT_AVAILABLE;
-  }
-
-  NS_ASSERTION(mDocShell, "Must have docshell here");
-
-  bool forceNoOpener = aForceNoOpener;
-  if (!forceNoOpener) {
-    // Unlike other window flags, "noopener" comes from splitting on commas with
-    // HTML whitespace trimming...
-    nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace> tok(
-      aOptions, ',');
-    while (tok.hasMoreTokens()) {
-      if (tok.nextToken().EqualsLiteral("noopener")) {
-        forceNoOpener = true;
-        break;
-      }
-    }
-  }
-
-  // XXXbz When this gets fixed to not use LegacyIsCallerNativeCode()
-  // (indirectly) maybe we can nix the AutoJSAPI usage OnLinkClickEvent::Run.
-  // But note that if you change this to GetEntryGlobal(), say, then
-  // OnLinkClickEvent::Run will need a full-blown AutoEntryScript.
-  const bool checkForPopup = !nsContentUtils::LegacyIsCallerChromeOrNativeCode() &&
-    !aDialog && !WindowExists(aName, forceNoOpener, !aCalledNoScript);
-
-  // Note: the Void handling here is very important, because the window watcher
-  // expects a null URL string (not an empty string) if there is no URL to load.
-  nsCString url;
-  url.SetIsVoid(true);
-  nsresult rv = NS_OK;
-
-  // It's important to do this security check before determining whether this
-  // window opening should be blocked, to ensure that we don't FireAbuseEvents
-  // for a window opening that wouldn't have succeeded in the first place.
-  if (!aUrl.IsEmpty()) {
-    AppendUTF16toUTF8(aUrl, url);
-
-    // It's safe to skip the security check below if we're not a dialog
-    // because window.openDialog is not callable from content script.  See bug
-    // 56851.
-    //
-    // If we're not navigating, we assume that whoever *does* navigate the
-    // window will do a security check of their own.
-    if (!url.IsVoid() && !aDialog && aNavigate)
-      rv = SecurityCheckURL(url.get());
-  }
-
-  if (NS_FAILED(rv))
-    return rv;
-
-  PopupControlState abuseLevel = gPopupControlState;
-  if (checkForPopup) {
-    abuseLevel = RevisePopupAbuseLevel(abuseLevel);
-    if (abuseLevel >= openBlocked) {
-      if (!aCalledNoScript) {
-        // If script in some other window is doing a window.open on us and
-        // it's being blocked, then it's OK to close us afterwards, probably.
-        // But if we're doing a window.open on ourselves and block the popup,
-        // prevent this window from closing until after this script terminates
-        // so that whatever popup blocker UI the app has will be visible.
-        nsCOMPtr<nsPIDOMWindowInner> entryWindow =
-          do_QueryInterface(GetEntryGlobal());
-        // Note that entryWindow can be null here if some JS component was the
-        // place where script was entered for this JS execution.
-        if (entryWindow &&
-            entryWindow->GetOuterWindow() == this->AsOuter()) {
-          mBlockScriptedClosingFlag = true;
-          closeUnblocker.emplace(AssertOuter());
-        }
-      }
-
-      FireAbuseEvents(aUrl, aName, aOptions);
-      return aDoJSFixups ? NS_OK : NS_ERROR_FAILURE;
-    }
-  }
-
-  nsCOMPtr<mozIDOMWindowProxy> domReturn;
-
-  nsCOMPtr<nsIWindowWatcher> wwatch =
-    do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
-  NS_ENSURE_TRUE(wwatch, rv);
-
-  NS_ConvertUTF16toUTF8 options(aOptions);
-  NS_ConvertUTF16toUTF8 name(aName);
-
-  const char *options_ptr = aOptions.IsEmpty() ? nullptr : options.get();
-  const char *name_ptr = aName.IsEmpty() ? nullptr : name.get();
-
-  nsCOMPtr<nsPIWindowWatcher> pwwatch(do_QueryInterface(wwatch));
-  NS_ENSURE_STATE(pwwatch);
-
-  MOZ_ASSERT_IF(checkForPopup, abuseLevel < openBlocked);
-  // At this point we should know for a fact that if checkForPopup then
-  // abuseLevel < openBlocked, so we could just check for abuseLevel ==
-  // openControlled.  But let's be defensive just in case and treat anything
-  // that fails the above assert as a spam popup too, if it ever happens.
-  bool isPopupSpamWindow = checkForPopup && (abuseLevel >= openControlled);
-
-  {
-    // Reset popup state while opening a window to prevent the
-    // current state from being active the whole time a modal
-    // dialog is open.
-    nsAutoPopupStatePusher popupStatePusher(openAbused, true);
-
-    if (!aCalledNoScript) {
-      // We asserted at the top of this function that aNavigate is true for
-      // !aCalledNoScript.
-      rv = pwwatch->OpenWindow2(AsOuter(), url.IsVoid() ? nullptr : url.get(),
-                                name_ptr,
-                                options_ptr, /* aCalledFromScript = */ true,
-                                aDialog, aNavigate, argv,
-                                isPopupSpamWindow,
-                                forceNoOpener,
-                                aLoadInfo,
-                                getter_AddRefs(domReturn));
-    } else {
-      // Force a system caller here so that the window watcher won't screw us
-      // up.  We do NOT want this case looking at the JS context on the stack
-      // when searching.  Compare comments on
-      // nsIDOMWindow::OpenWindow and nsIWindowWatcher::OpenWindow.
-
-      // Note: Because nsWindowWatcher is so broken, it's actually important
-      // that we don't force a system caller here, because that screws it up
-      // when it tries to compute the caller principal to associate with dialog
-      // arguments. That whole setup just really needs to be rewritten. :-(
-      Maybe<AutoNoJSAPI> nojsapi;
-      if (!aContentModal) {
-        nojsapi.emplace();
-      }
-
-      rv = pwwatch->OpenWindow2(AsOuter(), url.IsVoid() ? nullptr : url.get(),
-                                name_ptr,
-                                options_ptr, /* aCalledFromScript = */ false,
-                                aDialog, aNavigate, aExtraArgument,
-                                isPopupSpamWindow,
-                                forceNoOpener,
-                                aLoadInfo,
-                                getter_AddRefs(domReturn));
-
-    }
-  }
-
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // success!
-
-  NS_ENSURE_TRUE(domReturn, NS_OK);
-  nsCOMPtr<nsPIDOMWindowOuter> outerReturn =
-    nsPIDOMWindowOuter::From(domReturn);
-  outerReturn.swap(*aReturn);
-
-  if (aDoJSFixups) {
-    nsCOMPtr<nsIDOMChromeWindow> chrome_win(do_QueryInterface(*aReturn));
-    if (!chrome_win) {
-      // A new non-chrome window was created from a call to
-      // window.open() from JavaScript, make sure there's a document in
-      // the new window. We do this by simply asking the new window for
-      // its document, this will synchronously create an empty document
-      // if there is no document in the window.
-      // XXXbz should this just use EnsureInnerWindow()?
-
-      // Force document creation.
-      nsCOMPtr<nsIDocument> doc = (*aReturn)->GetDoc();
-      Unused << doc;
-    }
-  }
-
-  return rv;
+  MOZ_CRASH("Outer window only");
 }
 
 //*****************************************************************************
 // nsGlobalWindowInner: Timeout Functions
 //*****************************************************************************
 
 nsGlobalWindowInner*
 nsGlobalWindowInner::InnerForSetTimeoutOrInterval(ErrorResult& aError)
@@ -12972,30 +10017,16 @@ int32_t
 nsGlobalWindowInner::SetTimeout(JSContext* aCx, const nsAString& aHandler,
                            int32_t aTimeout,
                            const Sequence<JS::Value>& /* unused */,
                            ErrorResult& aError)
 {
   return SetTimeoutOrInterval(aCx, aHandler, aTimeout, false, aError);
 }
 
-static bool
-IsInterval(const Optional<int32_t>& aTimeout, int32_t& aResultTimeout)
-{
-  if (aTimeout.WasPassed()) {
-    aResultTimeout = aTimeout.Value();
-    return true;
-  }
-
-  // If no interval was specified, treat this like a timeout, to avoid setting
-  // an interval of 0 milliseconds.
-  aResultTimeout = 0;
-  return false;
-}
-
 int32_t
 nsGlobalWindowInner::SetInterval(JSContext* aCx, Function& aFunction,
                             const Optional<int32_t>& aTimeout,
                             const Sequence<JS::Value>& aArguments,
                             ErrorResult& aError)
 {
   int32_t timeout;
   bool isInterval = IsInterval(aTimeout, timeout);
@@ -13319,79 +10350,23 @@ nsGlobalWindowInner::EnsureSizeAndPositi
   if (parent) {
     parent->FlushPendingNotifications(FlushType::Layout);
   }
 }
 
 already_AddRefed<nsISupports>
 nsGlobalWindowInner::SaveWindowState()
 {
-  NS_PRECONDITION(IsOuterWindow(), "Can't save the inner window's state");
-
-  if (!mContext || !GetWrapperPreserveColor()) {
-    // The window may be getting torn down; don't bother saving state.
-    return nullptr;
-  }
-
-  nsGlobalWindowInner *inner = GetCurrentInnerWindowInternal();
-  NS_ASSERTION(inner, "No inner window to save");
-
-  // Don't do anything else to this inner window! After this point, all
-  // calls to SetTimeoutOrInterval will create entries in the timeout
-  // list that will only run after this window has come out of the bfcache.
-  // Also, while we're frozen, we won't dispatch online/offline events
-  // to the page.
-  inner->Freeze();
-
-  nsCOMPtr<nsISupports> state = new WindowStateHolder(inner);
-
-#ifdef DEBUG_PAGE_CACHE
-  printf("saving window state, state = %p\n", (void*)state);
-#endif
-
-  return state.forget();
+  MOZ_CRASH("Outer window only");
 }
 
 nsresult
 nsGlobalWindowInner::RestoreWindowState(nsISupports *aState)
 {
-  NS_ASSERTION(IsOuterWindow(), "Cannot restore an inner window");
-
-  if (!mContext || !GetWrapperPreserveColor()) {
-    // The window may be getting torn down; don't bother restoring state.
-    return NS_OK;
-  }
-
-  nsCOMPtr<WindowStateHolder> holder = do_QueryInterface(aState);
-  NS_ENSURE_TRUE(holder, NS_ERROR_FAILURE);
-
-#ifdef DEBUG_PAGE_CACHE
-  printf("restoring window state, state = %p\n", (void*)holder);
-#endif
-
-  // And we're ready to go!
-  nsGlobalWindowInner *inner = GetCurrentInnerWindowInternal();
-
-  // if a link is focused, refocus with the FLAG_SHOWRING flag set. This makes
-  // it easy to tell which link was last clicked when going back a page.
-  nsIContent* focusedNode = inner->GetFocusedNode();
-  if (IsLink(focusedNode)) {
-    nsIFocusManager* fm = nsFocusManager::GetFocusManager();
-    if (fm) {
-      nsCOMPtr<nsIDOMElement> focusedElement(do_QueryInterface(focusedNode));
-      fm->SetFocus(focusedElement, nsIFocusManager::FLAG_NOSCROLL |
-                                   nsIFocusManager::FLAG_SHOWRING);
-    }
-  }
-
-  inner->Thaw();
-
-  holder->DidRestoreWindow();
-
-  return NS_OK;
+  MOZ_CRASH("Outer window only");
 }
 
 void
 nsGlobalWindowInner::EnableDeviceSensor(uint32_t aType)
 {
   MOZ_ASSERT(IsInnerWindow());
 
   bool alreadyEnabled = false;
@@ -14414,35 +11389,16 @@ nsGlobalWindowInner::CreateNamedProperti
 bool
 nsGlobalWindowInner::GetIsPrerendered()
 {
   nsIDocShell* docShell = GetDocShell();
   return docShell && docShell->GetIsPrerendered();
 }
 
 void
-nsPIDOMWindowOuter::SetLargeAllocStatus(LargeAllocStatus aStatus)
-{
-  MOZ_ASSERT(mLargeAllocStatus == LargeAllocStatus::NONE);
-  mLargeAllocStatus = aStatus;
-}
-
-bool
-nsPIDOMWindowOuter::IsTopLevelWindow()
-{
-  return nsGlobalWindowOuter::Cast(this)->IsTopLevelWindow();
-}
-
-bool
-nsPIDOMWindowOuter::HadOriginalOpener() const
-{
-  return nsGlobalWindowOuter::Cast(this)->HadOriginalOpener();
-}
-
-void
 nsGlobalWindowInner::ReportLargeAllocStatus()
 {
   MOZ_RELEASE_ASSERT(IsOuterWindow());
 
   uint32_t errorFlags = nsIScriptError::warningFlag;
   const char* message = nullptr;
 
   switch (mLargeAllocStatus) {
@@ -14746,44 +11702,16 @@ nsGlobalWindowInner::TabGroupInner()
 #ifdef DEBUG
   nsGlobalWindowOuter* outer = GetOuterWindowInternal();
   MOZ_ASSERT_IF(outer, outer->TabGroup() == mTabGroup);
 #endif
 
   return mTabGroup;
 }
 
-template<typename T>
-mozilla::dom::TabGroup*
-nsPIDOMWindow<T>::TabGroup()
-{
-  if (IsInnerWindow()) {
-    nsGlobalWindowInner* globalWindow =
-      static_cast<nsGlobalWindowInner*>(
-        reinterpret_cast<nsPIDOMWindow<nsISupports>*>(this));
-    return globalWindow->TabGroupInner();
-  } else {
-    nsGlobalWindowOuter* globalWindow =
-      static_cast<nsGlobalWindowOuter*>(
-        reinterpret_cast<nsPIDOMWindow<nsISupports>*>(this));
-    return globalWindow->TabGroupOuter();
-  }
-}
-
-template<typename T>
-mozilla::dom::DocGroup*
-nsPIDOMWindow<T>::GetDocGroup() const
-{
-  nsIDocument* doc = GetExtantDoc();
-  if (doc) {
-    return doc->GetDocGroup();
-  }
-  return nullptr;
-}
-
 nsresult
 nsGlobalWindowInner::Dispatch(TaskCategory aCategory,
                          already_AddRefed<nsIRunnable>&& aRunnable)
 {
   MOZ_RELEASE_ASSERT(NS_IsMainThread());
   if (GetDocGroup()) {
     return GetDocGroup()->Dispatch(aCategory, Move(aRunnable));
   }
@@ -14906,12 +11834,8 @@ nsGlobalWindowInner::Create(nsGlobalWind
   if (aIsChrome) {
     window->mIsChrome = true;
     window->mCleanMessageManager = true;
   }
 
   window->InitWasOffline();
   return window.forget();
 }
-
-template class nsPIDOMWindow<mozIDOMWindowProxy>;
-template class nsPIDOMWindow<mozIDOMWindow>;
-template class nsPIDOMWindow<nsISupports>;
--- a/dom/base/nsGlobalWindowInner.h
+++ b/dom/base/nsGlobalWindowInner.h
@@ -177,16 +177,25 @@ struct IdleObserverHolder
   }
 
   ~IdleObserverHolder()
   {
     MOZ_COUNT_DTOR(IdleObserverHolder);
   }
 };
 
+inline void
+ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
+                            IdleObserverHolder& aField,
+                            const char* aName,
+                            unsigned aFlags)
+{
+  CycleCollectionNoteChild(aCallback, aField.mIdleObserver.get(), aName, aFlags);
+}
+
 // NOTE: Currently this file, despite being named mozilla/dom/Window.h, exports
 // the class nsGlobalWindowInner. It will be renamed in the future to
 // mozilla::dom::Window.
 
 //*****************************************************************************
 // nsGlobalWindow: Global Object for Scripting
 //*****************************************************************************
 // Beware that all scriptable interfaces implemented by
--- a/dom/base/nsGlobalWindowOuter.cpp
+++ b/dom/base/nsGlobalWindowOuter.cpp
@@ -1,510 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 "nsGlobalWindow.h"
-
-#include <algorithm>
-
-#include "mozilla/MemoryReporting.h"
-
-// Local Includes
-#include "Navigator.h"
-#include "nsContentSecurityManager.h"
-#include "nsScreen.h"
-#include "nsHistory.h"
-#include "nsDOMNavigationTiming.h"
-#include "nsIDOMStorageManager.h"
-#include "mozilla/dom/LocalStorage.h"
-#include "mozilla/dom/Storage.h"
-#include "mozilla/dom/IdleRequest.h"
-#include "mozilla/dom/Performance.h"
-#include "mozilla/dom/StorageEvent.h"
-#include "mozilla/dom/StorageEventBinding.h"
-#include "mozilla/dom/StorageNotifierService.h"
-#include "mozilla/dom/StorageUtils.h"
-#include "mozilla/dom/Timeout.h"
-#include "mozilla/dom/TimeoutHandler.h"
-#include "mozilla/dom/TimeoutManager.h"
-#include "mozilla/IntegerPrintfMacros.h"
-#if defined(MOZ_WIDGET_ANDROID)
-#include "mozilla/dom/WindowOrientationObserver.h"
-#endif
-#include "nsDOMOfflineResourceList.h"
-#include "nsError.h"
-#include "nsIIdleService.h"
-#include "nsISizeOfEventTarget.h"
-#include "nsDOMJSUtils.h"
-#include "nsArrayUtils.h"
-#include "nsIDOMWindowCollection.h"
-#include "nsDOMWindowList.h"
-#include "mozilla/dom/WakeLock.h"
-#include "mozilla/dom/power/PowerManagerService.h"
-#include "nsIDocShellTreeOwner.h"
-#include "nsIInterfaceRequestorUtils.h"
-#include "nsIPermissionManager.h"
-#include "nsIScriptContext.h"
-#include "nsIScriptTimeoutHandler.h"
-#include "nsITimeoutHandler.h"
-#include "nsIController.h"
-#include "nsScriptNameSpaceManager.h"
-#include "nsISlowScriptDebug.h"
-#include "nsWindowMemoryReporter.h"
-#include "nsWindowSizes.h"
-#include "WindowNamedPropertiesHandler.h"
-#include "nsFrameSelection.h"
-#include "nsNetUtil.h"
-#include "nsVariant.h"
-#include "nsPrintfCString.h"
-#include "mozilla/intl/LocaleService.h"
-
-// Helper Classes
-#include "nsJSUtils.h"
-#include "jsapi.h"              // for JSAutoRequest
-#include "jswrapper.h"
-#include "nsCharSeparatedTokenizer.h"
-#include "nsReadableUtils.h"
-#include "nsDOMClassInfo.h"
-#include "nsJSEnvironment.h"
-#include "mozilla/dom/ScriptSettings.h"
-#include "mozilla/Preferences.h"
-#include "mozilla/Likely.h"
-#include "mozilla/Sprintf.h"
-#include "mozilla/Unused.h"
-
-// Other Classes
-#include "mozilla/dom/BarProps.h"
-#include "nsContentCID.h"
-#include "nsLayoutStatics.h"
-#include "nsCCUncollectableMarker.h"
-#include "mozilla/dom/workers/Workers.h"
-#include "mozilla/dom/ToJSValue.h"
-#include "nsJSPrincipals.h"
-#include "mozilla/Attributes.h"
-#include "mozilla/Debug.h"
-#include "mozilla/EventListenerManager.h"
-#include "mozilla/EventStates.h"
-#include "mozilla/MouseEvents.h"
-#include "mozilla/ProcessHangMonitor.h"
-#include "mozilla/ThrottledEventQueue.h"
-#include "AudioChannelService.h"
-#include "nsAboutProtocolUtils.h"
-#include "nsCharTraits.h" // NS_IS_HIGH/LOW_SURROGATE
-#include "PostMessageEvent.h"
-#include "mozilla/dom/DocGroup.h"
-#include "mozilla/dom/TabGroup.h"
-
-// Interfaces Needed
-#include "nsIFrame.h"
-#include "nsCanvasFrame.h"
-#include "nsIWidget.h"
-#include "nsIWidgetListener.h"
-#include "nsIBaseWindow.h"
-#include "nsIDeviceSensors.h"
-#include "nsIContent.h"
-#include "nsIDocShell.h"
-#include "nsIDocCharset.h"
-#include "nsIDocument.h"
-#include "Crypto.h"
-#include "nsIDOMDocument.h"
-#include "nsIDOMElement.h"
-#include "nsIDOMEvent.h"
-#include "nsIDOMOfflineResourceList.h"
-#include "nsDOMString.h"
-#include "nsIEmbeddingSiteWindow.h"
-#include "nsThreadUtils.h"
-#include "nsILoadContext.h"
-#include "nsIPresShell.h"
-#include "nsIScrollableFrame.h"
-#include "nsView.h"
-#include "nsViewManager.h"
-#include "nsISelectionController.h"
-#include "nsISelection.h"
-#include "nsIPrompt.h"
-#include "nsIPromptService.h"
-#include "nsIPromptFactory.h"
-#include "nsIAddonPolicyService.h"
-#include "nsIWritablePropertyBag2.h"
-#include "nsIWebNavigation.h"
-#include "nsIWebBrowserChrome.h"
-#include "nsIWebBrowserFind.h"  // For window.find()
-#include "nsIWindowMediator.h"  // For window.find()
-#include "nsComputedDOMStyle.h"
-#include "nsDOMCID.h"
-#include "nsDOMWindowUtils.h"
-#include "nsIWindowWatcher.h"
-#include "nsPIWindowWatcher.h"
-#include "nsIContentViewer.h"
-#include "nsIScriptError.h"
-#include "nsIControllers.h"
-#include "nsIControllerContext.h"
-#include "nsGlobalWindowCommands.h"
-#include "nsQueryObject.h"
-#include "nsContentUtils.h"
-#include "nsCSSProps.h"
-#include "nsIDOMFileList.h"
-#include "nsIURIFixup.h"
-#ifndef DEBUG
-#include "nsIAppStartup.h"
-#include "nsToolkitCompsCID.h"
-#endif
-#include "nsCDefaultURIFixup.h"
-#include "mozilla/EventDispatcher.h"
-#include "mozilla/EventStateManager.h"
-#include "nsIObserverService.h"
-#include "nsFocusManager.h"
-#include "nsIXULWindow.h"
-#include "nsITimedChannel.h"
-#include "nsServiceManagerUtils.h"
-#ifdef MOZ_XUL
-#include "nsIDOMXULControlElement.h"
-#include "nsMenuPopupFrame.h"
-#endif
-#include "mozilla/dom/CustomEvent.h"
-#include "nsIJARChannel.h"
-#include "nsIScreenManager.h"
-#include "nsIEffectiveTLDService.h"
-
-#include "xpcprivate.h"
-
-#ifdef NS_PRINTING
-#include "nsIPrintSettings.h"
-#include "nsIPrintSettingsService.h"
-#include "nsIWebBrowserPrint.h"
-#endif
-
-#include "nsWindowRoot.h"
-#include "nsNetCID.h"
-#include "nsIArray.h"
-
-// XXX An unfortunate dependency exists here (two XUL files).
-#include "nsIDOMXULDocument.h"
-#include "nsIDOMXULCommandDispatcher.h"
-
-#include "nsBindingManager.h"
-#include "nsXBLService.h"
-
-// used for popup blocking, needs to be converted to something
-// belonging to the back-end like nsIContentPolicy
-#include "nsIPopupWindowManager.h"
-
-#include "nsIDragService.h"
-#include "mozilla/dom/Element.h"
-#include "mozilla/dom/Selection.h"
-#include "nsFrameLoader.h"
-#include "nsISupportsPrimitives.h"
-#include "nsXPCOMCID.h"
-#include "mozilla/Logging.h"
-#include "prenv.h"
-
-#include "mozilla/dom/IDBFactory.h"
-#include "mozilla/dom/MessageChannel.h"
-#include "mozilla/dom/Promise.h"
-
-#include "mozilla/dom/Gamepad.h"
-#include "mozilla/dom/GamepadManager.h"
-
-#include "gfxVR.h"
-#include "mozilla/dom/VRDisplay.h"
-#include "mozilla/dom/VRDisplayEvent.h"
-#include "mozilla/dom/VRDisplayEventBinding.h"
-#include "mozilla/dom/VREventObserver.h"
-
-#include "nsRefreshDriver.h"
-#include "Layers.h"
-
-#include "mozilla/AddonPathService.h"
-#include "mozilla/BasePrincipal.h"
-#include "mozilla/Services.h"
-#include "mozilla/Telemetry.h"
-#include "mozilla/dom/Location.h"
-#include "nsHTMLDocument.h"
-#include "nsWrapperCacheInlines.h"
-#include "mozilla/DOMEventTargetHelper.h"
-#include "prrng.h"
-#include "nsSandboxFlags.h"
-#include "TimeChangeObserver.h"
-#include "mozilla/dom/AudioContext.h"
-#include "mozilla/dom/BrowserElementDictionariesBinding.h"
-#include "mozilla/dom/cache/CacheStorage.h"
-#include "mozilla/dom/Console.h"
-#include "mozilla/dom/Fetch.h"
-#include "mozilla/dom/FunctionBinding.h"
-#include "mozilla/dom/HashChangeEvent.h"
-#include "mozilla/dom/IntlUtils.h"
-#include "mozilla/dom/MozSelfSupportBinding.h"
-#include "mozilla/dom/PopStateEvent.h"
-#include "mozilla/dom/PopupBlockedEvent.h"
-#include "mozilla/dom/PrimitiveConversions.h"
-#include "mozilla/dom/WindowBinding.h"
-#include "nsITabChild.h"
-#include "mozilla/dom/MediaQueryList.h"
-#include "mozilla/dom/ScriptSettings.h"
-#include "mozilla/dom/NavigatorBinding.h"
-#include "mozilla/dom/ImageBitmap.h"
-#include "mozilla/dom/ImageBitmapBinding.h"
-#include "mozilla/dom/ServiceWorkerRegistration.h"
-#include "mozilla/dom/U2F.h"
-#include "mozilla/dom/WebIDLGlobalNameHash.h"
-#include "mozilla/dom/Worklet.h"
-#ifdef HAVE_SIDEBAR
-#include "mozilla/dom/ExternalBinding.h"
-#endif
-
-#ifdef MOZ_WEBSPEECH
-#include "mozilla/dom/SpeechSynthesis.h"
-#endif
-
-// Apple system headers seem to have a check() macro.  <sigh>
-#ifdef check
-class nsIScriptTimeoutHandler;
-#undef check
-#endif // check
-#include "AccessCheck.h"
-
-#ifdef ANDROID
-#include <android/log.h>
-#endif
-
-#ifdef XP_WIN
-#include <process.h>
-#define getpid _getpid
-#else
-#include <unistd.h> // for getpid()
-#endif
-
-static const char kStorageEnabled[] = "dom.storage.enabled";
-
-using namespace mozilla;
-using namespace mozilla::dom;
-using namespace mozilla::dom::ipc;
-using mozilla::BasePrincipal;
-using mozilla::OriginAttributes;
-using mozilla::TimeStamp;
-using mozilla::TimeDuration;
-using mozilla::dom::cache::CacheStorage;
-
-static LazyLogModule gDOMLeakPRLog("DOMLeak");
-
-nsGlobalWindowInner::InnerWindowByIdTable *nsGlobalWindowInner::sInnerWindowsById = nullptr;
 nsGlobalWindowOuter::OuterWindowByIdTable *nsGlobalWindowOuter::sOuterWindowsById = nullptr;
 
-static int32_t              gRefCnt                           = 0;
-static int32_t              gOpenPopupSpamCount               = 0;
-static PopupControlState    gPopupControlState                = openAbused;
-static bool                 gMouseDown                        = false;
-static bool                 gDragServiceDisabled              = false;
-static FILE                *gDumpFile                         = nullptr;
-static uint32_t             gSerialCounter                    = 0;
-static bool                 gIdleObserversAPIFuzzTimeDisabled = false;
-
-#ifdef DEBUG_jst
-int32_t gTimeoutCnt                                    = 0;
-#endif
-
-#if defined(DEBUG_bryner) || defined(DEBUG_chb)
-#define DEBUG_PAGE_CACHE
-#endif
-
-#define DOM_TOUCH_LISTENER_ADDED "dom-touch-listener-added"
-
-#define MEMORY_PRESSURE_OBSERVER_TOPIC "memory-pressure"
-
-// The interval at which we execute idle callbacks
-static uint32_t gThrottledIdlePeriodLength;
-
-#define DEFAULT_THROTTLED_IDLE_PERIOD_LENGTH 10000
-
-#define FORWARD_TO_OUTER(method, args, err_rval)                              \
-  PR_BEGIN_MACRO                                                              \
-  if (IsInnerWindow()) {                                                      \
-    nsGlobalWindowOuter *outer = GetOuterWindowInternal();                    \
-    if (!AsInner()->HasActiveDocument()) {                                    \
-      NS_WARNING(outer ?                                                      \
-                 "Inner window does not have active document." :              \
-                 "No outer window available!");                               \
-      return err_rval;                                                        \
-    }                                                                         \
-    return outer->method args;                                                \
-  }                                                                           \
-  PR_END_MACRO
-
-#define FORWARD_TO_OUTER_OR_THROW(method, args, errorresult, err_rval)        \
-  PR_BEGIN_MACRO                                                              \
-  MOZ_RELEASE_ASSERT(IsInnerWindow());                                        \
-  nsGlobalWindowOuter *outer = GetOuterWindowInternal();                      \
-  if (MOZ_LIKELY(AsInner()->HasActiveDocument())) {                           \
-    return outer->method args;                                                \
-  }                                                                           \
-  if (!outer) {                                                               \
-    NS_WARNING("No outer window available!");                                 \
-    errorresult.Throw(NS_ERROR_NOT_INITIALIZED);                              \
-  } else {                                                                    \
-    errorresult.Throw(NS_ERROR_XPC_SECURITY_MANAGER_VETO);                    \
-  }                                                                           \
-  return err_rval;                                                            \
-  PR_END_MACRO
-
-#define FORWARD_TO_OUTER_VOID(method, args)                                   \
-  PR_BEGIN_MACRO                                                              \
-  if (IsInnerWindow()) {                                                      \
-    nsGlobalWindowOuter *outer = GetOuterWindowInternal();                    \
-    if (!AsInner()->HasActiveDocument()) {                                    \
-      NS_WARNING(outer ?                                                      \
-                 "Inner window does not have active document." :              \
-                 "No outer window available!");                               \
-      return;                                                                 \
-    }                                                                         \
-    outer->method args;                                                       \
-    return;                                                                   \
-  }                                                                           \
-  PR_END_MACRO
-
-#define FORWARD_TO_OUTER_MODAL_CONTENT_WINDOW(method, args, err_rval)         \
-  PR_BEGIN_MACRO                                                              \
-  if (IsInnerWindow()) {                                                      \
-    nsGlobalWindowOuter *outer = GetOuterWindowInternal();                    \
-    if (!AsInner()->HasActiveDocument()) {                                    \
-      NS_WARNING(outer ?                                                      \
-                 "Inner window does not have active document." :              \
-                 "No outer window available!");                               \
-      return err_rval;                                                        \
-    }                                                                         \
-    return ((nsGlobalModalWindow *)outer)->method args;                       \
-  }                                                                           \
-  PR_END_MACRO
-
-#define FORWARD_TO_INNER(method, args, err_rval)                              \
-  PR_BEGIN_MACRO                                                              \
-  if (IsOuterWindow()) {                                                      \
-    if (!mInnerWindow) {                                                      \
-      NS_WARNING("No inner window available!");                               \
-      return err_rval;                                                        \
-    }                                                                         \
-    return GetCurrentInnerWindowInternal()->method args;                      \
-  }                                                                           \
-  PR_END_MACRO
-
-#define FORWARD_TO_INNER_MODAL_CONTENT_WINDOW(method, args, err_rval)         \
-  PR_BEGIN_MACRO                                                              \
-  if (IsOuterWindow()) {                                                      \
-    if (!mInnerWindow) {                                                      \
-      NS_WARNING("No inner window available!");                               \
-      return err_rval;                                                        \
-    }                                                                         \
-    return ((nsGlobalModalWindow*)GetCurrentInnerWindowInternal())->method args; \
-  }                                                                           \
-  PR_END_MACRO
-
-#define FORWARD_TO_INNER_VOID(method, args)                                   \
-  PR_BEGIN_MACRO                                                              \
-  if (IsOuterWindow()) {                                                      \
-    if (!mInnerWindow) {                                                      \
-      NS_WARNING("No inner window available!");                               \
-      return;                                                                 \
-    }                                                                         \
-    GetCurrentInnerWindowInternal()->method args;                             \
-    return;                                                                   \
-  }                                                                           \
-  PR_END_MACRO
-
-// Same as FORWARD_TO_INNER, but this will create a fresh inner if an
-// inner doesn't already exists.
-#define FORWARD_TO_INNER_CREATE(method, args, err_rval)                       \
-  PR_BEGIN_MACRO                                                              \
-  if (IsOuterWindow()) {                                                      \
-    if (!mInnerWindow) {                                                      \
-      if (mIsClosed) {                                                        \
-        return err_rval;                                                      \
-      }                                                                       \
-      nsCOMPtr<nsIDocument> kungFuDeathGrip = GetDoc();                       \
-      ::mozilla::Unused << kungFuDeathGrip;                                   \
-      if (!mInnerWindow) {                                                    \
-        return err_rval;                                                      \
-      }                                                                       \
-    }                                                                         \
-    return GetCurrentInnerWindowInternal()->method args;                      \
-  }                                                                           \
-  PR_END_MACRO
-
-// CIDs
-static NS_DEFINE_CID(kXULControllersCID, NS_XULCONTROLLERS_CID);
-
-#define NETWORK_UPLOAD_EVENT_NAME     NS_LITERAL_STRING("moznetworkupload")
-#define NETWORK_DOWNLOAD_EVENT_NAME   NS_LITERAL_STRING("moznetworkdownload")
-
-/**
- * An indirect observer object that means we don't have to implement nsIObserver
- * on nsGlobalWindow, where any script could see it.
- */
-class nsGlobalWindowObserver final : public nsIObserver
-                                   , public nsIInterfaceRequestor
-                                   , public StorageNotificationObserver
-{
-public:
-  explicit nsGlobalWindowObserver(nsGlobalWindowInner* aWindow) : mWindow(aWindow) {}
-  NS_DECL_ISUPPORTS
-  NS_IMETHOD Observe(nsISupports* aSubject, const char* aTopic, const char16_t* aData) override
-  {
-    if (!mWindow)
-      return NS_OK;
-    return mWindow->Observe(aSubject, aTopic, aData);
-  }
-  void Forget() { mWindow = nullptr; }
-  NS_IMETHOD GetInterface(const nsIID& aIID, void** aResult) override
-  {
-    if (mWindow && aIID.Equals(NS_GET_IID(nsIDOMWindow)) && mWindow) {
-      return mWindow->QueryInterface(aIID, aResult);
-    }
-    return NS_NOINTERFACE;
-  }
-
-  void
-  ObserveStorageNotification(StorageEvent* aEvent,
-                             const char16_t* aStorageType,
-                             bool aPrivateBrowsing) override
-  {
-    if (mWindow) {
-      mWindow->ObserveStorageNotification(aEvent, aStorageType,
-                                          aPrivateBrowsing);
-    }
-  }
-
-  nsIPrincipal*
-  GetPrincipal() const override
-  {
-    return mWindow ? mWindow->GetPrincipal() : nullptr;
-  }
-
-  bool
-  IsPrivateBrowsing() const override
-  {
-    return mWindow ? mWindow->IsPrivateBrowsing() : false;
-  }
-
-  nsIEventTarget*
-  GetEventTarget() const override
-  {
-    return mWindow ? mWindow->EventTargetFor(TaskCategory::Other) : nullptr;
-  }
-
-private:
-  ~nsGlobalWindowObserver() = default;
-
-  // This reference is non-owning and safe because it's cleared by
-  // nsGlobalWindow::CleanUp().
-  nsGlobalWindowInner* MOZ_NON_OWNING_REF mWindow;
-};
-
-NS_IMPL_ISUPPORTS(nsGlobalWindowObserver, nsIObserver, nsIInterfaceRequestor)
-
 static already_AddRefed<nsIVariant>
 CreateVoidVariant()
 {
   RefPtr<nsVariantCC> writable = new nsVariantCC();
   writable->SetAsVoid();
   return writable.forget();
 }
 
@@ -530,291 +36,38 @@ DialogValueHolder::Get(JSContext* aCx, J
   if (aSubject->Subsumes(mOrigin)) {
     aError = nsContentUtils::XPConnect()->VariantToJS(aCx, aScope,
                                                       mValue, aResult);
   } else {
     aResult.setUndefined();
   }
 }
 
-class IdleRequestExecutor;
-
-class IdleRequestExecutorTimeoutHandler final : public TimeoutHandler
-{
-public:
-  explicit IdleRequestExecutorTimeoutHandler(IdleRequestExecutor* aExecutor)
-    : mExecutor(aExecutor)
-  {
-  }
-
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IdleRequestExecutorTimeoutHandler,
-                                           TimeoutHandler)
-
-  nsresult Call() override;
-
-private:
-  ~IdleRequestExecutorTimeoutHandler() override {}
-  RefPtr<IdleRequestExecutor> mExecutor;
-};
-
-NS_IMPL_CYCLE_COLLECTION_INHERITED(IdleRequestExecutorTimeoutHandler, TimeoutHandler, mExecutor)
-
-NS_IMPL_ADDREF_INHERITED(IdleRequestExecutorTimeoutHandler, TimeoutHandler)
-NS_IMPL_RELEASE_INHERITED(IdleRequestExecutorTimeoutHandler, TimeoutHandler)
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(IdleRequestExecutorTimeoutHandler)
-NS_INTERFACE_MAP_END_INHERITING(TimeoutHandler)
-
-
-class IdleRequestExecutor final : public nsIRunnable
-                                , public nsICancelableRunnable
-                                , public nsINamed
-                                , public nsIIdleRunnable
-{
-public:
-  explicit IdleRequestExecutor(nsGlobalWindowInner* aWindow)
-    : mDispatched(false)
-    , mDeadline(TimeStamp::Now())
-    , mWindow(aWindow)
-  {
-    MOZ_DIAGNOSTIC_ASSERT(mWindow);
-    MOZ_DIAGNOSTIC_ASSERT(mWindow->IsInnerWindow());
-
-    mIdlePeriodLimit = { mDeadline, mWindow->LastIdleRequestHandle() };
-    mDelayedExecutorDispatcher = new IdleRequestExecutorTimeoutHandler(this);
-  }
-
-  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(IdleRequestExecutor, nsIRunnable)
-
-  NS_DECL_NSIRUNNABLE
-  NS_DECL_NSINAMED
-  nsresult Cancel() override;
-  void SetDeadline(TimeStamp aDeadline) override;
-
-  bool IsCancelled() const { return !mWindow || mWindow->AsInner()->InnerObjectsFreed(); }
-  // Checks if aRequest shouldn't execute in the current idle period
-  // since it has been queued from a chained call to
-  // requestIdleCallback from within a running idle callback.
-  bool IneligibleForCurrentIdlePeriod(IdleRequest* aRequest) const
-  {
-    return aRequest->Handle() >= mIdlePeriodLimit.mLastRequestIdInIdlePeriod &&
-           TimeStamp::Now() <= mIdlePeriodLimit.mEndOfIdlePeriod;
-  }
-
-  void MaybeUpdateIdlePeriodLimit();
-
-  // Maybe dispatch the IdleRequestExecutor. MabyeDispatch will
-  // schedule a delayed dispatch if the associated window is in the
-  // background or if given a time to wait until dispatching.
-  void MaybeDispatch(TimeStamp aDelayUntil = TimeStamp());
-  void ScheduleDispatch();
-private:
-  struct IdlePeriodLimit
-  {
-    TimeStamp mEndOfIdlePeriod;
-    uint32_t mLastRequestIdInIdlePeriod;
-  };
-
-  void DelayedDispatch(uint32_t aDelay);
-
-  ~IdleRequestExecutor() override {}
-
-  bool mDispatched;
-  TimeStamp mDeadline;
-  IdlePeriodLimit mIdlePeriodLimit;
-  RefPtr<nsGlobalWindowInner> mWindow;
-  // The timeout handler responsible for dispatching this executor in
-  // the case of immediate dispatch to the idle queue isn't
-  // desirable. This is used if we've dispatched all idle callbacks
-  // that are allowed to run in the current idle period, or if the
-  // associated window is currently in the background.
-  nsCOMPtr<nsITimeoutHandler> mDelayedExecutorDispatcher;
-  // If not Nothing() then this value is the handle to the currently
-  // scheduled delayed executor dispatcher. This is needed to be able
-  // to cancel the timeout handler in case of the executor being
-  // cancelled.
-  Maybe<int32_t> mDelayedExecutorHandle;
-};
-
-NS_IMPL_CYCLE_COLLECTION_CLASS(IdleRequestExecutor)
-
-NS_IMPL_CYCLE_COLLECTING_ADDREF(IdleRequestExecutor)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(IdleRequestExecutor)
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(IdleRequestExecutor)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindow)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK(mDelayedExecutorDispatcher)
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(IdleRequestExecutor)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDelayedExecutorDispatcher)
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(IdleRequestExecutor)
-  NS_INTERFACE_MAP_ENTRY(nsIRunnable)
-  NS_INTERFACE_MAP_ENTRY(nsICancelableRunnable)
-  NS_INTERFACE_MAP_ENTRY(nsINamed)
-  NS_INTERFACE_MAP_ENTRY(nsIIdleRunnable)
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIRunnable)
-NS_INTERFACE_MAP_END
-
-NS_IMETHODIMP
-IdleRequestExecutor::GetName(nsACString& aName)
-{
-    aName.AssignASCII("IdleRequestExecutor");
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-IdleRequestExecutor::Run()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  mDispatched = false;
-  if (mWindow) {
-    return mWindow->ExecuteIdleRequest(mDeadline);
-  }
-
-  return NS_OK;
-}
-
-nsresult
-IdleRequestExecutor::Cancel()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  if (mDelayedExecutorHandle && mWindow) {
-    mWindow->AsInner()->TimeoutManager().ClearTimeout(
-      mDelayedExecutorHandle.value(),
-      Timeout::Reason::eIdleCallbackTimeout);
-  }
-
-  mWindow = nullptr;
-  return NS_OK;
-}
-
-void
-IdleRequestExecutor::SetDeadline(TimeStamp aDeadline)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  if (!mWindow) {
-    return;
-  }
-
-  mDeadline = aDeadline;
-}
-
-void
-IdleRequestExecutor::MaybeUpdateIdlePeriodLimit()
-{
-  if (TimeStamp::Now() > mIdlePeriodLimit.mEndOfIdlePeriod) {
-    mIdlePeriodLimit = { mDeadline, mWindow->LastIdleRequestHandle() };
-  }
-}
-
-void
-IdleRequestExecutor::MaybeDispatch(TimeStamp aDelayUntil)
-{
-  // If we've already dispatched the executor we don't want to do it
-  // again. Also, if we've called IdleRequestExecutor::Cancel mWindow
-  // will be null, which indicates that we shouldn't dispatch this
-  // executor either.
-  if (mDispatched || IsCancelled()) {
-    return;
-  }
-
-  mDispatched = true;
-
-  nsPIDOMWindowOuter* outer = mWindow->GetOuterWindow();
-  if (outer && outer->AsOuter()->IsBackground()) {
-    // Set a timeout handler with a timeout of 0 ms to throttle idle
-    // callback requests coming from a backround window using
-    // background timeout throttling.
-    DelayedDispatch(0);
-    return;
-  }
-
-  TimeStamp now = TimeStamp::Now();
-  if (!aDelayUntil || aDelayUntil < now) {
-    ScheduleDispatch();
-    return;
-  }
-
-  TimeDuration delay = aDelayUntil - now;
-  DelayedDispatch(static_cast<uint32_t>(delay.ToMilliseconds()));
-}
-
-void
-IdleRequestExecutor::ScheduleDispatch()
-{
-  MOZ_ASSERT(mWindow);
-  mDelayedExecutorHandle = Nothing();
-  RefPtr<IdleRequestExecutor> request = this;
-  NS_IdleDispatchToCurrentThread(request.forget());
-}
-
-void
-IdleRequestExecutor::DelayedDispatch(uint32_t aDelay)
-{
-  MOZ_ASSERT(mWindow);
-  MOZ_ASSERT(mDelayedExecutorHandle.isNothing());
-  int32_t handle;
-  mWindow->AsInner()->TimeoutManager().SetTimeout(
-    mDelayedExecutorDispatcher, aDelay, false, Timeout::Reason::eIdleCallbackTimeout, &handle);
-  mDelayedExecutorHandle = Some(handle);
-}
-
-nsresult
-IdleRequestExecutorTimeoutHandler::Call()
-{
-  if (!mExecutor->IsCancelled()) {
-    mExecutor->ScheduleDispatch();
-  }
-  return NS_OK;
-}
-
 void
 nsGlobalWindowOuter::ScheduleIdleRequestDispatch()
 {
-  AssertIsOnMainThread();
-
-  if (!mIdleRequestExecutor) {
-    mIdleRequestExecutor = new IdleRequestExecutor(AssertInner());
-  }
-
-  mIdleRequestExecutor->MaybeDispatch();
+  MOZ_CRASH("Inner Window Only");
 }
 
 void
 nsGlobalWindowOuter::SuspendIdleRequests()
 {
-  if (mIdleRequestExecutor) {
-    mIdleRequestExecutor->Cancel();
-    mIdleRequestExecutor = nullptr;
-  }
+  MOZ_CRASH("Inner window only");
 }
 
 void
 nsGlobalWindowOuter::ResumeIdleRequests()
 {
-  MOZ_ASSERT(!mIdleRequestExecutor);
-
-  ScheduleIdleRequestDispatch();
+  MOZ_CRASH("Inner window only");
 }
 
 void
 nsGlobalWindowOuter::InsertIdleCallback(IdleRequest* aRequest)
 {
-  AssertIsOnMainThread();
-  mIdleRequestCallbacks.insertBack(aRequest);
-  aRequest->AddRef();
+  MOZ_CRASH("Inner Window Only");
 }
 
 void
 nsGlobalWindowOuter::RemoveIdleCallback(mozilla::dom::IdleRequest* aRequest)
 {
   AssertIsOnMainThread();
 
   if (aRequest->HasTimeout()) {
@@ -835,126 +88,26 @@ nsGlobalWindowOuter::RunIdleRequest(Idle
   RefPtr<IdleRequest> request(aRequest);
   RemoveIdleCallback(request);
   return request->IdleRun(AsInner(), aDeadline, aDidTimeout);
 }
 
 nsresult
 nsGlobalWindowOuter::ExecuteIdleRequest(TimeStamp aDeadline)
 {
-  AssertIsOnMainThread();
-  RefPtr<IdleRequest> request = mIdleRequestCallbacks.getFirst();
-
-  if (!request) {
-    // There are no more idle requests, so stop scheduling idle
-    // request callbacks.
-    return NS_OK;
-  }
-
-  // If the request that we're trying to execute has been queued
-  // during the current idle period, then dispatch it again at the end
-  // of the idle period.
-  if (mIdleRequestExecutor->IneligibleForCurrentIdlePeriod(request)) {
-    mIdleRequestExecutor->MaybeDispatch(aDeadline);
-    return NS_OK;
-  }
-
-  DOMHighResTimeStamp deadline = 0.0;
-
-  if (Performance* perf = GetPerformance()) {
-    deadline = perf->GetDOMTiming()->TimeStampToDOMHighRes(aDeadline);
-  }
-
-  mIdleRequestExecutor->MaybeUpdateIdlePeriodLimit();
-  nsresult result = RunIdleRequest(request, deadline, false);
-
-  // Running the idle callback could've suspended the window, in which
-  // case mIdleRequestExecutor will be null.
-  if (mIdleRequestExecutor) {
-    mIdleRequestExecutor->MaybeDispatch();
-  }
-  return result;
-}
-
-class IdleRequestTimeoutHandler final : public TimeoutHandler
-{
-public:
-  IdleRequestTimeoutHandler(JSContext* aCx,
-                            IdleRequest* aIdleRequest,
-                            nsPIDOMWindowInner* aWindow)
-    : TimeoutHandler(aCx)
-    , mIdleRequest(aIdleRequest)
-    , mWindow(aWindow)
-  {
-  }
-
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IdleRequestTimeoutHandler,
-                                           TimeoutHandler)
-
-  nsresult Call() override
-  {
-    return nsGlobalWindowInner::Cast(mWindow)->RunIdleRequest(mIdleRequest, 0.0, true);
-  }
-
-private:
-  ~IdleRequestTimeoutHandler() override {}
-
-  RefPtr<IdleRequest> mIdleRequest;
-  nsCOMPtr<nsPIDOMWindowInner> mWindow;
-};
-
-NS_IMPL_CYCLE_COLLECTION_INHERITED(IdleRequestTimeoutHandler,
-                                   TimeoutHandler,
-                                   mIdleRequest,
-                                   mWindow)
-
-NS_IMPL_ADDREF_INHERITED(IdleRequestTimeoutHandler, TimeoutHandler)
-NS_IMPL_RELEASE_INHERITED(IdleRequestTimeoutHandler, TimeoutHandler)
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(IdleRequestTimeoutHandler)
-NS_INTERFACE_MAP_END_INHERITING(TimeoutHandler)
+  MOZ_CRASH("Inner window only");
+}
 
 uint32_t
 nsGlobalWindowOuter::RequestIdleCallback(JSContext* aCx,
                                     IdleRequestCallback& aCallback,
                                     const IdleRequestOptions& aOptions,
                                     ErrorResult& aError)
 {
-  MOZ_RELEASE_ASSERT(IsInnerWindow());
-  AssertIsOnMainThread();
-
-  uint32_t handle = mIdleRequestCallbackCounter++;
-
-  RefPtr<IdleRequest> request =
-    new IdleRequest(&aCallback, handle);
-
-  if (aOptions.mTimeout.WasPassed()) {
-    int32_t timeoutHandle;
-    nsCOMPtr<nsITimeoutHandler> handler(new IdleRequestTimeoutHandler(aCx, request, AsInner()));
-
-    nsresult rv = mTimeoutManager->SetTimeout(
-        handler, aOptions.mTimeout.Value(), false,
-        Timeout::Reason::eIdleCallbackTimeout, &timeoutHandle);
-
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return 0;
-    }
-
-    request->SetTimeoutHandle(timeoutHandle);
-  }
-
-  // mIdleRequestCallbacks now owns request
-  InsertIdleCallback(request);
-
-  if (!IsSuspended()) {
-    ScheduleIdleRequestDispatch();
-  }
-
-  return handle;
+  MOZ_CRASH("Inner window only");
 }
 
 void
 nsGlobalWindowOuter::CancelIdleCallback(uint32_t aHandle)
 {
   MOZ_RELEASE_ASSERT(IsInnerWindow());
 
   for (IdleRequest* r : mIdleRequestCallbacks) {
@@ -963,71 +116,24 @@ nsGlobalWindowOuter::CancelIdleCallback(
       break;
     }
   }
 }
 
 void
 nsGlobalWindowOuter::DisableIdleCallbackRequests()
 {
-  if (mIdleRequestExecutor) {
-    mIdleRequestExecutor->Cancel();
-    mIdleRequestExecutor = nullptr;
-  }
-
-  while (!mIdleRequestCallbacks.isEmpty()) {
-    RefPtr<IdleRequest> request = mIdleRequestCallbacks.getFirst();
-    RemoveIdleCallback(request);
-  }
+  MOZ_CRASH("Inner window only");
 }
 
 bool
 nsGlobalWindowOuter::IsBackgroundInternal() const
 {
   return !mOuterWindow || mOuterWindow->IsBackground();
 }
-namespace mozilla {
-namespace dom {
-extern uint64_t
-NextWindowID();
-} // namespace dom
-} // namespace mozilla
-
-template<class T>
-nsPIDOMWindow<T>::nsPIDOMWindow(nsPIDOMWindowOuter *aOuterWindow)
-: mFrameElement(nullptr), mDocShell(nullptr), mModalStateDepth(0),
-  mMutationBits(0), mActivePeerConnections(0), mIsDocumentLoaded(false),
-  mIsHandlingResizeEvent(false), mIsInnerWindow(aOuterWindow != nullptr),
-  mMayHavePaintEventListener(false), mMayHaveTouchEventListener(false),
-  mMayHaveSelectionChangeEventListener(false),
-  mMayHaveMouseEnterLeaveEventListener(false),
-  mMayHavePointerEnterLeaveEventListener(false),
-  mInnerObjectsFreed(false),
-  mIsActive(false), mIsBackground(false),
-  mMediaSuspend(Preferences::GetBool("media.block-autoplay-until-in-foreground", true) ?
-    nsISuspendedTypes::SUSPENDED_BLOCK : nsISuspendedTypes::NONE_SUSPENDED),
-  mAudioMuted(false), mAudioVolume(1.0), mAudioCaptured(false),
-  mDesktopModeViewport(false), mIsRootOuterWindow(false), mInnerWindow(nullptr),
-  mOuterWindow(aOuterWindow),
-  // Make sure no actual window ends up with mWindowID == 0
-  mWindowID(NextWindowID()), mHasNotifiedGlobalCreated(false),
-  mMarkedCCGeneration(0), mServiceWorkersTestingEnabled(false),
-  mLargeAllocStatus(LargeAllocStatus::NONE),
-  mHasTriedToCacheTopInnerWindow(false),
-  mNumOfIndexedDBDatabases(0),
-  mNumOfOpenWebSockets(0)
-{
-  if (aOuterWindow) {
-    mTimeoutManager =
-      MakeUnique<mozilla::dom::TimeoutManager>(*nsGlobalWindowInner::Cast(AsInner()));
-  }
-}
-
-template<class T>
-nsPIDOMWindow<T>::~nsPIDOMWindow() {}
 
 /* static */
 nsPIDOMWindowOuter*
 nsPIDOMWindowOuter::GetFromCurrentInner(nsPIDOMWindowInner* aInner)
 {
   if (!aInner) {
     return nullptr;
   }
@@ -1601,28 +707,17 @@ nsGlobalWindowOuter::nsGlobalWindowOuter
   }
 
   // We could have failed the first time through trying
   // to create the entropy collector, so we should
   // try to get one until we succeed.
 
   gRefCnt++;
 
-  static bool sFirstTime = true;
-  if (sFirstTime) {
-    TimeoutManager::Initialize();
-    Preferences::AddBoolVarCache(&gIdleObserversAPIFuzzTimeDisabled,
-                                 "dom.idle-observers-api.fuzz_time.disabled",
-                                 false);
-
-    Preferences::AddUintVarCache(&gThrottledIdlePeriodLength,
-                                 "dom.idle_period.throttled_length",
-                                 DEFAULT_THROTTLED_IDLE_PERIOD_LENGTH);
-    sFirstTime = false;
-  }
+  EnsurePrefCaches();
 
   if (gDumpFile == nullptr) {
     nsAutoCString fname;
     Preferences::GetCString("browser.dom.window.dump.file", fname);
     if (!fname.IsEmpty()) {
       // If this fails to open, Dump() knows to just go to stdout on null.
       gDumpFile = fopen(fname.get(), "wb+");
     } else {
@@ -1672,20 +767,17 @@ nsGlobalWindowOuter::AssertIsOnMainThrea
 /* static */
 void
 nsGlobalWindowOuter::Init()
 {
   AssertIsOnMainThread();
 
   NS_ASSERTION(gDOMLeakPRLog, "gDOMLeakPRLog should have been initialized!");
 
-  nsGlobalWindowOuter::sOuterWindowsById =
-    new nsGlobalWindowOuter::OuterWindowByIdTable();
-  nsGlobalWindowInner::sInnerWindowsById =
-    new nsGlobalWindowInner::InnerWindowByIdTable();
+  sOuterWindowsById = new OuterWindowByIdTable();
 }
 
 nsGlobalWindowOuter::~nsGlobalWindowOuter()
 {
   AssertIsOnMainThread();
 
   if (IsChromeWindow()) {
     MOZ_ASSERT(mCleanMessageManager,
@@ -1842,20 +934,18 @@ nsGlobalWindowOuter::ShutDown()
 {
   AssertIsOnMainThread();
 
   if (gDumpFile && gDumpFile != stdout) {
     fclose(gDumpFile);
   }
   gDumpFile = nullptr;
 
-  delete nsGlobalWindowInner::sInnerWindowsById;
-  nsGlobalWindowInner::sInnerWindowsById = nullptr;
-  delete nsGlobalWindowOuter::sOuterWindowsById;
-  nsGlobalWindowOuter::sOuterWindowsById = nullptr;
+  delete sOuterWindowsById;
+  sOuterWindowsById = nullptr;
 }
 
 // static
 void
 nsGlobalWindowOuter::CleanupCachedXBLHandlers()
 {
   if (mCachedXBLPrototypeHandlers &&
       mCachedXBLPrototypeHandlers->Count() > 0) {
@@ -1903,38 +993,17 @@ nsGlobalWindowOuter::CleanUp()
   if (mCleanedUp)
     return;
   mCleanedUp = true;
 
   StartDying();
 
   DisconnectEventTargetObjects();
 
-  if (mObserver) {
-    nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
-    if (os) {
-      os->RemoveObserver(mObserver, NS_IOSERVICE_OFFLINE_STATUS_TOPIC);
-      os->RemoveObserver(mObserver, MEMORY_PRESSURE_OBSERVER_TOPIC);
-    }
-
-    RefPtr<StorageNotifierService> sns = StorageNotifierService::GetOrCreate();
-    if (sns) {
-     sns->Unregister(mObserver);
-    }
-
-    if (mIdleService) {
-      mIdleService->RemoveIdleObserver(mObserver, MIN_IDLE_NOTIFICATION_TIME_S);
-    }
-
-    Preferences::RemoveObserver(mObserver, "intl.accept_languages");
-
-    // Drop its reference to this dying window, in case for some bogus reason
-    // the object stays around.
-    mObserver->Forget();
-  }
+  MOZ_RELEASE_ASSERT(!mObserver, "mObserver should only be set on the inner window");
 
   if (mNavigator) {
     mNavigator->Invalidate();
     mNavigator = nullptr;
   }
 
   mScreen = nullptr;
   mMenubar = nullptr;
@@ -1986,17 +1055,16 @@ nsGlobalWindowOuter::CleanUp()
   }
 
   if (IsInnerWindow()) {
     DisableGamepadUpdates();
     mHasGamepad = false;
     DisableVRUpdates();
     mHasVREvents = false;
     mHasVRDisplayActivateEvents = false;
-    DisableIdleCallbackRequests();
   } else {
     MOZ_ASSERT(!mHasGamepad);
     MOZ_ASSERT(!mHasVREvents);
     MOZ_ASSERT(!mHasVRDisplayActivateEvents);
   }
 
   if (mCleanMessageManager) {
     MOZ_ASSERT(mIsChrome, "only chrome should have msg manager cleaned");
@@ -2069,18 +1137,16 @@ nsGlobalWindowOuter::FreeInnerObjects()
 
   if (mIdleTimer) {
     mIdleTimer->Cancel();
     mIdleTimer = nullptr;
   }
 
   mIdleObservers.Clear();
 
-  DisableIdleCallbackRequests();
-
   mChromeEventHandler = nullptr;
 
   if (mListenerManager) {
     mListenerManager->Disconnect();
     mListenerManager = nullptr;
   }
 
   mHistory = nullptr;
@@ -2211,25 +1277,16 @@ NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(nsGlobalWindowOuter)
   return tmp->IsBlackForCC(true);
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END
 
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(nsGlobalWindowOuter)
   return tmp->IsBlackForCC(false);
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
 
-inline void
-ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
-                            IdleObserverHolder& aField,
-                            const char* aName,
-                            unsigned aFlags)
-{
-  CycleCollectionNoteChild(aCallback, aField.mIdleObserver.get(), aName, aFlags);
-}
-
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsGlobalWindowOuter)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGlobalWindowOuter)
   if (MOZ_UNLIKELY(cb.WantDebugInfo())) {
     char name[512];
     nsAutoCString uri;
     if (tmp->mDoc && tmp->mDoc->GetDocumentURI()) {
       uri = tmp->mDoc->GetDocumentURI()->GetSpecOrDefault();
@@ -2402,17 +1459,16 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mMozSelfSupport)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mIntlUtils)
 
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocShell)
 
   tmp->UnlinkHostObjectURIs();
 
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mIdleRequestExecutor)
-  tmp->DisableIdleCallbackRequests();
 
   if (tmp->IsChromeWindow()) {
     NS_IMPL_CYCLE_COLLECTION_UNLINK(mChromeFields.mBrowserDOMWindow)
     if (tmp->mChromeFields.mMessageManager) {
       static_cast<nsFrameMessageManager*>(
         tmp->mChromeFields.mMessageManager.get())->Disconnect();
       NS_IMPL_CYCLE_COLLECTION_UNLINK(mChromeFields.mMessageManager)
     }
@@ -2610,38 +1666,16 @@ nsGlobalWindowOuter::SetInitialPrincipal
     // Ensure that if someone plays with this document they will get
     // layout happening.
     nsRect r = shell->GetPresContext()->GetVisibleArea();
     shell->Initialize(r.Width(), r.Height());
   }
 }
 
 PopupControlState
-PushPopupControlState(PopupControlState aState, bool aForce)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  PopupControlState oldState = gPopupControlState;
-
-  if (aState < gPopupControlState || aForce) {
-    gPopupControlState = aState;
-  }
-
-  return oldState;
-}
-
-void
-PopPopupControlState(PopupControlState aState)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  gPopupControlState = aState;
-}
-
-PopupControlState
 nsGlobalWindowOuter::PushPopupControlState(PopupControlState aState,
                                       bool aForce) const
 {
   return ::PushPopupControlState(aState, aForce);
 }
 
 void
 nsGlobalWindowOuter::PopPopupControlState(PopupControlState aState) const
@@ -2708,69 +1742,16 @@ WindowStateHolder::~WindowStateHolder()
     // inner window if its outer has already had SetDocShell(null)
     // called.
     mInnerWindow->FreeInnerObjects();
   }
 }
 
 NS_IMPL_ISUPPORTS(WindowStateHolder, WindowStateHolder)
 
-// We need certain special behavior for remote XUL whitelisted domains, but we
-// don't want that behavior to take effect in automation, because we whitelist
-// all the mochitest domains. So we need to check a pref here.
-static bool
-TreatAsRemoteXUL(nsIPrincipal* aPrincipal)
-{
-  MOZ_ASSERT(!nsContentUtils::IsSystemPrincipal(aPrincipal));
-  return nsContentUtils::AllowXULXBLForPrincipal(aPrincipal) &&
-         !Preferences::GetBool("dom.use_xbl_scopes_for_remote_xul", false);
-}
-
-static bool
-EnablePrivilege(JSContext* cx, unsigned argc, JS::Value* vp)
-{
-  Telemetry::Accumulate(Telemetry::ENABLE_PRIVILEGE_EVER_CALLED, true);
-  return xpc::EnableUniversalXPConnect(cx);
-}
-
-static const JSFunctionSpec EnablePrivilegeSpec[] = {
-  JS_FN("enablePrivilege", EnablePrivilege, 1, 0),
-  JS_FS_END
-};
-
-static bool
-InitializeLegacyNetscapeObject(JSContext* aCx, JS::Handle<JSObject*> aGlobal)
-{
-  JSAutoCompartment ac(aCx, aGlobal);
-
-  // Note: MathJax depends on window.netscape being exposed. See bug 791526.
-  JS::Rooted<JSObject*> obj(aCx);
-  obj = JS_DefineObject(aCx, aGlobal, "netscape", nullptr);
-  NS_ENSURE_TRUE(obj, false);
-
-  obj = JS_DefineObject(aCx, obj, "security", nullptr);
-  NS_ENSURE_TRUE(obj, false);
-
-  // We hide enablePrivilege behind a pref because it has been altered in a
-  // way that makes it fundamentally insecure to use in production. Mozilla
-  // uses this pref during automated testing to support legacy test code that
-  // uses enablePrivilege. If you're not doing test automation, you _must_ not
-  // flip this pref, or you will be exposing all your users to security
-  // vulnerabilities.
-  if (!xpc::IsInAutomation()) {
-    return true;
-  }
-
-  /* Define PrivilegeManager object with the necessary "static" methods. */
-  obj = JS_DefineObject(aCx, obj, "PrivilegeManager", nullptr);
-  NS_ENSURE_TRUE(obj, false);
-
-  return JS_DefineFunctions(aCx, obj, EnablePrivilegeSpec);
-}
-
 bool
 nsGlobalWindowOuter::ComputeIsSecureContext(nsIDocument* aDocument, SecureContextFlags aFlags)
 {
   MOZ_ASSERT(IsOuterWindow());
 
   nsCOMPtr<nsIPrincipal> principal = aDocument->NodePrincipal();
   if (nsContentUtils::IsSystemPrincipal(principal)) {
     return true;
@@ -2845,112 +1826,16 @@ nsGlobalWindowOuter::ComputeIsSecureCont
     if (isTrustworthyOrigin) {
       return true;
     }
   }
 
   return false;
 }
 
-static JS::CompartmentCreationOptions&
-SelectZoneGroup(nsGlobalWindowInner* aNewInner,
-                JS::CompartmentCreationOptions& aOptions)
-{
-  JS::CompartmentCreationOptions options;
-
-  if (aNewInner->GetOuterWindow()) {
-    nsGlobalWindowOuter *top = aNewInner->GetTopInternal();
-
-    // If we have a top-level window, use its zone (and zone group).
-    if (top && top->GetGlobalJSObject()) {
-      return aOptions.setExistingZone(top->GetGlobalJSObject());
-    }
-  }
-
-  // If we're in the parent process, don't bother with zone groups.
-  if (XRE_IsParentProcess()) {
-    return aOptions.setNewZoneInSystemZoneGroup();
-  }
-
-  // Otherwise, find a zone group from the TabGroup. Typically we only have to
-  // go through one iteration of this loop.
-  RefPtr<TabGroup> tabGroup = aNewInner->TabGroup();
-  for (nsPIDOMWindowOuter* outer : tabGroup->GetWindows()) {
-    nsGlobalWindowOuter* window = nsGlobalWindowOuter::Cast(outer);
-    if (JSObject* global = window->GetGlobalJSObject()) {
-      return aOptions.setNewZoneInExistingZoneGroup(global);
-    }
-  }
-
-  return aOptions.setNewZoneInNewZoneGroup();
-}
-
-/**
- * Create a new global object that will be used for an inner window.
- * Return the native global and an nsISupports 'holder' that can be used
- * to manage the lifetime of it.
- */
-static nsresult
-CreateNativeGlobalForInner(JSContext* aCx,
-                           nsGlobalWindowInner* aNewInner,
-                           nsIURI* aURI,
-                           nsIPrincipal* aPrincipal,
-                           JS::MutableHandle<JSObject*> aGlobal,
-                           bool aIsSecureContext)
-{
-  MOZ_ASSERT(aCx);
-  MOZ_ASSERT(aNewInner);
-  MOZ_ASSERT(aNewInner->IsInnerWindow());
-  MOZ_ASSERT(aPrincipal);
-
-  // DOMWindow with nsEP is not supported, we have to make sure
-  // no one creates one accidentally.
-  nsCOMPtr<nsIExpandedPrincipal> nsEP = do_QueryInterface(aPrincipal);
-  MOZ_RELEASE_ASSERT(!nsEP, "DOMWindow with nsEP is not supported");
-
-  JS::CompartmentOptions options;
-
-  SelectZoneGroup(aNewInner, options.creationOptions());
-
-  // Sometimes add-ons load their own XUL windows, either as separate top-level
-  // windows or inside a browser element. In such cases we want to tag the
-  // window's compartment with the add-on ID. See bug 1092156.
-  if (nsContentUtils::IsSystemPrincipal(aPrincipal)) {
-    options.creationOptions().setAddonId(MapURIToAddonID(aURI));
-  }
-
-  options.creationOptions().setSecureContext(aIsSecureContext);
-
-  xpc::InitGlobalObjectOptions(options, aPrincipal);
-
-  // Determine if we need the Components object.
-  bool needComponents = nsContentUtils::IsSystemPrincipal(aPrincipal) ||
-                        TreatAsRemoteXUL(aPrincipal);
-  uint32_t flags = needComponents ? 0 : xpc::OMIT_COMPONENTS_OBJECT;
-  flags |= xpc::DONT_FIRE_ONNEWGLOBALHOOK;
-
-  if (!WindowBinding::Wrap(aCx, aNewInner, aNewInner, options,
-                           nsJSPrincipals::get(aPrincipal), false, aGlobal) ||
-      !xpc::InitGlobalObject(aCx, aGlobal, flags)) {
-    return NS_ERROR_FAILURE;
-  }
-
-  MOZ_ASSERT(aNewInner->GetWrapperPreserveColor() == aGlobal);
-
-  // Set the location information for the new global, so that tools like
-  // about:memory may use that information
-  xpc::SetLocationForGlobal(aGlobal, aURI);
-
-  if (!InitializeLegacyNetscapeObject(aCx, aGlobal)) {
-    return NS_ERROR_FAILURE;
-  }
-
-  return NS_OK;
-}
-
 nsresult
 nsGlobalWindowOuter::SetNewDocument(nsIDocument* aDocument,
                                nsISupports* aState,
                                bool aForceReuseInnerWindow)
 {
   NS_PRECONDITION(mDocumentPrincipal == nullptr,
                   "mDocumentPrincipal prematurely set!");
   MOZ_ASSERT(aDocument);
@@ -3624,34 +2509,16 @@ nsGlobalWindowOuter::SetOpenerWindow(nsP
       aOpener->GetCurrentInnerWindow()->IsSecureContext();
   }
 
 #ifdef DEBUG
   mSetOpenerWindowCalled = true;
 #endif
 }
 
-static
-already_AddRefed<EventTarget>
-TryGetTabChildGlobalAsEventTarget(nsISupports *aFrom)
-{
-  nsCOMPtr<nsIFrameLoaderOwner> frameLoaderOwner = do_QueryInterface(aFrom);
-  if (!frameLoaderOwner) {
-    return nullptr;
-  }
-
-  RefPtr<nsFrameLoader> frameLoader = frameLoaderOwner->GetFrameLoader();
-  if (!frameLoader) {
-    return nullptr;
-  }
-
-  nsCOMPtr<EventTarget> target = frameLoader->GetTabChildGlobalAsEventTarget();
-  return target.forget();
-}
-
 void
 nsGlobalWindowOuter::UpdateParentTarget()
 {
   // Try to get our frame element's tab child global (its in-process message
   // manager).  If that fails, fall back to the chrome event handler's tab
   // child global, and if it doesn't have one, just use the chrome event
   // handler itself.
 
@@ -4049,44 +2916,16 @@ nsGlobalWindowOuter::GetPrincipal()
 
   return nullptr;
 }
 
 //*****************************************************************************
 // nsGlobalWindowOuter::nsIDOMWindow
 //*****************************************************************************
 
-template <class T>
-nsIURI*
-nsPIDOMWindow<T>::GetDocumentURI() const
-{
-  return mDoc ? mDoc->GetDocumentURI() : mDocumentURI.get();
-}
-
-template <class T>
-nsIURI*
-nsPIDOMWindow<T>::GetDocBaseURI() const
-{
-  return mDoc ? mDoc->GetDocBaseURI() : mDocBaseURI.get();
-}
-
-template <class T>
-void
-nsPIDOMWindow<T>::MaybeCreateDoc()
-{
-  MOZ_ASSERT(!mDoc);
-  if (nsIDocShell* docShell = GetDocShell()) {
-    // Note that |document| here is the same thing as our mDoc, but we
-    // don't have to explicitly set the member variable because the docshell
-    // has already called SetNewDocument().
-    nsCOMPtr<nsIDocument> document = docShell->GetDocument();
-    Unused << document;
-  }
-}
-
 void
 nsPIDOMWindowOuter::SetInitialKeyboardIndicators(
   UIStateChangeType aShowAccelerators, UIStateChangeType aShowFocusRings)
 {
   MOZ_ASSERT(IsOuterWindow());
   MOZ_ASSERT(!GetCurrentInnerWindow());
 
   nsPIDOMWindowOuter* piWin = GetPrivateRoot();
@@ -4123,60 +2962,16 @@ nsPIDOMWindowOuter::GetFrameElementInter
 
 void
 nsPIDOMWindowOuter::SetFrameElementInternal(Element* aFrameElement)
 {
   MOZ_ASSERT(IsOuterWindow());
   mFrameElement = aFrameElement;
 }
 
-bool
-nsPIDOMWindowInner::AddAudioContext(AudioContext* aAudioContext)
-{
-  MOZ_ASSERT(IsInnerWindow());
-
-  mAudioContexts.AppendElement(aAudioContext);
-
-  // Return true if the context should be muted and false if not.
-  nsIDocShell* docShell = GetDocShell();
-  return docShell && !docShell->GetAllowMedia() && !aAudioContext->IsOffline();
-}
-
-void
-nsPIDOMWindowInner::RemoveAudioContext(AudioContext* aAudioContext)
-{
-  MOZ_ASSERT(IsInnerWindow());
-
-  mAudioContexts.RemoveElement(aAudioContext);
-}
-
-void
-nsPIDOMWindowInner::MuteAudioContexts()
-{
-  MOZ_ASSERT(IsInnerWindow());
-
-  for (uint32_t i = 0; i < mAudioContexts.Length(); ++i) {
-    if (!mAudioContexts[i]->IsOffline()) {
-      mAudioContexts[i]->Mute();
-    }
-  }
-}
-
-void
-nsPIDOMWindowInner::UnmuteAudioContexts()
-{
-  MOZ_ASSERT(IsInnerWindow());
-
-  for (uint32_t i = 0; i < mAudioContexts.Length(); ++i) {
-    if (!mAudioContexts[i]->IsOffline()) {
-      mAudioContexts[i]->Unmute();
-    }
-  }
-}
-
 nsGlobalWindowInner*
 nsGlobalWindowOuter::Window()
 {
   return AssertInner();
 }
 
 nsGlobalWindowInner*
 nsGlobalWindowOuter::Self()
@@ -4251,261 +3046,32 @@ nsGlobalWindowOuter::CustomElements()
   if (!mCustomElements) {
     mCustomElements = new CustomElementRegistry(AsInner());
   }
 
   return mCustomElements;
 }
 
 Performance*
-nsPIDOMWindowInner::GetPerformance()
-{
-  MOZ_ASSERT(IsInnerWindow());
-  CreatePerformanceObjectIfNeeded();
-  return mPerformance;
-}
-
-Performance*
 nsGlobalWindowOuter::GetPerformance()
 {
   return AsInner()->GetPerformance();
 }
 
 void
-nsPIDOMWindowInner::CreatePerformanceObjectIfNeeded()
-{
-  MOZ_ASSERT(IsInnerWindow());
-
-  if (mPerformance || !mDoc) {
-    return;
-  }
-  RefPtr<nsDOMNavigationTiming> timing = mDoc->GetNavigationTiming();
-  nsCOMPtr<nsITimedChannel> timedChannel(do_QueryInterface(mDoc->GetChannel()));
-  bool timingEnabled = false;
-  if (!timedChannel ||
-      !NS_SUCCEEDED(timedChannel->GetTimingEnabled(&timingEnabled)) ||
-      !timingEnabled) {
-    timedChannel = nullptr;
-  }
-  if (timing) {
-    mPerformance = Performance::CreateForMainThread(this, timing, timedChannel);
-  }
-}
-
-bool
-nsPIDOMWindowInner::IsSecureContext() const
-{
-  return nsGlobalWindowInner::Cast(this)->IsSecureContext();
-}
-
-bool
-nsPIDOMWindowInner::IsSecureContextIfOpenerIgnored() const
-{
-  return nsGlobalWindowInner::Cast(this)->IsSecureContextIfOpenerIgnored();
-}
-
-void
-nsPIDOMWindowInner::Suspend()
-{
-  nsGlobalWindowInner::Cast(this)->Suspend();
-}
-
-void
-nsPIDOMWindowInner::Resume()
-{
-  nsGlobalWindowInner::Cast(this)->Resume();
-}
-
-void
-nsPIDOMWindowInner::Freeze()
-{
-  nsGlobalWindowInner::Cast(this)->Freeze();
-}
-
-void
-nsPIDOMWindowInner::Thaw()
-{
-  nsGlobalWindowInner::Cast(this)->Thaw();
-}
-
-void
-nsPIDOMWindowInner::SyncStateFromParentWindow()
-{
-  nsGlobalWindowInner::Cast(this)->SyncStateFromParentWindow();
-}
-
-void
 nsGlobalWindowOuter::UpdateTopInnerWindow()
 {
   if (!IsInnerWindow() || AsInner()->IsTopInnerWindow() || !mTopInnerWindow) {
     return;
   }
 
   mTopInnerWindow->UpdateWebSocketCount(-(int32_t)mNumOfOpenWebSockets);
 }
 
 void
-nsPIDOMWindowInner::AddPeerConnection()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(IsInnerWindow());
-  mTopInnerWindow ? mTopInnerWindow->mActivePeerConnections++
-                  : mActivePeerConnections++;
-}
-
-void
-nsPIDOMWindowInner::RemovePeerConnection()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(IsInnerWindow());
-  MOZ_ASSERT(mTopInnerWindow ? mTopInnerWindow->mActivePeerConnections
-                             : mActivePeerConnections);
-
-  mTopInnerWindow ? mTopInnerWindow->mActivePeerConnections--
-                  : mActivePeerConnections--;
-}
-
-bool
-nsPIDOMWindowInner::HasActivePeerConnections()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(IsInnerWindow());
-  return mTopInnerWindow ? mTopInnerWindow->mActivePeerConnections
-                         : mActivePeerConnections;
-}
-
-bool
-nsPIDOMWindowInner::IsPlayingAudio()
-{
-  for (uint32_t i = 0; i < mAudioContexts.Length(); i++) {
-    if (mAudioContexts[i]->IsRunning()) {
-      return true;
-    }
-  }
-  RefPtr<AudioChannelService> acs = AudioChannelService::Get();
-  if (!acs) {
-    return false;
-  }
-  auto outer = GetOuterWindow();
-  if (!outer) {
-    // We've been unlinked and are about to die.  Not a good time to pretend to
-    // be playing audio.
-    return false;
-  }
-  return acs->IsWindowActive(outer);
-}
-
-bool
-nsPIDOMWindowInner::IsDocumentLoaded() const
-{
-  return mIsDocumentLoaded;
-}
-
-mozilla::dom::TimeoutManager&
-nsPIDOMWindowInner::TimeoutManager()
-{
-  return *mTimeoutManager;
-}
-
-bool
-nsPIDOMWindowInner::IsRunningTimeout()
-{
-  return TimeoutManager().IsRunningTimeout();
-}
-
-void
-nsPIDOMWindowInner::TryToCacheTopInnerWindow()
-{
-  if (mHasTriedToCacheTopInnerWindow) {
-    return;
-  }
-
-  MOZ_ASSERT(!mInnerObjectsFreed);
-
-  mHasTriedToCacheTopInnerWindow = true;
-
-  nsGlobalWindowInner* window = nsGlobalWindowInner::Cast(AsInner());
-
-  MOZ_ASSERT(window);
-
-  if (nsCOMPtr<nsPIDOMWindowOuter> topOutter = window->GetScriptableTop()) {
-    mTopInnerWindow = topOutter->GetCurrentInnerWindow();
-  }
-}
-
-void
-nsPIDOMWindowInner::UpdateActiveIndexedDBTransactionCount(int32_t aDelta)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  if (aDelta == 0) {
-    return;
-  }
-
-  TabGroup()->IndexedDBTransactionCounter() += aDelta;
-}
-
-void
-nsPIDOMWindowInner::UpdateActiveIndexedDBDatabaseCount(int32_t aDelta)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  if (aDelta == 0) {
-    return;
-  }
-
-  // We count databases but not transactions because only active databases
-  // could block throttling.
-  uint32_t& counter = mTopInnerWindow ?
-    mTopInnerWindow->mNumOfIndexedDBDatabases : mNumOfIndexedDBDatabases;
-
-  counter+= aDelta;
-
-  TabGroup()->IndexedDBDatabaseCounter() += aDelta;
-}
-
-bool
-nsPIDOMWindowInner::HasActiveIndexedDBDatabases()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  return mTopInnerWindow ?
-    mTopInnerWindow->mNumOfIndexedDBDatabases > 0 :
-    mNumOfIndexedDBDatabases > 0;
-}
-
-void
-nsPIDOMWindowInner::UpdateWebSocketCount(int32_t aDelta)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  if (aDelta == 0) {
-    return;
-  }
-
-  if (mTopInnerWindow && !IsTopInnerWindow()) {
-    mTopInnerWindow->UpdateWebSocketCount(aDelta);
-  }
-
-  MOZ_DIAGNOSTIC_ASSERT(
-    aDelta > 0 || ((aDelta + mNumOfOpenWebSockets) < mNumOfOpenWebSockets));
-
-  mNumOfOpenWebSockets += aDelta;
-}
-
-bool
-nsPIDOMWindowInner::HasOpenWebSockets() const
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  return mNumOfOpenWebSockets ||
-         (mTopInnerWindow && mTopInnerWindow->mNumOfOpenWebSockets);
-}
-
-void
 nsPIDOMWindowOuter::MaybeActiveMediaComponents()
 {
   if (IsInnerWindow()) {
     return mOuterWindow->MaybeActiveMediaComponents();
   }
 
   if (mMediaSuspend != nsISuspendedTypes::SUSPENDED_BLOCK) {
     return;
@@ -4657,38 +3223,16 @@ nsPIDOMWindowOuter::GetServiceWorkersTes
   // iframes get the correct devtools setting.
   nsCOMPtr<nsPIDOMWindowOuter> topWindow = GetScriptableTop();
   if (!topWindow) {
     return false;
   }
   return topWindow->mServiceWorkersTestingEnabled;
 }
 
-bool
-nsPIDOMWindowInner::GetAudioCaptured() const
-{
-  MOZ_ASSERT(IsInnerWindow());
-  return mAudioCaptured;
-}
-
-nsresult
-nsPIDOMWindowInner::SetAudioCapture(bool aCapture)
-{
-  MOZ_ASSERT(IsInnerWindow());
-
-  mAudioCaptured = aCapture;
-
-  RefPtr<AudioChannelService> service = AudioChannelService::GetOrCreate();
-  if (service) {
-    service->SetWindowAudioCaptured(GetOuterWindow(), mWindowID, aCapture);
-  }
-
-  return NS_OK;
-}
-
 // nsISpeechSynthesisGetter
 
 #ifdef MOZ_WEBSPEECH
 SpeechSynthesis*
 nsGlobalWindowOuter::GetSpeechSynthesis(ErrorResult& aError)
 {
   MOZ_RELEASE_ASSERT(IsInnerWindow());
 
@@ -9691,154 +8235,16 @@ nsGlobalWindowOuter::NotifyDOMWindowDest
     services::GetObserverService();
   if (observerService) {
     observerService->
       NotifyObservers(ToSupports(aWindow),
                       DOM_WINDOW_DESTROYED_TOPIC, nullptr);
   }
 }
 
-// Try to match compartments that are not web content by matching compartments
-// with principals that are either the system principal or an expanded principal.
-// This may not return true for all non-web-content compartments.
-struct BrowserCompartmentMatcher : public js::CompartmentFilter {
-  bool match(JSCompartment* aC) const override
-  {
-    nsCOMPtr<nsIPrincipal> pc = nsJSPrincipals::get(JS_GetCompartmentPrincipals(aC));
-    return nsContentUtils::IsSystemOrExpandedPrincipal(pc);
-  }
-};
-
-
-class WindowDestroyedEvent final : public Runnable
-{
-public:
-  WindowDestroyedEvent(nsGlobalWindowInner* aWindow, uint64_t aID, const char* aTopic)
-    : mozilla::Runnable("WindowDestroyedEvent")
-    , mID(aID)
-    , mPhase(Phase::Destroying)
-    , mTopic(aTopic)
-    , mIsInnerWindow(true)
-  {
-    mWindow = do_GetWeakReference(aWindow);
-  }
-  WindowDestroyedEvent(nsGlobalWindowOuter* aWindow, uint64_t aID, const char* aTopic)
-    : mozilla::Runnable("WindowDestroyedEvent")
-    , mID(aID)
-    , mPhase(Phase::Destroying)
-    , mTopic(aTopic)
-    , mIsInnerWindow(false)
-  {
-    mWindow = do_GetWeakReference(aWindow);
-  }
-
-  enum class Phase
-  {
-    Destroying,
-    Nuking
-  };
-
-  NS_IMETHOD Run() override
-  {
-    AUTO_PROFILER_LABEL("WindowDestroyedEvent::Run", OTHER);
-
-    nsCOMPtr<nsIObserverService> observerService =
-      services::GetObserverService();
-    if (!observerService) {
-      return NS_OK;
-    }
-
-    nsCOMPtr<nsISupportsPRUint64> wrapper =
-      do_CreateInstance(NS_SUPPORTS_PRUINT64_CONTRACTID);
-    if (wrapper) {
-      wrapper->SetData(mID);
-      observerService->NotifyObservers(wrapper, mTopic.get(), nullptr);
-    }
-
-    switch (mPhase) {
-      case Phase::Destroying:
-      {
-        bool skipNukeCrossCompartment = false;
-#ifndef DEBUG
-        nsCOMPtr<nsIAppStartup> appStartup =
-          do_GetService(NS_APPSTARTUP_CONTRACTID);
-
-        if (appStartup) {
-          appStartup->GetShuttingDown(&skipNukeCrossCompartment);
-        }
-#endif
-
-        if (!skipNukeCrossCompartment) {
-          // The compartment nuking phase might be too expensive, so do that
-          // part off of idle dispatch.
-
-          // For the compartment nuking phase, we dispatch either an
-          // inner-window-nuked or an outer-window-nuked notification.
-          // This will allow tests to wait for compartment nuking to happen.
-          if (mTopic.EqualsLiteral("inner-window-destroyed")) {
-            mTopic.AssignLiteral("inner-window-nuked");
-          } else if (mTopic.EqualsLiteral("outer-window-destroyed")) {
-            mTopic.AssignLiteral("outer-window-nuked");
-          }
-          mPhase = Phase::Nuking;
-
-          nsCOMPtr<nsIRunnable> copy(this);
-          NS_IdleDispatchToCurrentThread(copy.forget(), 1000);
-        }
-      }
-      break;
-
-      case Phase::Nuking:
-      {
-        nsCOMPtr<nsISupports> window = do_QueryReferent(mWindow);
-        if (window) {
-          nsGlobalWindowInner* currentInner;
-          if (mIsInnerWindow) {
-            currentInner = nsGlobalWindowInner::FromSupports(window);
-          } else {
-            nsGlobalWindowOuter* outer = nsGlobalWindowOuter::FromSupports(window);
-            currentInner = outer->GetCurrentInnerWindowInternal();
-          }
-          NS_ENSURE_TRUE(currentInner, NS_OK);
-
-          AutoSafeJSContext cx;
-          JS::Rooted<JSObject*> obj(cx, currentInner->FastGetGlobalJSObject());
-          if (obj && !js::IsSystemCompartment(js::GetObjectCompartment(obj))) {
-            JSCompartment* cpt = js::GetObjectCompartment(obj);
-            nsCOMPtr<nsIPrincipal> pc = nsJSPrincipals::get(JS_GetCompartmentPrincipals(cpt));
-
-            if (BasePrincipal::Cast(pc)->AddonPolicy()) {
-              // We want to nuke all references to the add-on compartment.
-              xpc::NukeAllWrappersForCompartment(cx, cpt,
-                                                 mIsInnerWindow ? js::DontNukeWindowReferences
-                                                                : js::NukeWindowReferences);
-            } else {
-              // We only want to nuke wrappers for the chrome->content case
-              js::NukeCrossCompartmentWrappers(cx, BrowserCompartmentMatcher(), cpt,
-                                               mIsInnerWindow ? js::DontNukeWindowReferences
-                                                              : js::NukeWindowReferences,
-                                               js::NukeIncomingReferences);
-            }
-          }
-        }
-      }
-      break;
-    }
-
-    return NS_OK;
-  }
-
-private:
-  uint64_t mID;
-  Phase mPhase;
-  nsCString mTopic;
-  nsWeakPtr mWindow;
-  bool mIsInnerWindow;
-};
-
 void
 nsGlobalWindowOuter::NotifyWindowIDDestroyed(const char* aTopic)
 {
   nsCOMPtr<nsIRunnable> runnable;
   if (IsInnerWindow()) {
     runnable = new WindowDestroyedEvent(AssertInner(), mWindowID, aTopic);
   } else {
     runnable = new WindowDestroyedEvent(AssertOuter(), mWindowID, aTopic);
@@ -10092,66 +8498,16 @@ nsGlobalWindowOuter::ConvertDialogOption
     if (iter == end ||
         !TokenizeDialogOptions(token, iter, end) ||
         !token.EqualsLiteral(";")) {
       break;
     }
   }
 }
 
-class ChildCommandDispatcher : public Runnable
-{
-public:
-  ChildCommandDispatcher(nsPIWindowRoot* aRoot,
-                         nsITabChild* aTabChild,
-                         const nsAString& aAction)
-    : mozilla::Runnable("ChildCommandDispatcher")
-    , mRoot(aRoot)
-    , mTabChild(aTabChild)
-    , mAction(aAction)
-  {
-  }
-
-  NS_IMETHOD Run() override
-  {
-    nsTArray<nsCString> enabledCommands, disabledCommands;
-    mRoot->GetEnabledDisabledCommands(enabledCommands, disabledCommands);
-    if (enabledCommands.Length() || disabledCommands.Length()) {
-      mTabChild->EnableDisableCommands(mAction, enabledCommands, disabledCommands);
-    }
-
-    return NS_OK;
-  }
-
-private:
-  nsCOMPtr<nsPIWindowRoot>             mRoot;
-  nsCOMPtr<nsITabChild>                mTabChild;
-  nsString                             mAction;
-};
-
-class CommandDispatcher : public Runnable
-{
-public:
-  CommandDispatcher(nsIDOMXULCommandDispatcher* aDispatcher,
-                    const nsAString& aAction)
-    : mozilla::Runnable("CommandDispatcher")
-    , mDispatcher(aDispatcher)
-    , mAction(aAction)
-  {
-  }
-
-  NS_IMETHOD Run() override
-  {
-    return mDispatcher->UpdateCommands(mAction);
-  }
-
-  nsCOMPtr<nsIDOMXULCommandDispatcher> mDispatcher;
-  nsString                             mAction;
-};
-
 nsresult
 nsGlobalWindowOuter::UpdateCommands(const nsAString& anAction, nsISelection* aSel, int16_t aReason)
 {
   // If this is a child process, redirect to the parent process.
   if (nsIDocShell* docShell = GetDocShell()) {
     if (nsCOMPtr<nsITabChild> child = docShell->GetTabChild()) {
       nsCOMPtr<nsPIWindowRoot> root = GetTopWindowRoot();
       if (root) {
@@ -10596,16 +8952,17 @@ NotifyDocumentTree(nsIDocument* aDocumen
   aDocument->EnumerateSubDocuments(NotifyDocumentTree, nullptr);
   aDocument->DocumentStatesChanged(NS_DOCUMENT_STATE_WINDOW_INACTIVE);
   return true;
 }
 
 void
 nsGlobalWindowOuter::SetActive(bool aActive)
 {
+  MOZ_RELEASE_ASSERT(IsOuterWindow());
   nsPIDOMWindow::SetActive(aActive);
   if (mDoc) {
     NotifyDocumentTree(mDoc, nullptr);
   }
 }
 
 bool
 nsGlobalWindowOuter::IsTopLevelWindowActive()
@@ -10620,17 +8977,18 @@ nsGlobalWindowOuter::IsTopLevelWindowAct
    if (!rootItem) {
      return false;
    }
 
    nsCOMPtr<nsPIDOMWindowOuter> domWindow = rootItem->GetWindow();
    return domWindow && domWindow->IsActive();
 }
 
-void nsGlobalWindowOuter::SetIsBackground(bool aIsBackground)
+void
+nsGlobalWindowOuter::SetIsBackground(bool aIsBackground)
 {
   MOZ_ASSERT(IsOuterWindow());
 
   bool changed = aIsBackground != AsOuter()->IsBackground();
   SetIsBackgroundInternal(aIsBackground);
 
   nsGlobalWindowInner* inner = GetCurrentInnerWindowInternal();
 
@@ -10664,17 +9022,18 @@ void
 nsGlobalWindowOuter::SetIsBackgroundInternal(bool aIsBackground)
 {
   if (mIsBackground != aIsBackground) {
     TabGroup()->WindowChangedBackgroundStatus(aIsBackground);
   }
   mIsBackground = aIsBackground;
 }
 
-void nsGlobalWindowOuter::MaybeUpdateTouchState()
+void
+nsGlobalWindowOuter::MaybeUpdateTouchState()
 {
   FORWARD_TO_INNER_VOID(MaybeUpdateTouchState, ());
 
   if (mMayHaveTouchEventListener) {
     nsCOMPtr<nsIObserverService> observerService =
       services::GetObserverService();
 
     if (observerService) {
@@ -10754,32 +9113,16 @@ nsGlobalWindowOuter::SetChromeEventHandl
     // in the list.
     inner = static_cast<nsGlobalWindowInner*>(node);
     NS_ASSERTION(!inner->mOuterWindow || inner->mOuterWindow == AsOuter(),
                  "bad outer window pointer");
     inner->SetChromeEventHandlerInternal(aChromeEventHandler);
   }
 }
 
-static bool IsLink(nsIContent* aContent)
-{
-  return aContent && (aContent->IsHTMLElement(nsGkAtoms::a) ||
-                      aContent->AttrValueIs(kNameSpaceID_XLink, nsGkAtoms::type,
-                                            nsGkAtoms::simple, eCaseMatters));
-}
-
-static bool ShouldShowFocusRingIfFocusedByMouse(nsIContent* aNode)
-{
-  if (!aNode) {
-    return true;
-  }
-  return !IsLink(aNode) &&
-         !aNode->IsAnyOfHTMLElements(nsGkAtoms::video, nsGkAtoms::audio);
-}
-
 void
 nsGlobalWindowOuter::SetFocusedNode(nsIContent* aNode,
                                uint32_t aFocusMethod,
                                bool aNeedsFocus)
 {
   FORWARD_TO_INNER_VOID(SetFocusedNode, (aNode, aFocusMethod, aNeedsFocus));
 
   if (aNode && aNode->GetComposedDoc() != mDoc) {
@@ -10945,72 +9288,20 @@ nsGlobalWindowOuter::PageHidden()
   nsIFocusManager* fm = nsFocusManager::GetFocusManager();
   if (fm) {
     fm->WindowHidden(GetOuterWindow());
   }
 
   mNeedsFocus = true;
 }
 
-class HashchangeCallback : public Runnable
-{
-public:
-  HashchangeCallback(const nsAString& aOldURL,
-                     const nsAString& aNewURL,
-                     nsGlobalWindowInner* aWindow)
-    : mozilla::Runnable("HashchangeCallback")
-    , mWindow(aWindow)
-  {
-    MOZ_ASSERT(mWindow);
-    MOZ_ASSERT(mWindow->IsInnerWindow());
-    mOldURL.Assign(aOldURL);
-    mNewURL.Assign(aNewURL);
-  }
-
-  NS_IMETHOD Run() override
-  {
-    NS_PRECONDITION(NS_IsMainThread(), "Should be called on the main thread.");
-    return mWindow->FireHashchange(mOldURL, mNewURL);
-  }
-
-private:
-  nsString mOldURL;
-  nsString mNewURL;
-  RefPtr<nsGlobalWindowInner> mWindow;
-};
-
 nsresult
 nsGlobalWindowOuter::DispatchAsyncHashchange(nsIURI *aOldURI, nsIURI *aNewURI)
 {
-  MOZ_RELEASE_ASSERT(IsInnerWindow());
-
-  // Make sure that aOldURI and aNewURI are identical up to the '#', and that
-  // their hashes are different.
-  bool equal = false;
-  NS_ENSURE_STATE(NS_SUCCEEDED(aOldURI->EqualsExceptRef(aNewURI, &equal)) && equal);
-  nsAutoCString oldHash, newHash;
-  bool oldHasHash, newHasHash;
-  NS_ENSURE_STATE(NS_SUCCEEDED(aOldURI->GetRef(oldHash)) &&
-                  NS_SUCCEEDED(aNewURI->GetRef(newHash)) &&
-                  NS_SUCCEEDED(aOldURI->GetHasRef(&oldHasHash)) &&
-                  NS_SUCCEEDED(aNewURI->GetHasRef(&newHasHash)) &&
-                  (oldHasHash != newHasHash || !oldHash.Equals(newHash)));
-
-  nsAutoCString oldSpec, newSpec;
-  nsresult rv = aOldURI->GetSpec(oldSpec);
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = aNewURI->GetSpec(newSpec);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  NS_ConvertUTF8toUTF16 oldWideSpec(oldSpec);
-  NS_ConvertUTF8toUTF16 newWideSpec(newSpec);
-
-  nsCOMPtr<nsIRunnable> callback =
-    new HashchangeCallback(oldWideSpec, newWideSpec, AssertInner());
-  return Dispatch(TaskCategory::Other, callback.forget());
+  MOZ_CRASH("Inner window only");
 }
 
 nsresult
 nsGlobalWindowOuter::FireHashchange(const nsAString &aOldURL,
                                const nsAString &aNewURL)
 {
   MOZ_ASSERT(IsInnerWindow());
 
@@ -11092,79 +9383,22 @@ nsGlobalWindowOuter::DispatchSyncPopStat
                                init);
   event->SetTrusted(true);
   event->SetTarget(this);
 
   bool dummy; // default action
   return DispatchEvent(event, &dummy);
 }
 
-// Find an nsICanvasFrame under aFrame.  Only search the principal
-// child lists.  aFrame must be non-null.
-static nsCanvasFrame* FindCanvasFrame(nsIFrame* aFrame)
-{
-    nsCanvasFrame* canvasFrame = do_QueryFrame(aFrame);
-    if (canvasFrame) {
-        return canvasFrame;
-    }
-
-    for (nsIFrame* kid : aFrame->PrincipalChildList()) {
-        canvasFrame = FindCanvasFrame(kid);
-        if (canvasFrame) {
-            return canvasFrame;
-        }
-    }
-
-    return nullptr;
-}
-
 //-------------------------------------------------------
 // Tells the HTMLFrame/CanvasFrame that is now has focus
 void
 nsGlobalWindowOuter::UpdateCanvasFocus(bool aFocusChanged, nsIContent* aNewContent)
 {
-  MOZ_ASSERT(IsInnerWindow());
-
-  // this is called from the inner window so use GetDocShell
-  nsIDocShell* docShell = GetDocShell();
-  if (!docShell)
-    return;
-
-  bool editable;
-  docShell->GetEditable(&editable);
-  if (editable)
-    return;
-
-  nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
-  if (!presShell || !mDoc)
-    return;
-
-  Element *rootElement = mDoc->GetRootElement();
-  if (rootElement) {
-      if ((mHasFocus || aFocusChanged) &&
-          (mFocusedNode == rootElement || aNewContent == rootElement)) {
-          nsIFrame* frame = rootElement->GetPrimaryFrame();
-          if (frame) {
-              frame = frame->GetParent();
-              nsCanvasFrame* canvasFrame = do_QueryFrame(frame);
-              if (canvasFrame) {
-                  canvasFrame->SetHasFocus(mHasFocus && rootElement == aNewContent);
-              }
-          }
-      }
-  } else {
-      // Look for the frame the hard way
-      nsIFrame* frame = presShell->GetRootFrame();
-      if (frame) {
-          nsCanvasFrame* canvasFrame = FindCanvasFrame(frame);
-          if (canvasFrame) {
-              canvasFrame->SetHasFocus(false);
-          }
-      }
-  }
+  MOZ_CRASH("Inner window only");
 }
 
 already_AddRefed<nsICSSDeclaration>
 nsGlobalWindowOuter::GetComputedStyle(Element& aElt, const nsAString& aPseudoElt,
                                  ErrorResult& aError)
 {
   MOZ_ASSERT(IsInnerWindow());
   return GetComputedStyleHelper(aElt, aPseudoElt, false, aError);
@@ -11502,35 +9736,16 @@ nsGlobalWindowOuter::GetCaches(ErrorResu
                                                      storageBlocked,
                                                      forceTrustedOrigin, aRv);
   }
 
   RefPtr<CacheStorage> ref = mCacheStorage;
   return ref.forget();
 }
 
-already_AddRefed<ServiceWorkerRegistration>
-nsPIDOMWindowInner::GetServiceWorkerRegistration(const nsAString& aScope)
-{
-  RefPtr<ServiceWorkerRegistration> registration;
-  if (!mServiceWorkerRegistrationTable.Get(aScope,
-                                           getter_AddRefs(registration))) {
-    registration =
-      ServiceWorkerRegistration::CreateForMainThread(this, aScope);
-    mServiceWorkerRegistrationTable.Put(aScope, registration);
-  }
-  return registration.forget();
-}
-
-void
-nsPIDOMWindowInner::InvalidateServiceWorkerRegistration(const nsAString& aScope)
-{
-  mServiceWorkerRegistrationTable.Remove(aScope);
-}
-
 void
 nsGlobalWindowOuter::FireOfflineStatusEventIfChanged()
 {
   if (!AsInner()->IsCurrentInnerWindow())
     return;
 
   // Don't fire an event if the status hasn't changed
   if (mWasOffline == NS_IsOffline()) {
@@ -11558,62 +9773,21 @@ nsGlobalWindowOuter::FireOfflineStatusEv
     Element* documentElement = mDoc->GetDocumentElement();
     if (documentElement) {
       eventTarget = documentElement;
     }
   }
   nsContentUtils::DispatchTrustedEvent(mDoc, eventTarget, name, true, false);
 }
 
-class NotifyIdleObserverRunnable : public Runnable
-{
-public:
-  NotifyIdleObserverRunnable(nsIIdleObserver* aIdleObserver,
-                             uint32_t aTimeInS,
-                             bool aCallOnidle,
-                             nsGlobalWindowInner* aIdleWindow)
-    : mozilla::Runnable("NotifyIdleObserverRunnable")
-    , mIdleObserver(aIdleObserver)
-    , mTimeInS(aTimeInS)
-    , mIdleWindow(aIdleWindow)
-    , mCallOnidle(aCallOnidle)
-  { }
-
-  NS_IMETHOD Run() override
-  {
-    if (mIdleWindow->ContainsIdleObserver(mIdleObserver, mTimeInS)) {
-      return mCallOnidle ? mIdleObserver->Onidle() : mIdleObserver->Onactive();
-    }
-    return NS_OK;
-  }
-
-private:
-  nsCOMPtr<nsIIdleObserver> mIdleObserver;
-  uint32_t mTimeInS;
-  RefPtr<nsGlobalWindowInner> mIdleWindow;
-
-  // If false then call on active
-  bool mCallOnidle;
-};
-
 void
 nsGlobalWindowOuter::NotifyIdleObserver(IdleObserverHolder* aIdleObserverHolder,
                                    bool aCallOnidle)
 {
-  MOZ_ASSERT(IsInnerWindow());
-  MOZ_ASSERT(aIdleObserverHolder);
-  aIdleObserverHolder->mPrevNotificationIdle = aCallOnidle;
-
-  nsCOMPtr<nsIRunnable> caller =
-    new NotifyIdleObserverRunnable(aIdleObserverHolder->mIdleObserver,
-                                   aIdleObserverHolder->mTimeInS,
-                                   aCallOnidle, AssertInner());
-  if (NS_FAILED(Dispatch(TaskCategory::Other, caller.forget()))) {
-    NS_WARNING("Failed to dispatch thread for idle observer notification.");
-  }
+  MOZ_CRASH("Inner window only");
 }
 
 bool
 nsGlobalWindowOuter::ContainsIdleObserver(nsIIdleObserver* aIdleObserver, uint32_t aTimeInS)
 {
   MOZ_ASSERT(aIdleObserver, "Idle observer not instantiated.");
   bool found = false;
   nsTObserverArray<IdleObserverHolder>::ForwardIterator iter(mIdleObservers);
@@ -11624,80 +9798,33 @@ nsGlobalWindowOuter::ContainsIdleObserve
       found = true;
       break;
     }
   }
   return found;
 }
 
 void
-IdleActiveTimerCallback(nsITimer* aTimer, void* aClosure)
-{
-  RefPtr<nsGlobalWindowInner> idleWindow =
-    static_cast<nsGlobalWindowInner*>(aClosure);
-  MOZ_ASSERT(idleWindow, "Idle window has not been instantiated.");
-  idleWindow->HandleIdleActiveEvent();
-}
-
-void
-IdleObserverTimerCallback(nsITimer* aTimer, void* aClosure)
-{
-  RefPtr<nsGlobalWindowInner> idleWindow =
-    static_cast<nsGlobalWindowInner*>(aClosure);
-  MOZ_ASSERT(idleWindow, "Idle window has not been instantiated.");
-  idleWindow->HandleIdleObserverCallback();
-}
-
-void
 nsGlobalWindowOuter::HandleIdleObserverCallback()
 {
   MOZ_ASSERT(IsInnerWindow(), "Must be an inner window!");
   MOZ_ASSERT(static_cast<uint32_t>(mIdleCallbackIndex) < mIdleObservers.Length(),
                                   "Idle callback index exceeds array bounds!");
   IdleObserverHolder& idleObserver = mIdleObservers.ElementAt(mIdleCallbackIndex);
   NotifyIdleObserver(&idleObserver, true);
   mIdleCallbackIndex++;
   if (NS_FAILED(ScheduleNextIdleObserverCallback())) {
     NS_WARNING("Failed to set next idle observer callback.");
   }
 }
 
 nsresult
 nsGlobalWindowOuter::ScheduleNextIdleObserverCallback()
 {
-  MOZ_ASSERT(IsInnerWindow(), "Must be an inner window!");
-  MOZ_ASSERT(mIdleService, "No idle service!");
-
-  if (mIdleCallbackIndex < 0 ||
-      static_cast<uint32_t>(mIdleCallbackIndex) >= mIdleObservers.Length()) {
-    return NS_OK;
-  }
-
-  IdleObserverHolder& idleObserver =
-    mIdleObservers.ElementAt(mIdleCallbackIndex);
-
-  uint32_t userIdleTimeMS = 0;
-  nsresult rv = mIdleService->GetIdleTime(&userIdleTimeMS);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  uint32_t callbackTimeMS = 0;
-  if (idleObserver.mTimeInS * 1000 + mIdleFuzzFactor > userIdleTimeMS) {
-    callbackTimeMS = idleObserver.mTimeInS * 1000 - userIdleTimeMS + mIdleFuzzFactor;
-  }
-
-  mIdleTimer->Cancel();
-  rv = mIdleTimer->InitWithNamedFuncCallback(
-    IdleObserverTimerCallback,
-    AssertInner(),
-    callbackTimeMS,
-    nsITimer::TYPE_ONE_SHOT,
-    "nsGlobalWindowOuter::ScheduleNextIdleObserverCallback");
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  return NS_OK;
+  MOZ_CRASH("Inner window only");
 }
 
 uint32_t
 nsGlobalWindowOuter::GetFuzzTimeMS()
 {
   MOZ_ASSERT(IsInnerWindow(), "Must be an inner window!");
 
   if (gIdleObserversAPIFuzzTimeDisabled) {
@@ -11716,34 +9843,17 @@ nsGlobalWindowOuter::GetFuzzTimeMS()
   }
 
   return randNum;
 }
 
 nsresult
 nsGlobalWindowOuter::ScheduleActiveTimerCallback()
 {
-  MOZ_ASSERT(IsInnerWindow(), "Must be an inner window!");
-
-  if (!mAddActiveEventFuzzTime) {
-    return HandleIdleActiveEvent();
-  }
-
-  MOZ_ASSERT(mIdleTimer);
-  mIdleTimer->Cancel();
-
-  uint32_t fuzzFactorInMS = GetFuzzTimeMS();
-  nsresult rv = mIdleTimer->InitWithNamedFuncCallback(
-    IdleActiveTimerCallback,
-    AssertInner(),
-    fuzzFactorInMS,
-    nsITimer::TYPE_ONE_SHOT,
-    "nsGlobalWindowOuter::ScheduleActiveTimerCallback");
-  NS_ENSURE_SUCCESS(rv, rv);
-  return NS_OK;
+  MOZ_CRASH("Inner window only");
 }
 
 nsresult
 nsGlobalWindowOuter::HandleIdleActiveEvent()
 {
   MOZ_ASSERT(IsInnerWindow(), "Must be an inner window!");
 
   if (mCurrentlyIdle) {
@@ -12021,82 +10131,17 @@ nsGlobalWindowOuter::FindInsertionIndex(
   }
 
   return i;
 }
 
 nsresult
 nsGlobalWindowOuter::RegisterIdleObserver(nsIIdleObserver* aIdleObserver)
 {
-  MOZ_ASSERT(IsInnerWindow(), "Must be an inner window!");
-
-  nsresult rv;
-  if (mIdleObservers.IsEmpty()) {
-    mIdleService = do_GetService("@mozilla.org/widget/idleservice;1", &rv);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    rv = mIdleService->AddIdleObserver(mObserver, MIN_IDLE_NOTIFICATION_TIME_S);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    if (!mIdleTimer) {
-      mIdleTimer = NS_NewTimer();
-      NS_ENSURE_TRUE(mIdleTimer, NS_ERROR_OUT_OF_MEMORY);
-    } else {
-      mIdleTimer->Cancel();
-    }
-  }
-
-  MOZ_ASSERT(mIdleService);
-  MOZ_ASSERT(mIdleTimer);
-
-  IdleObserverHolder tmpIdleObserver;
-  tmpIdleObserver.mIdleObserver = aIdleObserver;
-  rv = aIdleObserver->GetTime(&tmpIdleObserver.mTimeInS);
-  NS_ENSURE_SUCCESS(rv, rv);
-  NS_ENSURE_ARG_MAX(tmpIdleObserver.mTimeInS, UINT32_MAX / 1000);
-  NS_ENSURE_ARG_MIN(tmpIdleObserver.mTimeInS, MIN_IDLE_NOTIFICATION_TIME_S);
-
-  uint32_t insertAtIndex = FindInsertionIndex(&tmpIdleObserver);
-  if (insertAtIndex == mIdleObservers.Length()) {
-    mIdleObservers.AppendElement(tmpIdleObserver);
-  }
-  else {
-    mIdleObservers.InsertElementAt(insertAtIndex, tmpIdleObserver);
-  }
-
-  bool userIsIdle = false;
-  rv = nsContentUtils::IsUserIdle(MIN_IDLE_NOTIFICATION_TIME_S, &userIsIdle);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // Special case. First idle observer added to empty list while the user is idle.
-  // Haven't received 'idle' topic notification from slow idle service yet.
-  // Need to wait for the idle notification and then notify idle observers in the list.
-  if (userIsIdle && mIdleCallbackIndex == -1) {
-    return NS_OK;
-  }
-
-  if (!mCurrentlyIdle) {
-    return NS_OK;
-  }
-
-  MOZ_ASSERT(mIdleCallbackIndex >= 0);
-
-  if (static_cast<int32_t>(insertAtIndex) < mIdleCallbackIndex) {
-    IdleObserverHolder& idleObserver = mIdleObservers.ElementAt(insertAtIndex);
-    NotifyIdleObserver(&idleObserver, true);
-    mIdleCallbackIndex++;
-    return NS_OK;
-  }
-
-  if (static_cast<int32_t>(insertAtIndex) == mIdleCallbackIndex) {
-    mIdleTimer->Cancel();
-    rv = ScheduleNextIdleObserverCallback();
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-  return NS_OK;
+  MOZ_CRASH("Inner window only");
 }
 
 nsresult
 nsGlobalWindowOuter::FindIndexOfElementToRemove(nsIIdleObserver* aIdleObserver,
                                            int32_t* aRemoveElementIndex)
 {
   MOZ_ASSERT(IsInnerWindow(), "Must be an inner window!");
   MOZ_ASSERT(aIdleObserver, "Idle observer not instantiated.");
@@ -12122,67 +10167,17 @@ nsGlobalWindowOuter::FindIndexOfElementT
   }
   return static_cast<uint32_t>(*aRemoveElementIndex) >= mIdleObservers.Length() ?
     NS_ERROR_FAILURE : NS_OK;
 }
 
 nsresult
 nsGlobalWindowOuter::UnregisterIdleObserver(nsIIdleObserver* aIdleObserver)
 {
-  MOZ_ASSERT(IsInnerWindow(), "Must be an inner window!");
-
-  int32_t removeElementIndex;
-  nsresult rv = FindIndexOfElementToRemove(aIdleObserver, &removeElementIndex);
-  if (NS_FAILED(rv)) {
-    NS_WARNING("Idle observer not found in list of idle observers. No idle observer removed.");
-    return NS_OK;
-  }
-  mIdleObservers.RemoveElementAt(removeElementIndex);
-
-  MOZ_ASSERT(mIdleTimer);
-  if (mIdleObservers.IsEmpty() && mIdleService) {
-    rv = mIdleService->RemoveIdleObserver(mObserver, MIN_IDLE_NOTIFICATION_TIME_S);
-    NS_ENSURE_SUCCESS(rv, rv);
-    mIdleService = nullptr;
-
-    mIdleTimer->Cancel();
-    mIdleCallbackIndex = -1;
-    return NS_OK;
-  }
-
-  if (!mCurrentlyIdle) {
-    return NS_OK;
-  }
-
-  if (removeElementIndex < mIdleCallbackIndex) {
-    mIdleCallbackIndex--;
-    return NS_OK;
-  }
-
-  if (removeElementIndex != mIdleCallbackIndex) {
-    return NS_OK;
-  }
-
-  mIdleTimer->Cancel();
-
-  // If the last element in the array had been notified then decrement
-  // mIdleCallbackIndex because an idle was removed from the list of
-  // idle observers.
-  // Example: add idle observer with time 1, 2, 3,
-  // Idle notifications for idle observers with time 1, 2, 3 are complete
-  // Remove idle observer with time 3 while the user is still idle.
-  // The user never transitioned to active state.
-  // Add an idle observer with idle time 4
-  if (static_cast<uint32_t>(mIdleCallbackIndex) == mIdleObservers.Length()) {
-    mIdleCallbackIndex--;
-  }
-  rv = ScheduleNextIdleObserverCallback();
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  return NS_OK;
+  MOZ_CRASH("Inner window only");
 }
 
 nsresult
 nsGlobalWindowOuter::Observe(nsISupports* aSubject, const char* aTopic,
                         const char16_t* aData)
 {
   if (!nsCRT::strcmp(aTopic, NS_IOSERVICE_OFFLINE_STATUS_TOPIC)) {
     if (!IsFrozen()) {
@@ -13070,30 +11065,16 @@ int32_t
 nsGlobalWindowOuter::SetTimeout(JSContext* aCx, const nsAString& aHandler,
                            int32_t aTimeout,
                            const Sequence<JS::Value>& /* unused */,
                            ErrorResult& aError)
 {
   return SetTimeoutOrInterval(aCx, aHandler, aTimeout, false, aError);
 }
 
-static bool
-IsInterval(const Optional<int32_t>& aTimeout, int32_t& aResultTimeout)
-{
-  if (aTimeout.WasPassed()) {
-    aResultTimeout = aTimeout.Value();
-    return true;
-  }
-
-  // If no interval was specified, treat this like a timeout, to avoid setting
-  // an interval of 0 milliseconds.
-  aResultTimeout = 0;
-  return false;
-}
-
 int32_t
 nsGlobalWindowOuter::SetInterval(JSContext* aCx, Function& aFunction,
                             const Optional<int32_t>& aTimeout,
                             const Sequence<JS::Value>& aArguments,
                             ErrorResult& aError)
 {
   int32_t timeout;
   bool isInterval = IsInterval(aTimeout, timeout);
@@ -13983,47 +11964,20 @@ nsGlobalWindowOuter::DispatchVRDisplayPr
       Unused << DispatchEvent(event, &defaultActionEnabled);
       // Once we dispatch the event, we must not access any members as an event
       // listener can do anything, including closing windows.
       return;
     }
   }
 }
 
-enum WindowState {
-  // These constants need to match the constants in Window.webidl
-  STATE_MAXIMIZED = 1,
-  STATE_MINIMIZED = 2,
-  STATE_NORMAL = 3,
-  STATE_FULLSCREEN = 4
-};
-
 uint16_t
 nsGlobalWindowOuter::WindowState()
 {
-  MOZ_ASSERT(IsInnerWindow());
-  nsCOMPtr<nsIWidget> widget = GetMainWidget();
-
-  int32_t mode = widget ? widget->SizeMode() : 0;
-
-  switch (mode) {
-    case nsSizeMode_Minimized:
-      return STATE_MINIMIZED;
-    case nsSizeMode_Maximized:
-      return STATE_MAXIMIZED;
-    case nsSizeMode_Fullscreen:
-      return STATE_FULLSCREEN;
-    case nsSizeMode_Normal:
-      return STATE_NORMAL;
-    default:
-      NS_WARNING("Illegal window state for this chrome window");
-      break;
-  }
-
-  return STATE_NORMAL;
+  MOZ_CRASH("Inner window only");
 }
 
 bool
 nsGlobalWindowOuter::IsFullyOccluded()
 {
   MOZ_ASSERT(IsInnerWindow());
 
   nsCOMPtr<nsIWidget> widget = GetMainWidget();
@@ -14872,44 +12826,16 @@ nsGlobalWindowOuter::TabGroupInner()
 #ifdef DEBUG
   nsGlobalWindowOuter* outer = GetOuterWindowInternal();
   MOZ_ASSERT_IF(outer, outer->TabGroup() == mTabGroup);
 #endif
 
   return mTabGroup;
 }
 
-template<typename T>
-mozilla::dom::TabGroup*
-nsPIDOMWindow<T>::TabGroup()
-{
-  if (IsInnerWindow()) {
-    nsGlobalWindowInner* globalWindow =
-      static_cast<nsGlobalWindowInner*>(
-        reinterpret_cast<nsPIDOMWindow<nsISupports>*>(this));
-    return globalWindow->TabGroupInner();
-  } else {
-    nsGlobalWindowOuter* globalWindow =
-      static_cast<nsGlobalWindowOuter*>(
-        reinterpret_cast<nsPIDOMWindow<nsISupports>*>(this));
-    return globalWindow->TabGroupOuter();
-  }
-}
-
-template<typename T>
-mozilla::dom::DocGroup*
-nsPIDOMWindow<T>::GetDocGroup() const
-{
-  nsIDocument* doc = GetExtantDoc();
-  if (doc) {
-    return doc->GetDocGroup();
-  }
-  return nullptr;
-}
-
 nsresult
 nsGlobalWindowOuter::Dispatch(TaskCategory aCategory,
                          already_AddRefed<nsIRunnable>&& aRunnable)
 {
   MOZ_RELEASE_ASSERT(NS_IsMainThread());
   if (GetDocGroup()) {
     return GetDocGroup()->Dispatch(aCategory, Move(aRunnable));
   }
@@ -15032,13 +12958,8 @@ nsGlobalWindowOuter::Create(bool aIsChro
   if (aIsChrome) {
     window->mIsChrome = true;
     window->mCleanMessageManager = true;
   }
 
   window->InitWasOffline();
   return window.forget();
 }
-
-// XXX: Don't know what to do with these :-S
-template class nsPIDOMWindow<mozIDOMWindowProxy>;
-template class nsPIDOMWindow<mozIDOMWindow>;
-template class nsPIDOMWindow<nsISupports>;
--- a/layout/build/nsLayoutStatics.cpp
+++ b/layout/build/nsLayoutStatics.cpp
@@ -161,18 +161,18 @@ nsLayoutStatics::Initialize()
 
   StartupJSEnvironment();
   rv = nsRegion::InitStatic();
   if (NS_FAILED(rv)) {
     NS_ERROR("Could not initialize nsRegion");
     return rv;
   }
 
-  // XXX: Arbitrarially choose inner window?
   nsGlobalWindowInner::Init();
+  nsGlobalWindowOuter::Init();
   Navigator::Init();
   nsXBLService::Init();
 
   rv = nsContentUtils::Init();
   if (NS_FAILED(rv)) {
     NS_ERROR("Could not initialize nsContentUtils");
     return rv;
   }
@@ -376,18 +376,18 @@ nsLayoutStatics::Shutdown()
   nsTextFragment::Shutdown();
 
   nsAttrValue::Shutdown();
   nsContentUtils::Shutdown();
   nsLayoutStylesheetCache::Shutdown();
   RuleProcessorCache::Shutdown();
 
   ShutdownJSEnvironment();
-  // XXX: Arbitrarially choose inner window?
   nsGlobalWindowInner::ShutDown();
+  nsGlobalWindowOuter::ShutDown();
   nsDOMClassInfo::ShutDown();
   WebIDLGlobalNameHash::Shutdown();
   nsListControlFrame::Shutdown();
   nsXBLService::Shutdown();
   nsAutoCopyListener::Shutdown();
   FrameLayerBuilder::Shutdown();
 
   CubebUtils::ShutdownLibrary();