Bug 1479569 part 1. Add a ContentFrameMessageManager getter on nsIDocShell. r=kmag

This commit is contained in:
Boris Zbarsky 2018-08-02 23:49:09 -04:00
Родитель 088ecf7be1
Коммит 0bfdfe4699
11 изменённых файлов: 87 добавлений и 52 удалений

Просмотреть файл

@ -39,6 +39,7 @@
#include "mozilla/dom/ClientManager.h"
#include "mozilla/dom/ClientSource.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/ContentFrameMessageManager.h"
#include "mozilla/dom/DocGroup.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/HTMLAnchorElement.h"
@ -639,16 +640,10 @@ nsDocShell::GetInterface(const nsIID& aIID, void** aSink)
*aSink = GetTabChild().take();
return *aSink ? NS_OK : NS_ERROR_FAILURE;
} else if (aIID.Equals(NS_GET_IID(nsIContentFrameMessageManager))) {
RefPtr<TabChild> tabChild = TabChild::GetFrom(this);
nsCOMPtr<nsIContentFrameMessageManager> mm;
if (tabChild) {
mm = tabChild->GetMessageManager();
} else {
if (nsPIDOMWindowOuter* win = GetWindow()) {
mm = do_QueryInterface(win->GetParentTarget());
}
}
*aSink = mm.get();
RefPtr<ContentFrameMessageManager> mm = GetMessageManager();
nsCOMPtr<nsIContentFrameMessageManager> mm2 = do_QueryObject(mm);
mm2.forget(aSink);
return *aSink ? NS_OK : NS_NOINTERFACE;
} else {
return nsDocLoader::GetInterface(aIID, aSink);
}
@ -3976,6 +3971,19 @@ nsDocShell::GetDomWindow(mozIDOMWindowProxy** aWindow)
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::GetMessageManager(ContentFrameMessageManager** aMessageManager)
{
RefPtr<ContentFrameMessageManager> mm;
if (RefPtr<TabChild> tabChild = TabChild::GetFrom(this)) {
mm = tabChild->GetMessageManager();
} else if (nsPIDOMWindowOuter* win = GetWindow()) {
mm = win->GetMessageManager();
}
mm.forget(aMessageManager);
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::SetDeviceSizeIsPageSize(bool aValue)
{

Просмотреть файл

@ -65,6 +65,7 @@ interface nsILoadURIDelegate;
native TabChildRef(already_AddRefed<nsITabChild>);
native nsDocShellLoadInfoPtr(nsDocShellLoadInfo*);
webidl ContentFrameMessageManager;
webidl EventTarget;
[scriptable, builtinclass, uuid(049234fe-da10-478b-bc5d-bc6f9a1ba63d)]
@ -1200,4 +1201,10 @@ interface nsIDocShell : nsIDocShellTreeItem
* Media queries only look at the value in the top-most docshell.
*/
attribute unsigned long displayMode;
/**
* The message manager for this docshell. This does not throw, but
* can return null if the docshell has no message manager.
*/
[infallible] readonly attribute ContentFrameMessageManager messageManager;
};

Просмотреть файл

@ -31,6 +31,7 @@
#include "mozilla/CycleCollectedJSRuntime.h"
#include "mozilla/EventListenerManager.h"
#include "mozilla/dom/ChromeMessageBroadcaster.h"
#include "mozilla/dom/ContentFrameMessageManager.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/ParentProcessMessageManager.h"
#include "mozilla/dom/ProcessGlobal.h"
@ -119,11 +120,11 @@ MarkChildMessageManagers(MessageBroadcaster* aMM)
mozilla::dom::ipc::MessageManagerCallback* cb = tabMM->GetCallback();
if (cb) {
nsFrameLoader* fl = static_cast<nsFrameLoader*>(cb);
EventTarget* et = fl->GetTabChildGlobalAsEventTarget();
nsInProcessTabChildGlobal* et = fl->GetTabChildGlobal();
if (!et) {
continue;
}
static_cast<nsInProcessTabChildGlobal*>(et)->MarkForCC();
et->MarkForCC();
EventListenerManager* elm = et->GetExistingListenerManager();
if (elm) {
elm->MarkForCC();

Просмотреть файл

@ -121,6 +121,7 @@
#include "nsHtml5StringParser.h"
#include "nsHTMLDocument.h"
#include "nsHTMLTags.h"
#include "nsInProcessTabChildGlobal.h"
#include "nsIAddonPolicyService.h"
#include "nsIAnonymousContentCreator.h"
#include "nsIAsyncVerifyRedirectCallback.h"
@ -11087,8 +11088,8 @@ nsContentUtils::ContentIsLink(nsIContent* aContent)
kNameSpaceID_XLink, nsGkAtoms::type, nsGkAtoms::simple, eCaseMatters);
}
/* static */ already_AddRefed<EventTarget>
nsContentUtils::TryGetTabChildGlobalAsEventTarget(nsISupports* aFrom)
/* static */ already_AddRefed<ContentFrameMessageManager>
nsContentUtils::TryGetTabChildGlobal(nsISupports* aFrom)
{
nsCOMPtr<nsIFrameLoaderOwner> frameLoaderOwner = do_QueryInterface(aFrom);
if (!frameLoaderOwner) {
@ -11100,8 +11101,8 @@ nsContentUtils::TryGetTabChildGlobalAsEventTarget(nsISupports* aFrom)
return nullptr;
}
nsCOMPtr<EventTarget> target = frameLoader->GetTabChildGlobalAsEventTarget();
return target.forget();
RefPtr<ContentFrameMessageManager> manager = frameLoader->GetTabChildGlobal();
return manager.forget();
}
/* static */ uint32_t

Просмотреть файл

@ -124,6 +124,7 @@ class EventListenerManager;
class HTMLEditor;
namespace dom {
class ContentFrameMessageManager;
struct CustomElementDefinition;
class DocumentFragment;
class Element;
@ -3242,8 +3243,8 @@ public:
static bool ContentIsLink(nsIContent* aContent);
static already_AddRefed<mozilla::dom::EventTarget>
TryGetTabChildGlobalAsEventTarget(nsISupports* aFrom);
static already_AddRefed<mozilla::dom::ContentFrameMessageManager>
TryGetTabChildGlobal(nsISupports* aFrom);
static PopupControlState
PushPopupControlState(PopupControlState aState, bool aForce)

Просмотреть файл

@ -2820,8 +2820,7 @@ nsFrameLoader::DoLoadMessageManagerScript(const nsAString& aURL, bool aRunInGlob
if (tabParent) {
return tabParent->SendLoadRemoteScript(nsString(aURL), aRunInGlobalScope);
}
RefPtr<nsInProcessTabChildGlobal> tabChild =
static_cast<nsInProcessTabChildGlobal*>(GetTabChildGlobalAsEventTarget());
RefPtr<nsInProcessTabChildGlobal> tabChild = GetTabChildGlobal();
if (tabChild) {
tabChild->LoadFrameScript(aURL, aRunInGlobalScope);
}
@ -2979,12 +2978,6 @@ nsFrameLoader::ReallyLoadFrameScripts()
return NS_OK;
}
EventTarget*
nsFrameLoader::GetTabChildGlobalAsEventTarget()
{
return mChildMessageManager.get();
}
already_AddRefed<Element>
nsFrameLoader::GetOwnerElement()
{

Просмотреть файл

@ -106,7 +106,10 @@ public:
void DestroyDocShell();
void DestroyComplete();
nsIDocShell* GetExistingDocShell() { return mDocShell; }
mozilla::dom::EventTarget* GetTabChildGlobalAsEventTarget();
nsInProcessTabChildGlobal* GetTabChildGlobal() const
{
return mChildMessageManager;
}
nsresult CreateStaticClone(nsFrameLoader* aDest);
nsresult UpdatePositionAndSize(nsSubDocumentFrame *aIFrame);

Просмотреть файл

@ -18,6 +18,7 @@
#include "nsDOMNavigationTiming.h"
#include "nsIDOMStorageManager.h"
#include "mozilla/AutoplayPermissionManager.h"
#include "mozilla/dom/ContentFrameMessageManager.h"
#include "mozilla/dom/DOMJSProxyHandler.h"
#include "mozilla/dom/DOMPrefs.h"
#include "mozilla/dom/EventTarget.h"
@ -1910,20 +1911,18 @@ nsGlobalWindowInner::UpdateParentTarget()
nsCOMPtr<Element> frameElement = GetOuterWindow()->GetFrameElementInternal();
nsCOMPtr<EventTarget> eventTarget =
nsContentUtils::TryGetTabChildGlobalAsEventTarget(frameElement);
nsContentUtils::TryGetTabChildGlobal(frameElement);
if (!eventTarget) {
nsGlobalWindowOuter* topWin = GetScriptableTopInternal();
if (topWin) {
frameElement = topWin->AsOuter()->GetFrameElementInternal();
eventTarget =
nsContentUtils::TryGetTabChildGlobalAsEventTarget(frameElement);
eventTarget = nsContentUtils::TryGetTabChildGlobal(frameElement);
}
}
if (!eventTarget) {
eventTarget =
nsContentUtils::TryGetTabChildGlobalAsEventTarget(mChromeEventHandler);
eventTarget = nsContentUtils::TryGetTabChildGlobal(mChromeEventHandler);
}
if (!eventTarget) {

Просмотреть файл

@ -20,6 +20,7 @@
#include "nsISecureBrowserUI.h"
#include "nsIWebProgressListener.h"
#include "mozilla/AntiTrackingCommon.h"
#include "mozilla/dom/ContentFrameMessageManager.h"
#include "mozilla/dom/EventTarget.h"
#include "mozilla/dom/LocalStorage.h"
#include "mozilla/dom/Storage.h"
@ -1038,6 +1039,7 @@ nsGlobalWindowOuter::CleanUp()
}
mChromeEventHandler = nullptr; // Forces Release
mParentTarget = nullptr;
mMessageManager = nullptr;
mArguments = nullptr;
@ -1144,6 +1146,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGlobalWindowOuter)
// Traverse stuff from nsPIDOMWindow
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChromeEventHandler)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParentTarget)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMessageManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFrameElement)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOpenerForInitialContentBrowser)
@ -1170,6 +1173,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalWindowOuter)
// Unlink stuff from nsPIDOMWindow
NS_IMPL_CYCLE_COLLECTION_UNLINK(mChromeEventHandler)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mParentTarget)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mMessageManager)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFrameElement)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOpenerForInitialContentBrowser)
@ -2236,9 +2240,10 @@ nsGlobalWindowOuter::SetOpenerWindow(nsPIDOMWindowOuter* aOpener,
void
nsGlobalWindowOuter::UpdateParentTarget()
{
// NOTE: This method is identical to
// NOTE: This method is nearly identical to
// nsGlobalWindowInner::UpdateParentTarget(). IF YOU UPDATE THIS METHOD,
// UPDATE THE OTHER ONE TOO!
// UPDATE THE OTHER ONE TOO! The one difference is that this method updates
// mMessageManager as well, which inner windows don't have.
// 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
@ -2246,28 +2251,25 @@ nsGlobalWindowOuter::UpdateParentTarget()
// handler itself.
nsCOMPtr<Element> frameElement = GetOuterWindow()->GetFrameElementInternal();
nsCOMPtr<EventTarget> eventTarget =
nsContentUtils::TryGetTabChildGlobalAsEventTarget(frameElement);
mMessageManager = nsContentUtils::TryGetTabChildGlobal(frameElement);
if (!eventTarget) {
if (!mMessageManager) {
nsGlobalWindowOuter* topWin = GetScriptableTopInternal();
if (topWin) {
frameElement = topWin->GetFrameElementInternal();
eventTarget =
nsContentUtils::TryGetTabChildGlobalAsEventTarget(frameElement);
mMessageManager = nsContentUtils::TryGetTabChildGlobal(frameElement);
}
}
if (!eventTarget) {
eventTarget =
nsContentUtils::TryGetTabChildGlobalAsEventTarget(mChromeEventHandler);
if (!mMessageManager) {
mMessageManager = nsContentUtils::TryGetTabChildGlobal(mChromeEventHandler);
}
if (!eventTarget) {
eventTarget = mChromeEventHandler;
if (mMessageManager) {
mParentTarget = mMessageManager;
} else {
mParentTarget = mChromeEventHandler;
}
mParentTarget = eventTarget;
}
EventTarget*
@ -7627,6 +7629,19 @@ nsPIDOMWindowOuter::MaybeCreateDoc()
}
}
void
nsPIDOMWindowOuter::SetChromeEventHandlerInternal(EventTarget* aChromeEventHandler)
{
// Out-of-line so we don't need to include ContentFrameMessageManager.h in
// nsPIDOMWindow.h.
mChromeEventHandler = aChromeEventHandler;
// mParentTarget and mMessageManager will be set when the next event is
// dispatched or someone asks for our message manager.
mParentTarget = nullptr;
mMessageManager = nullptr;
}
mozilla::dom::DocGroup*
nsPIDOMWindowOuter::GetDocGroup() const
{

Просмотреть файл

@ -295,7 +295,7 @@ nsInProcessTabChildGlobal::GetEventTargetParent(EventChainPreVisitor& aVisitor)
nsCOMPtr<nsIFrameLoaderOwner> owner = do_QueryInterface(mOwner);
RefPtr<nsFrameLoader> fl = owner->GetFrameLoader();
if (fl) {
NS_ASSERTION(this == fl->GetTabChildGlobalAsEventTarget(),
NS_ASSERTION(this == fl->GetTabChildGlobal(),
"Wrong event target!");
NS_ASSERTION(fl->mMessageManager == mChromeMessageManager,
"Wrong message manager!");

Просмотреть файл

@ -51,6 +51,7 @@ namespace dom {
class AudioContext;
class ClientInfo;
class ClientState;
class ContentFrameMessageManager;
class DocGroup;
class TabGroup;
class Element;
@ -872,6 +873,15 @@ public:
return mParentTarget;
}
mozilla::dom::ContentFrameMessageManager* GetMessageManager()
{
// We maintain our mMessageManager state alongside mParentTarget.
if (!mParentTarget) {
UpdateParentTarget();
}
return mMessageManager;
}
nsIDocument* GetExtantDoc() const
{
return mDoc;
@ -1160,11 +1170,7 @@ protected:
// we have what it takes to do so.
void MaybeCreateDoc();
void SetChromeEventHandlerInternal(mozilla::dom::EventTarget* aChromeEventHandler) {
mChromeEventHandler = aChromeEventHandler;
// mParentTarget will be set when the next event is dispatched.
mParentTarget = nullptr;
}
void SetChromeEventHandlerInternal(mozilla::dom::EventTarget* aChromeEventHandler);
virtual void UpdateParentTarget() = 0;
@ -1177,6 +1183,7 @@ protected:
nsCOMPtr<nsIURI> mDocumentURI; // strong
nsCOMPtr<mozilla::dom::EventTarget> mParentTarget; // strong
RefPtr<mozilla::dom::ContentFrameMessageManager> mMessageManager; // strong
nsCOMPtr<mozilla::dom::Element> mFrameElement;