Bug 1936278 - Prevent search mode chiclet from being dismissed when clicking in page...
[gecko.git] / dom / ipc / BrowserBridgeChild.cpp
blob3a2f7d8f84c5289941a56f82e2e0414312a8378d
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 #ifdef ACCESSIBILITY
8 # include "mozilla/a11y/DocAccessible.h"
9 # include "mozilla/a11y/DocManager.h"
10 # include "mozilla/a11y/OuterDocAccessible.h"
11 #endif
12 #include "mozilla/dom/BrowserBridgeChild.h"
13 #include "mozilla/dom/BrowserBridgeHost.h"
14 #include "mozilla/dom/BrowsingContext.h"
15 #include "mozilla/dom/MozFrameLoaderOwnerBinding.h"
16 #include "mozilla/PresShell.h"
17 #include "nsFocusManager.h"
18 #include "nsFrameLoader.h"
19 #include "nsFrameLoaderOwner.h"
20 #include "nsObjectLoadingContent.h"
21 #include "nsQueryObject.h"
22 #include "nsSubDocumentFrame.h"
23 #include "nsView.h"
25 using namespace mozilla::ipc;
27 mozilla::LazyLogModule gBrowserChildFocusLog("BrowserChildFocus");
29 #define LOGBROWSERCHILDFOCUS(args) \
30 MOZ_LOG(gBrowserChildFocusLog, mozilla::LogLevel::Debug, args)
32 namespace mozilla::dom {
34 BrowserBridgeChild::BrowserBridgeChild(BrowsingContext* aBrowsingContext,
35 TabId aId, const LayersId& aLayersId)
36 : mId{aId}, mLayersId{aLayersId}, mBrowsingContext(aBrowsingContext) {}
38 BrowserBridgeChild::~BrowserBridgeChild() {}
40 already_AddRefed<BrowserBridgeHost> BrowserBridgeChild::FinishInit(
41 nsFrameLoader* aFrameLoader) {
42 MOZ_DIAGNOSTIC_ASSERT(!mFrameLoader);
43 mFrameLoader = aFrameLoader;
45 RefPtr<Element> owner = mFrameLoader->GetOwnerContent();
46 Document* doc = owner->OwnerDoc();
47 doc->OOPChildLoadStarted(this);
49 #if defined(ACCESSIBILITY)
50 if (a11y::DocAccessible* docAcc = a11y::GetExistingDocAccessible(doc)) {
51 if (a11y::LocalAccessible* ownerAcc = docAcc->GetAccessible(owner)) {
52 if (a11y::OuterDocAccessible* outerAcc = ownerAcc->AsOuterDoc()) {
53 outerAcc->SendEmbedderAccessible(this);
57 #endif // defined(ACCESSIBILITY)
59 return MakeAndAddRef<BrowserBridgeHost>(this);
62 nsILoadContext* BrowserBridgeChild::GetLoadContext() {
63 return mBrowsingContext;
66 void BrowserBridgeChild::NavigateByKey(bool aForward,
67 bool aForDocumentNavigation) {
68 Unused << SendNavigateByKey(aForward, aForDocumentNavigation);
71 void BrowserBridgeChild::Activate(uint64_t aActionId) {
72 LOGBROWSERCHILDFOCUS(
73 ("BrowserBridgeChild::Activate actionid: %" PRIu64, aActionId));
74 Unused << SendActivate(aActionId);
77 void BrowserBridgeChild::Deactivate(bool aWindowLowering, uint64_t aActionId) {
78 Unused << SendDeactivate(aWindowLowering, aActionId);
81 /*static*/
82 BrowserBridgeChild* BrowserBridgeChild::GetFrom(nsFrameLoader* aFrameLoader) {
83 if (!aFrameLoader) {
84 return nullptr;
86 return aFrameLoader->GetBrowserBridgeChild();
89 /*static*/
90 BrowserBridgeChild* BrowserBridgeChild::GetFrom(nsIContent* aContent) {
91 RefPtr<nsFrameLoaderOwner> loaderOwner = do_QueryObject(aContent);
92 if (!loaderOwner) {
93 return nullptr;
95 RefPtr<nsFrameLoader> frameLoader = loaderOwner->GetFrameLoader();
96 return GetFrom(frameLoader);
99 mozilla::ipc::IPCResult BrowserBridgeChild::RecvRequestFocus(
100 const bool& aCanRaise, const CallerType aCallerType) {
101 // Adapted from BrowserParent
102 RefPtr<Element> owner = mFrameLoader->GetOwnerContent();
103 if (!owner) {
104 return IPC_OK();
106 nsContentUtils::RequestFrameFocus(*owner, aCanRaise, aCallerType);
107 return IPC_OK();
110 mozilla::ipc::IPCResult BrowserBridgeChild::RecvMoveFocus(
111 const bool& aForward, const bool& aForDocumentNavigation) {
112 // Adapted from BrowserParent
113 RefPtr<nsFocusManager> fm = nsFocusManager::GetFocusManager();
114 if (!fm) {
115 return IPC_OK();
118 RefPtr<Element> owner = mFrameLoader->GetOwnerContent();
119 if (!owner) {
120 return IPC_OK();
123 RefPtr<Element> dummy;
125 uint32_t type =
126 aForward
127 ? (aForDocumentNavigation
128 ? static_cast<uint32_t>(nsIFocusManager::MOVEFOCUS_FORWARDDOC)
129 : static_cast<uint32_t>(nsIFocusManager::MOVEFOCUS_FORWARD))
130 : (aForDocumentNavigation
131 ? static_cast<uint32_t>(nsIFocusManager::MOVEFOCUS_BACKWARDDOC)
132 : static_cast<uint32_t>(nsIFocusManager::MOVEFOCUS_BACKWARD));
133 fm->MoveFocus(nullptr, owner, type, nsIFocusManager::FLAG_BYKEY,
134 getter_AddRefs(dummy));
135 return IPC_OK();
138 mozilla::ipc::IPCResult BrowserBridgeChild::RecvMaybeFireEmbedderLoadEvents(
139 EmbedderElementEventType aFireEventAtEmbeddingElement) {
140 RefPtr<Element> owner = mFrameLoader->GetOwnerContent();
141 if (!owner) {
142 return IPC_OK();
145 if (aFireEventAtEmbeddingElement == EmbedderElementEventType::LoadEvent) {
146 nsEventStatus status = nsEventStatus_eIgnore;
147 WidgetEvent event(/* aIsTrusted = */ true, eLoad);
148 event.mFlags.mBubbles = false;
149 event.mFlags.mCancelable = false;
150 EventDispatcher::Dispatch(owner, nullptr, &event, nullptr, &status);
151 } else if (aFireEventAtEmbeddingElement ==
152 EmbedderElementEventType::ErrorEvent) {
153 mFrameLoader->FireErrorEvent();
156 UnblockOwnerDocsLoadEvent();
158 return IPC_OK();
161 mozilla::ipc::IPCResult BrowserBridgeChild::RecvScrollRectIntoView(
162 const nsRect& aRect, const ScrollAxis& aVertical,
163 const ScrollAxis& aHorizontal, const ScrollFlags& aScrollFlags,
164 const int32_t& aAppUnitsPerDevPixel) {
165 RefPtr<Element> owner = mFrameLoader->GetOwnerContent();
166 if (!owner) {
167 return IPC_OK();
170 nsIFrame* frame = owner->GetPrimaryFrame();
171 if (!frame) {
172 return IPC_OK();
175 nsSubDocumentFrame* subdocumentFrame = do_QueryFrame(frame);
176 if (!subdocumentFrame) {
177 return IPC_OK();
180 nsPoint extraOffset = subdocumentFrame->GetExtraOffset();
182 int32_t parentAPD = frame->PresContext()->AppUnitsPerDevPixel();
183 nsRect rect =
184 aRect.ScaleToOtherAppUnitsRoundOut(aAppUnitsPerDevPixel, parentAPD);
185 rect += extraOffset;
186 RefPtr<PresShell> presShell = frame->PresShell();
187 presShell->ScrollFrameIntoView(frame, Some(rect), aVertical, aHorizontal,
188 aScrollFlags);
189 return IPC_OK();
192 mozilla::ipc::IPCResult BrowserBridgeChild::RecvSubFrameCrashed() {
193 if (RefPtr<nsFrameLoaderOwner> frameLoaderOwner =
194 do_QueryObject(mFrameLoader->GetOwnerContent())) {
195 frameLoaderOwner->SubframeCrashed();
197 return IPC_OK();
200 void BrowserBridgeChild::ActorDestroy(ActorDestroyReason aWhy) {
201 if (mFrameLoader) {
202 mFrameLoader->DestroyComplete();
205 if (!mBrowsingContext) {
206 // This BBC was never valid, skip teardown.
207 return;
210 // Ensure we unblock our document's 'load' event (in case the OOP-iframe has
211 // been removed before it finished loading, or its subprocess crashed):
212 UnblockOwnerDocsLoadEvent();
215 void BrowserBridgeChild::UnblockOwnerDocsLoadEvent() {
216 if (!mHadInitialLoad) {
217 mHadInitialLoad = true;
219 if (Document* doc = mBrowsingContext->GetParent()->GetExtantDocument()) {
220 doc->OOPChildLoadDone(this);
225 mozilla::ipc::IPCResult BrowserBridgeChild::RecvIntrinsicSizeOrRatioChanged(
226 const Maybe<IntrinsicSize>& aIntrinsicSize,
227 const Maybe<AspectRatio>& aIntrinsicRatio) {
228 if (RefPtr<Element> owner = mFrameLoader->GetOwnerContent()) {
229 if (nsCOMPtr<nsIObjectLoadingContent> olc = do_QueryInterface(owner)) {
230 static_cast<nsObjectLoadingContent*>(olc.get())
231 ->SubdocumentIntrinsicSizeOrRatioChanged(aIntrinsicSize,
232 aIntrinsicRatio);
235 return IPC_OK();
238 mozilla::ipc::IPCResult BrowserBridgeChild::RecvImageLoadComplete(
239 const nsresult& aResult) {
240 if (RefPtr<Element> owner = mFrameLoader->GetOwnerContent()) {
241 if (nsCOMPtr<nsIObjectLoadingContent> olc = do_QueryInterface(owner)) {
242 static_cast<nsObjectLoadingContent*>(olc.get())
243 ->SubdocumentImageLoadComplete(aResult);
246 return IPC_OK();
249 } // namespace mozilla::dom