Bug 1493634 - make docshell responsible for outer window IDs, r=bzbarsky
authorGijs Kruitbosch <gijskruitbosch@gmail.com>
Wed, 10 Oct 2018 10:20:36 +0000
changeset 440432 61ad878d2f66d0b129b326a526e6dff46d839e94
parent 440431 6b1fd4c384b953bf617f0d58f4ce0ddf0e0b2326
child 440433 003208b2dd175a1ecd16a9a781011c115a3d7d06
push id34820
push userdvarga@mozilla.com
push dateWed, 10 Oct 2018 16:07:50 +0000
treeherdermozilla-central@0f1d5395f801 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbzbarsky
bugs1493634
milestone64.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 1493634 - make docshell responsible for outer window IDs, r=bzbarsky Differential Revision: https://phabricator.services.mozilla.com/D7702
docshell/base/nsDocShell.cpp
docshell/base/nsDocShell.h
docshell/base/nsIDocShell.idl
dom/base/nsGlobalWindowOuter.cpp
dom/base/nsGlobalWindowOuter.h
dom/base/nsPIDOMWindow.h
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -308,16 +308,17 @@ DecreasePrivateDocShellCount()
     if (obsvc) {
       obsvc->NotifyObservers(nullptr, "last-pb-context-exited", nullptr);
     }
   }
 }
 
 nsDocShell::nsDocShell()
   : nsDocLoader()
+  , mContentWindowID(NextWindowID())
   , mForcedCharset(nullptr)
   , mParentCharset(nullptr)
   , mTreeOwner(nullptr)
   , mChromeEventHandler(nullptr)
   , mDefaultScrollbarPref(Scrollbar_Auto, Scrollbar_Auto)
   , mCharsetReloadState(eCharsetReloadInit)
   , mOrientationLock(hal::eScreenOrientation_None)
   , mParentCharsetSource(0)
@@ -1282,16 +1283,23 @@ nsDocShell::GetContentViewer(nsIContentV
   NS_ENSURE_ARG_POINTER(aContentViewer);
 
   *aContentViewer = mContentViewer;
   NS_IF_ADDREF(*aContentViewer);
   return NS_OK;
 }
 
 NS_IMETHODIMP
+nsDocShell::GetOuterWindowID(uint64_t *aWindowID)
+{
+  *aWindowID = mContentWindowID;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 nsDocShell::SetChromeEventHandler(EventTarget* aChromeEventHandler)
 {
   // Weak reference. Don't addref.
   mChromeEventHandler = aChromeEventHandler;
 
   if (mScriptGlobal) {
     mScriptGlobal->SetChromeEventHandler(mChromeEventHandler);
   }
@@ -12721,21 +12729,19 @@ nsDocShell::EnsureScriptEnvironment()
   nsCOMPtr<nsIWebBrowserChrome> browserChrome(do_GetInterface(mTreeOwner));
   NS_ENSURE_TRUE(browserChrome, NS_ERROR_NOT_AVAILABLE);
 
   uint32_t chromeFlags;
   browserChrome->GetChromeFlags(&chromeFlags);
 
   // If our window is modal and we're not opened as chrome, make
   // this window a modal content window.
-  mScriptGlobal = NS_NewScriptGlobalObject(mItemType == typeChrome);
+  mScriptGlobal = nsGlobalWindowOuter::Create(this, mItemType == typeChrome);
   MOZ_ASSERT(mScriptGlobal);
 
-  mScriptGlobal->SetDocShell(this);
-
   // Ensure the script object is set up to run script.
   return mScriptGlobal->EnsureScriptEnvironment();
 }
 
 nsresult
 nsDocShell::EnsureEditorData()
 {
   MOZ_ASSERT(!mIsBeingDestroyed);
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -931,16 +931,17 @@ private: // data members
   RefPtr<nsDOMNavigationTiming> mTiming;
   RefPtr<nsDSURIContentListener> mContentListener;
   RefPtr<nsGlobalWindowOuter> mScriptGlobal;
   nsCOMPtr<nsIPrincipal> mParentCharsetPrincipal;
   nsCOMPtr<nsILoadURIDelegate> mLoadURIDelegate;
   nsCOMPtr<nsIMutableArray> mRefreshURIList;
   nsCOMPtr<nsIMutableArray> mSavedRefreshURIList;
   nsCOMPtr<nsIDOMStorageManager> mSessionStorageManager;
+  uint64_t mContentWindowID;
   nsCOMPtr<nsIContentViewer> mContentViewer;
   nsCOMPtr<nsIWidget> mParentWidget;
   RefPtr<mozilla::dom::ChildSHistory> mSessionHistory;
   nsCOMPtr<nsIWebBrowserFind> mFind;
   nsCOMPtr<nsICommandManager> mCommandManager;
   RefPtr<mozilla::dom::BrowsingContext> mBrowsingContext;
 
   // Dimensions of the docshell
--- a/docshell/base/nsIDocShell.idl
+++ b/docshell/base/nsIDocShell.idl
@@ -261,16 +261,21 @@ interface nsIDocShell : nsIDocShellTreeI
 
   /**
    * Content Viewer that is currently loaded for this DocShell.  This may
    * change as the underlying content changes.
    */
   readonly attribute nsIContentViewer contentViewer;
 
   /**
+   * Get the id of the outer window that is or will be in this docshell.
+   */
+  [infallible] readonly attribute unsigned long long outerWindowID;
+
+  /**
    * This attribute allows chrome to tie in to handle DOM events that may
    * be of interest to chrome.
    */
   attribute EventTarget chromeEventHandler;
 
   /**
    * This allows chrome to set a custom User agent on a specific docshell
    */
--- a/dom/base/nsGlobalWindowOuter.cpp
+++ b/dom/base/nsGlobalWindowOuter.cpp
@@ -807,18 +807,18 @@ NewOuterWindowProxy(JSContext *cx, JS::H
   MOZ_ASSERT_IF(obj, js::IsWindowProxy(obj));
   return obj;
 }
 
 //*****************************************************************************
 //***    nsGlobalWindowOuter: Object Management
 //*****************************************************************************
 
-nsGlobalWindowOuter::nsGlobalWindowOuter()
-  : nsPIDOMWindowOuter(),
+nsGlobalWindowOuter::nsGlobalWindowOuter(uint64_t aWindowID)
+  : nsPIDOMWindowOuter(aWindowID),
     mIdleFuzzFactor(0),
     mIdleCallbackIndex(-1),
     mCurrentlyIdle(false),
     mAddActiveEventFuzzTime(true),
     mFullscreen(false),
     mFullscreenMode(false),
     mIsClosed(false),
     mInClose(false),
@@ -7656,22 +7656,24 @@ nsGlobalWindowOuter::TemporarilyDisableD
 
 mozilla::dom::TabGroup*
 nsPIDOMWindowOuter::TabGroup()
 {
   return nsGlobalWindowOuter::Cast(this)->TabGroupOuter();
 }
 
 /* static */ already_AddRefed<nsGlobalWindowOuter>
-nsGlobalWindowOuter::Create(bool aIsChrome)
-{
-  RefPtr<nsGlobalWindowOuter> window = new nsGlobalWindowOuter();
+nsGlobalWindowOuter::Create(nsIDocShell* aDocShell, bool aIsChrome)
+{
+  uint64_t outerWindowID = aDocShell->GetOuterWindowID();
+  RefPtr<nsGlobalWindowOuter> window = new nsGlobalWindowOuter(outerWindowID);
   if (aIsChrome) {
     window->mIsChrome = true;
   }
+  window->SetDocShell(aDocShell);
 
   window->InitWasOffline();
   return window.forget();
 }
 
 nsIURI*
 nsPIDOMWindowOuter::GetDocumentURI() const
 {
@@ -7710,42 +7712,32 @@ nsPIDOMWindowOuter::GetDocGroup() const
 {
   nsIDocument* doc = GetExtantDoc();
   if (doc) {
     return doc->GetDocGroup();
   }
   return nullptr;
 }
 
-// XXX: Can we define this in a header instead of here?
-namespace mozilla {
-namespace dom {
-extern uint64_t
-NextWindowID();
-} // namespace dom
-} // namespace mozilla
-
-nsPIDOMWindowOuter::nsPIDOMWindowOuter()
+nsPIDOMWindowOuter::nsPIDOMWindowOuter(uint64_t aWindowID)
   : mFrameElement(nullptr)
   , mDocShell(nullptr)
   , mModalStateDepth(0)
   , 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)
   , mDesktopModeViewport(false)
   , mIsRootOuterWindow(false)
   , mInnerWindow(nullptr)
-  ,
-  // Make sure no actual window ends up with mWindowID == 0
-  mWindowID(NextWindowID())
+  , mWindowID(aWindowID)
   , mMarkedCCGeneration(0)
   , mServiceWorkersTestingEnabled(false)
   , mLargeAllocStatus(LargeAllocStatus::NONE)
 {
 }
 
 nsPIDOMWindowOuter::~nsPIDOMWindowOuter() {}
 
--- a/dom/base/nsGlobalWindowOuter.h
+++ b/dom/base/nsGlobalWindowOuter.h
@@ -214,17 +214,17 @@ public:
   }
 
   static nsGlobalWindowOuter *FromSupports(nsISupports *supports)
   {
     // Make sure this matches the casts we do in QueryInterface().
     return (nsGlobalWindowOuter *)(mozilla::dom::EventTarget *)supports;
   }
 
-  static already_AddRefed<nsGlobalWindowOuter> Create(bool aIsChrome);
+  static already_AddRefed<nsGlobalWindowOuter> Create(nsIDocShell* aDocShell, bool aIsChrome);
 
   // public methods
   nsPIDOMWindowOuter* GetPrivateParent();
 
   // callback for close event
   void ReallyCloseWindow();
 
   // nsISupports
@@ -315,17 +315,16 @@ public:
   virtual bool IsSuspended() const override;
   virtual bool IsFrozen() const override;
 
   virtual nsresult FireDelayedDOMEvents() override;
 
   // Outer windows only.
   bool WouldReuseInnerWindow(nsIDocument* aNewDocument);
 
-  void SetDocShell(nsIDocShell* aDocShell);
   void DetachFromDocShell();
 
   virtual nsresult SetNewDocument(nsIDocument *aDocument,
                                   nsISupports *aState,
                                   bool aForceReuseInnerWindow) override;
 
   // Outer windows only.
   void DispatchDOMWindowCreated();
@@ -576,17 +575,16 @@ public:
   void BlurOuter();
   already_AddRefed<nsPIDOMWindowOuter> GetFramesOuter();
   nsDOMWindowList* GetFrames() final;
   uint32_t Length();
   already_AddRefed<nsPIDOMWindowOuter> GetTopOuter();
 
   nsresult GetPrompter(nsIPrompt** aPrompt) override;
 protected:
-  explicit nsGlobalWindowOuter();
   nsPIDOMWindowOuter* GetOpenerWindowOuter();
   // Initializes the mWasOffline member variable
   void InitWasOffline();
 public:
   nsPIDOMWindowOuter*
   GetSanitizedOpener(nsPIDOMWindowOuter* aOpener);
 
   already_AddRefed<nsPIDOMWindowOuter> GetOpener() override;
@@ -826,16 +824,18 @@ protected:
   // Outer windows only.
   virtual nsresult
   OpenNoNavigate(const nsAString& aUrl,
                  const nsAString& aName,
                  const nsAString& aOptions,
                  nsPIDOMWindowOuter** _retval) override;
 
 private:
+  explicit nsGlobalWindowOuter(uint64_t aWindowID);
+
   /**
    * @param aUrl the URL we intend to load into the window.  If aNavigate is
    *        true, we'll actually load this URL into the window. Otherwise,
    *        aUrl is advisory; OpenInternal will not load the URL into the
    *        new window.
    *
    * @param aName the name to use for the new window
    *
@@ -1042,16 +1042,18 @@ private:
     eIgnoreOpener
   };
   // Called only on outer windows to compute the value that will be returned by
   // IsSecureContext() for the inner window that corresponds to aDocument.
   bool ComputeIsSecureContext(nsIDocument* aDocument,
                               SecureContextFlags aFlags =
                                 SecureContextFlags::eDefault);
 
+  void SetDocShell(nsIDocShell* aDocShell);
+
   // nsPIDOMWindow{Inner,Outer} should be able to see these helper methods.
   friend class nsPIDOMWindowInner;
   friend class nsPIDOMWindowOuter;
 
   mozilla::dom::TabGroup* TabGroupOuter();
 
   void SetIsBackgroundInternal(bool aIsBackground);
 
@@ -1253,16 +1255,9 @@ nsGlobalWindowOuter::IsFrame()
 inline void
 nsGlobalWindowOuter::MaybeClearInnerWindow(nsGlobalWindowInner* aExpectedInner)
 {
   if(mInnerWindow == aExpectedInner->AsInner()) {
     mInnerWindow = nullptr;
   }
 }
 
-/* factory function */
-inline already_AddRefed<nsGlobalWindowOuter>
-NS_NewScriptGlobalObject(bool aIsChrome)
-{
-  return nsGlobalWindowOuter::Create(aIsChrome);
-}
-
 #endif /* nsGlobalWindowOuter_h___ */
--- a/dom/base/nsPIDOMWindow.h
+++ b/dom/base/nsPIDOMWindow.h
@@ -711,17 +711,17 @@ protected:
   mozilla::dom::Event* mEvent;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsPIDOMWindowInner, NS_PIDOMWINDOWINNER_IID)
 
 class nsPIDOMWindowOuter : public mozIDOMWindowProxy
 {
 protected:
-  explicit nsPIDOMWindowOuter();
+  explicit nsPIDOMWindowOuter(uint64_t aWindowID);
 
   ~nsPIDOMWindowOuter();
 
   void RefreshMediaElementsVolume();
   void RefreshMediaElementsSuspend(SuspendTypes aSuspend);
   bool IsDisposableSuspend(SuspendTypes aSuspend) const;
   void MaybeNotifyMediaResumedFromBlock(SuspendTypes aSuspend);