diff --git a/docshell/base/BrowsingContext.h b/docshell/base/BrowsingContext.h index d5d0794d59c4..4e2cd3ddf797 100644 --- a/docshell/base/BrowsingContext.h +++ b/docshell/base/BrowsingContext.h @@ -124,8 +124,8 @@ public: nsTArray>& aBrowsingContexts); nsISupports* GetParentObject() const; - virtual JSObject* WrapObject(JSContext* aCx, - JS::Handle aGivenProto) override; + JSObject* WrapObject(JSContext* aCx, + JS::Handle aGivenProto) override; MOZ_DECLARE_WEAKREFERENCE_TYPENAME(BrowsingContext) NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(BrowsingContext) diff --git a/docshell/base/ChromeBrowsingContext.cpp b/docshell/base/ChromeBrowsingContext.cpp index f7c225c9badf..b29f1794d7f7 100644 --- a/docshell/base/ChromeBrowsingContext.cpp +++ b/docshell/base/ChromeBrowsingContext.cpp @@ -63,6 +63,15 @@ ChromeBrowsingContext::Cast(const BrowsingContext* aContext) return static_cast(aContext); } +void +ChromeBrowsingContext::GetWindowGlobals(nsTArray>& aWindows) +{ + aWindows.SetCapacity(mWindowGlobals.Count()); + for (auto iter = mWindowGlobals.Iter(); !iter.Done(); iter.Next()) { + aWindows.AppendElement(iter.Get()->GetKey()); + } +} + void ChromeBrowsingContext::RegisterWindowGlobal(WindowGlobalParent* aGlobal) { @@ -77,6 +86,13 @@ ChromeBrowsingContext::UnregisterWindowGlobal(WindowGlobalParent* aGlobal) mWindowGlobals.RemoveEntry(aGlobal); } +JSObject* +ChromeBrowsingContext::WrapObject(JSContext* aCx, + JS::Handle aGivenProto) +{ + return ChromeBrowsingContext_Binding::Wrap(aCx, this, aGivenProto); +} + void ChromeBrowsingContext::Traverse(nsCycleCollectionTraversalCallback& cb) { diff --git a/docshell/base/ChromeBrowsingContext.h b/docshell/base/ChromeBrowsingContext.h index 9ac834908895..39c763919e4a 100644 --- a/docshell/base/ChromeBrowsingContext.h +++ b/docshell/base/ChromeBrowsingContext.h @@ -38,10 +38,15 @@ public: return mProcessId == aProcessId; } + void GetWindowGlobals(nsTArray>& aWindows); + // Called by WindowGlobalParent to register and unregister window globals. void RegisterWindowGlobal(WindowGlobalParent* aGlobal); void UnregisterWindowGlobal(WindowGlobalParent* aGlobal); + JSObject* WrapObject(JSContext* aCx, + JS::Handle aGivenProto) override; + protected: void Traverse(nsCycleCollectionTraversalCallback& cb); void Unlink(); diff --git a/dom/chrome-webidl/BrowsingContext.webidl b/dom/chrome-webidl/BrowsingContext.webidl index 236d51a9ce7e..92c0850d2dcc 100644 --- a/dom/chrome-webidl/BrowsingContext.webidl +++ b/dom/chrome-webidl/BrowsingContext.webidl @@ -17,3 +17,8 @@ interface BrowsingContext { readonly attribute BrowsingContext? opener; }; + +[Exposed=Window, ChromeOnly] +interface ChromeBrowsingContext : BrowsingContext { + sequence getWindowGlobals(); +}; diff --git a/dom/chrome-webidl/WindowGlobalActors.webidl b/dom/chrome-webidl/WindowGlobalActors.webidl new file mode 100644 index 000000000000..4b847720d380 --- /dev/null +++ b/dom/chrome-webidl/WindowGlobalActors.webidl @@ -0,0 +1,33 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +interface Principal; +interface URI; +interface nsIDocShell; + +[Exposed=Window, ChromeOnly] +interface WindowGlobalParent { + readonly attribute boolean isClosed; + readonly attribute boolean isInProcess; + readonly attribute ChromeBrowsingContext browsingContext; + + // XXX(nika): We would want to expose this, but |FrameLoader| isn't exposed on System. + // readonly attribute FrameLoader? rootFrameLoader; // Embedded (browser) only + + readonly attribute WindowGlobalChild? childActor; // in-process only + + // Information about the currently loaded document. + readonly attribute Principal documentPrincipal; + readonly attribute URI? documentURI; +}; + +[Exposed=Window, ChromeOnly] +interface WindowGlobalChild { + readonly attribute boolean isClosed; + readonly attribute boolean isInProcess; + readonly attribute BrowsingContext browsingContext; + + readonly attribute WindowGlobalParent? parentActor; // in-process only +}; diff --git a/dom/chrome-webidl/moz.build b/dom/chrome-webidl/moz.build index 19947457e13d..8a93ef30f47c 100644 --- a/dom/chrome-webidl/moz.build +++ b/dom/chrome-webidl/moz.build @@ -54,6 +54,7 @@ WEBIDL_FILES = [ 'TelemetryStopwatch.webidl', 'WebExtensionContentScript.webidl', 'WebExtensionPolicy.webidl', + 'WindowGlobalActors.webidl', 'XULFrameElement.webidl', 'XULMenuElement.webidl', 'XULScrollElement.webidl', diff --git a/dom/ipc/WindowGlobalChild.cpp b/dom/ipc/WindowGlobalChild.cpp index dd2026bb39ae..f19106c6ae01 100644 --- a/dom/ipc/WindowGlobalChild.cpp +++ b/dom/ipc/WindowGlobalChild.cpp @@ -7,6 +7,7 @@ #include "mozilla/dom/WindowGlobalChild.h" #include "mozilla/ipc/InProcessChild.h" #include "mozilla/dom/BrowsingContext.h" +#include "mozilla/dom/WindowGlobalActorsBinding.h" namespace mozilla { namespace dom { @@ -54,7 +55,7 @@ WindowGlobalChild::Create(nsGlobalWindowInner* aWindow) } already_AddRefed -WindowGlobalChild::GetOtherSide() +WindowGlobalChild::GetParentActor() { if (mIPCClosed) { return nullptr; @@ -73,7 +74,23 @@ WindowGlobalChild::~WindowGlobalChild() { } -NS_IMPL_CYCLE_COLLECTION(WindowGlobalChild, mWindowGlobal, mBrowsingContext) +JSObject* +WindowGlobalChild::WrapObject(JSContext* aCx, + JS::Handle aGivenProto) +{ + return WindowGlobalChild_Binding::Wrap(aCx, this, aGivenProto); +} + +nsISupports* +WindowGlobalChild::GetParentObject() +{ + return xpc::NativeGlobal(xpc::PrivilegedJunkScope()); +} + +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WindowGlobalChild, + mWindowGlobal, + mBrowsingContext) + NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WindowGlobalChild, AddRef) NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WindowGlobalChild, Release) diff --git a/dom/ipc/WindowGlobalChild.h b/dom/ipc/WindowGlobalChild.h index cce3f12e73f5..3dde74ef713b 100644 --- a/dom/ipc/WindowGlobalChild.h +++ b/dom/ipc/WindowGlobalChild.h @@ -9,6 +9,7 @@ #include "mozilla/RefPtr.h" #include "mozilla/dom/PWindowGlobalChild.h" +#include "nsWrapperCache.h" class nsGlobalWindowInner; class nsDocShell; @@ -23,11 +24,12 @@ class WindowGlobalParent; * Actor for a single nsGlobalWindowInner. This actor is used to communicate * information to the parent process asynchronously. */ -class WindowGlobalChild : public PWindowGlobalChild +class WindowGlobalChild : public nsWrapperCache + , public PWindowGlobalChild { public: NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WindowGlobalChild) - NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(WindowGlobalChild) + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WindowGlobalChild) dom::BrowsingContext* BrowsingContext() { return mBrowsingContext; } nsGlobalWindowInner* WindowGlobal() { return mWindowGlobal; } @@ -41,12 +43,16 @@ public: // Get the other side of this actor if it is an in-process actor. Returns // |nullptr| if the actor has been torn down, or is not in-process. - already_AddRefed GetOtherSide(); + already_AddRefed GetParentActor(); // Create and initialize the WindowGlobalChild object. static already_AddRefed Create(nsGlobalWindowInner* aWindow); + nsISupports* GetParentObject(); + JSObject* WrapObject(JSContext* aCx, + JS::Handle aGivenProto) override; + protected: virtual void ActorDestroy(ActorDestroyReason aWhy) override; diff --git a/dom/ipc/WindowGlobalParent.cpp b/dom/ipc/WindowGlobalParent.cpp index 19dcac8c9cb4..480f6c4d81e7 100644 --- a/dom/ipc/WindowGlobalParent.cpp +++ b/dom/ipc/WindowGlobalParent.cpp @@ -7,6 +7,7 @@ #include "mozilla/dom/WindowGlobalParent.h" #include "mozilla/ipc/InProcessParent.h" #include "mozilla/dom/ChromeBrowsingContext.h" +#include "mozilla/dom/WindowGlobalActorsBinding.h" using namespace mozilla::ipc; @@ -59,7 +60,7 @@ WindowGlobalParent::Init(const WindowGlobalInit& aInit) // In the in-process case, we can get it from the other side's // WindowGlobalChild. MOZ_ASSERT(Manager()->GetProtocolTypeId() == PInProcessMsgStart); - RefPtr otherSide = GetOtherSide(); + RefPtr otherSide = GetChildActor(); if (otherSide && otherSide->WindowGlobal()) { // Get the toplevel window from the other side. RefPtr docShell = nsDocShell::Cast(otherSide->WindowGlobal()->GetDocShell()); @@ -82,7 +83,7 @@ WindowGlobalParent::Init(const WindowGlobalInit& aInit) } already_AddRefed -WindowGlobalParent::GetOtherSide() +WindowGlobalParent::GetChildActor() { if (mIPCClosed) { return nullptr; @@ -111,7 +112,23 @@ WindowGlobalParent::~WindowGlobalParent() { } -NS_IMPL_CYCLE_COLLECTION(WindowGlobalParent, mFrameLoader, mBrowsingContext) +JSObject* +WindowGlobalParent::WrapObject(JSContext* aCx, + JS::Handle aGivenProto) +{ + return WindowGlobalParent_Binding::Wrap(aCx, this, aGivenProto); +} + +nsISupports* +WindowGlobalParent::GetParentObject() +{ + return xpc::NativeGlobal(xpc::PrivilegedJunkScope()); +} + +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WindowGlobalParent, + mFrameLoader, + mBrowsingContext) + NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WindowGlobalParent, AddRef) NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WindowGlobalParent, Release) diff --git a/dom/ipc/WindowGlobalParent.h b/dom/ipc/WindowGlobalParent.h index 1bed980da5d3..6ab6ac8f5985 100644 --- a/dom/ipc/WindowGlobalParent.h +++ b/dom/ipc/WindowGlobalParent.h @@ -9,6 +9,7 @@ #include "mozilla/RefPtr.h" #include "mozilla/dom/PWindowGlobalParent.h" +#include "nsWrapperCache.h" class nsIPrincipal; class nsIURI; @@ -23,11 +24,12 @@ class WindowGlobalChild; /** * A handle in the parent process to a specific nsGlobalWindowInner object. */ -class WindowGlobalParent final : public PWindowGlobalParent +class WindowGlobalParent final : public nsWrapperCache + , public PWindowGlobalParent { public: NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WindowGlobalParent) - NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(WindowGlobalParent) + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WindowGlobalParent) // Has this actor been shut down bool IsClosed() { return mIPCClosed; } @@ -38,7 +40,7 @@ public: // Get the other side of this actor if it is an in-process actor. Returns // |nullptr| if the actor has been torn down, or is not in-process. - already_AddRefed GetOtherSide(); + already_AddRefed GetChildActor(); // The principal of this WindowGlobal. This value will not change over the // lifetime of the WindowGlobal object, even to reflect changes in @@ -65,6 +67,10 @@ public: // be called after setting the Manager actor. void Init(const WindowGlobalInit& aInit); + nsISupports* GetParentObject(); + JSObject* WrapObject(JSContext* aCx, + JS::Handle aGivenProto) override; + protected: // IPC messages mozilla::ipc::IPCResult RecvUpdateDocumentURI(nsIURI* aURI) override;