summaryrefslogtreecommitdiffstats
path: root/dom/ipc/BrowserBridgeChild.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/ipc/BrowserBridgeChild.cpp')
-rw-r--r--dom/ipc/BrowserBridgeChild.cpp249
1 files changed, 249 insertions, 0 deletions
diff --git a/dom/ipc/BrowserBridgeChild.cpp b/dom/ipc/BrowserBridgeChild.cpp
new file mode 100644
index 0000000000..3a2f7d8f84
--- /dev/null
+++ b/dom/ipc/BrowserBridgeChild.cpp
@@ -0,0 +1,249 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifdef ACCESSIBILITY
+# include "mozilla/a11y/DocAccessible.h"
+# include "mozilla/a11y/DocManager.h"
+# include "mozilla/a11y/OuterDocAccessible.h"
+#endif
+#include "mozilla/dom/BrowserBridgeChild.h"
+#include "mozilla/dom/BrowserBridgeHost.h"
+#include "mozilla/dom/BrowsingContext.h"
+#include "mozilla/dom/MozFrameLoaderOwnerBinding.h"
+#include "mozilla/PresShell.h"
+#include "nsFocusManager.h"
+#include "nsFrameLoader.h"
+#include "nsFrameLoaderOwner.h"
+#include "nsObjectLoadingContent.h"
+#include "nsQueryObject.h"
+#include "nsSubDocumentFrame.h"
+#include "nsView.h"
+
+using namespace mozilla::ipc;
+
+mozilla::LazyLogModule gBrowserChildFocusLog("BrowserChildFocus");
+
+#define LOGBROWSERCHILDFOCUS(args) \
+ MOZ_LOG(gBrowserChildFocusLog, mozilla::LogLevel::Debug, args)
+
+namespace mozilla::dom {
+
+BrowserBridgeChild::BrowserBridgeChild(BrowsingContext* aBrowsingContext,
+ TabId aId, const LayersId& aLayersId)
+ : mId{aId}, mLayersId{aLayersId}, mBrowsingContext(aBrowsingContext) {}
+
+BrowserBridgeChild::~BrowserBridgeChild() {}
+
+already_AddRefed<BrowserBridgeHost> BrowserBridgeChild::FinishInit(
+ nsFrameLoader* aFrameLoader) {
+ MOZ_DIAGNOSTIC_ASSERT(!mFrameLoader);
+ mFrameLoader = aFrameLoader;
+
+ RefPtr<Element> owner = mFrameLoader->GetOwnerContent();
+ Document* doc = owner->OwnerDoc();
+ doc->OOPChildLoadStarted(this);
+
+#if defined(ACCESSIBILITY)
+ if (a11y::DocAccessible* docAcc = a11y::GetExistingDocAccessible(doc)) {
+ if (a11y::LocalAccessible* ownerAcc = docAcc->GetAccessible(owner)) {
+ if (a11y::OuterDocAccessible* outerAcc = ownerAcc->AsOuterDoc()) {
+ outerAcc->SendEmbedderAccessible(this);
+ }
+ }
+ }
+#endif // defined(ACCESSIBILITY)
+
+ return MakeAndAddRef<BrowserBridgeHost>(this);
+}
+
+nsILoadContext* BrowserBridgeChild::GetLoadContext() {
+ return mBrowsingContext;
+}
+
+void BrowserBridgeChild::NavigateByKey(bool aForward,
+ bool aForDocumentNavigation) {
+ Unused << SendNavigateByKey(aForward, aForDocumentNavigation);
+}
+
+void BrowserBridgeChild::Activate(uint64_t aActionId) {
+ LOGBROWSERCHILDFOCUS(
+ ("BrowserBridgeChild::Activate actionid: %" PRIu64, aActionId));
+ Unused << SendActivate(aActionId);
+}
+
+void BrowserBridgeChild::Deactivate(bool aWindowLowering, uint64_t aActionId) {
+ Unused << SendDeactivate(aWindowLowering, aActionId);
+}
+
+/*static*/
+BrowserBridgeChild* BrowserBridgeChild::GetFrom(nsFrameLoader* aFrameLoader) {
+ if (!aFrameLoader) {
+ return nullptr;
+ }
+ return aFrameLoader->GetBrowserBridgeChild();
+}
+
+/*static*/
+BrowserBridgeChild* BrowserBridgeChild::GetFrom(nsIContent* aContent) {
+ RefPtr<nsFrameLoaderOwner> loaderOwner = do_QueryObject(aContent);
+ if (!loaderOwner) {
+ return nullptr;
+ }
+ RefPtr<nsFrameLoader> frameLoader = loaderOwner->GetFrameLoader();
+ return GetFrom(frameLoader);
+}
+
+mozilla::ipc::IPCResult BrowserBridgeChild::RecvRequestFocus(
+ const bool& aCanRaise, const CallerType aCallerType) {
+ // Adapted from BrowserParent
+ RefPtr<Element> owner = mFrameLoader->GetOwnerContent();
+ if (!owner) {
+ return IPC_OK();
+ }
+ nsContentUtils::RequestFrameFocus(*owner, aCanRaise, aCallerType);
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult BrowserBridgeChild::RecvMoveFocus(
+ const bool& aForward, const bool& aForDocumentNavigation) {
+ // Adapted from BrowserParent
+ RefPtr<nsFocusManager> fm = nsFocusManager::GetFocusManager();
+ if (!fm) {
+ return IPC_OK();
+ }
+
+ RefPtr<Element> owner = mFrameLoader->GetOwnerContent();
+ if (!owner) {
+ return IPC_OK();
+ }
+
+ RefPtr<Element> dummy;
+
+ uint32_t type =
+ aForward
+ ? (aForDocumentNavigation
+ ? static_cast<uint32_t>(nsIFocusManager::MOVEFOCUS_FORWARDDOC)
+ : static_cast<uint32_t>(nsIFocusManager::MOVEFOCUS_FORWARD))
+ : (aForDocumentNavigation
+ ? static_cast<uint32_t>(nsIFocusManager::MOVEFOCUS_BACKWARDDOC)
+ : static_cast<uint32_t>(nsIFocusManager::MOVEFOCUS_BACKWARD));
+ fm->MoveFocus(nullptr, owner, type, nsIFocusManager::FLAG_BYKEY,
+ getter_AddRefs(dummy));
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult BrowserBridgeChild::RecvMaybeFireEmbedderLoadEvents(
+ EmbedderElementEventType aFireEventAtEmbeddingElement) {
+ RefPtr<Element> owner = mFrameLoader->GetOwnerContent();
+ if (!owner) {
+ return IPC_OK();
+ }
+
+ if (aFireEventAtEmbeddingElement == EmbedderElementEventType::LoadEvent) {
+ nsEventStatus status = nsEventStatus_eIgnore;
+ WidgetEvent event(/* aIsTrusted = */ true, eLoad);
+ event.mFlags.mBubbles = false;
+ event.mFlags.mCancelable = false;
+ EventDispatcher::Dispatch(owner, nullptr, &event, nullptr, &status);
+ } else if (aFireEventAtEmbeddingElement ==
+ EmbedderElementEventType::ErrorEvent) {
+ mFrameLoader->FireErrorEvent();
+ }
+
+ UnblockOwnerDocsLoadEvent();
+
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult BrowserBridgeChild::RecvScrollRectIntoView(
+ const nsRect& aRect, const ScrollAxis& aVertical,
+ const ScrollAxis& aHorizontal, const ScrollFlags& aScrollFlags,
+ const int32_t& aAppUnitsPerDevPixel) {
+ RefPtr<Element> owner = mFrameLoader->GetOwnerContent();
+ if (!owner) {
+ return IPC_OK();
+ }
+
+ nsIFrame* frame = owner->GetPrimaryFrame();
+ if (!frame) {
+ return IPC_OK();
+ }
+
+ nsSubDocumentFrame* subdocumentFrame = do_QueryFrame(frame);
+ if (!subdocumentFrame) {
+ return IPC_OK();
+ }
+
+ nsPoint extraOffset = subdocumentFrame->GetExtraOffset();
+
+ int32_t parentAPD = frame->PresContext()->AppUnitsPerDevPixel();
+ nsRect rect =
+ aRect.ScaleToOtherAppUnitsRoundOut(aAppUnitsPerDevPixel, parentAPD);
+ rect += extraOffset;
+ RefPtr<PresShell> presShell = frame->PresShell();
+ presShell->ScrollFrameIntoView(frame, Some(rect), aVertical, aHorizontal,
+ aScrollFlags);
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult BrowserBridgeChild::RecvSubFrameCrashed() {
+ if (RefPtr<nsFrameLoaderOwner> frameLoaderOwner =
+ do_QueryObject(mFrameLoader->GetOwnerContent())) {
+ frameLoaderOwner->SubframeCrashed();
+ }
+ return IPC_OK();
+}
+
+void BrowserBridgeChild::ActorDestroy(ActorDestroyReason aWhy) {
+ if (mFrameLoader) {
+ mFrameLoader->DestroyComplete();
+ }
+
+ if (!mBrowsingContext) {
+ // This BBC was never valid, skip teardown.
+ return;
+ }
+
+ // Ensure we unblock our document's 'load' event (in case the OOP-iframe has
+ // been removed before it finished loading, or its subprocess crashed):
+ UnblockOwnerDocsLoadEvent();
+}
+
+void BrowserBridgeChild::UnblockOwnerDocsLoadEvent() {
+ if (!mHadInitialLoad) {
+ mHadInitialLoad = true;
+
+ if (Document* doc = mBrowsingContext->GetParent()->GetExtantDocument()) {
+ doc->OOPChildLoadDone(this);
+ }
+ }
+}
+
+mozilla::ipc::IPCResult BrowserBridgeChild::RecvIntrinsicSizeOrRatioChanged(
+ const Maybe<IntrinsicSize>& aIntrinsicSize,
+ const Maybe<AspectRatio>& aIntrinsicRatio) {
+ if (RefPtr<Element> owner = mFrameLoader->GetOwnerContent()) {
+ if (nsCOMPtr<nsIObjectLoadingContent> olc = do_QueryInterface(owner)) {
+ static_cast<nsObjectLoadingContent*>(olc.get())
+ ->SubdocumentIntrinsicSizeOrRatioChanged(aIntrinsicSize,
+ aIntrinsicRatio);
+ }
+ }
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult BrowserBridgeChild::RecvImageLoadComplete(
+ const nsresult& aResult) {
+ if (RefPtr<Element> owner = mFrameLoader->GetOwnerContent()) {
+ if (nsCOMPtr<nsIObjectLoadingContent> olc = do_QueryInterface(owner)) {
+ static_cast<nsObjectLoadingContent*>(olc.get())
+ ->SubdocumentImageLoadComplete(aResult);
+ }
+ }
+ return IPC_OK();
+}
+
+} // namespace mozilla::dom