summaryrefslogtreecommitdiffstats
path: root/dom/ipc
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-15 03:35:49 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-15 03:35:49 +0000
commitd8bbc7858622b6d9c278469aab701ca0b609cddf (patch)
treeeff41dc61d9f714852212739e6b3738b82a2af87 /dom/ipc
parentReleasing progress-linux version 125.0.3-1~progress7.99u1. (diff)
downloadfirefox-d8bbc7858622b6d9c278469aab701ca0b609cddf.tar.xz
firefox-d8bbc7858622b6d9c278469aab701ca0b609cddf.zip
Merging upstream version 126.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/ipc')
-rw-r--r--dom/ipc/BrowserChild.cpp62
-rw-r--r--dom/ipc/BrowserChild.h15
-rw-r--r--dom/ipc/BrowserParent.cpp2
-rw-r--r--dom/ipc/CoalescedTouchData.cpp6
-rw-r--r--dom/ipc/ContentChild.cpp16
-rw-r--r--dom/ipc/ContentChild.h3
-rw-r--r--dom/ipc/ContentParent.cpp21
-rw-r--r--dom/ipc/ContentParent.h9
-rw-r--r--dom/ipc/ContentParent_NotifyUpdatedDictionaries.h17
-rw-r--r--dom/ipc/DOMTypes.ipdlh1
-rw-r--r--dom/ipc/MMPrinter.cpp29
-rw-r--r--dom/ipc/MMPrinter.h33
-rw-r--r--dom/ipc/PBrowser.ipdl29
-rw-r--r--dom/ipc/PContent.ipdl14
-rw-r--r--dom/ipc/ProcessIsolation.cpp5
-rw-r--r--dom/ipc/StructuredCloneData.h22
-rw-r--r--dom/ipc/WindowGlobalChild.cpp35
-rw-r--r--dom/ipc/WindowGlobalParent.cpp37
-rw-r--r--dom/ipc/jsactor/JSActor.cpp10
-rw-r--r--dom/ipc/moz.build1
-rw-r--r--dom/ipc/nsIHangReport.idl2
-rw-r--r--dom/ipc/nsILoginDetectionService.idl2
-rw-r--r--dom/ipc/tests/JSWindowActor/browser_event_listener.js10
-rw-r--r--dom/ipc/tests/browser.toml2
-rw-r--r--dom/ipc/tests/browser_isactiveintab.js138
25 files changed, 400 insertions, 121 deletions
diff --git a/dom/ipc/BrowserChild.cpp b/dom/ipc/BrowserChild.cpp
index bdd10fdcb2..3d1f399edb 100644
--- a/dom/ipc/BrowserChild.cpp
+++ b/dom/ipc/BrowserChild.cpp
@@ -2342,7 +2342,7 @@ mozilla::ipc::IPCResult BrowserChild::RecvPrintPreview(
/* aListener = */ nullptr, docShellToCloneInto,
nsGlobalWindowOuter::IsPreview::Yes,
nsGlobalWindowOuter::IsForWindowDotPrint::No,
- std::move(aCallback), IgnoreErrors());
+ std::move(aCallback), nullptr, IgnoreErrors());
#endif
return IPC_OK();
}
@@ -2359,8 +2359,9 @@ mozilla::ipc::IPCResult BrowserChild::RecvExitPrintPreview() {
return IPC_OK();
}
-mozilla::ipc::IPCResult BrowserChild::RecvPrint(
- const MaybeDiscardedBrowsingContext& aBc, const PrintData& aPrintData) {
+mozilla::ipc::IPCResult BrowserChild::CommonPrint(
+ const MaybeDiscardedBrowsingContext& aBc, const PrintData& aPrintData,
+ RefPtr<BrowsingContext>* aCachedBrowsingContext) {
#ifdef NS_PRINTING
if (NS_WARN_IF(aBc.IsNullOrDiscarded())) {
return IPC_OK();
@@ -2389,12 +2390,12 @@ mozilla::ipc::IPCResult BrowserChild::RecvPrint(
IgnoredErrorResult rv;
RefPtr printJob = static_cast<RemotePrintJobChild*>(
aPrintData.remotePrintJob().AsChild());
- outerWindow->Print(printSettings, printJob,
- /* aListener = */ nullptr,
- /* aWindowToCloneInto = */ nullptr,
- nsGlobalWindowOuter::IsPreview::No,
- nsGlobalWindowOuter::IsForWindowDotPrint::No,
- /* aPrintPreviewCallback = */ nullptr, rv);
+ outerWindow->Print(
+ printSettings, printJob,
+ /* aListener = */ nullptr,
+ /* aWindowToCloneInto = */ nullptr, nsGlobalWindowOuter::IsPreview::No,
+ nsGlobalWindowOuter::IsForWindowDotPrint::No,
+ /* aPrintPreviewCallback = */ nullptr, aCachedBrowsingContext, rv);
if (NS_WARN_IF(rv.Failed())) {
return IPC_OK();
}
@@ -2403,6 +2404,49 @@ mozilla::ipc::IPCResult BrowserChild::RecvPrint(
return IPC_OK();
}
+mozilla::ipc::IPCResult BrowserChild::RecvPrint(
+ const MaybeDiscardedBrowsingContext& aBc, const PrintData& aPrintData,
+ bool aReturnStaticClone, PrintResolver&& aResolve) {
+#ifdef NS_PRINTING
+ RefPtr<BrowsingContext> browsingContext;
+ auto result = CommonPrint(aBc, aPrintData,
+ aReturnStaticClone ? &browsingContext : nullptr);
+ aResolve(browsingContext);
+ return result;
+#else
+ aResolve(nullptr);
+ return IPC_OK();
+#endif
+}
+
+mozilla::ipc::IPCResult BrowserChild::RecvPrintClonedPage(
+ const MaybeDiscardedBrowsingContext& aBc, const PrintData& aPrintData,
+ const MaybeDiscardedBrowsingContext& aClonedBc) {
+#ifdef NS_PRINTING
+ if (aClonedBc.IsNullOrDiscarded()) {
+ return IPC_OK();
+ }
+ RefPtr<BrowsingContext> clonedBc = aClonedBc.get();
+ return CommonPrint(aBc, aPrintData, &clonedBc);
+#else
+ return IPC_OK();
+#endif
+}
+
+mozilla::ipc::IPCResult BrowserChild::RecvDestroyPrintClone(
+ const MaybeDiscardedBrowsingContext& aCachedPage) {
+#ifdef NS_PRINTING
+ if (aCachedPage) {
+ RefPtr<nsPIDOMWindowOuter> window = aCachedPage->GetDOMWindow();
+ if (NS_WARN_IF(!window)) {
+ return IPC_OK();
+ }
+ window->Close();
+ }
+#endif
+ return IPC_OK();
+}
+
mozilla::ipc::IPCResult BrowserChild::RecvUpdateNativeWindowHandle(
const uintptr_t& aNewHandle) {
#if defined(XP_WIN) && defined(ACCESSIBILITY)
diff --git a/dom/ipc/BrowserChild.h b/dom/ipc/BrowserChild.h
index ddbf8f0b74..90cb712476 100644
--- a/dom/ipc/BrowserChild.h
+++ b/dom/ipc/BrowserChild.h
@@ -507,7 +507,15 @@ class BrowserChild final : public nsMessageManagerScriptExecutor,
mozilla::ipc::IPCResult RecvExitPrintPreview();
MOZ_CAN_RUN_SCRIPT_BOUNDARY mozilla::ipc::IPCResult RecvPrint(
- const MaybeDiscardedBrowsingContext&, const PrintData&);
+ const MaybeDiscardedBrowsingContext&, const PrintData&, bool,
+ PrintResolver&&);
+
+ MOZ_CAN_RUN_SCRIPT_BOUNDARY mozilla::ipc::IPCResult RecvPrintClonedPage(
+ const MaybeDiscardedBrowsingContext&, const PrintData&,
+ const MaybeDiscardedBrowsingContext&);
+
+ mozilla::ipc::IPCResult RecvDestroyPrintClone(
+ const MaybeDiscardedBrowsingContext&);
mozilla::ipc::IPCResult RecvUpdateNativeWindowHandle(
const uintptr_t& aNewHandle);
@@ -712,6 +720,11 @@ class BrowserChild final : public nsMessageManagerScriptExecutor,
void InternalSetDocShellIsActive(bool aIsActive);
+ MOZ_CAN_RUN_SCRIPT
+ mozilla::ipc::IPCResult CommonPrint(
+ const MaybeDiscardedBrowsingContext& aBc, const PrintData& aPrintData,
+ RefPtr<BrowsingContext>* aCachedBrowsingContext);
+
bool CreateRemoteLayerManager(
mozilla::layers::PCompositorBridgeChild* aCompositorChild);
diff --git a/dom/ipc/BrowserParent.cpp b/dom/ipc/BrowserParent.cpp
index 5d13d2e814..23c677c09c 100644
--- a/dom/ipc/BrowserParent.cpp
+++ b/dom/ipc/BrowserParent.cpp
@@ -826,8 +826,6 @@ void BrowserParent::ActorDestroy(ActorDestroyReason why) {
// out-of-process iframe.
RefPtr<nsFrameLoader> frameLoader = GetFrameLoader(true);
if (frameLoader) {
- ReceiveMessage(CHILD_PROCESS_SHUTDOWN_MESSAGE, false, nullptr);
-
if (mBrowsingContext->IsTop()) {
// If this is a top-level BrowsingContext, tell the frameloader it's time
// to go away. Otherwise, this is a subframe crash, and we can keep the
diff --git a/dom/ipc/CoalescedTouchData.cpp b/dom/ipc/CoalescedTouchData.cpp
index 3c3bc71a0c..551e6ae901 100644
--- a/dom/ipc/CoalescedTouchData.cpp
+++ b/dom/ipc/CoalescedTouchData.cpp
@@ -25,8 +25,7 @@ void CoalescedTouchData::CreateCoalescedTouchEvent(
WidgetPointerEvent* event =
touch->mCoalescedWidgetEvents->mEvents.AppendElement(WidgetPointerEvent(
aEvent.IsTrusted(), ePointerMove, aEvent.mWidget));
- PointerEventHandler::InitPointerEventFromTouch(*event, aEvent, *touch,
- i == 0);
+ PointerEventHandler::InitPointerEventFromTouch(*event, aEvent, *touch);
event->mFlags.mBubbles = false;
event->mFlags.mCancelable = false;
}
@@ -63,8 +62,7 @@ void CoalescedTouchData::Coalesce(const WidgetTouchEvent& aEvent,
sameTouch->mCoalescedWidgetEvents->mEvents.AppendElement(
WidgetPointerEvent(aEvent.IsTrusted(), ePointerMove,
aEvent.mWidget));
- PointerEventHandler::InitPointerEventFromTouch(*event, aEvent, *touch,
- i == 0);
+ PointerEventHandler::InitPointerEventFromTouch(*event, aEvent, *touch);
event->mFlags.mBubbles = false;
event->mFlags.mCancelable = false;
}
diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp
index 7507d88fe0..2ebdd303d8 100644
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -2310,8 +2310,10 @@ mozilla::ipc::IPCResult ContentChild::RecvThemeChanged(
mozilla::ipc::IPCResult ContentChild::RecvLoadProcessScript(
const nsString& aURL) {
auto* global = ContentProcessMessageManager::Get();
- global->LoadScript(aURL);
- return IPC_OK();
+ if (global && global->LoadScript(aURL)) {
+ return IPC_OK();
+ }
+ return IPC_FAIL(this, "ContentProcessMessageManager::LoadScript failed");
}
mozilla::ipc::IPCResult ContentChild::RecvAsyncMessage(
@@ -3923,7 +3925,8 @@ mozilla::ipc::IPCResult ContentChild::RecvRaiseWindow(
mozilla::ipc::IPCResult ContentChild::RecvAdjustWindowFocus(
const MaybeDiscarded<BrowsingContext>& aContext, bool aIsVisible,
- uint64_t aActionId) {
+ uint64_t aActionId, bool aShouldClearAncestorFocus,
+ const MaybeDiscarded<BrowsingContext>& aAncestorBrowsingContextToFocus) {
if (aContext.IsNullOrDiscarded()) {
MOZ_LOG(BrowsingContext::GetLog(), LogLevel::Debug,
("ChildIPC: Trying to send a message to dead or detached context"));
@@ -3932,7 +3935,12 @@ mozilla::ipc::IPCResult ContentChild::RecvAdjustWindowFocus(
if (RefPtr<nsFocusManager> fm = nsFocusManager::GetFocusManager()) {
RefPtr<BrowsingContext> bc = aContext.get();
- fm->AdjustInProcessWindowFocus(bc, false, aIsVisible, aActionId);
+ RefPtr<BrowsingContext> ancestor =
+ aAncestorBrowsingContextToFocus.IsNullOrDiscarded()
+ ? nullptr
+ : aAncestorBrowsingContextToFocus.get();
+ fm->AdjustInProcessWindowFocus(bc, false, aIsVisible, aActionId,
+ aShouldClearAncestorFocus, ancestor);
}
return IPC_OK();
}
diff --git a/dom/ipc/ContentChild.h b/dom/ipc/ContentChild.h
index b9ab77ef5b..12b6c3cabf 100644
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -661,7 +661,8 @@ class ContentChild final : public PContentChild,
uint64_t aActionId);
MOZ_CAN_RUN_SCRIPT_BOUNDARY mozilla::ipc::IPCResult RecvAdjustWindowFocus(
const MaybeDiscarded<BrowsingContext>& aContext, bool aIsVisible,
- uint64_t aActionId);
+ uint64_t aActionId, bool aShouldClearFocus,
+ const MaybeDiscarded<BrowsingContext>& aAncestorBrowsingContextToFocus);
MOZ_CAN_RUN_SCRIPT_BOUNDARY mozilla::ipc::IPCResult RecvClearFocus(
const MaybeDiscarded<BrowsingContext>& aContext);
mozilla::ipc::IPCResult RecvSetFocusedBrowsingContext(
diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp
index 2dbdb662ff..412b7e8796 100644
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -644,6 +644,10 @@ static const char* sObserverTopics[] = {
DEFAULT_TIMEZONE_CHANGED_OBSERVER_TOPIC,
};
+void ContentParent_NotifyUpdatedDictionaries() {
+ ContentParent::NotifyUpdatedDictionaries();
+}
+
// PreallocateProcess is called by the PreallocatedProcessManager.
// ContentParent then takes this process back within GetNewOrUsedBrowserProcess.
/*static*/ already_AddRefed<ContentParent>
@@ -1895,10 +1899,6 @@ void ContentParent::ShutDownMessageManager() {
return;
}
- mMessageManager->ReceiveMessage(mMessageManager, nullptr,
- CHILD_PROCESS_SHUTDOWN_MESSAGE, false,
- nullptr, nullptr, IgnoreErrors());
-
mMessageManager->SetOsPid(-1);
mMessageManager->Disconnect();
mMessageManager = nullptr;
@@ -3273,7 +3273,7 @@ bool ContentParent::InitInternal(ProcessPriority aInitialPriority) {
// because content scripts mean that a moz-extension can live in any
// process. Same thing for system principal Blob URLs. Content Blob
// URL's are sent for content principals on-demand by
- // AboutToLoadHttpFtpDocumentForChild and RemoteWorkerManager.
+ // AboutToLoadHttpDocumentForChild and RemoteWorkerManager.
if (!BlobURLProtocolHandler::IsBlobURLBroadcastPrincipal(aPrincipal)) {
return true;
}
@@ -6365,7 +6365,7 @@ void ContentParent::UpdateCookieStatus(nsIChannel* aChannel) {
}
}
-nsresult ContentParent::AboutToLoadHttpFtpDocumentForChild(
+nsresult ContentParent::AboutToLoadHttpDocumentForChild(
nsIChannel* aChannel, bool* aShouldWaitForPermissionCookieUpdate) {
MOZ_ASSERT(aChannel);
@@ -7362,7 +7362,8 @@ mozilla::ipc::IPCResult ContentParent::RecvRaiseWindow(
mozilla::ipc::IPCResult ContentParent::RecvAdjustWindowFocus(
const MaybeDiscarded<BrowsingContext>& aContext, bool aIsVisible,
- uint64_t aActionId) {
+ uint64_t aActionId, bool aShouldClearFocus,
+ const MaybeDiscarded<BrowsingContext>& aAncestorBrowsingContextToFocus) {
if (aContext.IsNullOrDiscarded()) {
MOZ_LOG(
BrowsingContext::GetLog(), LogLevel::Debug,
@@ -7389,7 +7390,9 @@ mozilla::ipc::IPCResult ContentParent::RecvAdjustWindowFocus(
ContentParent* cp = cpm->GetContentProcessById(
ContentParentId(canonicalParent->OwnerProcessId()));
if (cp && !processes.Get(cp)) {
- Unused << cp->SendAdjustWindowFocus(context, aIsVisible, aActionId);
+ Unused << cp->SendAdjustWindowFocus(context, aIsVisible, aActionId,
+ aShouldClearFocus,
+ aAncestorBrowsingContextToFocus);
processes.InsertOrUpdate(cp, true);
}
context = canonicalParent;
@@ -8092,6 +8095,8 @@ IPCResult ContentParent::RecvRawMessage(
stack.emplace();
stack->BorrowFromClonedMessageData(*aStack);
}
+ MMPrinter::Print("ContentParent::RecvRawMessage", aMeta.actorName(),
+ aMeta.messageName(), aData);
ReceiveRawMessage(aMeta, std::move(data), std::move(stack));
return IPC_OK();
}
diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h
index 15139a93f1..31cfa6de88 100644
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -50,8 +50,6 @@
#include "DriverCrashGuard.h"
#include "nsIReferrerInfo.h"
-#define CHILD_PROCESS_SHUTDOWN_MESSAGE u"child-process-shutdown"_ns
-
class nsConsoleService;
class nsIContentProcessInfo;
class nsICycleCollectorLogSink;
@@ -551,12 +549,12 @@ class ContentParent final : public PContentParent,
void SetMainThreadQoSPriority(nsIThread::QoSPriority aQoSPriority);
// This function is called when we are about to load a document from an
- // HTTP(S) or FTP channel for a content process. It is a useful place
+ // HTTP(S) channel for a content process. It is a useful place
// to start to kick off work as early as possible in response to such
// document loads.
// aShouldWaitForPermissionCookieUpdate is set to true if main thread IPCs for
// updating permissions/cookies are sent.
- nsresult AboutToLoadHttpFtpDocumentForChild(
+ nsresult AboutToLoadHttpDocumentForChild(
nsIChannel* aChannel,
bool* aShouldWaitForPermissionCookieUpdate = nullptr);
@@ -618,7 +616,8 @@ class ContentParent final : public PContentParent,
uint64_t aActionId);
mozilla::ipc::IPCResult RecvAdjustWindowFocus(
const MaybeDiscarded<BrowsingContext>& aContext, bool aIsVisible,
- uint64_t aActionId);
+ uint64_t aActionId, bool aShouldClearFocus,
+ const MaybeDiscarded<BrowsingContext>& aAncestorBrowsingContextToFocus);
mozilla::ipc::IPCResult RecvClearFocus(
const MaybeDiscarded<BrowsingContext>& aContext);
mozilla::ipc::IPCResult RecvSetFocusedBrowsingContext(
diff --git a/dom/ipc/ContentParent_NotifyUpdatedDictionaries.h b/dom/ipc/ContentParent_NotifyUpdatedDictionaries.h
new file mode 100644
index 0000000000..0c78fb874d
--- /dev/null
+++ b/dom/ipc/ContentParent_NotifyUpdatedDictionaries.h
@@ -0,0 +1,17 @@
+/* -*- 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/. */
+
+#ifndef mozilla_dom_ContentParent_NotifyUpdatedDictionaries_h
+#define mozilla_dom_ContentParent_NotifyUpdatedDictionaries_h
+
+// Avoid including ContentParent.h because it ends up including WebGLTypes.h,
+// where we have our mozilla::malloc(ForbidNarrowing<size_t>) overrides, which
+// cause issues with the way hunspell overrides malloc for itself.
+namespace mozilla::dom {
+void ContentParent_NotifyUpdatedDictionaries();
+} // namespace mozilla::dom
+
+#endif // mozilla_dom_ContentParent_NotifyUpdatedDictionaries_h
diff --git a/dom/ipc/DOMTypes.ipdlh b/dom/ipc/DOMTypes.ipdlh
index faee4e861c..1be3537e68 100644
--- a/dom/ipc/DOMTypes.ipdlh
+++ b/dom/ipc/DOMTypes.ipdlh
@@ -114,6 +114,7 @@ struct ScreenDetails {
ScreenOrientation orientation;
uint16_t orientationAngle;
bool isPseudoDisplay;
+ bool isHDR;
};
struct DimensionInfo
diff --git a/dom/ipc/MMPrinter.cpp b/dom/ipc/MMPrinter.cpp
index be2911341a..796b4fbeb3 100644
--- a/dom/ipc/MMPrinter.cpp
+++ b/dom/ipc/MMPrinter.cpp
@@ -26,8 +26,8 @@ LazyLogModule MMPrinter::sMMLog("MessageManager");
// the output of the logs into logs more friendly to reading.
/* static */
-void MMPrinter::PrintImpl(char const* aLocation, const nsAString& aMsg,
- ClonedMessageData const& aData) {
+Maybe<uint64_t> MMPrinter::PrintHeader(char const* aLocation,
+ const nsAString& aMsg) {
NS_ConvertUTF16toUTF8 charMsg(aMsg);
/*
@@ -43,15 +43,29 @@ void MMPrinter::PrintImpl(char const* aLocation, const nsAString& aMsg,
char* mmSkipLog = PR_GetEnv("MOZ_LOG_MESSAGEMANAGER_SKIP");
if (mmSkipLog && strstr(mmSkipLog, charMsg.get())) {
- return;
+ return Nothing();
}
- uint64_t msg_id = RandomUint64OrDie();
+ uint64_t aMsgId = RandomUint64OrDie();
MOZ_LOG(MMPrinter::sMMLog, LogLevel::Debug,
- ("%" PRIu64 " %s Message: %s in process type: %s", msg_id, aLocation,
+ ("%" PRIu64 " %s Message: %s in process type: %s", aMsgId, aLocation,
charMsg.get(), XRE_GetProcessTypeString()));
+ return Some(aMsgId);
+}
+
+/* static */
+void MMPrinter::PrintNoData(uint64_t aMsgId) {
+ if (!MOZ_LOG_TEST(sMMLog, LogLevel::Verbose)) {
+ return;
+ }
+ MOZ_LOG(MMPrinter::sMMLog, LogLevel::Verbose,
+ ("%" PRIu64 " (No Data)", aMsgId));
+}
+
+/* static */
+void MMPrinter::PrintData(uint64_t aMsgId, ClonedMessageData const& aData) {
if (!MOZ_LOG_TEST(sMMLog, LogLevel::Verbose)) {
return;
}
@@ -75,8 +89,7 @@ void MMPrinter::PrintImpl(char const* aLocation, const nsAString& aMsg,
if (rv.Failed()) {
// In testing, the only reason this would fail was if there was no data in
// the message; so it seems like this is safe-ish.
- MOZ_LOG(MMPrinter::sMMLog, LogLevel::Verbose,
- ("%" PRIu64 " (No Data)", msg_id));
+ MMPrinter::PrintNoData(aMsgId);
rv.SuppressException();
return;
}
@@ -86,7 +99,7 @@ void MMPrinter::PrintImpl(char const* aLocation, const nsAString& aMsg,
if (!srcString.init(cx, unevalObj)) return;
MOZ_LOG(MMPrinter::sMMLog, LogLevel::Verbose,
- ("%" PRIu64 " %s", msg_id, NS_ConvertUTF16toUTF8(srcString).get()));
+ ("%" PRIu64 " %s", aMsgId, NS_ConvertUTF16toUTF8(srcString).get()));
}
} // namespace mozilla::dom
diff --git a/dom/ipc/MMPrinter.h b/dom/ipc/MMPrinter.h
index 7d89f9ee8f..1d00bfc2e6 100644
--- a/dom/ipc/MMPrinter.h
+++ b/dom/ipc/MMPrinter.h
@@ -7,6 +7,7 @@
#ifndef MMPrinter_h
#define MMPrinter_h
+#include "mozilla/Maybe.h"
#include "mozilla/dom/DOMTypes.h"
#include "nsString.h"
@@ -17,14 +18,40 @@ class MMPrinter {
static void Print(char const* aLocation, const nsAString& aMsg,
ClonedMessageData const& aData) {
if (MOZ_UNLIKELY(MOZ_LOG_TEST(MMPrinter::sMMLog, LogLevel::Debug))) {
- MMPrinter::PrintImpl(aLocation, aMsg, aData);
+ Maybe<uint64_t> msgId = MMPrinter::PrintHeader(aLocation, aMsg);
+ if (!msgId.isSome()) {
+ return;
+ }
+ MMPrinter::PrintData(*msgId, aData);
+ }
+ }
+
+ static void Print(char const* aLocation, const nsACString& aActorName,
+ const nsAString& aMessageName,
+ const Maybe<ClonedMessageData>& aData) {
+ if (MOZ_UNLIKELY(MOZ_LOG_TEST(MMPrinter::sMMLog, LogLevel::Debug))) {
+ Maybe<uint64_t> msgId = MMPrinter::PrintHeader(
+ aLocation,
+ NS_ConvertUTF8toUTF16(aActorName + " - "_ns) + aMessageName);
+
+ if (!msgId.isSome()) {
+ return;
+ }
+
+ if (aData.isSome()) {
+ MMPrinter::PrintData(*msgId, *aData);
+ } else {
+ MMPrinter::PrintNoData(*msgId);
+ }
}
}
private:
static LazyLogModule sMMLog;
- static void PrintImpl(char const* aLocation, const nsAString& aMsg,
- ClonedMessageData const& aData);
+ static Maybe<uint64_t> PrintHeader(char const* aLocation,
+ const nsAString& aMsg);
+ static void PrintNoData(uint64_t aMsgId);
+ static void PrintData(uint64_t aMsgId, ClonedMessageData const& aData);
};
} // namespace mozilla::dom
diff --git a/dom/ipc/PBrowser.ipdl b/dom/ipc/PBrowser.ipdl
index caef472ec2..372a81b139 100644
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -87,7 +87,7 @@ using nsCursor from "nsIWidget.h";
using struct LookAndFeelInt from "mozilla/widget/WidgetMessageUtils.h";
using struct mozilla::DimensionRequest from "mozilla/widget/WidgetMessageUtils.h";
using class mozilla::dom::MessagePort from "mozilla/dom/MessagePort.h";
-using class mozilla::dom::ipc::StructuredCloneData from "mozilla/dom/ipc/StructuredCloneData.h";
+[MoveOnly=data] using class mozilla::dom::ipc::StructuredCloneData from "mozilla/dom/ipc/StructuredCloneData.h";
using mozilla::dom::MaybeDiscardedWindowContext from "mozilla/dom/WindowContext.h";
using mozilla::EventMessage from "mozilla/EventForwards.h";
using nsEventStatus from "mozilla/EventForwards.h";
@@ -960,8 +960,33 @@ child:
*
* @param aBrowsingContext the browsing context to print.
* @param aPrintData the serialized settings to print with
+ * @param aReturnStaticClone If the document in aBrowsingContext is not a static clone, whether
+ * to return the static document clone created.
+ * Note that if you call this with true but do not later call PrintClonedPage(),
+ * you must call DestroyPrintCache() to avoid leaks.
*/
- async Print(MaybeDiscardedBrowsingContext aBC, PrintData aPrintData);
+ async Print(MaybeDiscardedBrowsingContext aBC, PrintData aPrintData, bool aReturnStaticClone) returns(MaybeDiscardedBrowsingContext staticCloneBrowsingContext);
+
+ /**
+ * Tell the child to print the passed in static clone browsing context with the given settings.
+ *
+ * @param aBrowsingContext the browsing context to print.
+ * @param aPrintData the serialized settings to print with
+ * @param aStaticCloneBrowsingContext The static clone of aBrowsingContext that
+ * was created by an earlier call to Print(). This is the page that will actually be
+ * printed.
+ */
+ async PrintClonedPage(MaybeDiscardedBrowsingContext aBC, PrintData aPrintData, MaybeDiscardedBrowsingContext aStaticCloneBrowsingContext);
+
+ /**
+ * Destroy the static document clone for printing, if present. See Print() for details.
+ * For callers' simplicity, it is safe to call this method even if aStaticCloneBrowsingContext
+ * is null or has already been discarded.
+ *
+ * @param aStaticCloneBrowsingContext The static clone that was created by
+ * an earlier call to Print().
+ */
+ async DestroyPrintClone(MaybeDiscardedBrowsingContext aStaticCloneBrowsingContext);
/**
* Update the child with the tab's current top-level native window handle.
diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl
index 3789c046c8..67c4c298e4 100644
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -104,7 +104,7 @@ using mozilla::ImagePoint from "Units.h";
using mozilla::ImageIntSize from "Units.h";
using mozilla::widget::ThemeChangeKind from "mozilla/widget/WidgetMessageUtils.h";
using class mozilla::dom::MessagePort from "mozilla/dom/MessagePort.h";
-using class mozilla::dom::ipc::StructuredCloneData from "mozilla/dom/ipc/StructuredCloneData.h";
+[MoveOnly=data] using class mozilla::dom::ipc::StructuredCloneData from "mozilla/dom/ipc/StructuredCloneData.h";
using mozilla::OriginAttributes from "mozilla/ipc/BackgroundUtils.h";
using struct mozilla::layers::TextureFactoryIdentifier from "mozilla/layers/CompositorTypes.h";
using mozilla::layers::CompositorOptions from "mozilla/layers/CompositorOptions.h";
@@ -1874,8 +1874,18 @@ both:
async DiscardBrowsingContext(MaybeDiscardedBrowsingContext aContext, bool aDoDiscard)
returns (uint64_t unused);
+ /**
+ * aContext is the one that's taking the affect. Either the one that
+ * receives the focus, or the one that loses the focus.
+ *
+ * aAncestorBrowsingContextToFocus can only be non-null when
+ * aShouldClearAncestorFocus is true. This is the browsing context
+ * that receives the focus when aContext loses the focus.
+ */
async AdjustWindowFocus(MaybeDiscardedBrowsingContext aContext,
- bool aIsVisible, uint64_t aActionId);
+ bool aIsVisible, uint64_t aActionId,
+ bool aShouldClearAncestorFocus,
+ MaybeDiscardedBrowsingContext aAncestorBrowsingContextToFocus);
async WindowClose(MaybeDiscardedBrowsingContext aContext,
bool aTrustedCaller);
async WindowFocus(MaybeDiscardedBrowsingContext aContext,
diff --git a/dom/ipc/ProcessIsolation.cpp b/dom/ipc/ProcessIsolation.cpp
index f0c6dd8863..ddfbeb3d28 100644
--- a/dom/ipc/ProcessIsolation.cpp
+++ b/dom/ipc/ProcessIsolation.cpp
@@ -343,6 +343,7 @@ static IsolationBehavior IsolationBehaviorForURI(nsIURI* aURI, bool aIsSubframe,
browser_tabs_remote_separatePrivilegedMozillaWebContentProcess()) {
nsAutoCString host;
if (NS_SUCCEEDED(aURI->GetAsciiHost(host))) {
+ // This code is duplicated in E10SUtils.sys.mjs, please update both
for (const auto& separatedDomain : sSeparatedMozillaDomains) {
// If the domain exactly matches our host, or our host ends with "." +
// separatedDomain, we consider it matching.
@@ -407,8 +408,8 @@ static already_AddRefed<BasePrincipal> GetAboutReaderURLPrincipal(
// Extract the "url" parameter from the `about:reader`'s query parameters,
// and recover a content principal from it.
- nsAutoString readerSpec;
- if (URLParams::Extract(query, u"url"_ns, readerSpec)) {
+ nsAutoCString readerSpec;
+ if (URLParams::Extract(query, "url"_ns, readerSpec)) {
nsCOMPtr<nsIURI> readerUri;
if (NS_SUCCEEDED(NS_NewURI(getter_AddRefs(readerUri), readerSpec))) {
return BasePrincipal::CreateContentPrincipal(readerUri, aAttrs);
diff --git a/dom/ipc/StructuredCloneData.h b/dom/ipc/StructuredCloneData.h
index 0566a3b07f..6beba4f745 100644
--- a/dom/ipc/StructuredCloneData.h
+++ b/dom/ipc/StructuredCloneData.h
@@ -93,20 +93,14 @@ class SharedJSAllocatedData final {
* to send a structured clone that may include blobs or transferables such as
* message ports.
* - To send the data, instantiate a StructuredCloneData instance and Write()
- * into it like a normal structure clone. When you are ready to send the
- * ClonedMessageData-bearing IPC message, use the appropriate
- * BuildClonedMessageDataFor{Parent,Child,BackgroundParent,BackgroundChild}
+ * into it like a normal structured clone. When you are ready to send the
+ * ClonedMessageData-bearing IPC message, call the BuildClonedMessageData
* method to populate the ClonedMessageData and then send it before your
* StructuredCloneData instance is destroyed. (Buffer borrowing is used
* under-the-hood to avoid duplicating the serialized data, requiring this.)
- * - To receive the data, instantiate a StructuredCloneData and use the
- * appropriate {Borrow,Copy,Steal}FromClonedMessageDataFor{Parent,Child,
- * BackgroundParent,BackgroundChild} method. See the memory management
- * section for more info.
- *
- * Variations:
- * - If transferables are not allowed (ex: BroadcastChannel), then use the
- * StructuredCloneDataNoTransfers subclass instead of StructuredCloneData.
+ * - To receive the data, instantiate a StructuredCloneData and then call
+ * the BorrowFromClonedMessageData method. See the memory management
+ * section for more information.
*
* ## Memory Management ##
*
@@ -135,11 +129,11 @@ class SharedJSAllocatedData final {
*
* 1: Specifically, in the Write() case an owning SharedJSAllocatedData is
* created efficiently (by stealing from StructuredCloneHolder). The
- * BuildClonedMessageDataFor* method can be called at any time and it will
+ * BuildClonedMessageData method can be called at any time and it will
* borrow the underlying memory. While it would be even better if
* SerializedStructuredCloneBuffer could hold a SharedJSAllocatedData ref,
- * there's no reason you can't wait to BuildClonedMessageDataFor* until you
- * need to make the IPC Send* call.
+ * there's no reason you can't wait to call the BuildClonedMessageData
+ * method until you need to make the IPC Send* call.
*/
class StructuredCloneData : public StructuredCloneHolder {
public:
diff --git a/dom/ipc/WindowGlobalChild.cpp b/dom/ipc/WindowGlobalChild.cpp
index ec2811f972..4072828911 100644
--- a/dom/ipc/WindowGlobalChild.cpp
+++ b/dom/ipc/WindowGlobalChild.cpp
@@ -35,7 +35,7 @@
#include "nsQueryObject.h"
#include "nsSerializationHelper.h"
#include "nsFrameLoader.h"
-#include "nsIScriptSecurityManager.h"
+#include "nsScriptSecurityManager.h"
#include "mozilla/dom/JSWindowActorBinding.h"
#include "mozilla/dom/JSWindowActorChild.h"
@@ -588,30 +588,19 @@ void WindowGlobalChild::SetDocumentURI(nsIURI* aDocumentURI) {
embedderInnerWindowID, BrowsingContext()->UsePrivateBrowsing());
if (StaticPrefs::dom_security_setdocumenturi()) {
- auto isLoadableViaInternet = [](nsIURI* uri) {
- return (uri && (net::SchemeIsHTTP(uri) || net::SchemeIsHTTPS(uri)));
- };
- if (isLoadableViaInternet(aDocumentURI)) {
- nsCOMPtr<nsIURI> principalURI = mDocumentPrincipal->GetURI();
- if (mDocumentPrincipal->GetIsNullPrincipal()) {
- nsCOMPtr<nsIPrincipal> precursor =
- mDocumentPrincipal->GetPrecursorPrincipal();
- if (precursor) {
- principalURI = precursor->GetURI();
- }
- }
-
- if (isLoadableViaInternet(principalURI)) {
- nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
-
- if (!NS_SUCCEEDED(ssm->CheckSameOriginURI(principalURI, aDocumentURI,
- false, false))) {
- MOZ_DIAGNOSTIC_ASSERT(false,
- "Setting DocumentURI with a different origin "
- "than principal URI");
- }
+ nsCOMPtr<nsIURI> principalURI = mDocumentPrincipal->GetURI();
+ if (mDocumentPrincipal->GetIsNullPrincipal()) {
+ nsCOMPtr<nsIPrincipal> precursor =
+ mDocumentPrincipal->GetPrecursorPrincipal();
+ if (precursor) {
+ principalURI = precursor->GetURI();
}
}
+
+ MOZ_DIAGNOSTIC_ASSERT(!nsScriptSecurityManager::IsHttpOrHttpsAndCrossOrigin(
+ principalURI, aDocumentURI),
+ "Setting DocumentURI with a different origin "
+ "than principal URI");
}
mDocumentURI = aDocumentURI;
diff --git a/dom/ipc/WindowGlobalParent.cpp b/dom/ipc/WindowGlobalParent.cpp
index 13fbe2940c..f60790a155 100644
--- a/dom/ipc/WindowGlobalParent.cpp
+++ b/dom/ipc/WindowGlobalParent.cpp
@@ -39,6 +39,7 @@
#include "mozilla/Telemetry.h"
#include "mozilla/Variant.h"
#include "mozilla/ipc/ProtocolUtils.h"
+#include "MMPrinter.h"
#include "nsContentUtils.h"
#include "nsDocShell.h"
#include "nsDocShellLoadState.h"
@@ -230,8 +231,8 @@ void WindowGlobalParent::OriginCounter::UpdateSiteOriginsFrom(
}
void WindowGlobalParent::OriginCounter::Accumulate() {
- mozilla::glean::geckoview::per_document_site_origins.AccumulateSamples(
- {mMaxOrigins});
+ mozilla::glean::geckoview::per_document_site_origins.AccumulateSingleSample(
+ mMaxOrigins);
mMaxOrigins = 0;
mOriginMap.Clear();
@@ -398,26 +399,20 @@ IPCResult WindowGlobalParent::RecvUpdateDocumentURI(NotNull<nsIURI*> aURI) {
return IPC_FAIL(this, "Setting DocumentURI with unknown protocol.");
}
- auto isLoadableViaInternet = [](nsIURI* uri) {
- return (uri && (net::SchemeIsHTTP(uri) || net::SchemeIsHTTPS(uri)));
- };
-
- if (isLoadableViaInternet(aURI)) {
- nsCOMPtr<nsIURI> principalURI = mDocumentPrincipal->GetURI();
- if (mDocumentPrincipal->GetIsNullPrincipal()) {
- nsCOMPtr<nsIPrincipal> precursor =
- mDocumentPrincipal->GetPrecursorPrincipal();
- if (precursor) {
- principalURI = precursor->GetURI();
- }
+ nsCOMPtr<nsIURI> principalURI = mDocumentPrincipal->GetURI();
+ if (mDocumentPrincipal->GetIsNullPrincipal()) {
+ nsCOMPtr<nsIPrincipal> precursor =
+ mDocumentPrincipal->GetPrecursorPrincipal();
+ if (precursor) {
+ principalURI = precursor->GetURI();
}
+ }
- if (isLoadableViaInternet(principalURI) &&
- !nsScriptSecurityManager::SecurityCompareURIs(principalURI, aURI)) {
- return IPC_FAIL(this,
- "Setting DocumentURI with a different Origin than "
- "principal URI");
- }
+ if (nsScriptSecurityManager::IsHttpOrHttpsAndCrossOrigin(principalURI,
+ aURI)) {
+ return IPC_FAIL(this,
+ "Setting DocumentURI with a different Origin than "
+ "principal URI");
}
}
@@ -570,6 +565,8 @@ IPCResult WindowGlobalParent::RecvRawMessage(
stack.emplace();
stack->BorrowFromClonedMessageData(*aStack);
}
+ MMPrinter::Print("WindowGlobalParent::RecvRawMessage", aMeta.actorName(),
+ aMeta.messageName(), aData);
ReceiveRawMessage(aMeta, std::move(data), std::move(stack));
return IPC_OK();
}
diff --git a/dom/ipc/jsactor/JSActor.cpp b/dom/ipc/jsactor/JSActor.cpp
index 03926fee04..2c706ca515 100644
--- a/dom/ipc/jsactor/JSActor.cpp
+++ b/dom/ipc/jsactor/JSActor.cpp
@@ -441,14 +441,8 @@ void JSActor::QueryHandler::ResolvedCallback(JSContext* aCx,
return;
}
- Maybe<ipc::StructuredCloneData> data{std::in_place};
- data->InitScope(JS::StructuredCloneScope::DifferentProcess);
-
- IgnoredErrorResult error;
- data->Write(aCx, aValue, error);
- if (NS_WARN_IF(error.Failed())) {
- JS_ClearPendingException(aCx);
-
+ Maybe<ipc::StructuredCloneData> data = TryClone(aCx, aValue);
+ if (!data) {
nsAutoCString msg;
msg.Append(mActor->Name());
msg.Append(':');
diff --git a/dom/ipc/moz.build b/dom/ipc/moz.build
index 3f10b9fbab..35b6039d89 100644
--- a/dom/ipc/moz.build
+++ b/dom/ipc/moz.build
@@ -52,6 +52,7 @@ EXPORTS.mozilla.dom += [
"CoalescedWheelData.h",
"ContentChild.h",
"ContentParent.h",
+ "ContentParent_NotifyUpdatedDictionaries.h",
"ContentProcess.h",
"ContentProcessManager.h",
"CSPMessageUtils.h",
diff --git a/dom/ipc/nsIHangReport.idl b/dom/ipc/nsIHangReport.idl
index ff01d7f51a..d99137d942 100644
--- a/dom/ipc/nsIHangReport.idl
+++ b/dom/ipc/nsIHangReport.idl
@@ -47,5 +47,5 @@ interface nsIHangReport : nsISupports
// Inquire whether the report is for a content process loaded by the given
// frameloader, or any descendents in its BrowsingContext tree.
- bool isReportForBrowserOrChildren(in FrameLoader aFrameLoader);
+ boolean isReportForBrowserOrChildren(in FrameLoader aFrameLoader);
};
diff --git a/dom/ipc/nsILoginDetectionService.idl b/dom/ipc/nsILoginDetectionService.idl
index a0b1ae90a7..123318d5db 100644
--- a/dom/ipc/nsILoginDetectionService.idl
+++ b/dom/ipc/nsILoginDetectionService.idl
@@ -18,5 +18,5 @@ interface nsILoginDetectionService : nsISupports
* Returns true if we have loaded logins from the password manager.
* This is now used by testcase only.
*/
- bool isLoginsLoaded();
+ boolean isLoginsLoaded();
};
diff --git a/dom/ipc/tests/JSWindowActor/browser_event_listener.js b/dom/ipc/tests/JSWindowActor/browser_event_listener.js
index 725c2c3753..21cb0c5ee9 100644
--- a/dom/ipc/tests/JSWindowActor/browser_event_listener.js
+++ b/dom/ipc/tests/JSWindowActor/browser_event_listener.js
@@ -144,7 +144,7 @@ declTest("test in-process content events are not processed twice", {
"content",
"Should be a content <browser>"
);
- is(browser.getAttribute("remotetype"), "", "Should not be remote");
+ is(browser.getAttribute("remotetype"), null, "Should not be remote");
await testEventProcessedOnce(browser);
},
});
@@ -160,8 +160,12 @@ declTest("test in-process chrome events are processed correctly", {
"chrome://mochitests/content/browser/dom/ipc/tests/JSWindowActor/file_dummyChromePage.html"
);
let chromeBrowser = dialog._frame;
- is(chromeBrowser.getAttribute("type"), "", "Should be a chrome <browser>");
- is(chromeBrowser.getAttribute("remotetype"), "", "Should not be remote");
+ is(
+ chromeBrowser.getAttribute("type"),
+ null,
+ "Should be a chrome <browser>"
+ );
+ is(chromeBrowser.getAttribute("remotetype"), null, "Should not be remote");
await testEventProcessedOnce(chromeBrowser, "dummyChromePage.html");
diff --git a/dom/ipc/tests/browser.toml b/dom/ipc/tests/browser.toml
index cd2129e9c1..550558ca46 100644
--- a/dom/ipc/tests/browser.toml
+++ b/dom/ipc/tests/browser.toml
@@ -64,6 +64,8 @@ skip-if = [
["browser_hide_tooltip.js"]
+["browser_isactiveintab.js"]
+
["browser_layers_unloaded_while_interruptingJS.js"]
["browser_memory_distribution_telemetry.js"]
diff --git a/dom/ipc/tests/browser_isactiveintab.js b/dom/ipc/tests/browser_isactiveintab.js
new file mode 100644
index 0000000000..bd189f1826
--- /dev/null
+++ b/dom/ipc/tests/browser_isactiveintab.js
@@ -0,0 +1,138 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function documentURL(origin, html) {
+ let params = new URLSearchParams();
+ params.append("html", html.trim());
+ return `${origin}/document-builder.sjs?${params.toString()}`;
+}
+
+add_task(async function checkIsActiveInTab() {
+ // This test creates a few tricky situations with navigation and iframes and
+ // examines the results of various ways you might think to check if a page
+ // is currently visible, and confirms that isActiveInTab works, even if the
+ // others don't.
+
+ // Make a top level page with two nested iframes.
+ const IFRAME2_URL = documentURL("https://example.com", `<h1>iframe2</h1>`);
+ const IFRAME1_URL = documentURL(
+ "https://example.com",
+ `<iframe src=${JSON.stringify(IFRAME2_URL)}></iframe><h1>iframe1</h1>`
+ );
+ const TEST_URL = documentURL(
+ "https://example.com",
+ `<iframe src=${JSON.stringify(IFRAME1_URL)}></iframe><h1>top window</h1>`
+ );
+
+ await BrowserTestUtils.withNewTab(TEST_URL, async browser => {
+ let topBC1 = browser.browsingContext;
+ let topWindowGlobal1 = topBC1.currentWindowGlobal;
+
+ is(
+ browser.browsingContext.children.length,
+ 1,
+ "only one child for top window"
+ );
+ let iframe1 = browser.browsingContext.children[0];
+ let iframeWindowGlobal1a = iframe1.currentWindowGlobal;
+
+ is(iframe1.children.length, 1, "only one child for iframe");
+ let iframe2 = iframe1.children[0];
+ let iframeWindowGlobal2 = iframe2.currentWindowGlobal;
+
+ ok(topWindowGlobal1.isActiveInTab, "top window global is active in tab");
+ ok(iframeWindowGlobal1a.isActiveInTab, "topmost iframe is active in tab");
+ ok(iframeWindowGlobal2.isActiveInTab, "innermost iframe is active in tab");
+
+ // Do a same-origin navigation on the topmost iframe.
+ let iframe1bURI =
+ "https://example.com/browser/dom/ipc/tests/file_dummy.html";
+ let loadedIframe = BrowserTestUtils.browserLoaded(
+ browser,
+ true,
+ iframe1bURI
+ );
+ await SpecialPowers.spawn(
+ iframe1,
+ [iframe1bURI],
+ async function (_iframe1bURI) {
+ content.location = _iframe1bURI;
+ }
+ );
+ await loadedIframe;
+
+ ok(
+ topWindowGlobal1.isActiveInTab,
+ "top window global is still active in tab"
+ );
+
+ let iframeWindowGlobal1b = iframe1.currentWindowGlobal;
+ isnot(
+ iframeWindowGlobal1a,
+ iframeWindowGlobal1b,
+ "navigating changed the iframe's current window"
+ );
+
+ // This tests the !CanSend() case but unfortunately not the
+ // `bc->GetCurrentWindowGlobal() != this` case. Apparently the latter will
+ // only hold temporarily, so that is likely hard to test.
+ ok(
+ !iframeWindowGlobal1a.isActiveInTab,
+ "topmost iframe is not active in tab"
+ );
+
+ ok(iframeWindowGlobal1b.isActiveInTab, "new iframe is active in tab");
+
+ is(
+ iframe2.currentWindowGlobal,
+ iframeWindowGlobal2,
+ "innermost iframe current window global has not changed"
+ );
+
+ ok(
+ iframeWindowGlobal2.isCurrentGlobal,
+ "innermost iframe is still the current global for its BC"
+ );
+
+ // With a same-origin navigation, this hits the !bc->AncestorsAreCurrent()
+ // case. (With a cross-origin navigation, this hits the !CanSend() case.)
+ ok(
+ !iframeWindowGlobal2.isActiveInTab,
+ "innermost iframe is not active in tab"
+ );
+
+ // Load a new page into the tab to test the behavior when a page is in
+ // the BFCache.
+ let newTopURI = "https://example.com/browser/dom/ipc/tests/file_dummy.html";
+ let loadedTop2 = BrowserTestUtils.browserLoaded(browser, false, newTopURI);
+ await BrowserTestUtils.startLoadingURIString(browser, newTopURI);
+ await loadedTop2;
+
+ isnot(browser.browsingContext, topBC1, "Navigated to a new BC");
+
+ is(
+ topBC1.currentWindowGlobal,
+ topWindowGlobal1,
+ "old top window is still the current window global for the old BC"
+ );
+ ok(topWindowGlobal1.isInBFCache, "old top window's BC is in the BFCache");
+ ok(!topWindowGlobal1.isCurrentGlobal, "old top frame isn't current");
+ ok(!topWindowGlobal1.isActiveInTab, "old top frame not active in tab");
+
+ is(
+ iframe1.currentWindowGlobal,
+ iframeWindowGlobal1b,
+ "old iframe is still the current window global for the BC"
+ );
+ ok(!iframeWindowGlobal1b.isCurrentGlobal, "newer top iframe isn't current");
+ ok(
+ iframeWindowGlobal1b.isInBFCache,
+ "old top window's BC is in the BFCache"
+ );
+ ok(iframe1.ancestorsAreCurrent, "ancestors of iframe are current");
+ ok(
+ !iframeWindowGlobal1b.isActiveInTab,
+ "newer top iframe is active in not active in tab after top level navigation"
+ );
+ });
+});