Bug 1700051: part 35) Reduce accessibility of `mSoftText.mDOMMapping` to `private...
[gecko.git] / dom / base / InProcessBrowserChildMessageManager.cpp
blob1d5d8feac9c8f21bf257e9bd40e0530b63b76d96
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "InProcessBrowserChildMessageManager.h"
8 #include "nsContentUtils.h"
9 #include "nsDocShell.h"
10 #include "nsIInterfaceRequestorUtils.h"
11 #include "nsComponentManagerUtils.h"
12 #include "nsFrameLoader.h"
13 #include "nsFrameLoaderOwner.h"
14 #include "nsQueryObject.h"
15 #include "xpcpublic.h"
16 #include "nsIMozBrowserFrame.h"
17 #include "mozilla/EventDispatcher.h"
18 #include "mozilla/dom/ChromeMessageSender.h"
19 #include "mozilla/dom/Document.h"
20 #include "mozilla/dom/MessageManagerBinding.h"
21 #include "mozilla/dom/SameProcessMessageQueue.h"
22 #include "mozilla/dom/ScriptLoader.h"
23 #include "mozilla/dom/WindowProxyHolder.h"
24 #include "mozilla/dom/JSActorService.h"
25 #include "mozilla/HoldDropJSObjects.h"
27 using namespace mozilla;
28 using namespace mozilla::dom;
29 using namespace mozilla::dom::ipc;
31 /* static */
32 already_AddRefed<InProcessBrowserChildMessageManager>
33 InProcessBrowserChildMessageManager::Create(nsDocShell* aShell,
34 nsIContent* aOwner,
35 nsFrameMessageManager* aChrome) {
36 RefPtr<InProcessBrowserChildMessageManager> mm =
37 new InProcessBrowserChildMessageManager(aShell, aOwner, aChrome);
39 NS_ENSURE_TRUE(mm->Init(), nullptr);
41 if (XRE_IsParentProcess()) {
42 RefPtr<JSActorService> wasvc = JSActorService::GetSingleton();
43 wasvc->RegisterChromeEventTarget(mm);
46 return mm.forget();
49 bool InProcessBrowserChildMessageManager::DoSendBlockingMessage(
50 const nsAString& aMessage, StructuredCloneData& aData,
51 nsTArray<StructuredCloneData>* aRetVal) {
52 SameProcessMessageQueue* queue = SameProcessMessageQueue::Get();
53 queue->Flush();
55 if (mChromeMessageManager) {
56 RefPtr<nsFrameMessageManager> mm = mChromeMessageManager;
57 RefPtr<nsFrameLoader> fl = GetFrameLoader();
58 mm->ReceiveMessage(mOwner, fl, aMessage, true, &aData, aRetVal,
59 IgnoreErrors());
61 return true;
64 class nsAsyncMessageToParent : public nsSameProcessAsyncMessageBase,
65 public SameProcessMessageQueue::Runnable {
66 public:
67 explicit nsAsyncMessageToParent(
68 InProcessBrowserChildMessageManager* aBrowserChild)
69 : nsSameProcessAsyncMessageBase(), mBrowserChild(aBrowserChild) {}
71 virtual nsresult HandleMessage() override {
72 RefPtr<nsFrameLoader> fl = mBrowserChild->GetFrameLoader();
73 ReceiveMessage(mBrowserChild->mOwner, fl,
74 mBrowserChild->mChromeMessageManager);
75 return NS_OK;
77 RefPtr<InProcessBrowserChildMessageManager> mBrowserChild;
80 nsresult InProcessBrowserChildMessageManager::DoSendAsyncMessage(
81 const nsAString& aMessage, StructuredCloneData& aData) {
82 SameProcessMessageQueue* queue = SameProcessMessageQueue::Get();
83 RefPtr<nsAsyncMessageToParent> ev = new nsAsyncMessageToParent(this);
85 nsresult rv = ev->Init(aMessage, aData);
86 if (NS_FAILED(rv)) {
87 return rv;
90 queue->Push(ev);
91 return NS_OK;
94 InProcessBrowserChildMessageManager::InProcessBrowserChildMessageManager(
95 nsDocShell* aShell, nsIContent* aOwner, nsFrameMessageManager* aChrome)
96 : ContentFrameMessageManager(new nsFrameMessageManager(this)),
97 mDocShell(aShell),
98 mLoadingScript(false),
99 mPreventEventsEscaping(false),
100 mOwner(aOwner),
101 mChromeMessageManager(aChrome) {
102 mozilla::HoldJSObjects(this);
104 // If owner corresponds to an <iframe mozbrowser>, we'll have to tweak our
105 // GetEventTargetParent implementation.
106 nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(mOwner);
107 if (browserFrame) {
108 mIsBrowserFrame = browserFrame->GetReallyIsBrowser();
109 } else {
110 mIsBrowserFrame = false;
114 InProcessBrowserChildMessageManager::~InProcessBrowserChildMessageManager() {
115 if (XRE_IsParentProcess()) {
116 JSActorService::UnregisterChromeEventTarget(this);
119 mAnonymousGlobalScopes.Clear();
120 mozilla::DropJSObjects(this);
123 // This method isn't automatically forwarded safely because it's notxpcom, so
124 // the IDL binding doesn't know what value to return.
125 void InProcessBrowserChildMessageManager::MarkForCC() {
126 MarkScopesForCC();
127 MessageManagerGlobal::MarkForCC();
130 NS_IMPL_CYCLE_COLLECTION_CLASS(InProcessBrowserChildMessageManager)
132 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(
133 InProcessBrowserChildMessageManager, DOMEventTargetHelper)
134 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMessageManager)
135 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocShell)
136 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
138 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(
139 InProcessBrowserChildMessageManager, DOMEventTargetHelper)
140 tmp->nsMessageManagerScriptExecutor::Trace(aCallbacks, aClosure);
141 NS_IMPL_CYCLE_COLLECTION_TRACE_END
143 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(
144 InProcessBrowserChildMessageManager, DOMEventTargetHelper)
145 if (XRE_IsParentProcess()) {
146 JSActorService::UnregisterChromeEventTarget(tmp);
149 NS_IMPL_CYCLE_COLLECTION_UNLINK(mMessageManager)
150 NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocShell)
151 tmp->nsMessageManagerScriptExecutor::Unlink();
152 NS_IMPL_CYCLE_COLLECTION_UNLINK_WEAK_REFERENCE
153 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
155 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(InProcessBrowserChildMessageManager)
156 NS_INTERFACE_MAP_ENTRY(nsIMessageSender)
157 NS_INTERFACE_MAP_ENTRY(nsIInProcessContentFrameMessageManager)
158 NS_INTERFACE_MAP_ENTRY(ContentFrameMessageManager)
159 NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
160 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
162 NS_IMPL_ADDREF_INHERITED(InProcessBrowserChildMessageManager,
163 DOMEventTargetHelper)
164 NS_IMPL_RELEASE_INHERITED(InProcessBrowserChildMessageManager,
165 DOMEventTargetHelper)
167 JSObject* InProcessBrowserChildMessageManager::WrapObject(
168 JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
169 return ContentFrameMessageManager_Binding::Wrap(aCx, this, aGivenProto);
172 void InProcessBrowserChildMessageManager::CacheFrameLoader(
173 nsFrameLoader* aFrameLoader) {
174 mFrameLoader = aFrameLoader;
177 Nullable<WindowProxyHolder> InProcessBrowserChildMessageManager::GetContent(
178 ErrorResult& aError) {
179 if (!mDocShell) {
180 return nullptr;
182 return WindowProxyHolder(mDocShell->GetBrowsingContext());
185 already_AddRefed<nsIEventTarget>
186 InProcessBrowserChildMessageManager::GetTabEventTarget() {
187 nsCOMPtr<nsIEventTarget> target = GetMainThreadEventTarget();
188 return target.forget();
191 void InProcessBrowserChildMessageManager::FireUnloadEvent() {
192 // We're called from Document::MaybeInitializeFinalizeFrameLoaders, so it
193 // should be safe to run script.
194 MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
196 // Don't let the unload event propagate to chrome event handlers.
197 mPreventEventsEscaping = true;
198 DOMEventTargetHelper::DispatchTrustedEvent(u"unload"_ns);
200 // Allow events fired during docshell destruction (pagehide, unload) to
201 // propagate to the <browser> element since chrome code depends on this.
202 mPreventEventsEscaping = false;
205 void InProcessBrowserChildMessageManager::DisconnectEventListeners() {
206 if (mDocShell) {
207 if (nsCOMPtr<nsPIDOMWindowOuter> win = mDocShell->GetWindow()) {
208 win->SetChromeEventHandler(win->GetChromeEventHandler());
211 if (mListenerManager) {
212 mListenerManager->Disconnect();
215 mDocShell = nullptr;
218 void InProcessBrowserChildMessageManager::Disconnect() {
219 mChromeMessageManager = nullptr;
220 mOwner = nullptr;
221 if (mMessageManager) {
222 static_cast<nsFrameMessageManager*>(mMessageManager.get())->Disconnect();
223 mMessageManager = nullptr;
227 NS_IMETHODIMP_(nsIContent*)
228 InProcessBrowserChildMessageManager::GetOwnerContent() { return mOwner; }
230 void InProcessBrowserChildMessageManager::GetEventTargetParent(
231 EventChainPreVisitor& aVisitor) {
232 aVisitor.mForceContentDispatch = true;
233 aVisitor.mCanHandle = true;
235 if (mPreventEventsEscaping) {
236 aVisitor.SetParentTarget(nullptr, false);
237 return;
240 if (mIsBrowserFrame &&
241 (!mOwner || !nsContentUtils::IsInChromeDocshell(mOwner->OwnerDoc()))) {
242 if (mOwner) {
243 if (nsPIDOMWindowInner* innerWindow =
244 mOwner->OwnerDoc()->GetInnerWindow()) {
245 // 'this' is already a "chrome handler", so we consider window's
246 // parent target to be part of that same part of the event path.
247 aVisitor.SetParentTarget(innerWindow->GetParentTarget(), false);
250 } else {
251 aVisitor.SetParentTarget(mOwner, false);
255 class nsAsyncScriptLoad : public Runnable {
256 public:
257 nsAsyncScriptLoad(InProcessBrowserChildMessageManager* aBrowserChild,
258 const nsAString& aURL, bool aRunInGlobalScope)
259 : mozilla::Runnable("nsAsyncScriptLoad"),
260 mBrowserChild(aBrowserChild),
261 mURL(aURL),
262 mRunInGlobalScope(aRunInGlobalScope) {}
264 NS_IMETHOD Run() override {
265 mBrowserChild->LoadFrameScript(mURL, mRunInGlobalScope);
266 return NS_OK;
268 RefPtr<InProcessBrowserChildMessageManager> mBrowserChild;
269 nsString mURL;
270 bool mRunInGlobalScope;
273 void InProcessBrowserChildMessageManager::LoadFrameScript(
274 const nsAString& aURL, bool aRunInGlobalScope) {
275 if (!nsContentUtils::IsSafeToRunScript()) {
276 nsContentUtils::AddScriptRunner(
277 new nsAsyncScriptLoad(this, aURL, aRunInGlobalScope));
278 return;
280 bool tmp = mLoadingScript;
281 mLoadingScript = true;
282 JS::Rooted<JSObject*> mm(mozilla::dom::RootingCx(), GetOrCreateWrapper());
283 LoadScriptInternal(mm, aURL, !aRunInGlobalScope);
284 mLoadingScript = tmp;
287 already_AddRefed<nsFrameLoader>
288 InProcessBrowserChildMessageManager::GetFrameLoader() {
289 RefPtr<nsFrameLoaderOwner> owner = do_QueryObject(mOwner);
290 RefPtr<nsFrameLoader> fl = owner ? owner->GetFrameLoader() : nullptr;
291 if (!fl) {
292 fl = mFrameLoader;
294 return fl.forget();