зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1525427 - Part 1: Expose WindowGlobalParent & Element on BrowsingContext, r=farre
Differential Revision: https://phabricator.services.mozilla.com/D25181 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
7f4ecdea61
Коммит
0bc40288dc
|
@ -13,9 +13,12 @@
|
||||||
#include "mozilla/dom/BrowsingContextBinding.h"
|
#include "mozilla/dom/BrowsingContextBinding.h"
|
||||||
#include "mozilla/dom/ContentChild.h"
|
#include "mozilla/dom/ContentChild.h"
|
||||||
#include "mozilla/dom/ContentParent.h"
|
#include "mozilla/dom/ContentParent.h"
|
||||||
|
#include "mozilla/dom/Element.h"
|
||||||
#include "mozilla/dom/Location.h"
|
#include "mozilla/dom/Location.h"
|
||||||
#include "mozilla/dom/LocationBinding.h"
|
#include "mozilla/dom/LocationBinding.h"
|
||||||
#include "mozilla/dom/WindowBinding.h"
|
#include "mozilla/dom/WindowBinding.h"
|
||||||
|
#include "mozilla/dom/WindowGlobalChild.h"
|
||||||
|
#include "mozilla/dom/WindowGlobalParent.h"
|
||||||
#include "mozilla/dom/WindowProxyHolder.h"
|
#include "mozilla/dom/WindowProxyHolder.h"
|
||||||
#include "mozilla/Assertions.h"
|
#include "mozilla/Assertions.h"
|
||||||
#include "mozilla/ClearOnShutdown.h"
|
#include "mozilla/ClearOnShutdown.h"
|
||||||
|
@ -201,6 +204,27 @@ void BrowsingContext::SetDocShell(nsIDocShell* aDocShell) {
|
||||||
mIsInProcess = true;
|
mIsInProcess = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BrowsingContext::SetEmbedderElement(Element* aEmbedder) {
|
||||||
|
mEmbedderElement = aEmbedder;
|
||||||
|
|
||||||
|
// Notify the parent process of the embedding status. We don't need to do
|
||||||
|
// this when clearing our embedder, as we're being destroyed either way.
|
||||||
|
if (mEmbedderElement) {
|
||||||
|
nsCOMPtr<nsPIDOMWindowInner> embedderGlobal =
|
||||||
|
do_QueryInterface(mEmbedderElement->GetOwnerGlobal());
|
||||||
|
RefPtr<WindowGlobalChild> wgc = embedderGlobal->GetWindowGlobalChild();
|
||||||
|
|
||||||
|
// If we're in-process, synchronously perform the update to ensure we don't
|
||||||
|
// get out of sync.
|
||||||
|
// XXX(nika): This is super gross, and I don't like it one bit.
|
||||||
|
if (RefPtr<WindowGlobalParent> wgp = wgc->GetParentActor()) {
|
||||||
|
Canonical()->SetEmbedderWindowGlobal(wgp);
|
||||||
|
} else {
|
||||||
|
wgc->SendDidEmbedBrowsingContext(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void BrowsingContext::Attach(bool aFromIPC) {
|
void BrowsingContext::Attach(bool aFromIPC) {
|
||||||
MOZ_LOG(GetLog(), LogLevel::Debug,
|
MOZ_LOG(GetLog(), LogLevel::Debug,
|
||||||
("%s: %s 0x%08" PRIx64 " to 0x%08" PRIx64,
|
("%s: %s 0x%08" PRIx64 " to 0x%08" PRIx64,
|
||||||
|
@ -518,7 +542,8 @@ bool BrowsingContext::GetUserGestureActivation() {
|
||||||
NS_IMPL_CYCLE_COLLECTION_CLASS(BrowsingContext)
|
NS_IMPL_CYCLE_COLLECTION_CLASS(BrowsingContext)
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(BrowsingContext)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(BrowsingContext)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocShell, mChildren, mParent, mGroup)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocShell, mChildren, mParent, mGroup,
|
||||||
|
mEmbedderElement)
|
||||||
if (XRE_IsParentProcess()) {
|
if (XRE_IsParentProcess()) {
|
||||||
CanonicalBrowsingContext::Cast(tmp)->Unlink();
|
CanonicalBrowsingContext::Cast(tmp)->Unlink();
|
||||||
}
|
}
|
||||||
|
@ -526,7 +551,8 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(BrowsingContext)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(BrowsingContext)
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(BrowsingContext)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocShell, mChildren, mParent, mGroup)
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocShell, mChildren, mParent, mGroup,
|
||||||
|
mEmbedderElement)
|
||||||
if (XRE_IsParentProcess()) {
|
if (XRE_IsParentProcess()) {
|
||||||
CanonicalBrowsingContext::Cast(tmp)->Traverse(cb);
|
CanonicalBrowsingContext::Cast(tmp)->Traverse(cb);
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,7 @@ class BrowsingContent;
|
||||||
class BrowsingContextGroup;
|
class BrowsingContextGroup;
|
||||||
class CanonicalBrowsingContext;
|
class CanonicalBrowsingContext;
|
||||||
class ContentParent;
|
class ContentParent;
|
||||||
|
class Element;
|
||||||
template <typename>
|
template <typename>
|
||||||
struct Nullable;
|
struct Nullable;
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -123,6 +124,11 @@ class BrowsingContext : public nsWrapperCache,
|
||||||
void SetDocShell(nsIDocShell* aDocShell);
|
void SetDocShell(nsIDocShell* aDocShell);
|
||||||
void ClearDocShell() { mDocShell = nullptr; }
|
void ClearDocShell() { mDocShell = nullptr; }
|
||||||
|
|
||||||
|
// Get the embedder element for this BrowsingContext if the embedder is
|
||||||
|
// in-process, or null if it's not.
|
||||||
|
Element* GetEmbedderElement() const { return mEmbedderElement; }
|
||||||
|
void SetEmbedderElement(Element* aEmbedder);
|
||||||
|
|
||||||
// Get the outer window object for this BrowsingContext if it is in-process
|
// Get the outer window object for this BrowsingContext if it is in-process
|
||||||
// and still has a docshell, or null otherwise.
|
// and still has a docshell, or null otherwise.
|
||||||
nsPIDOMWindowOuter* GetDOMWindow() const {
|
nsPIDOMWindowOuter* GetDOMWindow() const {
|
||||||
|
@ -439,6 +445,8 @@ class BrowsingContext : public nsWrapperCache,
|
||||||
Children mChildren;
|
Children mChildren;
|
||||||
nsCOMPtr<nsIDocShell> mDocShell;
|
nsCOMPtr<nsIDocShell> mDocShell;
|
||||||
|
|
||||||
|
RefPtr<Element> mEmbedderElement;
|
||||||
|
|
||||||
// This is not a strong reference, but using a JS::Heap for that should be
|
// This is not a strong reference, but using a JS::Heap for that should be
|
||||||
// fine. The JSObject stored in here should be a proxy with a
|
// fine. The JSObject stored in here should be a proxy with a
|
||||||
// nsOuterWindowProxy handler, which will update the pointer from its
|
// nsOuterWindowProxy handler, which will update the pointer from its
|
||||||
|
|
|
@ -116,6 +116,20 @@ void CanonicalBrowsingContext::SetCurrentWindowGlobal(
|
||||||
mCurrentWindowGlobal = aGlobal;
|
mCurrentWindowGlobal = aGlobal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CanonicalBrowsingContext::SetEmbedderWindowGlobal(
|
||||||
|
WindowGlobalParent* aGlobal) {
|
||||||
|
MOZ_RELEASE_ASSERT(aGlobal, "null embedder");
|
||||||
|
if (RefPtr<BrowsingContext> parent = GetParent()) {
|
||||||
|
MOZ_RELEASE_ASSERT(aGlobal->BrowsingContext() == parent,
|
||||||
|
"Embedder has incorrect browsing context");
|
||||||
|
} else {
|
||||||
|
MOZ_RELEASE_ASSERT(aGlobal->IsInProcess(),
|
||||||
|
"Toplevel must have a parent-process embedder");
|
||||||
|
}
|
||||||
|
|
||||||
|
mEmbedderWindowGlobal = aGlobal;
|
||||||
|
}
|
||||||
|
|
||||||
bool CanonicalBrowsingContext::ValidateTransaction(
|
bool CanonicalBrowsingContext::ValidateTransaction(
|
||||||
const Transaction& aTransaction, ContentParent* aProcess) {
|
const Transaction& aTransaction, ContentParent* aProcess) {
|
||||||
// Check that the correct process is performing sets for transactions with
|
// Check that the correct process is performing sets for transactions with
|
||||||
|
@ -137,12 +151,14 @@ JSObject* CanonicalBrowsingContext::WrapObject(
|
||||||
void CanonicalBrowsingContext::Traverse(
|
void CanonicalBrowsingContext::Traverse(
|
||||||
nsCycleCollectionTraversalCallback& cb) {
|
nsCycleCollectionTraversalCallback& cb) {
|
||||||
CanonicalBrowsingContext* tmp = this;
|
CanonicalBrowsingContext* tmp = this;
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindowGlobals);
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindowGlobals, mCurrentWindowGlobal,
|
||||||
|
mEmbedderWindowGlobal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CanonicalBrowsingContext::Unlink() {
|
void CanonicalBrowsingContext::Unlink() {
|
||||||
CanonicalBrowsingContext* tmp = this;
|
CanonicalBrowsingContext* tmp = this;
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindowGlobals);
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindowGlobals, mCurrentWindowGlobal,
|
||||||
|
mEmbedderWindowGlobal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CanonicalBrowsingContext::NotifyStartDelayedAutoplayMedia() {
|
void CanonicalBrowsingContext::NotifyStartDelayedAutoplayMedia() {
|
||||||
|
|
|
@ -52,6 +52,11 @@ class CanonicalBrowsingContext final : public BrowsingContext {
|
||||||
}
|
}
|
||||||
void SetCurrentWindowGlobal(WindowGlobalParent* aGlobal);
|
void SetCurrentWindowGlobal(WindowGlobalParent* aGlobal);
|
||||||
|
|
||||||
|
WindowGlobalParent* GetEmbedderWindowGlobal() const {
|
||||||
|
return mEmbedderWindowGlobal;
|
||||||
|
}
|
||||||
|
void SetEmbedderWindowGlobal(WindowGlobalParent* aGlobal);
|
||||||
|
|
||||||
JSObject* WrapObject(JSContext* aCx,
|
JSObject* WrapObject(JSContext* aCx,
|
||||||
JS::Handle<JSObject*> aGivenProto) override;
|
JS::Handle<JSObject*> aGivenProto) override;
|
||||||
|
|
||||||
|
@ -97,6 +102,7 @@ class CanonicalBrowsingContext final : public BrowsingContext {
|
||||||
// All live window globals within this browsing context.
|
// All live window globals within this browsing context.
|
||||||
nsTHashtable<nsRefPtrHashKey<WindowGlobalParent>> mWindowGlobals;
|
nsTHashtable<nsRefPtrHashKey<WindowGlobalParent>> mWindowGlobals;
|
||||||
RefPtr<WindowGlobalParent> mCurrentWindowGlobal;
|
RefPtr<WindowGlobalParent> mCurrentWindowGlobal;
|
||||||
|
RefPtr<WindowGlobalParent> mEmbedderWindowGlobal;
|
||||||
|
|
||||||
// Generation information for each content process which has interacted with
|
// Generation information for each content process which has interacted with
|
||||||
// this CanonicalBrowsingContext, by ChildID.
|
// this CanonicalBrowsingContext, by ChildID.
|
||||||
|
|
|
@ -1893,6 +1893,10 @@ void nsFrameLoader::SetOwnerContent(Element* aContent) {
|
||||||
}
|
}
|
||||||
mOwnerContent = aContent;
|
mOwnerContent = aContent;
|
||||||
|
|
||||||
|
if (RefPtr<BrowsingContext> browsingContext = GetBrowsingContext()) {
|
||||||
|
browsingContext->SetEmbedderElement(mOwnerContent);
|
||||||
|
}
|
||||||
|
|
||||||
AutoJSAPI jsapi;
|
AutoJSAPI jsapi;
|
||||||
jsapi.Init();
|
jsapi.Init();
|
||||||
|
|
||||||
|
@ -2009,6 +2013,8 @@ nsresult nsFrameLoader::MaybeCreateDocShell() {
|
||||||
RefPtr<nsDocShell> docShell = nsDocShell::Create(mBrowsingContext);
|
RefPtr<nsDocShell> docShell = nsDocShell::Create(mBrowsingContext);
|
||||||
NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
mBrowsingContext->SetEmbedderElement(mOwnerContent);
|
||||||
|
|
||||||
mIsTopLevelContent =
|
mIsTopLevelContent =
|
||||||
mBrowsingContext->IsContent() && !mBrowsingContext->GetParent();
|
mBrowsingContext->IsContent() && !mBrowsingContext->GetParent();
|
||||||
if (!mNetworkCreated && !mIsTopLevelContent) {
|
if (!mNetworkCreated && !mIsTopLevelContent) {
|
||||||
|
@ -2604,6 +2610,8 @@ bool nsFrameLoader::TryRemoteBrowser() {
|
||||||
|
|
||||||
// If we're in a content process, create a BrowserBridgeChild actor.
|
// If we're in a content process, create a BrowserBridgeChild actor.
|
||||||
if (XRE_IsContentProcess()) {
|
if (XRE_IsContentProcess()) {
|
||||||
|
mBrowsingContext->SetEmbedderElement(mOwnerContent);
|
||||||
|
|
||||||
mBrowserBridgeChild = BrowserBridgeChild::Create(
|
mBrowserBridgeChild = BrowserBridgeChild::Create(
|
||||||
this, context, NS_LITERAL_STRING(DEFAULT_REMOTE_TYPE),
|
this, context, NS_LITERAL_STRING(DEFAULT_REMOTE_TYPE),
|
||||||
mBrowsingContext);
|
mBrowsingContext);
|
||||||
|
|
|
@ -22,6 +22,8 @@ interface BrowsingContext {
|
||||||
|
|
||||||
readonly attribute nsIDocShell? docShell;
|
readonly attribute nsIDocShell? docShell;
|
||||||
|
|
||||||
|
readonly attribute Element? embedderElement;
|
||||||
|
|
||||||
readonly attribute unsigned long long id;
|
readonly attribute unsigned long long id;
|
||||||
|
|
||||||
readonly attribute BrowsingContext? opener;
|
readonly attribute BrowsingContext? opener;
|
||||||
|
@ -41,6 +43,8 @@ interface CanonicalBrowsingContext : BrowsingContext {
|
||||||
[Throws]
|
[Throws]
|
||||||
readonly attribute DOMString? currentRemoteType;
|
readonly attribute DOMString? currentRemoteType;
|
||||||
|
|
||||||
|
readonly attribute WindowGlobalParent? embedderWindowGlobal;
|
||||||
|
|
||||||
void notifyStartDelayedAutoplayMedia();
|
void notifyStartDelayedAutoplayMedia();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1148,6 +1148,8 @@ TabParent* ContentParent::CreateBrowser(const TabContext& aContext,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
aBrowsingContext->SetEmbedderElement(aFrameElement);
|
||||||
|
|
||||||
// Ensure that our content process is subscribed to our newly created
|
// Ensure that our content process is subscribed to our newly created
|
||||||
// BrowsingContextGroup.
|
// BrowsingContextGroup.
|
||||||
aBrowsingContext->Group()->EnsureSubscribed(constructorSender);
|
aBrowsingContext->Group()->EnsureSubscribed(constructorSender);
|
||||||
|
|
|
@ -36,6 +36,10 @@ parent:
|
||||||
/// Notify the parent that this PWindowGlobal is now the current global.
|
/// Notify the parent that this PWindowGlobal is now the current global.
|
||||||
async BecomeCurrentWindowGlobal();
|
async BecomeCurrentWindowGlobal();
|
||||||
|
|
||||||
|
/// Notify the parent that this PWindowGlobal has embedded the given
|
||||||
|
/// BrowsingContext.
|
||||||
|
async DidEmbedBrowsingContext(BrowsingContext aContext);
|
||||||
|
|
||||||
async Destroy();
|
async Destroy();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -334,6 +334,21 @@ void TabParent::SetOwnerElement(Element* aElement) {
|
||||||
if (mRenderFrame.IsInitialized()) {
|
if (mRenderFrame.IsInitialized()) {
|
||||||
mRenderFrame.OwnerContentChanged();
|
mRenderFrame.OwnerContentChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set our BrowsingContext's embedder if we're not embedded within a
|
||||||
|
// BrowserBridgeParent.
|
||||||
|
if (!GetBrowserBridgeParent() && mBrowsingContext) {
|
||||||
|
mBrowsingContext->SetEmbedderElement(mFrameElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure all TabParent actors within BrowserBridges are also updated.
|
||||||
|
const auto& browserBridges = ManagedPBrowserBridgeParent();
|
||||||
|
for (auto iter = browserBridges.ConstIter(); !iter.Done(); iter.Next()) {
|
||||||
|
BrowserBridgeParent* browserBridge =
|
||||||
|
static_cast<BrowserBridgeParent*>(iter.Get()->GetKey());
|
||||||
|
|
||||||
|
browserBridge->GetTabParent()->SetOwnerElement(aElement);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP TabParent::GetOwnerElement(Element** aElement) {
|
NS_IMETHODIMP TabParent::GetOwnerElement(Element** aElement) {
|
||||||
|
|
|
@ -87,6 +87,12 @@ void WindowGlobalParent::Init(const WindowGlobalInit& aInit) {
|
||||||
// Attach ourself to the browsing context.
|
// Attach ourself to the browsing context.
|
||||||
mBrowsingContext->RegisterWindowGlobal(this);
|
mBrowsingContext->RegisterWindowGlobal(this);
|
||||||
|
|
||||||
|
// If there is no current window global, assume we're about to become it
|
||||||
|
// optimistically.
|
||||||
|
if (!mBrowsingContext->GetCurrentWindowGlobal()) {
|
||||||
|
mBrowsingContext->SetCurrentWindowGlobal(this);
|
||||||
|
}
|
||||||
|
|
||||||
// Determine what toplevel frame element our WindowGlobalParent is being
|
// Determine what toplevel frame element our WindowGlobalParent is being
|
||||||
// embedded in.
|
// embedded in.
|
||||||
RefPtr<Element> frameElement;
|
RefPtr<Element> frameElement;
|
||||||
|
@ -252,6 +258,13 @@ bool WindowGlobalParent::IsCurrentGlobal() {
|
||||||
return !mIPCClosed && mBrowsingContext->GetCurrentWindowGlobal() == this;
|
return !mIPCClosed && mBrowsingContext->GetCurrentWindowGlobal() == this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IPCResult WindowGlobalParent::RecvDidEmbedBrowsingContext(
|
||||||
|
dom::BrowsingContext* aContext) {
|
||||||
|
MOZ_ASSERT(aContext);
|
||||||
|
aContext->Canonical()->SetEmbedderWindowGlobal(this);
|
||||||
|
return IPC_OK();
|
||||||
|
}
|
||||||
|
|
||||||
void WindowGlobalParent::ActorDestroy(ActorDestroyReason aWhy) {
|
void WindowGlobalParent::ActorDestroy(ActorDestroyReason aWhy) {
|
||||||
mIPCClosed = true;
|
mIPCClosed = true;
|
||||||
gWindowGlobalParentsById->Remove(mInnerWindowId);
|
gWindowGlobalParentsById->Remove(mInnerWindowId);
|
||||||
|
|
|
@ -111,6 +111,8 @@ class WindowGlobalParent final : public nsISupports,
|
||||||
mozilla::ipc::IPCResult RecvAsyncMessage(const nsString& aActorName,
|
mozilla::ipc::IPCResult RecvAsyncMessage(const nsString& aActorName,
|
||||||
const nsString& aMessageName,
|
const nsString& aMessageName,
|
||||||
const ClonedMessageData& aData);
|
const ClonedMessageData& aData);
|
||||||
|
mozilla::ipc::IPCResult RecvDidEmbedBrowsingContext(
|
||||||
|
dom::BrowsingContext* aContext);
|
||||||
|
|
||||||
void ActorDestroy(ActorDestroyReason aWhy) override;
|
void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче