BrowserBridgeChild.cpp (8026B)
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/. */ 6 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/PresShell.h" 13 #include "mozilla/dom/BrowserBridgeChild.h" 14 #include "mozilla/dom/BrowserBridgeHost.h" 15 #include "mozilla/dom/BrowsingContext.h" 16 #include "mozilla/dom/MozFrameLoaderOwnerBinding.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 24 using namespace mozilla::ipc; 25 26 mozilla::LazyLogModule gBrowserChildFocusLog("BrowserChildFocus"); 27 28 #define LOGBROWSERCHILDFOCUS(args) \ 29 MOZ_LOG(gBrowserChildFocusLog, mozilla::LogLevel::Debug, args) 30 31 namespace mozilla::dom { 32 33 BrowserBridgeChild::BrowserBridgeChild(BrowsingContext* aBrowsingContext, 34 TabId aId, const LayersId& aLayersId) 35 : mId{aId}, mLayersId{aLayersId}, mBrowsingContext(aBrowsingContext) {} 36 37 BrowserBridgeChild::~BrowserBridgeChild() {} 38 39 already_AddRefed<BrowserBridgeHost> BrowserBridgeChild::FinishInit( 40 nsFrameLoader* aFrameLoader) { 41 MOZ_DIAGNOSTIC_ASSERT(!mFrameLoader); 42 mFrameLoader = aFrameLoader; 43 44 RefPtr<Element> owner = mFrameLoader->GetOwnerContent(); 45 Document* doc = owner->OwnerDoc(); 46 doc->OOPChildLoadStarted(this); 47 48 #if defined(ACCESSIBILITY) 49 if (a11y::DocAccessible* docAcc = a11y::GetExistingDocAccessible(doc)) { 50 if (a11y::LocalAccessible* ownerAcc = docAcc->GetAccessible(owner)) { 51 if (a11y::OuterDocAccessible* outerAcc = ownerAcc->AsOuterDoc()) { 52 outerAcc->SendEmbedderAccessible(this); 53 } 54 } 55 } 56 #endif // defined(ACCESSIBILITY) 57 58 return MakeAndAddRef<BrowserBridgeHost>(this); 59 } 60 61 nsILoadContext* BrowserBridgeChild::GetLoadContext() { 62 return mBrowsingContext; 63 } 64 65 void BrowserBridgeChild::NavigateByKey(bool aForward, 66 bool aForDocumentNavigation) { 67 (void)SendNavigateByKey(aForward, aForDocumentNavigation); 68 } 69 70 void BrowserBridgeChild::Activate(uint64_t aActionId) { 71 LOGBROWSERCHILDFOCUS( 72 ("BrowserBridgeChild::Activate actionid: %" PRIu64, aActionId)); 73 (void)SendActivate(aActionId); 74 } 75 76 void BrowserBridgeChild::Deactivate(bool aWindowLowering, uint64_t aActionId) { 77 (void)SendDeactivate(aWindowLowering, aActionId); 78 } 79 80 /*static*/ 81 BrowserBridgeChild* BrowserBridgeChild::GetFrom(nsFrameLoader* aFrameLoader) { 82 if (!aFrameLoader) { 83 return nullptr; 84 } 85 return aFrameLoader->GetBrowserBridgeChild(); 86 } 87 88 /*static*/ 89 BrowserBridgeChild* BrowserBridgeChild::GetFrom(nsIContent* aContent) { 90 RefPtr<nsFrameLoaderOwner> loaderOwner = do_QueryObject(aContent); 91 if (!loaderOwner) { 92 return nullptr; 93 } 94 RefPtr<nsFrameLoader> frameLoader = loaderOwner->GetFrameLoader(); 95 return GetFrom(frameLoader); 96 } 97 98 mozilla::ipc::IPCResult BrowserBridgeChild::RecvRequestFocus( 99 const bool& aCanRaise, const CallerType aCallerType) { 100 // Adapted from BrowserParent 101 RefPtr<Element> owner = mFrameLoader->GetOwnerContent(); 102 if (!owner) { 103 return IPC_OK(); 104 } 105 nsContentUtils::RequestFrameFocus(*owner, aCanRaise, aCallerType); 106 return IPC_OK(); 107 } 108 109 mozilla::ipc::IPCResult BrowserBridgeChild::RecvMoveFocus( 110 const bool& aForward, const bool& aForDocumentNavigation) { 111 // Adapted from BrowserParent 112 RefPtr<nsFocusManager> fm = nsFocusManager::GetFocusManager(); 113 if (!fm) { 114 return IPC_OK(); 115 } 116 117 RefPtr<Element> owner = mFrameLoader->GetOwnerContent(); 118 if (!owner) { 119 return IPC_OK(); 120 } 121 122 RefPtr<Element> dummy; 123 124 uint32_t type = 125 aForward 126 ? (aForDocumentNavigation 127 ? static_cast<uint32_t>(nsIFocusManager::MOVEFOCUS_FORWARDDOC) 128 : static_cast<uint32_t>(nsIFocusManager::MOVEFOCUS_FORWARD)) 129 : (aForDocumentNavigation 130 ? static_cast<uint32_t>(nsIFocusManager::MOVEFOCUS_BACKWARDDOC) 131 : static_cast<uint32_t>(nsIFocusManager::MOVEFOCUS_BACKWARD)); 132 fm->MoveFocus(nullptr, owner, type, nsIFocusManager::FLAG_BYKEY, 133 getter_AddRefs(dummy)); 134 return IPC_OK(); 135 } 136 137 mozilla::ipc::IPCResult BrowserBridgeChild::RecvMaybeFireEmbedderLoadEvents( 138 EmbedderElementEventType aFireEventAtEmbeddingElement) { 139 RefPtr<Element> owner = mFrameLoader->GetOwnerContent(); 140 if (!owner) { 141 return IPC_OK(); 142 } 143 144 if (aFireEventAtEmbeddingElement == EmbedderElementEventType::LoadEvent) { 145 nsEventStatus status = nsEventStatus_eIgnore; 146 WidgetEvent event(/* aIsTrusted = */ true, eLoad); 147 event.mFlags.mBubbles = false; 148 event.mFlags.mCancelable = false; 149 EventDispatcher::Dispatch(owner, nullptr, &event, nullptr, &status); 150 } else if (aFireEventAtEmbeddingElement == 151 EmbedderElementEventType::ErrorEvent) { 152 mFrameLoader->FireErrorEvent(); 153 } 154 155 UnblockOwnerDocsLoadEvent(); 156 157 return IPC_OK(); 158 } 159 160 mozilla::ipc::IPCResult BrowserBridgeChild::RecvScrollRectIntoView( 161 const nsRect& aRect, const ScrollAxis& aVertical, 162 const ScrollAxis& aHorizontal, const ScrollFlags& aScrollFlags, 163 const int32_t& aAppUnitsPerDevPixel) { 164 RefPtr<Element> owner = mFrameLoader->GetOwnerContent(); 165 if (!owner) { 166 return IPC_OK(); 167 } 168 169 nsIFrame* frame = owner->GetPrimaryFrame(); 170 if (!frame) { 171 return IPC_OK(); 172 } 173 174 nsSubDocumentFrame* subdocumentFrame = do_QueryFrame(frame); 175 if (!subdocumentFrame) { 176 return IPC_OK(); 177 } 178 179 nsPoint extraOffset = subdocumentFrame->GetExtraOffset(); 180 181 int32_t parentAPD = frame->PresContext()->AppUnitsPerDevPixel(); 182 nsRect rect = 183 aRect.ScaleToOtherAppUnitsRoundOut(aAppUnitsPerDevPixel, parentAPD); 184 rect += extraOffset; 185 RefPtr<PresShell> presShell = frame->PresShell(); 186 presShell->ScrollFrameIntoView(frame, Some(rect), aVertical, aHorizontal, 187 aScrollFlags); 188 return IPC_OK(); 189 } 190 191 mozilla::ipc::IPCResult BrowserBridgeChild::RecvSubFrameCrashed() { 192 if (RefPtr<nsFrameLoaderOwner> frameLoaderOwner = 193 do_QueryObject(mFrameLoader->GetOwnerContent())) { 194 frameLoaderOwner->SubframeCrashed(); 195 } 196 return IPC_OK(); 197 } 198 199 void BrowserBridgeChild::ActorDestroy(ActorDestroyReason aWhy) { 200 if (mFrameLoader) { 201 mFrameLoader->DestroyComplete(); 202 } 203 204 if (!mBrowsingContext) { 205 // This BBC was never valid, skip teardown. 206 return; 207 } 208 209 // Ensure we unblock our document's 'load' event (in case the OOP-iframe has 210 // been removed before it finished loading, or its subprocess crashed): 211 UnblockOwnerDocsLoadEvent(); 212 } 213 214 void BrowserBridgeChild::UnblockOwnerDocsLoadEvent() { 215 if (!mHadInitialLoad) { 216 mHadInitialLoad = true; 217 218 if (Document* doc = mBrowsingContext->GetParent()->GetExtantDocument()) { 219 doc->OOPChildLoadDone(this); 220 } 221 } 222 } 223 224 mozilla::ipc::IPCResult BrowserBridgeChild::RecvIntrinsicSizeOrRatioChanged( 225 const Maybe<IntrinsicSize>& aIntrinsicSize, 226 const Maybe<AspectRatio>& aIntrinsicRatio) { 227 if (RefPtr<Element> owner = mFrameLoader->GetOwnerContent()) { 228 if (nsCOMPtr<nsIObjectLoadingContent> olc = do_QueryInterface(owner)) { 229 static_cast<nsObjectLoadingContent*>(olc.get()) 230 ->SubdocumentIntrinsicSizeOrRatioChanged(aIntrinsicSize, 231 aIntrinsicRatio); 232 } 233 } 234 return IPC_OK(); 235 } 236 237 mozilla::ipc::IPCResult BrowserBridgeChild::RecvImageLoadComplete( 238 const nsresult& aResult) { 239 if (RefPtr<Element> owner = mFrameLoader->GetOwnerContent()) { 240 if (nsCOMPtr<nsIObjectLoadingContent> olc = do_QueryInterface(owner)) { 241 static_cast<nsObjectLoadingContent*>(olc.get()) 242 ->SubdocumentImageLoadComplete(aResult); 243 } 244 } 245 return IPC_OK(); 246 } 247 248 } // namespace mozilla::dom