mirror of
https://github.com/microsoft/playwright.git
synced 2024-12-17 16:21:55 +03:00
66292a5895
Review URL: 4cedc704b1
Firefox 96 changes default sameSite cookie value, so this patch
updates tests to accomodate for this.
2811 lines
109 KiB
Diff
2811 lines
109 KiB
Diff
diff --git a/accessible/base/NotificationController.h b/accessible/base/NotificationController.h
|
|
index 8bc6fdb5f1f9a9bdd4d42eebfd4fc3437e906868..cef1d4b76df94c969516f2b74d8317cf430aeb6a 100644
|
|
--- a/accessible/base/NotificationController.h
|
|
+++ b/accessible/base/NotificationController.h
|
|
@@ -275,6 +275,8 @@ class NotificationController final : public EventQueue,
|
|
}
|
|
#endif
|
|
|
|
+ bool IsUpdatePendingForJugglerAccessibility() { return IsUpdatePending(); }
|
|
+
|
|
protected:
|
|
virtual ~NotificationController();
|
|
|
|
diff --git a/accessible/interfaces/nsIAccessibleDocument.idl b/accessible/interfaces/nsIAccessibleDocument.idl
|
|
index a91df31c96afda66f478a5a38eaa4352039c2a0b..ee777c1746284027fb3aa2f1686f8082af9d89ee 100644
|
|
--- a/accessible/interfaces/nsIAccessibleDocument.idl
|
|
+++ b/accessible/interfaces/nsIAccessibleDocument.idl
|
|
@@ -72,4 +72,9 @@ interface nsIAccessibleDocument : nsISupports
|
|
* Return the child document accessible at the given index.
|
|
*/
|
|
nsIAccessibleDocument getChildDocumentAt(in unsigned long index);
|
|
+
|
|
+ /**
|
|
+ * Return whether it is updating.
|
|
+ */
|
|
+ readonly attribute boolean isUpdatePendingForJugglerAccessibility;
|
|
};
|
|
diff --git a/accessible/xpcom/xpcAccessibleDocument.cpp b/accessible/xpcom/xpcAccessibleDocument.cpp
|
|
index ec83b699e1449b2610b43b35694ee18d80cee2ff..66854bda7d8c20627949289b9f2e2e161a00fea8 100644
|
|
--- a/accessible/xpcom/xpcAccessibleDocument.cpp
|
|
+++ b/accessible/xpcom/xpcAccessibleDocument.cpp
|
|
@@ -142,6 +142,15 @@ xpcAccessibleDocument::GetVirtualCursor(nsIAccessiblePivot** aVirtualCursor) {
|
|
return NS_OK;
|
|
}
|
|
|
|
+
|
|
+NS_IMETHODIMP
|
|
+xpcAccessibleDocument::GetIsUpdatePendingForJugglerAccessibility(bool* updating) {
|
|
+ NS_ENSURE_ARG_POINTER(updating);
|
|
+ *updating = Intl()->Controller()->IsUpdatePendingForJugglerAccessibility();
|
|
+ return NS_OK;
|
|
+}
|
|
+
|
|
+
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// xpcAccessibleDocument
|
|
|
|
diff --git a/accessible/xpcom/xpcAccessibleDocument.h b/accessible/xpcom/xpcAccessibleDocument.h
|
|
index 94aab80cef662a0ba092557cf2a9882c3dc919ac..f1df85042035d89665d7103faf52a8922856a052 100644
|
|
--- a/accessible/xpcom/xpcAccessibleDocument.h
|
|
+++ b/accessible/xpcom/xpcAccessibleDocument.h
|
|
@@ -48,6 +48,8 @@ class xpcAccessibleDocument : public xpcAccessibleHyperText,
|
|
nsIAccessibleDocument** aDocument) final;
|
|
NS_IMETHOD GetVirtualCursor(nsIAccessiblePivot** aVirtualCursor) final;
|
|
|
|
+ NS_IMETHOD GetIsUpdatePendingForJugglerAccessibility(bool* aUpdating) final;
|
|
+
|
|
/**
|
|
* Return XPCOM wrapper for the internal accessible.
|
|
*/
|
|
diff --git a/browser/app/winlauncher/LauncherProcessWin.cpp b/browser/app/winlauncher/LauncherProcessWin.cpp
|
|
index c8104483ac57b54ca846803f584ff0146b81006d..f1763cc82998d03ac751a21b977a029ba400c9af 100644
|
|
--- a/browser/app/winlauncher/LauncherProcessWin.cpp
|
|
+++ b/browser/app/winlauncher/LauncherProcessWin.cpp
|
|
@@ -23,6 +23,7 @@
|
|
#include "mozilla/WinHeaderOnlyUtils.h"
|
|
#include "nsWindowsHelpers.h"
|
|
|
|
+#include <io.h>
|
|
#include <windows.h>
|
|
#include <processthreadsapi.h>
|
|
|
|
@@ -359,8 +360,19 @@ Maybe<int> LauncherMain(int& argc, wchar_t* argv[],
|
|
HANDLE stdHandles[] = {::GetStdHandle(STD_INPUT_HANDLE),
|
|
::GetStdHandle(STD_OUTPUT_HANDLE),
|
|
::GetStdHandle(STD_ERROR_HANDLE)};
|
|
-
|
|
attrs.AddInheritableHandles(stdHandles);
|
|
+ // Playwright pipe installation.
|
|
+ bool hasJugglerPipe =
|
|
+ mozilla::CheckArg(argc, argv, L"juggler-pipe",
|
|
+ static_cast<const wchar_t**>(nullptr),
|
|
+ mozilla::CheckArgFlag::None) == mozilla::ARG_FOUND;
|
|
+ if (hasJugglerPipe) {
|
|
+ intptr_t stdio3 = _get_osfhandle(3);
|
|
+ intptr_t stdio4 = _get_osfhandle(4);
|
|
+ HANDLE pipeHandles[] = {reinterpret_cast<HANDLE>(stdio3),
|
|
+ reinterpret_cast<HANDLE>(stdio4)};
|
|
+ attrs.AddInheritableHandles(pipeHandles);
|
|
+ }
|
|
|
|
DWORD creationFlags = CREATE_SUSPENDED | CREATE_UNICODE_ENVIRONMENT;
|
|
|
|
diff --git a/browser/installer/allowed-dupes.mn b/browser/installer/allowed-dupes.mn
|
|
index b59fe4b1854fec7cb329139f9c6773498fb9de51..29973af04902848808e850b40bf85e5f694d349a 100644
|
|
--- a/browser/installer/allowed-dupes.mn
|
|
+++ b/browser/installer/allowed-dupes.mn
|
|
@@ -71,6 +71,12 @@ browser/features/webcompat@mozilla.org/shims/empty-shim.txt
|
|
removed-files
|
|
#endif
|
|
|
|
+# Juggler/marionette files
|
|
+chrome/juggler/content/content/floating-scrollbars.css
|
|
+browser/chrome/devtools/skin/floating-scrollbars-responsive-design.css
|
|
+chrome/juggler/content/server/stream-utils.js
|
|
+chrome/marionette/content/stream-utils.js
|
|
+
|
|
#ifdef MOZ_EME_WIN32_ARTIFACT
|
|
gmp-clearkey/0.1/manifest.json
|
|
i686/gmp-clearkey/0.1/manifest.json
|
|
diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in
|
|
index 4d7a4810a7f27167c2c2c23dd3bfdbb7709fd87c..c251763ad0c248212f117da91bd0d95288e1ee4c 100644
|
|
--- a/browser/installer/package-manifest.in
|
|
+++ b/browser/installer/package-manifest.in
|
|
@@ -198,6 +198,11 @@
|
|
@RESPATH@/chrome/remote.manifest
|
|
#endif
|
|
|
|
+@RESPATH@/chrome/juggler@JAREXT@
|
|
+@RESPATH@/chrome/juggler.manifest
|
|
+@RESPATH@/components/juggler.manifest
|
|
+@RESPATH@/components/juggler.js
|
|
+
|
|
#if defined(ENABLE_TESTS) && defined(MOZ_DEBUG)
|
|
@RESPATH@/components/TestInterfaceJS.js
|
|
@RESPATH@/components/TestInterfaceJS.manifest
|
|
diff --git a/devtools/server/socket/websocket-server.js b/devtools/server/socket/websocket-server.js
|
|
index 040c7b124dec6bb254563bbe74fe50012cb077a3..b4e6b8132786af70e8ad0dce88b67c2835307f88 100644
|
|
--- a/devtools/server/socket/websocket-server.js
|
|
+++ b/devtools/server/socket/websocket-server.js
|
|
@@ -133,13 +133,12 @@ function writeHttpResponse(output, response) {
|
|
* Process the WebSocket handshake headers and return the key to be sent in
|
|
* Sec-WebSocket-Accept response header.
|
|
*/
|
|
-function processRequest({ requestLine, headers }) {
|
|
+function processRequest({ requestLine, headers }, expectedPath) {
|
|
const [method, path] = requestLine.split(" ");
|
|
if (method !== "GET") {
|
|
throw new Error("The handshake request must use GET method");
|
|
}
|
|
-
|
|
- if (path !== "/") {
|
|
+ if (path !== expectedPath) {
|
|
throw new Error("The handshake request has unknown path");
|
|
}
|
|
|
|
@@ -189,13 +188,13 @@ function computeKey(key) {
|
|
/**
|
|
* Perform the server part of a WebSocket opening handshake on an incoming connection.
|
|
*/
|
|
-const serverHandshake = async function(input, output) {
|
|
+const serverHandshake = async function(input, output, expectedPath) {
|
|
// Read the request
|
|
const request = await readHttpRequest(input);
|
|
|
|
try {
|
|
// Check and extract info from the request
|
|
- const { acceptKey } = processRequest(request);
|
|
+ const { acceptKey } = processRequest(request, expectedPath);
|
|
|
|
// Send response headers
|
|
await writeHttpResponse(output, [
|
|
@@ -217,8 +216,8 @@ const serverHandshake = async function(input, output) {
|
|
* Performs the WebSocket handshake and waits for the WebSocket to open.
|
|
* Returns Promise with a WebSocket ready to send and receive messages.
|
|
*/
|
|
-const accept = async function(transport, input, output) {
|
|
- await serverHandshake(input, output);
|
|
+const accept = async function(transport, input, output, expectedPath) {
|
|
+ await serverHandshake(input, output, expectedPath || "/");
|
|
|
|
const transportProvider = {
|
|
setListener(upgradeListener) {
|
|
diff --git a/docshell/base/BrowsingContext.cpp b/docshell/base/BrowsingContext.cpp
|
|
index 8025adb2d19f392ce8f82a228b13ad8dcf9394d8..d339e7aaaab9719289a7c61aaa0a8d5b8afb9847 100644
|
|
--- a/docshell/base/BrowsingContext.cpp
|
|
+++ b/docshell/base/BrowsingContext.cpp
|
|
@@ -109,6 +109,20 @@ struct ParamTraits<mozilla::dom::PrefersColorSchemeOverride>
|
|
mozilla::dom::PrefersColorSchemeOverride::None,
|
|
mozilla::dom::PrefersColorSchemeOverride::EndGuard_> {};
|
|
|
|
+template <>
|
|
+struct ParamTraits<mozilla::dom::PrefersReducedMotionOverride>
|
|
+ : public ContiguousEnumSerializer<
|
|
+ mozilla::dom::PrefersReducedMotionOverride,
|
|
+ mozilla::dom::PrefersReducedMotionOverride::None,
|
|
+ mozilla::dom::PrefersReducedMotionOverride::EndGuard_> {};
|
|
+
|
|
+template <>
|
|
+struct ParamTraits<mozilla::dom::ForcedColorsOverride>
|
|
+ : public ContiguousEnumSerializer<
|
|
+ mozilla::dom::ForcedColorsOverride,
|
|
+ mozilla::dom::ForcedColorsOverride::None,
|
|
+ mozilla::dom::ForcedColorsOverride::EndGuard_> {};
|
|
+
|
|
template <>
|
|
struct ParamTraits<mozilla::dom::ExplicitActiveStatus>
|
|
: public ContiguousEnumSerializer<
|
|
@@ -2774,6 +2788,40 @@ void BrowsingContext::DidSet(FieldIndex<IDX_PrefersColorSchemeOverride>,
|
|
});
|
|
}
|
|
|
|
+void BrowsingContext::DidSet(FieldIndex<IDX_PrefersReducedMotionOverride>,
|
|
+ dom::PrefersReducedMotionOverride aOldValue) {
|
|
+ MOZ_ASSERT(IsTop());
|
|
+ if (PrefersReducedMotionOverride() == aOldValue) {
|
|
+ return;
|
|
+ }
|
|
+ PreOrderWalk([&](BrowsingContext* aContext) {
|
|
+ if (nsIDocShell* shell = aContext->GetDocShell()) {
|
|
+ if (nsPresContext* pc = shell->GetPresContext()) {
|
|
+ pc->MediaFeatureValuesChanged(
|
|
+ {MediaFeatureChangeReason::SystemMetricsChange},
|
|
+ MediaFeatureChangePropagation::JustThisDocument);
|
|
+ }
|
|
+ }
|
|
+ });
|
|
+}
|
|
+
|
|
+void BrowsingContext::DidSet(FieldIndex<IDX_ForcedColorsOverride>,
|
|
+ dom::ForcedColorsOverride aOldValue) {
|
|
+ MOZ_ASSERT(IsTop());
|
|
+ if (ForcedColorsOverride() == aOldValue) {
|
|
+ return;
|
|
+ }
|
|
+ PreOrderWalk([&](BrowsingContext* aContext) {
|
|
+ if (nsIDocShell* shell = aContext->GetDocShell()) {
|
|
+ if (nsPresContext* pc = shell->GetPresContext()) {
|
|
+ pc->MediaFeatureValuesChanged(
|
|
+ {MediaFeatureChangeReason::SystemMetricsChange},
|
|
+ MediaFeatureChangePropagation::JustThisDocument);
|
|
+ }
|
|
+ }
|
|
+ });
|
|
+}
|
|
+
|
|
void BrowsingContext::DidSet(FieldIndex<IDX_MediumOverride>,
|
|
nsString&& aOldValue) {
|
|
MOZ_ASSERT(IsTop());
|
|
diff --git a/docshell/base/BrowsingContext.h b/docshell/base/BrowsingContext.h
|
|
index eeb742c95e515aaa3d51760ec1505aaee54b78e2..f3c9a91fb331c3803a70b5bc64d59fbd8088323a 100644
|
|
--- a/docshell/base/BrowsingContext.h
|
|
+++ b/docshell/base/BrowsingContext.h
|
|
@@ -207,6 +207,8 @@ enum class ExplicitActiveStatus : uint8_t {
|
|
FIELD(ServiceWorkersTestingEnabled, bool) \
|
|
FIELD(MediumOverride, nsString) \
|
|
FIELD(PrefersColorSchemeOverride, mozilla::dom::PrefersColorSchemeOverride) \
|
|
+ FIELD(PrefersReducedMotionOverride, mozilla::dom::PrefersReducedMotionOverride) \
|
|
+ FIELD(ForcedColorsOverride, mozilla::dom::ForcedColorsOverride) \
|
|
FIELD(DisplayMode, mozilla::dom::DisplayMode) \
|
|
/* The number of entries added to the session history because of this \
|
|
* browsing context. */ \
|
|
@@ -868,6 +870,14 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
|
|
return GetPrefersColorSchemeOverride();
|
|
}
|
|
|
|
+ dom::PrefersReducedMotionOverride PrefersReducedMotionOverride() const {
|
|
+ return GetPrefersReducedMotionOverride();
|
|
+ }
|
|
+
|
|
+ dom::ForcedColorsOverride ForcedColorsOverride() const {
|
|
+ return GetForcedColorsOverride();
|
|
+ }
|
|
+
|
|
void FlushSessionStore();
|
|
|
|
bool IsInBFCache() const;
|
|
@@ -1007,6 +1017,23 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
|
|
void DidSet(FieldIndex<IDX_PrefersColorSchemeOverride>,
|
|
dom::PrefersColorSchemeOverride aOldValue);
|
|
|
|
+ bool CanSet(FieldIndex<IDX_PrefersReducedMotionOverride>,
|
|
+ dom::PrefersReducedMotionOverride, ContentParent*) {
|
|
+ return IsTop();
|
|
+ }
|
|
+
|
|
+ void DidSet(FieldIndex<IDX_PrefersReducedMotionOverride>,
|
|
+ dom::PrefersReducedMotionOverride aOldValue);
|
|
+
|
|
+
|
|
+ bool CanSet(FieldIndex<IDX_ForcedColorsOverride>,
|
|
+ dom::ForcedColorsOverride, ContentParent*) {
|
|
+ return IsTop();
|
|
+ }
|
|
+
|
|
+ void DidSet(FieldIndex<IDX_ForcedColorsOverride>,
|
|
+ dom::ForcedColorsOverride aOldValue);
|
|
+
|
|
void DidSet(FieldIndex<IDX_MediumOverride>, nsString&& aOldValue);
|
|
|
|
bool CanSet(FieldIndex<IDX_SuspendMediaWhenInactive>, bool, ContentParent*) {
|
|
diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp
|
|
index 67d78caa63174823c4c1947f087cfdfbafa36bda..ce3952ae8ad870ffcc664b95abfd81e6b592baa8 100644
|
|
--- a/docshell/base/nsDocShell.cpp
|
|
+++ b/docshell/base/nsDocShell.cpp
|
|
@@ -15,6 +15,12 @@
|
|
# include <unistd.h> // for getpid()
|
|
#endif
|
|
|
|
+#if JS_HAS_INTL_API && !MOZ_SYSTEM_ICU
|
|
+# include "unicode/locid.h"
|
|
+#endif /* JS_HAS_INTL_API && !MOZ_SYSTEM_ICU */
|
|
+
|
|
+#include "js/LocaleSensitive.h"
|
|
+
|
|
#include "mozilla/ArrayUtils.h"
|
|
#include "mozilla/Attributes.h"
|
|
#include "mozilla/AutoRestore.h"
|
|
@@ -64,6 +70,7 @@
|
|
#include "mozilla/dom/ContentFrameMessageManager.h"
|
|
#include "mozilla/dom/DocGroup.h"
|
|
#include "mozilla/dom/Element.h"
|
|
+#include "mozilla/dom/Geolocation.h"
|
|
#include "mozilla/dom/HTMLAnchorElement.h"
|
|
#include "mozilla/dom/HTMLIFrameElement.h"
|
|
#include "mozilla/dom/PerformanceNavigation.h"
|
|
@@ -88,6 +95,7 @@
|
|
#include "mozilla/dom/LoadURIOptionsBinding.h"
|
|
#include "mozilla/dom/JSWindowActorChild.h"
|
|
#include "mozilla/ipc/ProtocolUtils.h"
|
|
+#include "mozilla/dom/WorkerCommon.h"
|
|
#include "mozilla/net/DocumentChannel.h"
|
|
#include "mozilla/net/DocumentChannelChild.h"
|
|
#include "mozilla/net/ParentChannelWrapper.h"
|
|
@@ -111,6 +119,7 @@
|
|
#include "nsIDocShellTreeItem.h"
|
|
#include "nsIDocShellTreeOwner.h"
|
|
#include "mozilla/dom/Document.h"
|
|
+#include "mozilla/dom/Element.h"
|
|
#include "nsIDocumentLoaderFactory.h"
|
|
#include "nsIDOMWindow.h"
|
|
#include "nsIEditingSession.h"
|
|
@@ -205,6 +214,7 @@
|
|
#include "nsFocusManager.h"
|
|
#include "nsGlobalWindow.h"
|
|
#include "nsJSEnvironment.h"
|
|
+#include "nsJSUtils.h"
|
|
#include "nsNetCID.h"
|
|
#include "nsNetUtil.h"
|
|
#include "nsObjectLoadingContent.h"
|
|
@@ -368,6 +378,13 @@ nsDocShell::nsDocShell(BrowsingContext* aBrowsingContext,
|
|
mAllowDNSPrefetch(true),
|
|
mAllowWindowControl(true),
|
|
mCSSErrorReportingEnabled(false),
|
|
+ mFileInputInterceptionEnabled(false),
|
|
+ mOverrideHasFocus(false),
|
|
+ mBypassCSPEnabled(false),
|
|
+ mForceActiveState(false),
|
|
+ mOnlineOverride(nsIDocShell::ONLINE_OVERRIDE_NONE),
|
|
+ mReducedMotionOverride(REDUCED_MOTION_OVERRIDE_NONE),
|
|
+ mForcedColorsOverride(FORCED_COLORS_OVERRIDE_NO_OVERRIDE),
|
|
mAllowAuth(mItemType == typeContent),
|
|
mAllowKeywordFixup(false),
|
|
mDisableMetaRefreshWhenInactive(false),
|
|
@@ -3126,6 +3143,221 @@ nsDocShell::GetMessageManager(ContentFrameMessageManager** aMessageManager) {
|
|
return NS_OK;
|
|
}
|
|
|
|
+// =============== Juggler Begin =======================
|
|
+
|
|
+nsDocShell* nsDocShell::GetRootDocShell() {
|
|
+ nsCOMPtr<nsIDocShellTreeItem> rootAsItem;
|
|
+ GetInProcessSameTypeRootTreeItem(getter_AddRefs(rootAsItem));
|
|
+ nsCOMPtr<nsIDocShell> rootShell = do_QueryInterface(rootAsItem);
|
|
+ return nsDocShell::Cast(rootShell);
|
|
+}
|
|
+
|
|
+NS_IMETHODIMP
|
|
+nsDocShell::GetBypassCSPEnabled(bool* aEnabled) {
|
|
+ MOZ_ASSERT(aEnabled);
|
|
+ *aEnabled = mBypassCSPEnabled;
|
|
+ return NS_OK;
|
|
+}
|
|
+
|
|
+NS_IMETHODIMP
|
|
+nsDocShell::SetBypassCSPEnabled(bool aEnabled) {
|
|
+ mBypassCSPEnabled = aEnabled;
|
|
+ return NS_OK;
|
|
+}
|
|
+
|
|
+NS_IMETHODIMP
|
|
+nsDocShell::GetForceActiveState(bool* aEnabled) {
|
|
+ MOZ_ASSERT(aEnabled);
|
|
+ *aEnabled = mForceActiveState;
|
|
+ return NS_OK;
|
|
+}
|
|
+
|
|
+NS_IMETHODIMP
|
|
+nsDocShell::SetForceActiveState(bool aEnabled) {
|
|
+ mForceActiveState = aEnabled;
|
|
+ ActivenessMaybeChanged();
|
|
+ return NS_OK;
|
|
+}
|
|
+
|
|
+bool nsDocShell::IsBypassCSPEnabled() {
|
|
+ return GetRootDocShell()->mBypassCSPEnabled;
|
|
+}
|
|
+
|
|
+NS_IMETHODIMP
|
|
+nsDocShell::GetOverrideHasFocus(bool* aEnabled) {
|
|
+ MOZ_ASSERT(aEnabled);
|
|
+ *aEnabled = mOverrideHasFocus;
|
|
+ return NS_OK;
|
|
+}
|
|
+
|
|
+NS_IMETHODIMP
|
|
+nsDocShell::SetOverrideHasFocus(bool aEnabled) {
|
|
+ mOverrideHasFocus = aEnabled;
|
|
+ return NS_OK;
|
|
+}
|
|
+
|
|
+bool nsDocShell::ShouldOverrideHasFocus() const {
|
|
+ return mOverrideHasFocus;
|
|
+}
|
|
+
|
|
+NS_IMETHODIMP
|
|
+nsDocShell::GetLanguageOverride(nsAString& aLanguageOverride) {
|
|
+ aLanguageOverride = GetRootDocShell()->mLanguageOverride;
|
|
+ return NS_OK;
|
|
+}
|
|
+
|
|
+
|
|
+static void SetIcuLocale(const nsAString& aLanguageOverride) {
|
|
+ icu::Locale locale(NS_LossyConvertUTF16toASCII(aLanguageOverride).get());
|
|
+ if (icu::Locale::getDefault() == locale)
|
|
+ return;
|
|
+ UErrorCode error_code = U_ZERO_ERROR;
|
|
+ const char* lang = locale.getLanguage();
|
|
+ if (lang != nullptr && *lang != '\0') {
|
|
+ icu::Locale::setDefault(locale, error_code);
|
|
+ } else {
|
|
+ fprintf(stderr, "SetIcuLocale Failed to set the ICU default locale to %s\n", NS_LossyConvertUTF16toASCII(aLanguageOverride).get());
|
|
+ }
|
|
+
|
|
+ AutoJSAPI jsapi;
|
|
+ jsapi.Init();
|
|
+ JSContext* cx = jsapi.cx();
|
|
+ JS_ResetDefaultLocale(JS_GetRuntime(cx));
|
|
+
|
|
+ ResetDefaultLocaleInAllWorkers();
|
|
+}
|
|
+
|
|
+NS_IMETHODIMP
|
|
+nsDocShell::SetLanguageOverride(const nsAString& aLanguageOverride) {
|
|
+ mLanguageOverride = aLanguageOverride;
|
|
+ SetIcuLocale(aLanguageOverride);
|
|
+ return NS_OK;
|
|
+}
|
|
+
|
|
+NS_IMETHODIMP
|
|
+nsDocShell::OverrideTimezone(const nsAString& aTimezoneOverride,
|
|
+ bool* aSuccess) {
|
|
+ NS_ENSURE_ARG(aSuccess);
|
|
+ NS_LossyConvertUTF16toASCII timeZoneId(aTimezoneOverride);
|
|
+ *aSuccess = nsJSUtils::SetTimeZoneOverride(timeZoneId.get());
|
|
+
|
|
+ // Set TZ which affects localtime_s().
|
|
+ auto setTimeZoneEnv = [](const char* value) {
|
|
+#if defined(_WIN32)
|
|
+ return _putenv_s("TZ", value) == 0;
|
|
+#else
|
|
+ return setenv("TZ", value, true) == 0;
|
|
+#endif /* _WIN32 */
|
|
+ };
|
|
+ if (*aSuccess) {
|
|
+ *aSuccess = setTimeZoneEnv(timeZoneId.get());
|
|
+ if (!*aSuccess) {
|
|
+ fprintf(stderr, "Failed to set 'TZ' to '%s'\n", timeZoneId.get());
|
|
+ }
|
|
+ }
|
|
+ return NS_OK;
|
|
+}
|
|
+
|
|
+NS_IMETHODIMP
|
|
+nsDocShell::GetFileInputInterceptionEnabled(bool* aEnabled) {
|
|
+ MOZ_ASSERT(aEnabled);
|
|
+ *aEnabled = GetRootDocShell()->mFileInputInterceptionEnabled;
|
|
+ return NS_OK;
|
|
+}
|
|
+
|
|
+NS_IMETHODIMP
|
|
+nsDocShell::SetFileInputInterceptionEnabled(bool aEnabled) {
|
|
+ mFileInputInterceptionEnabled = aEnabled;
|
|
+ return NS_OK;
|
|
+}
|
|
+
|
|
+bool nsDocShell::IsFileInputInterceptionEnabled() {
|
|
+ return GetRootDocShell()->mFileInputInterceptionEnabled;
|
|
+}
|
|
+
|
|
+void nsDocShell::FilePickerShown(mozilla::dom::Element* element) {
|
|
+ nsCOMPtr<nsIObserverService> observerService =
|
|
+ mozilla::services::GetObserverService();
|
|
+ observerService->NotifyObservers(
|
|
+ ToSupports(element), "juggler-file-picker-shown", nullptr);
|
|
+}
|
|
+
|
|
+RefPtr<nsGeolocationService> nsDocShell::GetGeolocationServiceOverride() {
|
|
+ return GetRootDocShell()->mGeolocationServiceOverride;
|
|
+}
|
|
+
|
|
+NS_IMETHODIMP
|
|
+nsDocShell::SetGeolocationOverride(nsIDOMGeoPosition* aGeolocationOverride) {
|
|
+ if (aGeolocationOverride) {
|
|
+ if (!mGeolocationServiceOverride) {
|
|
+ mGeolocationServiceOverride = new nsGeolocationService();
|
|
+ mGeolocationServiceOverride->Init();
|
|
+ }
|
|
+ mGeolocationServiceOverride->Update(aGeolocationOverride);
|
|
+ } else {
|
|
+ mGeolocationServiceOverride = nullptr;
|
|
+ }
|
|
+ return NS_OK;
|
|
+}
|
|
+
|
|
+NS_IMETHODIMP
|
|
+nsDocShell::GetOnlineOverride(OnlineOverride* aOnlineOverride) {
|
|
+ *aOnlineOverride = GetRootDocShell()->mOnlineOverride;
|
|
+ return NS_OK;
|
|
+}
|
|
+
|
|
+NS_IMETHODIMP
|
|
+nsDocShell::SetOnlineOverride(OnlineOverride aOnlineOverride) {
|
|
+ // We don't have a way to verify this coming from Javascript, so this check is
|
|
+ // still needed.
|
|
+ if (!(aOnlineOverride == ONLINE_OVERRIDE_NONE ||
|
|
+ aOnlineOverride == ONLINE_OVERRIDE_ONLINE ||
|
|
+ aOnlineOverride == ONLINE_OVERRIDE_OFFLINE)) {
|
|
+ return NS_ERROR_INVALID_ARG;
|
|
+ }
|
|
+
|
|
+ mOnlineOverride = aOnlineOverride;
|
|
+ return NS_OK;
|
|
+}
|
|
+
|
|
+NS_IMETHODIMP
|
|
+nsDocShell::GetReducedMotionOverride(ReducedMotionOverride* aReducedMotionOverride) {
|
|
+ *aReducedMotionOverride = GetRootDocShell()->mReducedMotionOverride;
|
|
+ return NS_OK;
|
|
+}
|
|
+
|
|
+NS_IMETHODIMP
|
|
+nsDocShell::SetReducedMotionOverride(ReducedMotionOverride aReducedMotionOverride) {
|
|
+ mReducedMotionOverride = aReducedMotionOverride;
|
|
+ RefPtr<nsPresContext> presContext = GetPresContext();
|
|
+ if (presContext) {
|
|
+ presContext->MediaFeatureValuesChanged(
|
|
+ {MediaFeatureChangeReason::SystemMetricsChange},
|
|
+ MediaFeatureChangePropagation::JustThisDocument);
|
|
+ }
|
|
+ return NS_OK;
|
|
+}
|
|
+
|
|
+NS_IMETHODIMP
|
|
+nsDocShell::GetForcedColorsOverride(ForcedColorsOverride* aForcedColorsOverride) {
|
|
+ *aForcedColorsOverride = GetRootDocShell()->mForcedColorsOverride;
|
|
+ return NS_OK;
|
|
+}
|
|
+
|
|
+NS_IMETHODIMP
|
|
+nsDocShell::SetForcedColorsOverride(ForcedColorsOverride aForcedColorsOverride) {
|
|
+ mForcedColorsOverride = aForcedColorsOverride;
|
|
+ RefPtr<nsPresContext> presContext = GetPresContext();
|
|
+ if (presContext) {
|
|
+ presContext->MediaFeatureValuesChanged(
|
|
+ {MediaFeatureChangeReason::SystemMetricsChange},
|
|
+ MediaFeatureChangePropagation::JustThisDocument);
|
|
+ }
|
|
+ return NS_OK;
|
|
+}
|
|
+
|
|
+// =============== Juggler End =======================
|
|
+
|
|
NS_IMETHODIMP
|
|
nsDocShell::GetIsNavigating(bool* aOut) {
|
|
*aOut = mIsNavigating;
|
|
@@ -4761,7 +4993,7 @@ nsDocShell::GetVisibility(bool* aVisibility) {
|
|
}
|
|
|
|
void nsDocShell::ActivenessMaybeChanged() {
|
|
- const bool isActive = mBrowsingContext->IsActive();
|
|
+ const bool isActive = mForceActiveState || mBrowsingContext->IsActive();
|
|
if (RefPtr<PresShell> presShell = GetPresShell()) {
|
|
presShell->ActivenessMaybeChanged();
|
|
}
|
|
@@ -8521,6 +8753,12 @@ nsresult nsDocShell::PerformRetargeting(nsDocShellLoadState* aLoadState) {
|
|
true, // aForceNoOpener
|
|
getter_AddRefs(newBC));
|
|
MOZ_ASSERT(!newBC);
|
|
+ if (rv == NS_OK) {
|
|
+ nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
|
|
+ if (observerService) {
|
|
+ observerService->NotifyObservers(GetAsSupports(this), "juggler-window-open-in-new-context", nullptr);
|
|
+ }
|
|
+ }
|
|
return rv;
|
|
}
|
|
|
|
@@ -12593,6 +12831,9 @@ class OnLinkClickEvent : public Runnable {
|
|
mHandler->OnLinkClickSync(mContent, mLoadState, mNoOpenerImplied,
|
|
mTriggeringPrincipal);
|
|
}
|
|
+ nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
|
|
+ observerService->NotifyObservers(ToSupports(mContent), "juggler-link-click-sync", nullptr);
|
|
+
|
|
return NS_OK;
|
|
}
|
|
|
|
@@ -12671,6 +12912,8 @@ nsresult nsDocShell::OnLinkClick(
|
|
nsCOMPtr<nsIRunnable> ev =
|
|
new OnLinkClickEvent(this, aContent, loadState, noOpenerImplied,
|
|
aIsTrusted, aTriggeringPrincipal);
|
|
+ nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
|
|
+ observerService->NotifyObservers(ToSupports(aContent), "juggler-link-click", nullptr);
|
|
return Dispatch(TaskCategory::UI, ev.forget());
|
|
}
|
|
|
|
diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h
|
|
index de5b6326e76dc0243ea9a823efbb5eafe1f158a0..b2bc54af5ae18b5551968360088e31237a020049 100644
|
|
--- a/docshell/base/nsDocShell.h
|
|
+++ b/docshell/base/nsDocShell.h
|
|
@@ -16,6 +16,7 @@
|
|
#include "mozilla/UniquePtr.h"
|
|
#include "mozilla/WeakPtr.h"
|
|
#include "mozilla/dom/BrowsingContext.h"
|
|
+#include "mozilla/dom/Element.h"
|
|
#include "mozilla/dom/WindowProxyHolder.h"
|
|
#include "nsCOMPtr.h"
|
|
#include "nsCharsetSource.h"
|
|
@@ -76,6 +77,7 @@ class nsCommandManager;
|
|
class nsDocShellEditorData;
|
|
class nsDOMNavigationTiming;
|
|
class nsDSURIContentListener;
|
|
+class nsGeolocationService;
|
|
class nsGlobalWindowOuter;
|
|
|
|
class FramingChecker;
|
|
@@ -400,6 +402,15 @@ class nsDocShell final : public nsDocLoader,
|
|
void SetWillChangeProcess() { mWillChangeProcess = true; }
|
|
bool WillChangeProcess() { return mWillChangeProcess; }
|
|
|
|
+ bool IsFileInputInterceptionEnabled();
|
|
+ void FilePickerShown(mozilla::dom::Element* element);
|
|
+
|
|
+ bool ShouldOverrideHasFocus() const;
|
|
+
|
|
+ bool IsBypassCSPEnabled();
|
|
+
|
|
+ RefPtr<nsGeolocationService> GetGeolocationServiceOverride();
|
|
+
|
|
// Create a content viewer within this nsDocShell for the given
|
|
// `WindowGlobalChild` actor.
|
|
nsresult CreateContentViewerForActor(
|
|
@@ -1002,6 +1013,8 @@ class nsDocShell final : public nsDocLoader,
|
|
|
|
bool CSSErrorReportingEnabled() const { return mCSSErrorReportingEnabled; }
|
|
|
|
+ nsDocShell* GetRootDocShell();
|
|
+
|
|
// Handles retrieval of subframe session history for nsDocShell::LoadURI. If a
|
|
// load is requested in a subframe of the current DocShell, the subframe
|
|
// loadType may need to reflect the loadType of the parent document, or in
|
|
@@ -1282,6 +1295,16 @@ class nsDocShell final : public nsDocLoader,
|
|
bool mAllowDNSPrefetch : 1;
|
|
bool mAllowWindowControl : 1;
|
|
bool mCSSErrorReportingEnabled : 1;
|
|
+ bool mFileInputInterceptionEnabled: 1;
|
|
+ bool mOverrideHasFocus : 1;
|
|
+ bool mBypassCSPEnabled : 1;
|
|
+ bool mForceActiveState : 1;
|
|
+ nsString mLanguageOverride;
|
|
+ RefPtr<nsGeolocationService> mGeolocationServiceOverride;
|
|
+ OnlineOverride mOnlineOverride;
|
|
+ ReducedMotionOverride mReducedMotionOverride;
|
|
+ ForcedColorsOverride mForcedColorsOverride;
|
|
+
|
|
bool mAllowAuth : 1;
|
|
bool mAllowKeywordFixup : 1;
|
|
bool mDisableMetaRefreshWhenInactive : 1;
|
|
diff --git a/docshell/base/nsIDocShell.idl b/docshell/base/nsIDocShell.idl
|
|
index cde0c30784c28f4bef85e0100fd374a1823f2896..3d52eb1f3e511b48607de1baad0719e10b6c4460 100644
|
|
--- a/docshell/base/nsIDocShell.idl
|
|
+++ b/docshell/base/nsIDocShell.idl
|
|
@@ -44,6 +44,7 @@ interface nsIURI;
|
|
interface nsIChannel;
|
|
interface nsIContentViewer;
|
|
interface nsIContentSecurityPolicy;
|
|
+interface nsIDOMGeoPosition;
|
|
interface nsIEditor;
|
|
interface nsIEditingSession;
|
|
interface nsIInputStream;
|
|
@@ -805,6 +806,41 @@ interface nsIDocShell : nsIDocShellTreeItem
|
|
*/
|
|
void synchronizeLayoutHistoryState();
|
|
|
|
+ attribute boolean fileInputInterceptionEnabled;
|
|
+
|
|
+ attribute boolean overrideHasFocus;
|
|
+
|
|
+ attribute boolean bypassCSPEnabled;
|
|
+
|
|
+ attribute boolean forceActiveState;
|
|
+
|
|
+ attribute AString languageOverride;
|
|
+
|
|
+ boolean overrideTimezone(in AString timezoneId);
|
|
+
|
|
+ cenum OnlineOverride: 8 {
|
|
+ ONLINE_OVERRIDE_NONE = 0,
|
|
+ ONLINE_OVERRIDE_ONLINE = 1,
|
|
+ ONLINE_OVERRIDE_OFFLINE = 2,
|
|
+ };
|
|
+ [infallible] attribute nsIDocShell_OnlineOverride onlineOverride;
|
|
+
|
|
+ cenum ReducedMotionOverride : 8 {
|
|
+ REDUCED_MOTION_OVERRIDE_REDUCE,
|
|
+ REDUCED_MOTION_OVERRIDE_NO_PREFERENCE,
|
|
+ REDUCED_MOTION_OVERRIDE_NONE, /* This clears the override. */
|
|
+ };
|
|
+ [infallible] attribute nsIDocShell_ReducedMotionOverride reducedMotionOverride;
|
|
+
|
|
+ cenum ForcedColorsOverride : 8 {
|
|
+ FORCED_COLORS_OVERRIDE_ACTIVE,
|
|
+ FORCED_COLORS_OVERRIDE_NONE,
|
|
+ FORCED_COLORS_OVERRIDE_NO_OVERRIDE, /* This clears the override. */
|
|
+ };
|
|
+ [infallible] attribute nsIDocShell_ForcedColorsOverride forcedColorsOverride;
|
|
+
|
|
+ void setGeolocationOverride(in nsIDOMGeoPosition position);
|
|
+
|
|
/**
|
|
* This attempts to save any applicable layout history state (like
|
|
* scroll position) in the nsISHEntry. This is normally done
|
|
diff --git a/dom/base/Document.cpp b/dom/base/Document.cpp
|
|
index e0fabdac8d31b76a468047f188c095eea5271f5c..e2cc19744968c62b5891f1a74d86f599c946f85e 100644
|
|
--- a/dom/base/Document.cpp
|
|
+++ b/dom/base/Document.cpp
|
|
@@ -3548,6 +3548,9 @@ void Document::SendToConsole(nsCOMArray<nsISecurityConsoleMessage>& aMessages) {
|
|
}
|
|
|
|
void Document::ApplySettingsFromCSP(bool aSpeculative) {
|
|
+ if (mDocumentContainer && mDocumentContainer->IsBypassCSPEnabled())
|
|
+ return;
|
|
+
|
|
nsresult rv = NS_OK;
|
|
if (!aSpeculative) {
|
|
// 1) apply settings from regular CSP
|
|
@@ -3610,6 +3613,11 @@ nsresult Document::InitCSP(nsIChannel* aChannel) {
|
|
return NS_OK;
|
|
}
|
|
|
|
+ nsCOMPtr<nsIDocShell> shell(mDocumentContainer);
|
|
+ if (shell && nsDocShell::Cast(shell)->IsBypassCSPEnabled()) {
|
|
+ return NS_OK;
|
|
+ }
|
|
+
|
|
// If this is a data document - no need to set CSP.
|
|
if (mLoadedAsData) {
|
|
return NS_OK;
|
|
@@ -4398,6 +4406,10 @@ bool Document::HasFocus(ErrorResult& rv) const {
|
|
return false;
|
|
}
|
|
|
|
+ if (IsActive() && mDocumentContainer->ShouldOverrideHasFocus()) {
|
|
+ return true;
|
|
+ }
|
|
+
|
|
if (!fm->IsInActiveWindow(bc)) {
|
|
return false;
|
|
}
|
|
@@ -17716,6 +17728,71 @@ ColorScheme Document::PreferredColorScheme(IgnoreRFP aIgnoreRFP) const {
|
|
return LookAndFeel::PreferredColorSchemeForContent();
|
|
}
|
|
|
|
+bool Document::PrefersReducedMotion() const {
|
|
+ auto* docShell = static_cast<nsDocShell*>(GetDocShell());
|
|
+ nsIDocShell::ReducedMotionOverride reducedMotion;
|
|
+ if (docShell && docShell->GetReducedMotionOverride(&reducedMotion) == NS_OK &&
|
|
+ reducedMotion != nsIDocShell::REDUCED_MOTION_OVERRIDE_NONE) {
|
|
+ switch (reducedMotion) {
|
|
+ case nsIDocShell::REDUCED_MOTION_OVERRIDE_REDUCE:
|
|
+ return true;
|
|
+ case nsIDocShell::REDUCED_MOTION_OVERRIDE_NO_PREFERENCE:
|
|
+ return false;
|
|
+ case nsIDocShell::REDUCED_MOTION_OVERRIDE_NONE:
|
|
+ break;
|
|
+ };
|
|
+ }
|
|
+
|
|
+ if (auto* bc = GetBrowsingContext()) {
|
|
+ switch (bc->Top()->PrefersReducedMotionOverride()) {
|
|
+ case dom::PrefersReducedMotionOverride::Reduce:
|
|
+ return true;
|
|
+ case dom::PrefersReducedMotionOverride::No_preference:
|
|
+ return false;
|
|
+ case dom::PrefersReducedMotionOverride::None:
|
|
+ case dom::PrefersReducedMotionOverride::EndGuard_:
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (nsContentUtils::ShouldResistFingerprinting(this)) {
|
|
+ return false;
|
|
+ }
|
|
+ return LookAndFeel::GetInt(LookAndFeel::IntID::PrefersReducedMotion, 0) == 1;
|
|
+}
|
|
+
|
|
+bool Document::ForcedColors() const {
|
|
+ auto* docShell = static_cast<nsDocShell*>(GetDocShell());
|
|
+ nsIDocShell::ForcedColorsOverride forcedColors;
|
|
+ if (docShell && docShell->GetForcedColorsOverride(&forcedColors) == NS_OK) {
|
|
+ switch (forcedColors) {
|
|
+ case nsIDocShell::FORCED_COLORS_OVERRIDE_ACTIVE:
|
|
+ return true;
|
|
+ case nsIDocShell::FORCED_COLORS_OVERRIDE_NONE:
|
|
+ return false;
|
|
+ case nsIDocShell::FORCED_COLORS_OVERRIDE_NO_OVERRIDE:
|
|
+ break;
|
|
+ };
|
|
+ }
|
|
+
|
|
+ if (auto* bc = GetBrowsingContext()) {
|
|
+ switch (bc->Top()->ForcedColorsOverride()) {
|
|
+ case dom::ForcedColorsOverride::Active:
|
|
+ return true;
|
|
+ case dom::ForcedColorsOverride::None:
|
|
+ return false;
|
|
+ case dom::ForcedColorsOverride::No_override:
|
|
+ case dom::ForcedColorsOverride::EndGuard_:
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (mIsBeingUsedAsImage) {
|
|
+ return false;
|
|
+ }
|
|
+ return !PreferenceSheet::PrefsFor(*this).mUseDocumentColors;
|
|
+}
|
|
+
|
|
bool Document::HasRecentlyStartedForegroundLoads() {
|
|
if (!sLoadingForegroundTopLevelContentDocument) {
|
|
return false;
|
|
diff --git a/dom/base/Document.h b/dom/base/Document.h
|
|
index 12cd9796445fe0f2dc85351f56dbe4eaa3aa4f1a..8ff0ed956b4ed5015dd1541492a69c6582648153 100644
|
|
--- a/dom/base/Document.h
|
|
+++ b/dom/base/Document.h
|
|
@@ -4031,6 +4031,9 @@ class Document : public nsINode,
|
|
// color-scheme meta tag.
|
|
ColorScheme DefaultColorScheme() const;
|
|
|
|
+ bool PrefersReducedMotion() const;
|
|
+ bool ForcedColors() const;
|
|
+
|
|
static bool HasRecentlyStartedForegroundLoads();
|
|
|
|
static bool AutomaticStorageAccessPermissionCanBeGranted(
|
|
diff --git a/dom/base/Navigator.cpp b/dom/base/Navigator.cpp
|
|
index 028104e23ade143e9288a9c7b9832e59fb1b2b6f..515f3f34a095c7f27a3bab072dd16f79dc054386 100644
|
|
--- a/dom/base/Navigator.cpp
|
|
+++ b/dom/base/Navigator.cpp
|
|
@@ -333,14 +333,18 @@ void Navigator::GetAppName(nsAString& aAppName, CallerType aCallerType) const {
|
|
* for more detail.
|
|
*/
|
|
/* static */
|
|
-void Navigator::GetAcceptLanguages(nsTArray<nsString>& aLanguages) {
|
|
+void Navigator::GetAcceptLanguages(const nsString* aLanguageOverride, nsTArray<nsString>& aLanguages) {
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
aLanguages.Clear();
|
|
|
|
// E.g. "de-de, en-us,en".
|
|
nsAutoString acceptLang;
|
|
- Preferences::GetLocalizedString("intl.accept_languages", acceptLang);
|
|
+ if (aLanguageOverride && aLanguageOverride->Length())
|
|
+ acceptLang = *aLanguageOverride;
|
|
+ else
|
|
+ Preferences::GetLocalizedString("intl.accept_languages", acceptLang);
|
|
+
|
|
|
|
// Split values on commas.
|
|
for (nsDependentSubstring lang :
|
|
@@ -392,7 +396,9 @@ void Navigator::GetLanguage(nsAString& aLanguage) {
|
|
}
|
|
|
|
void Navigator::GetLanguages(nsTArray<nsString>& aLanguages) {
|
|
- GetAcceptLanguages(aLanguages);
|
|
+ nsString languageOverride;
|
|
+ mWindow->GetDocShell()->GetLanguageOverride(languageOverride);
|
|
+ GetAcceptLanguages(&languageOverride, aLanguages);
|
|
|
|
// The returned value is cached by the binding code. The window listens to the
|
|
// accept languages change and will clear the cache when needed. It has to
|
|
@@ -560,7 +566,13 @@ bool Navigator::CookieEnabled() {
|
|
return granted;
|
|
}
|
|
|
|
-bool Navigator::OnLine() { return !NS_IsOffline(); }
|
|
+bool Navigator::OnLine() {
|
|
+ nsDocShell* docShell = static_cast<nsDocShell*>(GetDocShell());
|
|
+ nsIDocShell::OnlineOverride onlineOverride;
|
|
+ if (!docShell || docShell->GetOnlineOverride(&onlineOverride) != NS_OK || onlineOverride == nsIDocShell::ONLINE_OVERRIDE_NONE)
|
|
+ return !NS_IsOffline();
|
|
+ return onlineOverride == nsIDocShell::ONLINE_OVERRIDE_ONLINE;
|
|
+}
|
|
|
|
void Navigator::GetBuildID(nsAString& aBuildID, CallerType aCallerType,
|
|
ErrorResult& aRv) const {
|
|
diff --git a/dom/base/Navigator.h b/dom/base/Navigator.h
|
|
index e36cd43b76fd09596f6ccc1e0d70848b3d4ab7c0..40b7f24d8507219a3a7c42857b068e507b63cff9 100644
|
|
--- a/dom/base/Navigator.h
|
|
+++ b/dom/base/Navigator.h
|
|
@@ -215,7 +215,7 @@ class Navigator final : public nsISupports, public nsWrapperCache {
|
|
|
|
StorageManager* Storage();
|
|
|
|
- static void GetAcceptLanguages(nsTArray<nsString>& aLanguages);
|
|
+ static void GetAcceptLanguages(const nsString* aLanguageOverride, nsTArray<nsString>& aLanguages);
|
|
|
|
dom::MediaCapabilities* MediaCapabilities();
|
|
dom::MediaSession* MediaSession();
|
|
diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp
|
|
index 0239d370c05758b7f891dd8c9b667f07092f6d72..0fd2e8478a9c81bca54f1e5054a018558314c786 100644
|
|
--- a/dom/base/nsContentUtils.cpp
|
|
+++ b/dom/base/nsContentUtils.cpp
|
|
@@ -8163,7 +8163,8 @@ nsresult nsContentUtils::SendMouseEvent(
|
|
bool aIgnoreRootScrollFrame, float aPressure,
|
|
unsigned short aInputSourceArg, uint32_t aIdentifier, bool aToWindow,
|
|
PreventDefaultResult* aPreventDefault, bool aIsDOMEventSynthesized,
|
|
- bool aIsWidgetEventSynthesized) {
|
|
+ bool aIsWidgetEventSynthesized,
|
|
+ bool convertToPointer) {
|
|
nsPoint offset;
|
|
nsCOMPtr<nsIWidget> widget = GetWidget(aPresShell, &offset);
|
|
if (!widget) return NS_ERROR_FAILURE;
|
|
@@ -8220,6 +8221,7 @@ nsresult nsContentUtils::SendMouseEvent(
|
|
event.mTime = PR_IntervalNow();
|
|
event.mFlags.mIsSynthesizedForTests = aIsDOMEventSynthesized;
|
|
event.mExitFrom = exitFrom;
|
|
+ event.convertToPointer = convertToPointer;
|
|
|
|
nsPresContext* presContext = aPresShell->GetPresContext();
|
|
if (!presContext) return NS_ERROR_FAILURE;
|
|
diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h
|
|
index 1da3e3005af42c3f1a383c762b08a797899db926..103a83eda019aac8d5e4736cd80dd961d05effab 100644
|
|
--- a/dom/base/nsContentUtils.h
|
|
+++ b/dom/base/nsContentUtils.h
|
|
@@ -2884,7 +2884,8 @@ class nsContentUtils {
|
|
int32_t aModifiers, bool aIgnoreRootScrollFrame, float aPressure,
|
|
unsigned short aInputSourceArg, uint32_t aIdentifier, bool aToWindow,
|
|
mozilla::PreventDefaultResult* aPreventDefault,
|
|
- bool aIsDOMEventSynthesized, bool aIsWidgetEventSynthesized);
|
|
+ bool aIsDOMEventSynthesized, bool aIsWidgetEventSynthesized,
|
|
+ bool convertToPointer = true);
|
|
|
|
static void FirePageShowEventForFrameLoaderSwap(
|
|
nsIDocShellTreeItem* aItem,
|
|
diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp
|
|
index be5a841ba2ecdb03dac6fda601b26a6b6b15e3f3..5b7c4024f3f3995d2113579ab9e0246c6183695f 100644
|
|
--- a/dom/base/nsDOMWindowUtils.cpp
|
|
+++ b/dom/base/nsDOMWindowUtils.cpp
|
|
@@ -642,7 +642,7 @@ nsDOMWindowUtils::SendMouseEvent(
|
|
int32_t aClickCount, int32_t aModifiers, bool aIgnoreRootScrollFrame,
|
|
float aPressure, unsigned short aInputSourceArg,
|
|
bool aIsDOMEventSynthesized, bool aIsWidgetEventSynthesized,
|
|
- int32_t aButtons, uint32_t aIdentifier, uint8_t aOptionalArgCount,
|
|
+ int32_t aButtons, uint32_t aIdentifier, bool aDisablePointerEvent, uint8_t aOptionalArgCount,
|
|
bool* aPreventDefault) {
|
|
return SendMouseEventCommon(
|
|
aType, aX, aY, aButton, aClickCount, aModifiers, aIgnoreRootScrollFrame,
|
|
@@ -650,7 +650,7 @@ nsDOMWindowUtils::SendMouseEvent(
|
|
aOptionalArgCount >= 7 ? aIdentifier : DEFAULT_MOUSE_POINTER_ID, false,
|
|
aPreventDefault, aOptionalArgCount >= 4 ? aIsDOMEventSynthesized : true,
|
|
aOptionalArgCount >= 5 ? aIsWidgetEventSynthesized : false,
|
|
- aOptionalArgCount >= 6 ? aButtons : MOUSE_BUTTONS_NOT_SPECIFIED);
|
|
+ aOptionalArgCount >= 6 ? aButtons : MOUSE_BUTTONS_NOT_SPECIFIED, !aDisablePointerEvent);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
@@ -677,13 +677,13 @@ nsDOMWindowUtils::SendMouseEventCommon(
|
|
int32_t aClickCount, int32_t aModifiers, bool aIgnoreRootScrollFrame,
|
|
float aPressure, unsigned short aInputSourceArg, uint32_t aPointerId,
|
|
bool aToWindow, bool* aPreventDefault, bool aIsDOMEventSynthesized,
|
|
- bool aIsWidgetEventSynthesized, int32_t aButtons) {
|
|
+ bool aIsWidgetEventSynthesized, int32_t aButtons, bool aConvertToPointer) {
|
|
RefPtr<PresShell> presShell = GetPresShell();
|
|
PreventDefaultResult preventDefaultResult;
|
|
nsresult rv = nsContentUtils::SendMouseEvent(
|
|
presShell, aType, aX, aY, aButton, aButtons, aClickCount, aModifiers,
|
|
aIgnoreRootScrollFrame, aPressure, aInputSourceArg, aPointerId, aToWindow,
|
|
- &preventDefaultResult, aIsDOMEventSynthesized, aIsWidgetEventSynthesized);
|
|
+ &preventDefaultResult, aIsDOMEventSynthesized, aIsWidgetEventSynthesized, aConvertToPointer);
|
|
|
|
if (aPreventDefault) {
|
|
*aPreventDefault = preventDefaultResult != PreventDefaultResult::No;
|
|
diff --git a/dom/base/nsDOMWindowUtils.h b/dom/base/nsDOMWindowUtils.h
|
|
index 30e0fafa77857c33e9871259a6ac0cebac965df8..3d8810abcfac1c220529b4e6163b0159475723ff 100644
|
|
--- a/dom/base/nsDOMWindowUtils.h
|
|
+++ b/dom/base/nsDOMWindowUtils.h
|
|
@@ -93,7 +93,7 @@ class nsDOMWindowUtils final : public nsIDOMWindowUtils,
|
|
int32_t aClickCount, int32_t aModifiers, bool aIgnoreRootScrollFrame,
|
|
float aPressure, unsigned short aInputSourceArg, uint32_t aIdentifier,
|
|
bool aToWindow, bool* aPreventDefault, bool aIsDOMEventSynthesized,
|
|
- bool aIsWidgetEventSynthesized, int32_t aButtons);
|
|
+ bool aIsWidgetEventSynthesized, int32_t aButtons, bool aConvertToPointer = true);
|
|
|
|
MOZ_CAN_RUN_SCRIPT
|
|
nsresult SendTouchEventCommon(
|
|
diff --git a/dom/base/nsFocusManager.cpp b/dom/base/nsFocusManager.cpp
|
|
index 1e9d313f27302b7cd5d67fe14425923223192a55..a92d37e245d8a33eefe8bc88a2cb26b7b0b8d11d 100644
|
|
--- a/dom/base/nsFocusManager.cpp
|
|
+++ b/dom/base/nsFocusManager.cpp
|
|
@@ -1620,6 +1620,10 @@ void nsFocusManager::SetFocusInner(Element* aNewContent, int32_t aFlags,
|
|
(GetActiveBrowsingContext() == newRootBrowsingContext);
|
|
}
|
|
|
|
+ // In Playwright, we want to send focus events even if the element
|
|
+ // isn't actually in the active window.
|
|
+ isElementInActiveWindow = true;
|
|
+
|
|
// Exit fullscreen if a website focuses another window
|
|
if (StaticPrefs::full_screen_api_exit_on_windowRaise() &&
|
|
!isElementInActiveWindow && (aFlags & FLAG_RAISE) &&
|
|
@@ -2924,7 +2928,9 @@ void nsFocusManager::RaiseWindow(nsPIDOMWindowOuter* aWindow,
|
|
}
|
|
}
|
|
|
|
- if (sTestMode) {
|
|
+ // In Playwright, we still want to execte the embedder functions
|
|
+ // to actually show / focus windows.
|
|
+ if (false && sTestMode) {
|
|
// In test mode, emulate raising the window. WindowRaised takes
|
|
// care of lowering the present active window. This happens in
|
|
// a separate runnable to avoid touching multiple windows in
|
|
diff --git a/dom/base/nsGlobalWindowOuter.cpp b/dom/base/nsGlobalWindowOuter.cpp
|
|
index 7d367074cf16e5351e7d3784a17c2cc9332087e8..9d94aec268c54e517be00dd649f876cbd26802d9 100644
|
|
--- a/dom/base/nsGlobalWindowOuter.cpp
|
|
+++ b/dom/base/nsGlobalWindowOuter.cpp
|
|
@@ -2497,7 +2497,7 @@ nsresult nsGlobalWindowOuter::SetNewDocument(Document* aDocument,
|
|
&nsGlobalWindowInner::FireOnNewGlobalObject));
|
|
}
|
|
|
|
- if (newInnerWindow && !newInnerWindow->mHasNotifiedGlobalCreated && mDoc) {
|
|
+ if (newInnerWindow && mDoc) {
|
|
// We should probably notify. However if this is the, arguably bad,
|
|
// situation when we're creating a temporary non-chrome-about-blank
|
|
// document in a chrome docshell, don't notify just yet. Instead wait
|
|
@@ -2516,10 +2516,16 @@ nsresult nsGlobalWindowOuter::SetNewDocument(Document* aDocument,
|
|
}();
|
|
|
|
if (!isContentAboutBlankInChromeDocshell) {
|
|
- newInnerWindow->mHasNotifiedGlobalCreated = true;
|
|
- nsContentUtils::AddScriptRunner(NewRunnableMethod(
|
|
- "nsGlobalWindowOuter::DispatchDOMWindowCreated", this,
|
|
- &nsGlobalWindowOuter::DispatchDOMWindowCreated));
|
|
+ if (!newInnerWindow->mHasNotifiedGlobalCreated) {
|
|
+ newInnerWindow->mHasNotifiedGlobalCreated = true;
|
|
+ nsContentUtils::AddScriptRunner(NewRunnableMethod(
|
|
+ "nsGlobalWindowOuter::DispatchDOMWindowCreated", this,
|
|
+ &nsGlobalWindowOuter::DispatchDOMWindowCreated));
|
|
+ } else if (!reUseInnerWindow) {
|
|
+ nsContentUtils::AddScriptRunner(NewRunnableMethod(
|
|
+ "nsGlobalWindowOuter::JugglerDispatchDOMWindowReused", this,
|
|
+ &nsGlobalWindowOuter::JugglerDispatchDOMWindowReused));
|
|
+ }
|
|
}
|
|
}
|
|
|
|
@@ -2643,6 +2649,19 @@ void nsGlobalWindowOuter::DispatchDOMWindowCreated() {
|
|
}
|
|
}
|
|
|
|
+void nsGlobalWindowOuter::JugglerDispatchDOMWindowReused() {
|
|
+ nsCOMPtr<nsIObserverService> observerService =
|
|
+ mozilla::services::GetObserverService();
|
|
+ if (observerService && mDoc) {
|
|
+ nsIPrincipal* principal = mDoc->NodePrincipal();
|
|
+ if (!principal->IsSystemPrincipal()) {
|
|
+ observerService->NotifyObservers(static_cast<nsIDOMWindow*>(this),
|
|
+ "juggler-dom-window-reused",
|
|
+ nullptr);
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
void nsGlobalWindowOuter::ClearStatus() { SetStatusOuter(u""_ns); }
|
|
|
|
void nsGlobalWindowOuter::SetDocShell(nsDocShell* aDocShell) {
|
|
@@ -3826,6 +3845,14 @@ Maybe<CSSIntSize> nsGlobalWindowOuter::GetRDMDeviceSize(
|
|
}
|
|
}
|
|
}
|
|
+ if (topInProcessContentDoc) {
|
|
+ nsIDocShell* docShell = topInProcessContentDoc->GetDocShell();
|
|
+ if (docShell && docShell->GetDeviceSizeIsPageSize()) {
|
|
+ nsPresContext* presContext = docShell->GetPresContext();
|
|
+ if (presContext)
|
|
+ return Some(CSSPixel::FromAppUnitsRounded(presContext->GetVisibleArea().Size()));
|
|
+ }
|
|
+ }
|
|
return Nothing();
|
|
}
|
|
|
|
diff --git a/dom/base/nsGlobalWindowOuter.h b/dom/base/nsGlobalWindowOuter.h
|
|
index 36a0e44fe07aab8f94127eba008aac39d961820d..70545b547d5bd43f559ce86af29205f7a9641262 100644
|
|
--- a/dom/base/nsGlobalWindowOuter.h
|
|
+++ b/dom/base/nsGlobalWindowOuter.h
|
|
@@ -330,6 +330,7 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
|
|
|
|
// Outer windows only.
|
|
void DispatchDOMWindowCreated();
|
|
+ void JugglerDispatchDOMWindowReused();
|
|
|
|
// Outer windows only.
|
|
virtual void EnsureSizeAndPositionUpToDate() override;
|
|
diff --git a/dom/base/nsINode.cpp b/dom/base/nsINode.cpp
|
|
index 46341f6e79e4c6d7b473aafe30c4043e4acb80ac..fb982d65a62978df0f51363a6327409135b1c761 100644
|
|
--- a/dom/base/nsINode.cpp
|
|
+++ b/dom/base/nsINode.cpp
|
|
@@ -1315,6 +1315,49 @@ void nsINode::GetBoxQuadsFromWindowOrigin(const BoxQuadOptions& aOptions,
|
|
mozilla::GetBoxQuadsFromWindowOrigin(this, aOptions, aResult, aRv);
|
|
}
|
|
|
|
+void nsINode::ScrollRectIntoViewIfNeeded(int32_t x, int32_t y,
|
|
+ int32_t w, int32_t h,
|
|
+ ErrorResult& aRv) {
|
|
+ aRv = NS_ERROR_UNEXPECTED;
|
|
+ nsCOMPtr<Document> document = OwnerDoc();
|
|
+ if (!document) {
|
|
+ return aRv.ThrowNotFoundError("Node is detached from document");
|
|
+ }
|
|
+ PresShell* presShell = document->GetPresShell();
|
|
+ if (!presShell) {
|
|
+ return aRv.ThrowNotFoundError("Node is detached from document");
|
|
+ }
|
|
+ if (!IsContent()) {
|
|
+ return aRv.ThrowNotFoundError("Node does not have a layout object");
|
|
+ }
|
|
+ aRv = NS_OK;
|
|
+ nsIFrame* primaryFrame = AsContent()->GetPrimaryFrame(FlushType::Frames);
|
|
+ if (!primaryFrame) {
|
|
+ return aRv.ThrowNotFoundError("Node does not have a layout object");
|
|
+ }
|
|
+ nsRect rect;
|
|
+ if (x == -1 && y == -1 && w == -1 && h == -1) {
|
|
+ rect = primaryFrame->GetRectRelativeToSelf();
|
|
+ } else {
|
|
+ rect = nsRect(nsPresContext::CSSPixelsToAppUnits(x),
|
|
+ nsPresContext::CSSPixelsToAppUnits(y),
|
|
+ nsPresContext::CSSPixelsToAppUnits(w),
|
|
+ nsPresContext::CSSPixelsToAppUnits(h));
|
|
+ }
|
|
+ presShell->ScrollFrameRectIntoView(
|
|
+ primaryFrame, rect,
|
|
+ nsMargin(),
|
|
+ ScrollAxis(kScrollToCenter, WhenToScroll::Always),
|
|
+ ScrollAxis(kScrollToCenter, WhenToScroll::Always),
|
|
+ ScrollFlags::ScrollOverflowHidden);
|
|
+ // If a _visual_ scroll update is pending, cancel it; otherwise, it will
|
|
+ // clobber next scroll (e.g. subsequent window.scrollTo(0, 0) wlll break).
|
|
+ if (presShell->GetPendingVisualScrollUpdate()) {
|
|
+ presShell->AcknowledgePendingVisualScrollUpdate();
|
|
+ presShell->ClearPendingVisualScrollUpdate();
|
|
+ }
|
|
+}
|
|
+
|
|
already_AddRefed<DOMQuad> nsINode::ConvertQuadFromNode(
|
|
DOMQuad& aQuad, const GeometryNode& aFrom,
|
|
const ConvertCoordinateOptions& aOptions, CallerType aCallerType,
|
|
diff --git a/dom/base/nsINode.h b/dom/base/nsINode.h
|
|
index 21d03a3c7b219d38161f91e78dd2cf144c916ecb..c7620cb4c193c8ee1d11c7caff3aea6f72d56c88 100644
|
|
--- a/dom/base/nsINode.h
|
|
+++ b/dom/base/nsINode.h
|
|
@@ -2076,6 +2076,10 @@ class nsINode : public mozilla::dom::EventTarget {
|
|
nsTArray<RefPtr<DOMQuad>>& aResult,
|
|
ErrorResult& aRv);
|
|
|
|
+ void ScrollRectIntoViewIfNeeded(int32_t x, int32_t y,
|
|
+ int32_t w, int32_t h,
|
|
+ ErrorResult& aRv);
|
|
+
|
|
already_AddRefed<DOMQuad> ConvertQuadFromNode(
|
|
DOMQuad& aQuad, const TextOrElementOrDocument& aFrom,
|
|
const ConvertCoordinateOptions& aOptions, CallerType aCallerType,
|
|
diff --git a/dom/base/nsJSUtils.cpp b/dom/base/nsJSUtils.cpp
|
|
index 871b9336718377f185d52c839ef2dc953b4e4210..096cf1dc8261d1d4d6d6b554afe9c3d42b4d1299 100644
|
|
--- a/dom/base/nsJSUtils.cpp
|
|
+++ b/dom/base/nsJSUtils.cpp
|
|
@@ -243,6 +243,11 @@ bool nsJSUtils::GetScopeChainForElement(
|
|
return true;
|
|
}
|
|
|
|
+/* static */
|
|
+bool nsJSUtils::SetTimeZoneOverride(const char* timezoneId) {
|
|
+ return JS::SetTimeZoneOverride(timezoneId);
|
|
+}
|
|
+
|
|
/* static */
|
|
void nsJSUtils::ResetTimeZone() { JS::ResetTimeZone(); }
|
|
|
|
diff --git a/dom/base/nsJSUtils.h b/dom/base/nsJSUtils.h
|
|
index c22cddecd75ee538aa401b9195d23bad71e067b3..1b48a12fd30c305aecf1929a47cb22a1bb4a5e80 100644
|
|
--- a/dom/base/nsJSUtils.h
|
|
+++ b/dom/base/nsJSUtils.h
|
|
@@ -107,6 +107,7 @@ class nsJSUtils {
|
|
JSContext* aCx, mozilla::dom::Element* aElement,
|
|
JS::MutableHandleVector<JSObject*> aScopeChain);
|
|
|
|
+ static bool SetTimeZoneOverride(const char* timezoneId);
|
|
static void ResetTimeZone();
|
|
|
|
static bool DumpEnabled();
|
|
diff --git a/dom/chrome-webidl/BrowsingContext.webidl b/dom/chrome-webidl/BrowsingContext.webidl
|
|
index 4f8f8df3cecec37d87dfb6f23d5888419d9b8d6c..2e5ef8dc4599a6bd26654023360421394cc59c3e 100644
|
|
--- a/dom/chrome-webidl/BrowsingContext.webidl
|
|
+++ b/dom/chrome-webidl/BrowsingContext.webidl
|
|
@@ -52,6 +52,24 @@ enum PrefersColorSchemeOverride {
|
|
"dark",
|
|
};
|
|
|
|
+/**
|
|
+ * CSS prefers-reduced-motion values.
|
|
+ */
|
|
+enum PrefersReducedMotionOverride {
|
|
+ "none",
|
|
+ "reduce",
|
|
+ "no-preference",
|
|
+};
|
|
+
|
|
+/**
|
|
+ * CSS forced-colors values.
|
|
+ */
|
|
+enum ForcedColorsOverride {
|
|
+ "none",
|
|
+ "active",
|
|
+ "no-override", /* This clears the override. */
|
|
+};
|
|
+
|
|
/**
|
|
* Allowed overrides of platform/pref default behaviour for touch events.
|
|
*/
|
|
@@ -178,6 +196,12 @@ interface BrowsingContext {
|
|
// Color-scheme simulation, for DevTools.
|
|
[SetterThrows] attribute PrefersColorSchemeOverride prefersColorSchemeOverride;
|
|
|
|
+ // Reduced-Motion simulation, for DevTools.
|
|
+ [SetterThrows] attribute PrefersReducedMotionOverride prefersReducedMotionOverride;
|
|
+
|
|
+ // Forced-Colors simulation, for DevTools.
|
|
+ [SetterThrows] attribute ForcedColorsOverride forcedColorsOverride;
|
|
+
|
|
/**
|
|
* A unique identifier for the browser element that is hosting this
|
|
* BrowsingContext tree. Every BrowsingContext in the element's tree will
|
|
diff --git a/dom/geolocation/Geolocation.cpp b/dom/geolocation/Geolocation.cpp
|
|
index 3a159442ed8e37bc94154c5f49c036c82517c575..7a456405b2e69a01a450ef7886724cee557e325c 100644
|
|
--- a/dom/geolocation/Geolocation.cpp
|
|
+++ b/dom/geolocation/Geolocation.cpp
|
|
@@ -23,6 +23,7 @@
|
|
#include "nsComponentManagerUtils.h"
|
|
#include "nsContentPermissionHelper.h"
|
|
#include "nsContentUtils.h"
|
|
+#include "nsDocShell.h"
|
|
#include "nsGlobalWindow.h"
|
|
#include "mozilla/dom/Document.h"
|
|
#include "nsINamed.h"
|
|
@@ -254,10 +255,8 @@ nsGeolocationRequest::Allow(JS::HandleValue aChoices) {
|
|
return NS_OK;
|
|
}
|
|
|
|
- RefPtr<nsGeolocationService> gs =
|
|
- nsGeolocationService::GetGeolocationService();
|
|
-
|
|
- bool canUseCache = false;
|
|
+ nsGeolocationService* gs = mLocator->GetGeolocationService();
|
|
+ bool canUseCache = gs != nsGeolocationService::sService.get();
|
|
CachedPositionAndAccuracy lastPosition = gs->GetCachedPosition();
|
|
if (lastPosition.position) {
|
|
EpochTimeStamp cachedPositionTime_ms;
|
|
@@ -431,8 +430,7 @@ void nsGeolocationRequest::Shutdown() {
|
|
// If there are no other high accuracy requests, the geolocation service will
|
|
// notify the provider to switch to the default accuracy.
|
|
if (mOptions && mOptions->mEnableHighAccuracy) {
|
|
- RefPtr<nsGeolocationService> gs =
|
|
- nsGeolocationService::GetGeolocationService();
|
|
+ nsGeolocationService* gs = mLocator ? mLocator->GetGeolocationService() : nullptr;
|
|
if (gs) {
|
|
gs->UpdateAccuracy();
|
|
}
|
|
@@ -708,8 +706,14 @@ void nsGeolocationService::StopDevice() {
|
|
StaticRefPtr<nsGeolocationService> nsGeolocationService::sService;
|
|
|
|
already_AddRefed<nsGeolocationService>
|
|
-nsGeolocationService::GetGeolocationService() {
|
|
+nsGeolocationService::GetGeolocationService(nsDocShell* docShell) {
|
|
RefPtr<nsGeolocationService> result;
|
|
+ if (docShell) {
|
|
+ result = docShell->GetGeolocationServiceOverride();
|
|
+ if (result)
|
|
+ return result.forget();
|
|
+ }
|
|
+
|
|
if (nsGeolocationService::sService) {
|
|
result = nsGeolocationService::sService;
|
|
|
|
@@ -801,7 +805,9 @@ nsresult Geolocation::Init(nsPIDOMWindowInner* aContentDom) {
|
|
// If no aContentDom was passed into us, we are being used
|
|
// by chrome/c++ and have no mOwner, no mPrincipal, and no need
|
|
// to prompt.
|
|
- mService = nsGeolocationService::GetGeolocationService();
|
|
+ nsCOMPtr<Document> doc = aContentDom ? aContentDom->GetDoc() : nullptr;
|
|
+ mService = nsGeolocationService::GetGeolocationService(
|
|
+ doc ? static_cast<nsDocShell*>(doc->GetDocShell()) : nullptr);
|
|
if (mService) {
|
|
mService->AddLocator(this);
|
|
}
|
|
diff --git a/dom/geolocation/Geolocation.h b/dom/geolocation/Geolocation.h
|
|
index ed81524ff3ce803802578a38433b6b724df8ccf2..55022f28db9ca5695c0bdee8ffd9509c5e2467d3 100644
|
|
--- a/dom/geolocation/Geolocation.h
|
|
+++ b/dom/geolocation/Geolocation.h
|
|
@@ -31,6 +31,7 @@
|
|
|
|
#include "nsIGeolocationProvider.h"
|
|
#include "mozilla/Attributes.h"
|
|
+#include "nsDocShell.h"
|
|
|
|
class nsGeolocationService;
|
|
class nsGeolocationRequest;
|
|
@@ -42,6 +43,11 @@ using GeoPositionCallback =
|
|
CallbackObjectHolder<PositionCallback, nsIDOMGeoPositionCallback>;
|
|
using GeoPositionErrorCallback =
|
|
CallbackObjectHolder<PositionErrorCallback, nsIDOMGeoPositionErrorCallback>;
|
|
+typedef CallbackObjectHolder<PositionCallback, nsIDOMGeoPositionCallback>
|
|
+ GeoPositionCallback;
|
|
+typedef CallbackObjectHolder<PositionErrorCallback,
|
|
+ nsIDOMGeoPositionErrorCallback>
|
|
+ GeoPositionErrorCallback;
|
|
} // namespace dom
|
|
} // namespace mozilla
|
|
|
|
@@ -50,13 +56,14 @@ struct CachedPositionAndAccuracy {
|
|
bool isHighAccuracy;
|
|
};
|
|
|
|
+
|
|
/**
|
|
* Singleton that manages the geolocation provider
|
|
*/
|
|
class nsGeolocationService final : public nsIGeolocationUpdate,
|
|
public nsIObserver {
|
|
public:
|
|
- static already_AddRefed<nsGeolocationService> GetGeolocationService();
|
|
+ static already_AddRefed<nsGeolocationService> GetGeolocationService(nsDocShell* docShell = nullptr);
|
|
static mozilla::StaticRefPtr<nsGeolocationService> sService;
|
|
|
|
NS_DECL_THREADSAFE_ISUPPORTS
|
|
@@ -183,6 +190,8 @@ class Geolocation final : public nsIGeolocationUpdate, public nsWrapperCache {
|
|
// null.
|
|
static already_AddRefed<Geolocation> NonWindowSingleton();
|
|
|
|
+ nsGeolocationService* GetGeolocationService() { return mService; };
|
|
+
|
|
private:
|
|
~Geolocation();
|
|
|
|
diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp
|
|
index 5b6f967e4002f62a9276abf841e7c5ead538ede8..04832d5ca36ed87f48f01def7fb6cd92082859f4 100644
|
|
--- a/dom/html/HTMLInputElement.cpp
|
|
+++ b/dom/html/HTMLInputElement.cpp
|
|
@@ -52,6 +52,7 @@
|
|
#include "nsMappedAttributes.h"
|
|
#include "nsIFormControl.h"
|
|
#include "mozilla/dom/Document.h"
|
|
+#include "nsDocShell.h"
|
|
#include "nsIFormControlFrame.h"
|
|
#include "nsITextControlFrame.h"
|
|
#include "nsIFrame.h"
|
|
@@ -744,6 +745,12 @@ nsresult HTMLInputElement::InitFilePicker(FilePickerType aType) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
+ nsDocShell* docShell = static_cast<nsDocShell*>(win->GetDocShell());
|
|
+ if (docShell && docShell->IsFileInputInterceptionEnabled()) {
|
|
+ docShell->FilePickerShown(this);
|
|
+ return NS_OK;
|
|
+ }
|
|
+
|
|
if (IsPopupBlocked(doc)) {
|
|
return NS_OK;
|
|
}
|
|
diff --git a/dom/interfaces/base/nsIDOMWindowUtils.idl b/dom/interfaces/base/nsIDOMWindowUtils.idl
|
|
index fb5efd4252a3495b9626ce1c84851b25e5a1b9d7..b20ecf18fe32d04403134998372789563031aff3 100644
|
|
--- a/dom/interfaces/base/nsIDOMWindowUtils.idl
|
|
+++ b/dom/interfaces/base/nsIDOMWindowUtils.idl
|
|
@@ -353,7 +353,8 @@ interface nsIDOMWindowUtils : nsISupports {
|
|
[optional] in boolean aIsDOMEventSynthesized,
|
|
[optional] in boolean aIsWidgetEventSynthesized,
|
|
[optional] in long aButtons,
|
|
- [optional] in unsigned long aIdentifier);
|
|
+ [optional] in unsigned long aIdentifier,
|
|
+ [optional] in boolean aDisablePointerEvent);
|
|
|
|
/** Synthesize a touch event. The event types supported are:
|
|
* touchstart, touchend, touchmove, and touchcancel
|
|
diff --git a/dom/media/systemservices/video_engine/desktop_capture_impl.cc b/dom/media/systemservices/video_engine/desktop_capture_impl.cc
|
|
index e744940a8e7517b39a73509da3942c2cac9ee0c1..9ba6fe797ed0707137f9cf32b784544d0db0195c 100644
|
|
--- a/dom/media/systemservices/video_engine/desktop_capture_impl.cc
|
|
+++ b/dom/media/systemservices/video_engine/desktop_capture_impl.cc
|
|
@@ -122,10 +122,11 @@ int32_t ScreenDeviceInfoImpl::GetOrientation(const char* deviceUniqueIdUTF8,
|
|
return 0;
|
|
}
|
|
|
|
-VideoCaptureModule* DesktopCaptureImpl::Create(const int32_t id,
|
|
+VideoCaptureModuleEx* DesktopCaptureImpl::Create(const int32_t id,
|
|
const char* uniqueId,
|
|
- const CaptureDeviceType type) {
|
|
- return new rtc::RefCountedObject<DesktopCaptureImpl>(id, uniqueId, type);
|
|
+ const CaptureDeviceType type,
|
|
+ bool captureCursor) {
|
|
+ return new rtc::RefCountedObject<DesktopCaptureImpl>(id, uniqueId, type, captureCursor);
|
|
}
|
|
|
|
int32_t WindowDeviceInfoImpl::Init() {
|
|
@@ -357,9 +358,13 @@ int32_t DesktopCaptureImpl::Init() {
|
|
DesktopCapturer::SourceId sourceId = atoi(_deviceUniqueId.c_str());
|
|
pWindowCapturer->SelectSource(sourceId);
|
|
|
|
- desktop_capturer_cursor_composer_ =
|
|
- std::unique_ptr<DesktopAndCursorComposer>(
|
|
- new DesktopAndCursorComposer(std::move(pWindowCapturer), options));
|
|
+ if (capture_cursor_) {
|
|
+ desktop_capturer_cursor_composer_ =
|
|
+ std::unique_ptr<DesktopAndCursorComposer>(
|
|
+ new DesktopAndCursorComposer(std::move(pWindowCapturer), options));
|
|
+ } else {
|
|
+ desktop_capturer_cursor_composer_ = std::move(pWindowCapturer);
|
|
+ }
|
|
} else if (_deviceType == CaptureDeviceType::Browser) {
|
|
// XXX We don't capture cursors, so avoid the extra indirection layer. We
|
|
// could also pass null for the pMouseCursorMonitor.
|
|
@@ -376,13 +381,15 @@ int32_t DesktopCaptureImpl::Init() {
|
|
}
|
|
|
|
DesktopCaptureImpl::DesktopCaptureImpl(const int32_t id, const char* uniqueId,
|
|
- const CaptureDeviceType type)
|
|
+ const CaptureDeviceType type,
|
|
+ bool captureCursor)
|
|
: _id(id),
|
|
_deviceUniqueId(uniqueId),
|
|
_deviceType(type),
|
|
_requestedCapability(),
|
|
_rotateFrame(kVideoRotation_0),
|
|
last_capture_time_ms_(rtc::TimeMillis()),
|
|
+ capture_cursor_(captureCursor),
|
|
time_event_(EventWrapper::Create()),
|
|
#if defined(_WIN32)
|
|
capturer_thread_(
|
|
@@ -427,6 +434,19 @@ void DesktopCaptureImpl::DeRegisterCaptureDataCallback(
|
|
}
|
|
}
|
|
|
|
+void DesktopCaptureImpl::RegisterRawFrameCallback(RawFrameCallback* rawFrameCallback) {
|
|
+ rtc::CritScope lock(&_apiCs);
|
|
+ _rawFrameCallbacks.insert(rawFrameCallback);
|
|
+}
|
|
+
|
|
+void DesktopCaptureImpl::DeRegisterRawFrameCallback(RawFrameCallback* rawFrameCallback) {
|
|
+ rtc::CritScope lock(&_apiCs);
|
|
+ auto it = _rawFrameCallbacks.find(rawFrameCallback);
|
|
+ if (it != _rawFrameCallbacks.end()) {
|
|
+ _rawFrameCallbacks.erase(it);
|
|
+ }
|
|
+}
|
|
+
|
|
int32_t DesktopCaptureImpl::StopCaptureIfAllClientsClose() {
|
|
if (_dataCallBacks.empty()) {
|
|
return StopCapture();
|
|
@@ -627,6 +647,12 @@ void DesktopCaptureImpl::OnCaptureResult(DesktopCapturer::Result result,
|
|
frameInfo.height = frame->size().height();
|
|
frameInfo.videoType = VideoType::kARGB;
|
|
|
|
+ size_t videoFrameStride =
|
|
+ frameInfo.width * DesktopFrame::kBytesPerPixel;
|
|
+ for (auto rawFrameCallback : _rawFrameCallbacks) {
|
|
+ rawFrameCallback->OnRawFrame(videoFrame, videoFrameStride, frameInfo);
|
|
+ }
|
|
+
|
|
size_t videoFrameLength =
|
|
frameInfo.width * frameInfo.height * DesktopFrame::kBytesPerPixel;
|
|
IncomingFrame(videoFrame, videoFrameLength,
|
|
diff --git a/dom/media/systemservices/video_engine/desktop_capture_impl.h b/dom/media/systemservices/video_engine/desktop_capture_impl.h
|
|
index a07735e4f046b98d4380ecaa8327620e3819c4d8..29b9b63f1b8dfbcec302a5db49f1032205076795 100644
|
|
--- a/dom/media/systemservices/video_engine/desktop_capture_impl.h
|
|
+++ b/dom/media/systemservices/video_engine/desktop_capture_impl.h
|
|
@@ -44,6 +44,21 @@ namespace webrtc {
|
|
|
|
class VideoCaptureEncodeInterface;
|
|
|
|
+class RawFrameCallback {
|
|
+ public:
|
|
+ virtual ~RawFrameCallback() {}
|
|
+
|
|
+ virtual void OnRawFrame(uint8_t* videoFrame, size_t videoFrameLength, const VideoCaptureCapability& frameInfo) = 0;
|
|
+};
|
|
+
|
|
+class VideoCaptureModuleEx : public VideoCaptureModule {
|
|
+ public:
|
|
+ virtual ~VideoCaptureModuleEx() {}
|
|
+
|
|
+ virtual void RegisterRawFrameCallback(RawFrameCallback* rawFrameCallback) = 0;
|
|
+ virtual void DeRegisterRawFrameCallback(RawFrameCallback* rawFrameCallback) = 0;
|
|
+};
|
|
+
|
|
// simulate deviceInfo interface for video engine, bridge screen/application and
|
|
// real screen/application device info
|
|
|
|
@@ -156,12 +171,13 @@ class BrowserDeviceInfoImpl : public VideoCaptureModule::DeviceInfo {
|
|
// As with video, DesktopCaptureImpl is a proxy for screen sharing
|
|
// and follows the video pipeline design
|
|
class DesktopCaptureImpl : public DesktopCapturer::Callback,
|
|
- public VideoCaptureModule {
|
|
+ public VideoCaptureModuleEx {
|
|
public:
|
|
/* Create a screen capture modules object
|
|
*/
|
|
- static VideoCaptureModule* Create(const int32_t id, const char* uniqueId,
|
|
- const CaptureDeviceType type);
|
|
+ static VideoCaptureModuleEx* Create(const int32_t id, const char* uniqueId,
|
|
+ const CaptureDeviceType type,
|
|
+ bool captureCursor = true);
|
|
static VideoCaptureModule::DeviceInfo* CreateDeviceInfo(
|
|
const int32_t id, const CaptureDeviceType type);
|
|
|
|
@@ -171,6 +187,8 @@ class DesktopCaptureImpl : public DesktopCapturer::Callback,
|
|
void DeRegisterCaptureDataCallback(
|
|
rtc::VideoSinkInterface<VideoFrame>* dataCallback) override;
|
|
int32_t StopCaptureIfAllClientsClose() override;
|
|
+ void RegisterRawFrameCallback(RawFrameCallback* rawFrameCallback) override;
|
|
+ void DeRegisterRawFrameCallback(RawFrameCallback* rawFrameCallback) override;
|
|
|
|
int32_t SetCaptureRotation(VideoRotation rotation) override;
|
|
bool SetApplyRotation(bool enable) override;
|
|
@@ -191,7 +209,7 @@ class DesktopCaptureImpl : public DesktopCapturer::Callback,
|
|
|
|
protected:
|
|
DesktopCaptureImpl(const int32_t id, const char* uniqueId,
|
|
- const CaptureDeviceType type);
|
|
+ const CaptureDeviceType type, bool captureCursor);
|
|
virtual ~DesktopCaptureImpl();
|
|
int32_t DeliverCapturedFrame(webrtc::VideoFrame& captureFrame);
|
|
|
|
@@ -213,6 +231,7 @@ class DesktopCaptureImpl : public DesktopCapturer::Callback,
|
|
rtc::RecursiveCriticalSection _apiCs;
|
|
|
|
std::set<rtc::VideoSinkInterface<VideoFrame>*> _dataCallBacks;
|
|
+ std::set<RawFrameCallback*> _rawFrameCallbacks;
|
|
|
|
int64_t _incomingFrameTimesNanos
|
|
[kFrameRateCountHistorySize]; // timestamp for local captured frames
|
|
@@ -234,6 +253,7 @@ class DesktopCaptureImpl : public DesktopCapturer::Callback,
|
|
void process();
|
|
|
|
private:
|
|
+ bool capture_cursor_ = true;
|
|
// This is created on the main thread and accessed on both the main thread
|
|
// and the capturer thread. It is created prior to the capturer thread
|
|
// starting and is destroyed after it is stopped.
|
|
diff --git a/dom/script/ScriptSettings.cpp b/dom/script/ScriptSettings.cpp
|
|
index f6406aa45fdfec169255eca38d772f5cbfb24007..f723a4490ddd9ae27bb3b792fc1d71949c5af7b4 100644
|
|
--- a/dom/script/ScriptSettings.cpp
|
|
+++ b/dom/script/ScriptSettings.cpp
|
|
@@ -181,6 +181,30 @@ ScriptSettingsStackEntry::~ScriptSettingsStackEntry() {
|
|
MOZ_ASSERT_IF(mGlobalObject, mGlobalObject->HasJSGlobal());
|
|
}
|
|
|
|
+static nsIGlobalObject* UnwrapSandboxGlobal(nsIGlobalObject* global) {
|
|
+ if (!global)
|
|
+ return global;
|
|
+ JSObject* globalObject = global->GetGlobalJSObject();
|
|
+ if (!globalObject)
|
|
+ return global;
|
|
+ JSContext* cx = nsContentUtils::GetCurrentJSContext();
|
|
+ if (!cx)
|
|
+ return global;
|
|
+ JS::Rooted<JSObject*> proto(cx);
|
|
+ JS::RootedObject rootedGlobal(cx, globalObject);
|
|
+ if (!JS_GetPrototype(cx, rootedGlobal, &proto))
|
|
+ return global;
|
|
+ if (!proto || !xpc::IsSandboxPrototypeProxy(proto))
|
|
+ return global;
|
|
+ // If this is a sandbox associated with a DOMWindow via a
|
|
+ // sandboxPrototype, use that DOMWindow. This supports GreaseMonkey
|
|
+ // and JetPack content scripts.
|
|
+ proto = js::CheckedUnwrapDynamic(proto, cx, /* stopAtWindowProxy = */ false);
|
|
+ if (!proto)
|
|
+ return global;
|
|
+ return xpc::WindowGlobalOrNull(proto);
|
|
+}
|
|
+
|
|
// If the entry or incumbent global ends up being something that the subject
|
|
// principal doesn't subsume, we don't want to use it. This never happens on
|
|
// the web, but can happen with asymmetric privilege relationships (i.e.
|
|
@@ -208,7 +232,7 @@ static nsIGlobalObject* ClampToSubject(nsIGlobalObject* aGlobalOrNull) {
|
|
NS_ENSURE_TRUE(globalPrin, GetCurrentGlobal());
|
|
if (!nsContentUtils::SubjectPrincipalOrSystemIfNativeCaller()
|
|
->SubsumesConsideringDomain(globalPrin)) {
|
|
- return GetCurrentGlobal();
|
|
+ return UnwrapSandboxGlobal(GetCurrentGlobal());
|
|
}
|
|
|
|
return aGlobalOrNull;
|
|
diff --git a/dom/security/nsCSPUtils.cpp b/dom/security/nsCSPUtils.cpp
|
|
index 554d83e29d139aadc030ec954162c4b200e717a7..450594e24c5d80b2d0519262581fdbf662549421 100644
|
|
--- a/dom/security/nsCSPUtils.cpp
|
|
+++ b/dom/security/nsCSPUtils.cpp
|
|
@@ -127,6 +127,11 @@ void CSP_ApplyMetaCSPToDoc(mozilla::dom::Document& aDoc,
|
|
return;
|
|
}
|
|
|
|
+ if (aDoc.GetDocShell() &&
|
|
+ nsDocShell::Cast(aDoc.GetDocShell())->IsBypassCSPEnabled()) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
nsAutoString policyStr(
|
|
nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(
|
|
aPolicyStr));
|
|
diff --git a/dom/webidl/GeometryUtils.webidl b/dom/webidl/GeometryUtils.webidl
|
|
index 2f71b284ee5f7e11f117c447834b48355784448c..d996e0a3cbbb19c1dc320c305c6d74037bffa0d3 100644
|
|
--- a/dom/webidl/GeometryUtils.webidl
|
|
+++ b/dom/webidl/GeometryUtils.webidl
|
|
@@ -27,6 +27,9 @@ interface mixin GeometryUtils {
|
|
[Throws, Func="nsINode::HasBoxQuadsSupport", NeedsCallerType]
|
|
sequence<DOMQuad> getBoxQuads(optional BoxQuadOptions options = {});
|
|
|
|
+ [ChromeOnly, Throws, Func="nsINode::HasBoxQuadsSupport"]
|
|
+ void scrollRectIntoViewIfNeeded(long x, long y, long w, long h);
|
|
+
|
|
/* getBoxQuadsFromWindowOrigin is similar to getBoxQuads, but the
|
|
* returned quads are further translated relative to the window
|
|
* origin -- which is not the layout origin. Further translation
|
|
diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp
|
|
index f13e980bbf4c29c22d3773e21f59e3e18c8c8a26..e8168f962b86c684517e84d700546036145ee6a6 100644
|
|
--- a/dom/workers/RuntimeService.cpp
|
|
+++ b/dom/workers/RuntimeService.cpp
|
|
@@ -1007,7 +1007,7 @@ void PrefLanguagesChanged(const char* /* aPrefName */, void* /* aClosure */) {
|
|
AssertIsOnMainThread();
|
|
|
|
nsTArray<nsString> languages;
|
|
- Navigator::GetAcceptLanguages(languages);
|
|
+ Navigator::GetAcceptLanguages(nullptr, languages);
|
|
|
|
RuntimeService* runtime = RuntimeService::GetService();
|
|
if (runtime) {
|
|
@@ -1210,8 +1210,7 @@ bool RuntimeService::RegisterWorker(WorkerPrivate& aWorkerPrivate) {
|
|
}
|
|
|
|
// The navigator overridden properties should have already been read.
|
|
-
|
|
- Navigator::GetAcceptLanguages(mNavigatorProperties.mLanguages);
|
|
+ Navigator::GetAcceptLanguages(nullptr, mNavigatorProperties.mLanguages);
|
|
mNavigatorPropertiesLoaded = true;
|
|
}
|
|
|
|
@@ -1919,6 +1918,13 @@ void RuntimeService::PropagateStorageAccessPermissionGranted(
|
|
}
|
|
}
|
|
|
|
+void RuntimeService::ResetDefaultLocaleInAllWorkers() {
|
|
+ AssertIsOnMainThread();
|
|
+ BroadcastAllWorkers([](auto& worker) {
|
|
+ worker.ResetDefaultLocale();
|
|
+ });
|
|
+}
|
|
+
|
|
void RuntimeService::NoteIdleThread(SafeRefPtr<WorkerThread> aThread) {
|
|
AssertIsOnMainThread();
|
|
MOZ_ASSERT(aThread);
|
|
@@ -2338,6 +2344,14 @@ void PropagateStorageAccessPermissionGrantedToWorkers(
|
|
}
|
|
}
|
|
|
|
+void ResetDefaultLocaleInAllWorkers() {
|
|
+ AssertIsOnMainThread();
|
|
+ RuntimeService* runtime = RuntimeService::GetService();
|
|
+ if (runtime) {
|
|
+ runtime->ResetDefaultLocaleInAllWorkers();
|
|
+ }
|
|
+}
|
|
+
|
|
WorkerPrivate* GetWorkerPrivateFromContext(JSContext* aCx) {
|
|
MOZ_ASSERT(!NS_IsMainThread());
|
|
MOZ_ASSERT(aCx);
|
|
diff --git a/dom/workers/RuntimeService.h b/dom/workers/RuntimeService.h
|
|
index 0ca5f99fab6fe97135a0852d538d6fed027ae054..472c00b8b75c4d79e0dd62973445824420e14d2e 100644
|
|
--- a/dom/workers/RuntimeService.h
|
|
+++ b/dom/workers/RuntimeService.h
|
|
@@ -122,6 +122,8 @@ class RuntimeService final : public nsIObserver {
|
|
void PropagateStorageAccessPermissionGranted(
|
|
const nsPIDOMWindowInner& aWindow);
|
|
|
|
+ void ResetDefaultLocaleInAllWorkers();
|
|
+
|
|
const NavigatorProperties& GetNavigatorProperties() const {
|
|
return mNavigatorProperties;
|
|
}
|
|
diff --git a/dom/workers/WorkerCommon.h b/dom/workers/WorkerCommon.h
|
|
index 8b1b46d69f2c90d851d292c285a1ba9bdbd4d9b7..dea5259b0a82e5e6d3c431fc78e60d5df80b3eda 100644
|
|
--- a/dom/workers/WorkerCommon.h
|
|
+++ b/dom/workers/WorkerCommon.h
|
|
@@ -45,6 +45,8 @@ void ResumeWorkersForWindow(const nsPIDOMWindowInner& aWindow);
|
|
void PropagateStorageAccessPermissionGrantedToWorkers(
|
|
const nsPIDOMWindowInner& aWindow);
|
|
|
|
+void ResetDefaultLocaleInAllWorkers();
|
|
+
|
|
// All of these are implemented in WorkerScope.cpp
|
|
|
|
bool IsWorkerGlobal(JSObject* global);
|
|
diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp
|
|
index 3add7b222eb614bd1f42d3694da36e6381980a02..3d8a0af73f4c5fc43836f06a2d6351800f3aca0e 100644
|
|
--- a/dom/workers/WorkerPrivate.cpp
|
|
+++ b/dom/workers/WorkerPrivate.cpp
|
|
@@ -686,6 +686,18 @@ class UpdateContextOptionsRunnable final : public WorkerControlRunnable {
|
|
}
|
|
};
|
|
|
|
+class ResetDefaultLocaleRunnable final : public WorkerControlRunnable {
|
|
+ public:
|
|
+ explicit ResetDefaultLocaleRunnable(WorkerPrivate* aWorkerPrivate)
|
|
+ : WorkerControlRunnable(aWorkerPrivate, WorkerThreadUnchangedBusyCount) {}
|
|
+
|
|
+ virtual bool WorkerRun(JSContext* aCx,
|
|
+ WorkerPrivate* aWorkerPrivate) override {
|
|
+ aWorkerPrivate->ResetDefaultLocaleInternal(aCx);
|
|
+ return true;
|
|
+ }
|
|
+};
|
|
+
|
|
class UpdateLanguagesRunnable final : public WorkerRunnable {
|
|
nsTArray<nsString> mLanguages;
|
|
|
|
@@ -1881,6 +1893,16 @@ void WorkerPrivate::UpdateContextOptions(
|
|
}
|
|
}
|
|
|
|
+void WorkerPrivate::ResetDefaultLocale() {
|
|
+ AssertIsOnParentThread();
|
|
+
|
|
+ RefPtr<ResetDefaultLocaleRunnable> runnable =
|
|
+ new ResetDefaultLocaleRunnable(this);
|
|
+ if (!runnable->Dispatch()) {
|
|
+ NS_WARNING("Failed to reset default locale in worker!");
|
|
+ }
|
|
+}
|
|
+
|
|
void WorkerPrivate::UpdateLanguages(const nsTArray<nsString>& aLanguages) {
|
|
AssertIsOnParentThread();
|
|
|
|
@@ -4956,6 +4978,15 @@ void WorkerPrivate::UpdateContextOptionsInternal(
|
|
}
|
|
}
|
|
|
|
+void WorkerPrivate::ResetDefaultLocaleInternal(JSContext* aCx) {
|
|
+ JS_ResetDefaultLocale(JS_GetRuntime(aCx));
|
|
+ auto data = mWorkerThreadAccessible.Access();
|
|
+
|
|
+ for (uint32_t index = 0; index < data->mChildWorkers.Length(); index++) {
|
|
+ data->mChildWorkers[index]->ResetDefaultLocale();
|
|
+ }
|
|
+}
|
|
+
|
|
void WorkerPrivate::UpdateLanguagesInternal(
|
|
const nsTArray<nsString>& aLanguages) {
|
|
WorkerGlobalScope* globalScope = GlobalScope();
|
|
diff --git a/dom/workers/WorkerPrivate.h b/dom/workers/WorkerPrivate.h
|
|
index 107e2d0511bcf1a2a48e4bffa3ca030739c9ac79..6ee65636633c1d02c57050dd4763d5b418e6710b 100644
|
|
--- a/dom/workers/WorkerPrivate.h
|
|
+++ b/dom/workers/WorkerPrivate.h
|
|
@@ -307,6 +307,8 @@ class WorkerPrivate final : public RelativeTimeline {
|
|
void UpdateContextOptionsInternal(JSContext* aCx,
|
|
const JS::ContextOptions& aContextOptions);
|
|
|
|
+ void ResetDefaultLocaleInternal(JSContext* aCx);
|
|
+
|
|
void UpdateLanguagesInternal(const nsTArray<nsString>& aLanguages);
|
|
|
|
void UpdateJSWorkerMemoryParameterInternal(JSContext* aCx, JSGCParamKey key,
|
|
@@ -920,6 +922,8 @@ class WorkerPrivate final : public RelativeTimeline {
|
|
|
|
void UpdateContextOptions(const JS::ContextOptions& aContextOptions);
|
|
|
|
+ void ResetDefaultLocale();
|
|
+
|
|
void UpdateLanguages(const nsTArray<nsString>& aLanguages);
|
|
|
|
void UpdateJSWorkerMemoryParameter(JSGCParamKey key, Maybe<uint32_t> value);
|
|
diff --git a/intl/components/src/TimeZone.cpp b/intl/components/src/TimeZone.cpp
|
|
index db5ebebd663689371464a14e5b35ace2637cc8e6..dcb3b79a6d68854f56491616401f134712886e15 100644
|
|
--- a/intl/components/src/TimeZone.cpp
|
|
+++ b/intl/components/src/TimeZone.cpp
|
|
@@ -16,6 +16,7 @@
|
|
|
|
namespace mozilla::intl {
|
|
|
|
+
|
|
/* static */
|
|
Result<UniquePtr<TimeZone>, ICUError> TimeZone::TryCreate(
|
|
Maybe<Span<const char16_t>> aTimeZoneOverride) {
|
|
@@ -244,6 +245,13 @@ static ICUResult SetDefaultTimeZone(TimeZoneIdentifierVector& timeZone) {
|
|
}
|
|
#endif
|
|
|
|
+bool TimeZone::IsValidTimeZoneId(const char* timeZoneId) {
|
|
+ // Validate timezone id.
|
|
+ mozilla::UniquePtr<icu::TimeZone> timeZone(icu::TimeZone::createTimeZone(
|
|
+ icu::UnicodeString(timeZoneId, -1, US_INV)));
|
|
+ return timeZone && *timeZone != icu::TimeZone::getUnknown();
|
|
+}
|
|
+
|
|
Result<bool, ICUError> TimeZone::SetDefaultTimeZone(
|
|
Span<const char> aTimeZone) {
|
|
#if MOZ_INTL_USE_ICU_CPP_TIMEZONE
|
|
diff --git a/intl/components/src/TimeZone.h b/intl/components/src/TimeZone.h
|
|
index 180092bd3fc0b70462cc6ba67e72946e4c4c7604..bcaecb9fcd7b630c75289581a887cc6894733168 100644
|
|
--- a/intl/components/src/TimeZone.h
|
|
+++ b/intl/components/src/TimeZone.h
|
|
@@ -154,6 +154,8 @@ class TimeZone final {
|
|
return FillBufferWithICUCall(aBuffer, ucal_getHostTimeZone);
|
|
}
|
|
|
|
+ static bool IsValidTimeZoneId(const char* timeZoneId);
|
|
+
|
|
/**
|
|
* Set the default time zone.
|
|
*/
|
|
diff --git a/js/public/Date.h b/js/public/Date.h
|
|
index bb69d58dc96ed7f0b37f73e26abdd0bdfeaaf556..8436d439f72287176a2fe6a1a837d3db73409e67 100644
|
|
--- a/js/public/Date.h
|
|
+++ b/js/public/Date.h
|
|
@@ -53,6 +53,8 @@ namespace JS {
|
|
*/
|
|
extern JS_PUBLIC_API void ResetTimeZone();
|
|
|
|
+extern JS_PUBLIC_API bool SetTimeZoneOverride(const char* timezoneId);
|
|
+
|
|
class ClippedTime;
|
|
inline ClippedTime TimeClip(double time);
|
|
|
|
diff --git a/js/src/debugger/Object.cpp b/js/src/debugger/Object.cpp
|
|
index b32d426ba38045d14e6f1e79d17e8e6061e78227..df782034e79466fcc251e9a06e99d2e1f4f073aa 100644
|
|
--- a/js/src/debugger/Object.cpp
|
|
+++ b/js/src/debugger/Object.cpp
|
|
@@ -2337,7 +2337,11 @@ Maybe<Completion> DebuggerObject::call(JSContext* cx,
|
|
invokeArgs[i].set(args2[i]);
|
|
}
|
|
|
|
+ // Disable CSP for the scope of the call.
|
|
+ const JSSecurityCallbacks* securityCallbacks = JS_GetSecurityCallbacks(cx);
|
|
+ JS_SetSecurityCallbacks(cx, nullptr);
|
|
ok = js::Call(cx, calleev, thisv, invokeArgs, &result);
|
|
+ JS_SetSecurityCallbacks(cx, securityCallbacks);
|
|
}
|
|
}
|
|
|
|
diff --git a/js/src/vm/DateTime.cpp b/js/src/vm/DateTime.cpp
|
|
index e8f27fb69691aa6062c860a14ec94660fb9e5189..67715cbbc8257f11927564b45bbc8ee5384f809d 100644
|
|
--- a/js/src/vm/DateTime.cpp
|
|
+++ b/js/src/vm/DateTime.cpp
|
|
@@ -170,6 +170,11 @@ void js::DateTimeInfo::internalResetTimeZone(ResetTimeZoneMode mode) {
|
|
}
|
|
}
|
|
|
|
+void js::DateTimeInfo::internalSetTimeZoneOverride(std::string timeZone) {
|
|
+ timeZoneOverride_ = std::move(timeZone);
|
|
+ internalResetTimeZone(ResetTimeZoneMode::ResetEvenIfOffsetUnchanged);
|
|
+}
|
|
+
|
|
void js::DateTimeInfo::updateTimeZone() {
|
|
MOZ_ASSERT(timeZoneStatus_ != TimeZoneStatus::Valid);
|
|
|
|
@@ -494,10 +499,24 @@ void js::ResetTimeZoneInternal(ResetTimeZoneMode mode) {
|
|
js::DateTimeInfo::resetTimeZone(mode);
|
|
}
|
|
|
|
+void js::SetTimeZoneOverrideInternal(std::string timeZone) {
|
|
+ auto guard = js::DateTimeInfo::instance->lock();
|
|
+ guard->internalSetTimeZoneOverride(timeZone);
|
|
+}
|
|
+
|
|
JS_PUBLIC_API void JS::ResetTimeZone() {
|
|
js::ResetTimeZoneInternal(js::ResetTimeZoneMode::ResetEvenIfOffsetUnchanged);
|
|
}
|
|
|
|
+JS_PUBLIC_API bool JS::SetTimeZoneOverride(const char* timeZoneId) {
|
|
+ if (!mozilla::intl::TimeZone::IsValidTimeZoneId(timeZoneId)) {
|
|
+ fprintf(stderr, "Invalid timezone id: %s\n", timeZoneId);
|
|
+ return false;
|
|
+ }
|
|
+ js::SetTimeZoneOverrideInternal(std::string(timeZoneId));
|
|
+ return true;
|
|
+}
|
|
+
|
|
#if JS_HAS_INTL_API
|
|
# if defined(XP_WIN)
|
|
static bool IsOlsonCompatibleWindowsTimeZoneId(std::string_view tz) {
|
|
@@ -719,9 +738,14 @@ void js::ResyncICUDefaultTimeZone() {
|
|
|
|
void js::DateTimeInfo::internalResyncICUDefaultTimeZone() {
|
|
#if JS_HAS_INTL_API
|
|
+ if (!timeZoneOverride_.empty()) {
|
|
+ mozilla::Span<const char> tzid = mozilla::Span(timeZoneOverride_.data(), timeZoneOverride_.length());
|
|
+ mozilla::intl::TimeZone::SetDefaultTimeZone(tzid);
|
|
+ return;
|
|
+ }
|
|
+
|
|
if (const char* tzenv = std::getenv("TZ")) {
|
|
std::string_view tz(tzenv);
|
|
-
|
|
mozilla::Span<const char> tzid;
|
|
|
|
# if defined(XP_WIN)
|
|
diff --git a/js/src/vm/DateTime.h b/js/src/vm/DateTime.h
|
|
index 3ce936fe3a4a83f9161eddc9e5289322d6a363e3..6b1c34244d8b2f2102ec423e2d96812fb5d41a9d 100644
|
|
--- a/js/src/vm/DateTime.h
|
|
+++ b/js/src/vm/DateTime.h
|
|
@@ -63,6 +63,8 @@ enum class ResetTimeZoneMode : bool {
|
|
*/
|
|
extern void ResetTimeZoneInternal(ResetTimeZoneMode mode);
|
|
|
|
+extern void SetTimeZoneOverrideInternal(std::string timeZone);
|
|
+
|
|
/**
|
|
* ICU's default time zone, used for various date/time formatting operations
|
|
* that include the local time in the representation, is allowed to go stale
|
|
@@ -202,6 +204,7 @@ class DateTimeInfo {
|
|
// and js::ResyncICUDefaultTimeZone().
|
|
friend void js::ResetTimeZoneInternal(ResetTimeZoneMode);
|
|
friend void js::ResyncICUDefaultTimeZone();
|
|
+ friend void js::SetTimeZoneOverrideInternal(std::string);
|
|
|
|
static void resetTimeZone(ResetTimeZoneMode mode) {
|
|
auto guard = instance->lock();
|
|
@@ -293,6 +296,8 @@ class DateTimeInfo {
|
|
JS::UniqueChars locale_;
|
|
JS::UniqueTwoByteChars standardName_;
|
|
JS::UniqueTwoByteChars daylightSavingsName_;
|
|
+
|
|
+ std::string timeZoneOverride_;
|
|
#else
|
|
// Restrict the data-time range to the minimum required time_t range as
|
|
// specified in POSIX. Most operating systems support 64-bit time_t
|
|
@@ -308,6 +313,8 @@ class DateTimeInfo {
|
|
|
|
void internalResetTimeZone(ResetTimeZoneMode mode);
|
|
|
|
+ void internalSetTimeZoneOverride(std::string timeZone);
|
|
+
|
|
void updateTimeZone();
|
|
|
|
void internalResyncICUDefaultTimeZone();
|
|
diff --git a/layout/style/GeckoBindings.h b/layout/style/GeckoBindings.h
|
|
index a235e29eee1ae369969ed7cceaa96800d988c011..ed8e4a314265871d604cdd494d2fc8eab6d7b7da 100644
|
|
--- a/layout/style/GeckoBindings.h
|
|
+++ b/layout/style/GeckoBindings.h
|
|
@@ -585,6 +585,7 @@ void Gecko_MediaFeatures_GetDeviceSize(const mozilla::dom::Document*,
|
|
|
|
float Gecko_MediaFeatures_GetResolution(const mozilla::dom::Document*);
|
|
bool Gecko_MediaFeatures_PrefersReducedMotion(const mozilla::dom::Document*);
|
|
+bool Gecko_MediaFeatures_ForcedColors(const mozilla::dom::Document*);
|
|
mozilla::StylePrefersContrast Gecko_MediaFeatures_PrefersContrast(
|
|
const mozilla::dom::Document*);
|
|
mozilla::StylePrefersColorScheme Gecko_MediaFeatures_PrefersColorScheme(
|
|
diff --git a/layout/style/nsMediaFeatures.cpp b/layout/style/nsMediaFeatures.cpp
|
|
index 5ad53c310e9d7b36e039b71302ca3bd3651121e8..33360198010937dac00af1017f4e7a2b77540b12 100644
|
|
--- a/layout/style/nsMediaFeatures.cpp
|
|
+++ b/layout/style/nsMediaFeatures.cpp
|
|
@@ -251,10 +251,11 @@ nsAtom* Gecko_MediaFeatures_GetOperatingSystemVersion(
|
|
}
|
|
|
|
bool Gecko_MediaFeatures_PrefersReducedMotion(const Document* aDocument) {
|
|
- if (nsContentUtils::ShouldResistFingerprinting(aDocument)) {
|
|
- return false;
|
|
- }
|
|
- return LookAndFeel::GetInt(LookAndFeel::IntID::PrefersReducedMotion, 0) == 1;
|
|
+ return aDocument->PrefersReducedMotion();
|
|
+}
|
|
+
|
|
+bool Gecko_MediaFeatures_ForcedColors(const Document* aDocument) {
|
|
+ return aDocument->ForcedColors();
|
|
}
|
|
|
|
StylePrefersColorScheme Gecko_MediaFeatures_PrefersColorScheme(
|
|
diff --git a/media/libjpeg/jconfig.h b/media/libjpeg/jconfig.h
|
|
index f2723e654098ff27542e1eb16a536c11ad0af617..b0b480551ff7d895dfdeb5a9800874858929c8ba 100644
|
|
--- a/media/libjpeg/jconfig.h
|
|
+++ b/media/libjpeg/jconfig.h
|
|
@@ -17,6 +17,7 @@
|
|
/* #undef D_ARITH_CODING_SUPPORTED */
|
|
|
|
/* Support in-memory source/destination managers */
|
|
+#define MEM_SRCDST_SUPPORTED 1
|
|
/* #undef MEM_SRCDST_SUPPORTED */
|
|
|
|
/* Use accelerated SIMD routines. */
|
|
diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js
|
|
index 0033f645bafdfb8253f130f3dd73524ec04f8e25..3e7032d58bd5e5f0a14fb8b4733e6f4b50fe2e16 100644
|
|
--- a/modules/libpref/init/all.js
|
|
+++ b/modules/libpref/init/all.js
|
|
@@ -4588,7 +4588,9 @@ pref("devtools.experiment.f12.shortcut_disabled", false);
|
|
// doesn't provide a way to lock the pref
|
|
pref("dom.postMessage.sharedArrayBuffer.bypassCOOP_COEP.insecure.enabled", false);
|
|
#else
|
|
-pref("dom.postMessage.sharedArrayBuffer.bypassCOOP_COEP.insecure.enabled", false, locked);
|
|
+// Playwright: DO NOT make preference locked so that we can overwrite it
|
|
+// later in our playwright.cfg file.
|
|
+pref("dom.postMessage.sharedArrayBuffer.bypassCOOP_COEP.insecure.enabled", false);
|
|
#endif
|
|
|
|
// Whether to start the private browsing mode at application startup
|
|
diff --git a/netwerk/base/nsINetworkInterceptController.idl b/netwerk/base/nsINetworkInterceptController.idl
|
|
index e869cd28d396aa87c522241d3e63d435ee8dbae6..2d307f089209721d88d231b03e8628890b8228ea 100644
|
|
--- a/netwerk/base/nsINetworkInterceptController.idl
|
|
+++ b/netwerk/base/nsINetworkInterceptController.idl
|
|
@@ -59,6 +59,7 @@ interface nsIInterceptedChannel : nsISupports
|
|
* results in the resulting client not being controlled.
|
|
*/
|
|
void resetInterception(in boolean bypass);
|
|
+ void resetInterceptionWithURI(in nsIURI aURI);
|
|
|
|
/**
|
|
* Set the status and reason for the forthcoming synthesized response.
|
|
diff --git a/netwerk/protocol/http/InterceptedHttpChannel.cpp b/netwerk/protocol/http/InterceptedHttpChannel.cpp
|
|
index fd62f6f45fe58ecfbdba2b0726e6f151bca43267..14a835e3639d19036e6794ecb57cd4f80bf517bc 100644
|
|
--- a/netwerk/protocol/http/InterceptedHttpChannel.cpp
|
|
+++ b/netwerk/protocol/http/InterceptedHttpChannel.cpp
|
|
@@ -649,6 +649,14 @@ void InterceptedHttpChannel::DoAsyncAbort(nsresult aStatus) {
|
|
Unused << AsyncAbort(aStatus);
|
|
}
|
|
|
|
+NS_IMETHODIMP
|
|
+InterceptedHttpChannel::ResetInterceptionWithURI(nsIURI* aURI) {
|
|
+ if (aURI) {
|
|
+ mURI = aURI;
|
|
+ }
|
|
+ return ResetInterception(true);
|
|
+}
|
|
+
|
|
NS_IMETHODIMP
|
|
InterceptedHttpChannel::ResetInterception(bool aBypass) {
|
|
if (mCanceled) {
|
|
diff --git a/parser/html/nsHtml5TreeOpExecutor.cpp b/parser/html/nsHtml5TreeOpExecutor.cpp
|
|
index 35526ca3a37327b324166dd42e450d108667a643..a2c70b2b432b2a714a928a1c08f520b058cb0583 100644
|
|
--- a/parser/html/nsHtml5TreeOpExecutor.cpp
|
|
+++ b/parser/html/nsHtml5TreeOpExecutor.cpp
|
|
@@ -1280,9 +1280,12 @@ void nsHtml5TreeOpExecutor::AddSpeculationCSP(const nsAString& aCSP) {
|
|
if (!StaticPrefs::security_csp_enable()) {
|
|
return;
|
|
}
|
|
-
|
|
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
|
|
+ if (mDocShell && static_cast<nsDocShell*>(mDocShell.get())->IsBypassCSPEnabled()) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
nsresult rv = NS_OK;
|
|
nsCOMPtr<nsIContentSecurityPolicy> preloadCsp = mDocument->GetPreloadCsp();
|
|
if (!preloadCsp) {
|
|
diff --git a/security/manager/ssl/nsCertOverrideService.cpp b/security/manager/ssl/nsCertOverrideService.cpp
|
|
index 03e2907b34448eef0843902e4fbe3e03ae0db720..0e24ebe3bddbf76fdc7fb6a02a20edb81a12db18 100644
|
|
--- a/security/manager/ssl/nsCertOverrideService.cpp
|
|
+++ b/security/manager/ssl/nsCertOverrideService.cpp
|
|
@@ -565,7 +565,12 @@ nsCertOverrideService::HasMatchingOverride(
|
|
bool disableAllSecurityCheck = false;
|
|
{
|
|
MutexAutoLock lock(mMutex);
|
|
- disableAllSecurityCheck = mDisableAllSecurityCheck;
|
|
+ if (aOriginAttributes.mUserContextId) {
|
|
+ disableAllSecurityCheck = mUserContextIdsWithDisabledSecurityChecks.has(
|
|
+ aOriginAttributes.mUserContextId);
|
|
+ } else {
|
|
+ disableAllSecurityCheck = mDisableAllSecurityCheck;
|
|
+ }
|
|
}
|
|
if (disableAllSecurityCheck) {
|
|
nsCertOverride::OverrideBits all = nsCertOverride::OverrideBits::Untrusted |
|
|
@@ -769,14 +774,24 @@ static bool IsDebugger() {
|
|
|
|
NS_IMETHODIMP
|
|
nsCertOverrideService::
|
|
- SetDisableAllSecurityChecksAndLetAttackersInterceptMyData(bool aDisable) {
|
|
- if (!(PR_GetEnv("XPCSHELL_TEST_PROFILE_DIR") || IsDebugger())) {
|
|
+ SetDisableAllSecurityChecksAndLetAttackersInterceptMyData(
|
|
+ bool aDisable, uint32_t aUserContextId) {
|
|
+ if (false /* juggler hacks */ && !(PR_GetEnv("XPCSHELL_TEST_PROFILE_DIR") || IsDebugger())) {
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
}
|
|
|
|
{
|
|
MutexAutoLock lock(mMutex);
|
|
- mDisableAllSecurityCheck = aDisable;
|
|
+ if (aUserContextId) {
|
|
+ if (aDisable) {
|
|
+ mozilla::Unused << mUserContextIdsWithDisabledSecurityChecks.put(aUserContextId);
|
|
+ } else {
|
|
+ mUserContextIdsWithDisabledSecurityChecks.remove(aUserContextId);
|
|
+ }
|
|
+ return NS_OK;
|
|
+ } else {
|
|
+ mDisableAllSecurityCheck = aDisable;
|
|
+ }
|
|
}
|
|
|
|
nsCOMPtr<nsINSSComponent> nss(do_GetService(PSM_COMPONENT_CONTRACTID));
|
|
diff --git a/security/manager/ssl/nsCertOverrideService.h b/security/manager/ssl/nsCertOverrideService.h
|
|
index 4c23cd20b9ccb72c2bc9d25ef7a832fe54993127..f43754414de091e5d745b96d440f9df8ac87f008 100644
|
|
--- a/security/manager/ssl/nsCertOverrideService.h
|
|
+++ b/security/manager/ssl/nsCertOverrideService.h
|
|
@@ -132,6 +132,7 @@ class nsCertOverrideService final : public nsICertOverrideService,
|
|
private:
|
|
~nsCertOverrideService();
|
|
|
|
+ mozilla::HashSet<uint32_t> mUserContextIdsWithDisabledSecurityChecks;
|
|
mozilla::Mutex mMutex;
|
|
bool mDisableAllSecurityCheck;
|
|
nsCOMPtr<nsIFile> mSettingsFile;
|
|
diff --git a/security/manager/ssl/nsICertOverrideService.idl b/security/manager/ssl/nsICertOverrideService.idl
|
|
index 3862fe6830874c036592fd217cab7ad5f4cd3e27..3166b37db0e52f7f2972d2bcb7a72ed819805794 100644
|
|
--- a/security/manager/ssl/nsICertOverrideService.idl
|
|
+++ b/security/manager/ssl/nsICertOverrideService.idl
|
|
@@ -201,7 +201,9 @@ interface nsICertOverrideService : nsISupports {
|
|
* @param aDisable If true, disable all security check and make
|
|
* hasMatchingOverride always return true.
|
|
*/
|
|
- void setDisableAllSecurityChecksAndLetAttackersInterceptMyData(in boolean aDisable);
|
|
+ void setDisableAllSecurityChecksAndLetAttackersInterceptMyData(
|
|
+ in boolean aDisable,
|
|
+ [optional] in uint32_t aUserContextId);
|
|
|
|
readonly attribute boolean securityCheckDisabled;
|
|
};
|
|
diff --git a/services/settings/Utils.jsm b/services/settings/Utils.jsm
|
|
index 4a5dd759a6deefa5b0431e1e4d1595a9866d28d5..08242057a294b90fb8943c39f230d27e747b928a 100644
|
|
--- a/services/settings/Utils.jsm
|
|
+++ b/services/settings/Utils.jsm
|
|
@@ -63,7 +63,7 @@ var Utils = {
|
|
);
|
|
const isXpcshell = env.exists("XPCSHELL_TEST_PROFILE_DIR");
|
|
const isNotThunderbird = AppConstants.MOZ_APP_NAME != "thunderbird";
|
|
- return AppConstants.RELEASE_OR_BETA &&
|
|
+ return false && AppConstants.RELEASE_OR_BETA &&
|
|
!Cu.isInAutomation &&
|
|
!isXpcshell &&
|
|
isNotThunderbird
|
|
diff --git a/servo/components/style/gecko/media_features.rs b/servo/components/style/gecko/media_features.rs
|
|
index be30e5f0b6f43341c727c2f033b8ce71fdd2b121..53921de6374505614f2c2e89e6e74f64b82903b5 100644
|
|
--- a/servo/components/style/gecko/media_features.rs
|
|
+++ b/servo/components/style/gecko/media_features.rs
|
|
@@ -336,10 +336,15 @@ pub enum ForcedColors {
|
|
|
|
/// https://drafts.csswg.org/mediaqueries-5/#forced-colors
|
|
fn eval_forced_colors(device: &Device, query_value: Option<ForcedColors>) -> bool {
|
|
- let forced = !device.use_document_colors();
|
|
+ let prefers_forced_colors =
|
|
+ unsafe { bindings::Gecko_MediaFeatures_ForcedColors(device.document()) };
|
|
+ let query_value = match query_value {
|
|
+ Some(v) => v,
|
|
+ None => return prefers_forced_colors,
|
|
+ };
|
|
match query_value {
|
|
- Some(query_value) => forced == (query_value == ForcedColors::Active),
|
|
- None => forced,
|
|
+ ForcedColors::Active => prefers_forced_colors,
|
|
+ ForcedColors::None => !prefers_forced_colors,
|
|
}
|
|
}
|
|
|
|
diff --git a/toolkit/components/browser/nsIWebBrowserChrome.idl b/toolkit/components/browser/nsIWebBrowserChrome.idl
|
|
index 4f7337926efbb086a2be97cdbcb3dca39e27c786..f2005cb726ff153d6b1011d6af0479dbf1af02a5 100644
|
|
--- a/toolkit/components/browser/nsIWebBrowserChrome.idl
|
|
+++ b/toolkit/components/browser/nsIWebBrowserChrome.idl
|
|
@@ -70,6 +70,9 @@ interface nsIWebBrowserChrome : nsISupports
|
|
// Whether this window should use out-of-process cross-origin subframes.
|
|
const unsigned long CHROME_FISSION_WINDOW = 0x00200000;
|
|
|
|
+ // Whether this window has "width" or "height" defined in features
|
|
+ const unsigned long JUGGLER_WINDOW_EXPLICIT_SIZE = 0x00400000;
|
|
+
|
|
// Prevents new window animations on MacOS and Windows. Currently
|
|
// ignored for Linux.
|
|
const unsigned long CHROME_SUPPRESS_ANIMATION = 0x01000000;
|
|
diff --git a/toolkit/components/enterprisepolicies/EnterprisePoliciesParent.jsm b/toolkit/components/enterprisepolicies/EnterprisePoliciesParent.jsm
|
|
index dbe939fd0e9d7e28a3faa5d285cc3c2e2b21e4ae..8a471c6b05a49d88d7583484cd2e9d8a8d3b4011 100644
|
|
--- a/toolkit/components/enterprisepolicies/EnterprisePoliciesParent.jsm
|
|
+++ b/toolkit/components/enterprisepolicies/EnterprisePoliciesParent.jsm
|
|
@@ -115,6 +115,12 @@ EnterprisePoliciesManager.prototype = {
|
|
Services.prefs.clearUserPref(PREF_POLICIES_APPLIED);
|
|
}
|
|
|
|
+ // Playwright: Disable enterprise policies
|
|
+ if (true) {
|
|
+ this.status = Ci.nsIEnterprisePolicies.INACTIVE;
|
|
+ return;
|
|
+ }
|
|
+
|
|
let provider = this._chooseProvider();
|
|
|
|
if (provider.failed) {
|
|
diff --git a/toolkit/components/startup/nsAppStartup.cpp b/toolkit/components/startup/nsAppStartup.cpp
|
|
index a28e55b794ff79a3d891d31d45281444984ebed4..8d9e5fa02511ead57da80158c8e9d58fccebaa24 100644
|
|
--- a/toolkit/components/startup/nsAppStartup.cpp
|
|
+++ b/toolkit/components/startup/nsAppStartup.cpp
|
|
@@ -370,7 +370,7 @@ nsAppStartup::Quit(uint32_t aMode, int aExitCode, bool* aUserAllowedQuit) {
|
|
nsCOMPtr<nsISimpleEnumerator> windowEnumerator;
|
|
nsCOMPtr<nsIWindowMediator> mediator(
|
|
do_GetService(NS_WINDOWMEDIATOR_CONTRACTID));
|
|
- if (mediator) {
|
|
+ if (ferocity != eForceQuit && mediator) {
|
|
mediator->GetEnumerator(nullptr, getter_AddRefs(windowEnumerator));
|
|
if (windowEnumerator) {
|
|
bool more;
|
|
diff --git a/toolkit/components/statusfilter/nsBrowserStatusFilter.cpp b/toolkit/components/statusfilter/nsBrowserStatusFilter.cpp
|
|
index 86f9574c8519b8e3f27d25339d44b83828a04f5c..adb5bba55421b27656d9b9e236f83b95b41300ba 100644
|
|
--- a/toolkit/components/statusfilter/nsBrowserStatusFilter.cpp
|
|
+++ b/toolkit/components/statusfilter/nsBrowserStatusFilter.cpp
|
|
@@ -174,8 +174,8 @@ nsBrowserStatusFilter::OnStateChange(nsIWebProgress* aWebProgress,
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
-nsBrowserStatusFilter::OnProgressChange(nsIWebProgress* aWebProgress,
|
|
- nsIRequest* aRequest,
|
|
+nsBrowserStatusFilter::OnProgressChange(nsIWebProgress *aWebProgress,
|
|
+ nsIRequest *aRequest,
|
|
int32_t aCurSelfProgress,
|
|
int32_t aMaxSelfProgress,
|
|
int32_t aCurTotalProgress,
|
|
diff --git a/toolkit/components/windowwatcher/nsWindowWatcher.cpp b/toolkit/components/windowwatcher/nsWindowWatcher.cpp
|
|
index 29f40f921f08aa7b6eeb0e0e1a21c9a783b6ae07..b1dc651b5dd3ad4db2082a1cd4e6c6c3607e5fd0 100644
|
|
--- a/toolkit/components/windowwatcher/nsWindowWatcher.cpp
|
|
+++ b/toolkit/components/windowwatcher/nsWindowWatcher.cpp
|
|
@@ -1783,7 +1783,11 @@ uint32_t nsWindowWatcher::CalculateChromeFlagsForContent(
|
|
|
|
// Open a minimal popup.
|
|
*aIsPopupRequested = true;
|
|
- return nsIWebBrowserChrome::CHROME_MINIMAL_POPUP;
|
|
+ uint32_t chromeFlags = 0;
|
|
+ if (aFeatures.Exists("width") || aFeatures.Exists("height")) {
|
|
+ chromeFlags |= nsIWebBrowserChrome::JUGGLER_WINDOW_EXPLICIT_SIZE;
|
|
+ }
|
|
+ return chromeFlags | nsIWebBrowserChrome::CHROME_MINIMAL_POPUP;
|
|
}
|
|
|
|
/**
|
|
diff --git a/toolkit/mozapps/update/UpdateService.jsm b/toolkit/mozapps/update/UpdateService.jsm
|
|
index ea89e5feee339b10f5fbcffddecb8826bbe3f977..965536cd90863dacbb06979c84f271fc9182351a 100644
|
|
--- a/toolkit/mozapps/update/UpdateService.jsm
|
|
+++ b/toolkit/mozapps/update/UpdateService.jsm
|
|
@@ -3703,7 +3703,7 @@ UpdateService.prototype = {
|
|
},
|
|
|
|
get disabledForTesting() {
|
|
- return (
|
|
+ return true || (
|
|
(Cu.isInAutomation || Marionette.running || RemoteAgent.listening) &&
|
|
Services.prefs.getBoolPref(PREF_APP_UPDATE_DISABLEDFORTESTING, false)
|
|
);
|
|
diff --git a/toolkit/toolkit.mozbuild b/toolkit/toolkit.mozbuild
|
|
index fd9903bac5b07c655ee77c94f8f795b6773676ad..a8dd1a58457d28271366cd9d57ab072a3b3dfec7 100644
|
|
--- a/toolkit/toolkit.mozbuild
|
|
+++ b/toolkit/toolkit.mozbuild
|
|
@@ -168,6 +168,7 @@ if CONFIG['ENABLE_WEBDRIVER']:
|
|
'/remote',
|
|
'/testing/firefox-ui',
|
|
'/testing/marionette',
|
|
+ '/juggler',
|
|
'/toolkit/components/telemetry/tests/marionette',
|
|
]
|
|
|
|
diff --git a/toolkit/xre/nsWindowsWMain.cpp b/toolkit/xre/nsWindowsWMain.cpp
|
|
index 11f4ff8bbe2679f224f55c9e5a0c8bbf79cf0688..7e41e029504b057ba166ee3765317714390c3289 100644
|
|
--- a/toolkit/xre/nsWindowsWMain.cpp
|
|
+++ b/toolkit/xre/nsWindowsWMain.cpp
|
|
@@ -14,9 +14,11 @@
|
|
#endif
|
|
|
|
#include "mozilla/Char16.h"
|
|
+#include "mozilla/CmdLineAndEnvUtils.h"
|
|
#include "nsUTF8Utils.h"
|
|
#include "nsWindowsHelpers.h"
|
|
|
|
+#include <io.h>
|
|
#include <windows.h>
|
|
#include <versionhelpers.h>
|
|
|
|
@@ -110,6 +112,20 @@ int wmain(int argc, WCHAR** argv) {
|
|
|
|
SanitizeEnvironmentVariables();
|
|
SetDllDirectoryW(L"");
|
|
+ bool hasJugglerPipe =
|
|
+ mozilla::CheckArg(argc, argv, L"juggler-pipe",
|
|
+ static_cast<const wchar_t**>(nullptr),
|
|
+ mozilla::CheckArgFlag::None) == mozilla::ARG_FOUND;
|
|
+ if (hasJugglerPipe && !mozilla::EnvHasValue("PW_PIPE_READ")) {
|
|
+ intptr_t stdio3 = _get_osfhandle(3);
|
|
+ intptr_t stdio4 = _get_osfhandle(4);
|
|
+ CHAR stdio3str[20];
|
|
+ CHAR stdio4str[20];
|
|
+ itoa(stdio3, stdio3str, 10);
|
|
+ itoa(stdio4, stdio4str, 10);
|
|
+ SetEnvironmentVariableA("PW_PIPE_READ", stdio3str);
|
|
+ SetEnvironmentVariableA("PW_PIPE_WRITE", stdio4str);
|
|
+ }
|
|
|
|
// Only run this code if LauncherProcessWin.h was included beforehand, thus
|
|
// signalling that the hosting process should support launcher mode.
|
|
diff --git a/uriloader/base/nsDocLoader.cpp b/uriloader/base/nsDocLoader.cpp
|
|
index 4fd3b29938cb2d355b6b18ee21c3a4ee4cb5d67e..0700601b843dfc9a3925b4a28f16047fb13aa3fc 100644
|
|
--- a/uriloader/base/nsDocLoader.cpp
|
|
+++ b/uriloader/base/nsDocLoader.cpp
|
|
@@ -826,6 +826,13 @@ void nsDocLoader::DocLoaderIsEmpty(bool aFlushLayout,
|
|
("DocLoader:%p: Firing load event for document.open\n",
|
|
this));
|
|
|
|
+ nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
|
+ if (os) {
|
|
+ nsIPrincipal* principal = doc->NodePrincipal();
|
|
+ if (!principal->IsSystemPrincipal())
|
|
+ os->NotifyObservers(ToSupports(doc), "juggler-document-open-loaded", nullptr);
|
|
+ }
|
|
+
|
|
// This is a very cut-down version of
|
|
// nsDocumentViewer::LoadComplete that doesn't do various things
|
|
// that are not relevant here because this wasn't an actual
|
|
diff --git a/uriloader/exthandler/nsExternalHelperAppService.cpp b/uriloader/exthandler/nsExternalHelperAppService.cpp
|
|
index d9d656ff94988c4bddfc076d2e2e013c1f8d28af..7e0729df152ed5d30247171f025c22411d00ebb8 100644
|
|
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
|
|
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
|
|
@@ -102,6 +102,7 @@
|
|
|
|
#include "mozilla/Components.h"
|
|
#include "mozilla/ClearOnShutdown.h"
|
|
+#include "mozilla/ErrorNames.h"
|
|
#include "mozilla/Preferences.h"
|
|
#include "mozilla/ipc/URIUtils.h"
|
|
|
|
@@ -956,6 +957,12 @@ NS_IMETHODIMP nsExternalHelperAppService::ApplyDecodingForExtension(
|
|
return NS_OK;
|
|
}
|
|
|
|
+NS_IMETHODIMP nsExternalHelperAppService::SetDownloadInterceptor(
|
|
+ nsIDownloadInterceptor* interceptor) {
|
|
+ mInterceptor = interceptor;
|
|
+ return NS_OK;
|
|
+}
|
|
+
|
|
nsresult nsExternalHelperAppService::GetFileTokenForPath(
|
|
const char16_t* aPlatformAppPath, nsIFile** aFile) {
|
|
nsDependentString platformAppPath(aPlatformAppPath);
|
|
@@ -1636,7 +1643,12 @@ nsresult nsExternalAppHandler::SetUpTempFile(nsIChannel* aChannel) {
|
|
// Strip off the ".part" from mTempLeafName
|
|
mTempLeafName.Truncate(mTempLeafName.Length() - ArrayLength(".part") + 1);
|
|
|
|
+ return CreateSaverForTempFile();
|
|
+}
|
|
+
|
|
+nsresult nsExternalAppHandler::CreateSaverForTempFile() {
|
|
MOZ_ASSERT(!mSaver, "Output file initialization called more than once!");
|
|
+ nsresult rv;
|
|
mSaver =
|
|
do_CreateInstance(NS_BACKGROUNDFILESAVERSTREAMLISTENER_CONTRACTID, &rv);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
@@ -1816,7 +1828,36 @@ NS_IMETHODIMP nsExternalAppHandler::OnStartRequest(nsIRequest* request) {
|
|
return NS_OK;
|
|
}
|
|
|
|
- rv = SetUpTempFile(aChannel);
|
|
+ bool isIntercepted = false;
|
|
+ nsCOMPtr<nsIDownloadInterceptor> interceptor = mExtProtSvc->mInterceptor;
|
|
+ if (interceptor) {
|
|
+ nsCOMPtr<nsIFile> fileToUse;
|
|
+ rv = interceptor->InterceptDownloadRequest(this, request, mBrowsingContext, getter_AddRefs(fileToUse), &isIntercepted);
|
|
+ if (!NS_SUCCEEDED(rv)) {
|
|
+ LOG((" failed to call nsIDowloadInterceptor.interceptDownloadRequest"));
|
|
+ return rv;
|
|
+ }
|
|
+ if (isIntercepted) {
|
|
+ LOG((" request interceped by nsIDowloadInterceptor"));
|
|
+ if (fileToUse) {
|
|
+ mTempFile = fileToUse;
|
|
+ rv = mTempFile->GetLeafName(mTempLeafName);
|
|
+ NS_ENSURE_SUCCESS(rv, rv);
|
|
+ } else {
|
|
+ Cancel(NS_BINDING_ABORTED);
|
|
+ return NS_OK;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // Temp file is the final destination when download is intercepted. In that
|
|
+ // case we only need to create saver (and not create transfer later). Not creating
|
|
+ // mTransfer also cuts off all downloads handling logic in the js compoenents and
|
|
+ // browser UI.
|
|
+ if (isIntercepted)
|
|
+ rv = CreateSaverForTempFile();
|
|
+ else
|
|
+ rv = SetUpTempFile(aChannel);
|
|
if (NS_FAILED(rv)) {
|
|
nsresult transferError = rv;
|
|
|
|
@@ -1871,6 +1912,9 @@ NS_IMETHODIMP nsExternalAppHandler::OnStartRequest(nsIRequest* request) {
|
|
|
|
bool alwaysAsk = true;
|
|
mMimeInfo->GetAlwaysAskBeforeHandling(&alwaysAsk);
|
|
+ if (isIntercepted) {
|
|
+ return NS_OK;
|
|
+ }
|
|
if (alwaysAsk) {
|
|
// But we *don't* ask if this mimeInfo didn't come from
|
|
// our user configuration datastore and the user has said
|
|
@@ -2414,6 +2458,16 @@ nsExternalAppHandler::OnSaveComplete(nsIBackgroundFileSaver* aSaver,
|
|
NotifyTransfer(aStatus);
|
|
}
|
|
|
|
+ if (!mCanceled) {
|
|
+ nsCOMPtr<nsIDownloadInterceptor> interceptor = mExtProtSvc->mInterceptor;
|
|
+ if (interceptor) {
|
|
+ nsCString noError;
|
|
+ nsresult rv = interceptor->OnDownloadComplete(this, noError);
|
|
+ MOZ_ASSERT(NS_SUCCEEDED(rv), "Failed to call nsIDowloadInterceptor.OnDownloadComplete");
|
|
+ Unused << rv;
|
|
+ }
|
|
+ }
|
|
+
|
|
return NS_OK;
|
|
}
|
|
|
|
@@ -2846,6 +2900,15 @@ NS_IMETHODIMP nsExternalAppHandler::Cancel(nsresult aReason) {
|
|
}
|
|
}
|
|
|
|
+ nsCOMPtr<nsIDownloadInterceptor> interceptor = mExtProtSvc->mInterceptor;
|
|
+ if (interceptor) {
|
|
+ nsCString errorName;
|
|
+ GetErrorName(aReason, errorName);
|
|
+ nsresult rv = interceptor->OnDownloadComplete(this, errorName);
|
|
+ MOZ_ASSERT(NS_SUCCEEDED(rv), "Failed notify nsIDowloadInterceptor about cancel");
|
|
+ Unused << rv;
|
|
+ }
|
|
+
|
|
// Break our reference cycle with the helper app dialog (set up in
|
|
// OnStartRequest)
|
|
mDialog = nullptr;
|
|
diff --git a/uriloader/exthandler/nsExternalHelperAppService.h b/uriloader/exthandler/nsExternalHelperAppService.h
|
|
index 6121ab22e4d552cc3d54181c7cb308df5d47f98e..502b2cbc4292b1001824ff153e0231df201b7648 100644
|
|
--- a/uriloader/exthandler/nsExternalHelperAppService.h
|
|
+++ b/uriloader/exthandler/nsExternalHelperAppService.h
|
|
@@ -214,6 +214,8 @@ class nsExternalHelperAppService : public nsIExternalHelperAppService,
|
|
mozilla::dom::BrowsingContext* aContentContext, bool aForceSave,
|
|
nsIInterfaceRequestor* aWindowContext,
|
|
nsIStreamListener** aStreamListener);
|
|
+
|
|
+ nsCOMPtr<nsIDownloadInterceptor> mInterceptor;
|
|
};
|
|
|
|
/**
|
|
@@ -410,6 +412,9 @@ class nsExternalAppHandler final : public nsIStreamListener,
|
|
* Upon successful return, both mTempFile and mSaver will be valid.
|
|
*/
|
|
nsresult SetUpTempFile(nsIChannel* aChannel);
|
|
+
|
|
+ nsresult CreateSaverForTempFile();
|
|
+
|
|
/**
|
|
* When we download a helper app, we are going to retarget all load
|
|
* notifications into our own docloader and load group instead of
|
|
diff --git a/uriloader/exthandler/nsIExternalHelperAppService.idl b/uriloader/exthandler/nsIExternalHelperAppService.idl
|
|
index 39de4279e763488fef763ad6cb99e6f4bd672bcb..030de86fcff8b48603697dcc50d56bdc39582754 100644
|
|
--- a/uriloader/exthandler/nsIExternalHelperAppService.idl
|
|
+++ b/uriloader/exthandler/nsIExternalHelperAppService.idl
|
|
@@ -6,6 +6,8 @@
|
|
|
|
#include "nsICancelable.idl"
|
|
|
|
+webidl BrowsingContext;
|
|
+interface nsIHelperAppLauncher;
|
|
interface nsIURI;
|
|
interface nsIRequest;
|
|
interface nsIStreamListener;
|
|
@@ -15,6 +17,17 @@ interface nsIWebProgressListener2;
|
|
interface nsIInterfaceRequestor;
|
|
webidl BrowsingContext;
|
|
|
|
+/**
|
|
+ * Interceptor interface used by Juggler.
|
|
+ */
|
|
+[scriptable, uuid(9a20e9b0-75d0-11ea-bc55-0242ac130003)]
|
|
+interface nsIDownloadInterceptor : nsISupports
|
|
+{
|
|
+ bool interceptDownloadRequest(in nsIHelperAppLauncher aHandler, in nsIRequest aRequest, in BrowsingContext aBrowsingContext, out nsIFile file);
|
|
+
|
|
+ void onDownloadComplete(in nsIHelperAppLauncher aHandler, in ACString aErrorName);
|
|
+};
|
|
+
|
|
/**
|
|
* The external helper app service is used for finding and launching
|
|
* platform specific external applications for a given mime content type.
|
|
@@ -76,6 +89,7 @@ interface nsIExternalHelperAppService : nsISupports
|
|
boolean applyDecodingForExtension(in AUTF8String aExtension,
|
|
in ACString aEncodingType);
|
|
|
|
+ void setDownloadInterceptor(in nsIDownloadInterceptor interceptor);
|
|
};
|
|
|
|
/**
|
|
diff --git a/widget/InProcessCompositorWidget.cpp b/widget/InProcessCompositorWidget.cpp
|
|
index 1c25e9d9a101233f71e92288a0f93125b81ac1c5..22cf67b0f6e3ddd2b3ed725a314ba6a9896abd1c 100644
|
|
--- a/widget/InProcessCompositorWidget.cpp
|
|
+++ b/widget/InProcessCompositorWidget.cpp
|
|
@@ -4,7 +4,10 @@
|
|
|
|
#include "InProcessCompositorWidget.h"
|
|
|
|
+#include "HeadlessCompositorWidget.h"
|
|
+#include "HeadlessWidget.h"
|
|
#include "mozilla/VsyncDispatcher.h"
|
|
+#include "mozilla/widget/PlatformWidgetTypes.h"
|
|
#include "nsBaseWidget.h"
|
|
|
|
namespace mozilla {
|
|
@@ -23,6 +26,12 @@ RefPtr<CompositorWidget> CompositorWidget::CreateLocal(
|
|
// do it after the static_cast.
|
|
nsBaseWidget* widget = static_cast<nsBaseWidget*>(aWidget);
|
|
MOZ_RELEASE_ASSERT(widget);
|
|
+ if (aInitData.type() ==
|
|
+ CompositorWidgetInitData::THeadlessCompositorWidgetInitData) {
|
|
+ return new HeadlessCompositorWidget(
|
|
+ aInitData.get_HeadlessCompositorWidgetInitData(), aOptions,
|
|
+ static_cast<HeadlessWidget*>(aWidget));
|
|
+ }
|
|
return new InProcessCompositorWidget(aOptions, widget);
|
|
}
|
|
#endif
|
|
diff --git a/widget/cocoa/NativeKeyBindings.mm b/widget/cocoa/NativeKeyBindings.mm
|
|
index 2b11df66d9445080d4d8a19a915b3e00285c5d32..caef1b65bbcff899f45c3e3cddfe76e88479ec30 100644
|
|
--- a/widget/cocoa/NativeKeyBindings.mm
|
|
+++ b/widget/cocoa/NativeKeyBindings.mm
|
|
@@ -491,6 +491,13 @@
|
|
break;
|
|
case KEY_NAME_INDEX_ArrowLeft:
|
|
if (aEvent.IsAlt()) {
|
|
+ if (aEvent.IsMeta() || aEvent.IsControl())
|
|
+ break;
|
|
+ instance->AppendEditCommandsForSelector(
|
|
+ !aEvent.IsShift()
|
|
+ ? ToObjcSelectorPtr(@selector(moveWordLeft:))
|
|
+ : ToObjcSelectorPtr(@selector(moveWordLeftAndModifySelection:)),
|
|
+ aCommands);
|
|
break;
|
|
}
|
|
if (aEvent.IsMeta() || (aEvent.IsControl() && aEvent.IsShift())) {
|
|
@@ -511,6 +518,13 @@
|
|
break;
|
|
case KEY_NAME_INDEX_ArrowRight:
|
|
if (aEvent.IsAlt()) {
|
|
+ if (aEvent.IsMeta() || aEvent.IsControl())
|
|
+ break;
|
|
+ instance->AppendEditCommandsForSelector(
|
|
+ !aEvent.IsShift()
|
|
+ ? ToObjcSelectorPtr(@selector(moveWordRight:))
|
|
+ : ToObjcSelectorPtr(@selector(moveWordRightAndModifySelection:)),
|
|
+ aCommands);
|
|
break;
|
|
}
|
|
if (aEvent.IsMeta() || (aEvent.IsControl() && aEvent.IsShift())) {
|
|
@@ -531,6 +545,10 @@
|
|
break;
|
|
case KEY_NAME_INDEX_ArrowUp:
|
|
if (aEvent.IsControl()) {
|
|
+ if (aEvent.IsMeta() || aEvent.IsAlt())
|
|
+ break;
|
|
+ instance->AppendEditCommandsForSelector(
|
|
+ ToObjcSelectorPtr(@selector(scrollPageUp:)), aCommands);
|
|
break;
|
|
}
|
|
if (aEvent.IsMeta()) {
|
|
@@ -540,7 +558,7 @@
|
|
instance->AppendEditCommandsForSelector(
|
|
!aEvent.IsShift()
|
|
? ToObjcSelectorPtr(@selector(moveToBeginningOfDocument:))
|
|
- : ToObjcSelectorPtr(@selector(moveToBegginingOfDocumentAndModifySelection:)),
|
|
+ : ToObjcSelectorPtr(@selector(moveToBeginningOfDocumentAndModifySelection:)),
|
|
aCommands);
|
|
break;
|
|
}
|
|
@@ -563,6 +581,10 @@
|
|
break;
|
|
case KEY_NAME_INDEX_ArrowDown:
|
|
if (aEvent.IsControl()) {
|
|
+ if (aEvent.IsMeta() || aEvent.IsAlt())
|
|
+ break;
|
|
+ instance->AppendEditCommandsForSelector(
|
|
+ ToObjcSelectorPtr(@selector(scrollPageDown:)), aCommands);
|
|
break;
|
|
}
|
|
if (aEvent.IsMeta()) {
|
|
diff --git a/widget/headless/HeadlessCompositorWidget.cpp b/widget/headless/HeadlessCompositorWidget.cpp
|
|
index b31a969b7ab3d0fc80912b110d91dfdf3e5991f4..52aed4f9fb51f3f58a440d7e57eaccd6dfcbc2ab 100644
|
|
--- a/widget/headless/HeadlessCompositorWidget.cpp
|
|
+++ b/widget/headless/HeadlessCompositorWidget.cpp
|
|
@@ -3,6 +3,7 @@
|
|
* 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/. */
|
|
|
|
+#include "mozilla/layers/CompositorThread.h"
|
|
#include "mozilla/widget/PlatformWidgetTypes.h"
|
|
#include "HeadlessCompositorWidget.h"
|
|
#include "VsyncDispatcher.h"
|
|
@@ -13,10 +14,32 @@ namespace widget {
|
|
HeadlessCompositorWidget::HeadlessCompositorWidget(
|
|
const HeadlessCompositorWidgetInitData& aInitData,
|
|
const layers::CompositorOptions& aOptions, HeadlessWidget* aWindow)
|
|
- : CompositorWidget(aOptions), mWidget(aWindow) {
|
|
+ : CompositorWidget(aOptions), mWidget(aWindow), mMon("snapshotListener") {
|
|
mClientSize = aInitData.InitialClientSize();
|
|
}
|
|
|
|
+void HeadlessCompositorWidget::SetSnapshotListener(HeadlessWidget::SnapshotListener&& listener) {
|
|
+ MOZ_ASSERT(NS_IsMainThread());
|
|
+
|
|
+ ReentrantMonitorAutoEnter lock(mMon);
|
|
+ mSnapshotListener = std::move(listener);
|
|
+ layers::CompositorThread()->Dispatch(NewRunnableMethod(
|
|
+ "HeadlessCompositorWidget::PeriodicSnapshot", this,
|
|
+ &HeadlessCompositorWidget::PeriodicSnapshot
|
|
+ ));
|
|
+}
|
|
+
|
|
+already_AddRefed<gfx::DrawTarget> HeadlessCompositorWidget::StartRemoteDrawingInRegion(
|
|
+ const LayoutDeviceIntRegion& aInvalidRegion,
|
|
+ layers::BufferMode* aBufferMode) {
|
|
+ if (!mDrawTarget)
|
|
+ return nullptr;
|
|
+
|
|
+ *aBufferMode = layers::BufferMode::BUFFER_NONE;
|
|
+ RefPtr<gfx::DrawTarget> result = mDrawTarget;
|
|
+ return result.forget();
|
|
+}
|
|
+
|
|
void HeadlessCompositorWidget::ObserveVsync(VsyncObserver* aObserver) {
|
|
if (RefPtr<CompositorVsyncDispatcher> cvd =
|
|
mWidget->GetCompositorVsyncDispatcher()) {
|
|
@@ -29,6 +52,59 @@ nsIWidget* HeadlessCompositorWidget::RealWidget() { return mWidget; }
|
|
void HeadlessCompositorWidget::NotifyClientSizeChanged(
|
|
const LayoutDeviceIntSize& aClientSize) {
|
|
mClientSize = aClientSize;
|
|
+ layers::CompositorThread()->Dispatch(NewRunnableMethod<LayoutDeviceIntSize>(
|
|
+ "HeadlessCompositorWidget::UpdateDrawTarget", this,
|
|
+ &HeadlessCompositorWidget::UpdateDrawTarget,
|
|
+ aClientSize));
|
|
+}
|
|
+
|
|
+void HeadlessCompositorWidget::UpdateDrawTarget(const LayoutDeviceIntSize& aClientSize) {
|
|
+ MOZ_ASSERT(NS_IsInCompositorThread());
|
|
+ if (aClientSize.IsEmpty()) {
|
|
+ mDrawTarget = nullptr;
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ RefPtr<gfx::DrawTarget> old = std::move(mDrawTarget);
|
|
+ gfx::SurfaceFormat format = gfx::SurfaceFormat::B8G8R8A8;
|
|
+ gfx::IntSize size = aClientSize.ToUnknownSize();
|
|
+ mDrawTarget = mozilla::gfx::Factory::CreateDrawTarget(
|
|
+ mozilla::gfx::BackendType::SKIA, size, format);
|
|
+ if (old) {
|
|
+ RefPtr<gfx::SourceSurface> snapshot = old->Snapshot();
|
|
+ if (snapshot)
|
|
+ mDrawTarget->CopySurface(snapshot.get(), old->GetRect(), gfx::IntPoint(0, 0));
|
|
+ }
|
|
+}
|
|
+
|
|
+void HeadlessCompositorWidget::PeriodicSnapshot() {
|
|
+ ReentrantMonitorAutoEnter lock(mMon);
|
|
+ if (!mSnapshotListener)
|
|
+ return;
|
|
+
|
|
+ TakeSnapshot();
|
|
+ NS_DelayedDispatchToCurrentThread(NewRunnableMethod(
|
|
+ "HeadlessCompositorWidget::PeriodicSnapshot", this,
|
|
+ &HeadlessCompositorWidget::PeriodicSnapshot), 40);
|
|
+}
|
|
+
|
|
+void HeadlessCompositorWidget::TakeSnapshot() {
|
|
+ if (!mDrawTarget)
|
|
+ return;
|
|
+
|
|
+ RefPtr<gfx::SourceSurface> snapshot = mDrawTarget->Snapshot();
|
|
+ if (!snapshot) {
|
|
+ fprintf(stderr, "Failed to get snapshot of draw target\n");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ RefPtr<gfx::DataSourceSurface> dataSurface = snapshot->GetDataSurface();
|
|
+ if (!dataSurface) {
|
|
+ fprintf(stderr, "Failed to get data surface from snapshot\n");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ mSnapshotListener(std::move(dataSurface));
|
|
}
|
|
|
|
LayoutDeviceIntSize HeadlessCompositorWidget::GetClientSize() {
|
|
diff --git a/widget/headless/HeadlessCompositorWidget.h b/widget/headless/HeadlessCompositorWidget.h
|
|
index 7f91de9e67d7ffa02de3eef1d760e5cfd05e7ad6..753b8902026626e8f0a190ea3130ba5e65c24835 100644
|
|
--- a/widget/headless/HeadlessCompositorWidget.h
|
|
+++ b/widget/headless/HeadlessCompositorWidget.h
|
|
@@ -6,6 +6,7 @@
|
|
#ifndef widget_headless_HeadlessCompositorWidget_h
|
|
#define widget_headless_HeadlessCompositorWidget_h
|
|
|
|
+#include "mozilla/ReentrantMonitor.h"
|
|
#include "mozilla/widget/CompositorWidget.h"
|
|
|
|
#include "HeadlessWidget.h"
|
|
@@ -23,8 +24,12 @@ class HeadlessCompositorWidget final : public CompositorWidget,
|
|
HeadlessWidget* aWindow);
|
|
|
|
void NotifyClientSizeChanged(const LayoutDeviceIntSize& aClientSize);
|
|
+ void SetSnapshotListener(HeadlessWidget::SnapshotListener&& listener);
|
|
|
|
// CompositorWidget Overrides
|
|
+ already_AddRefed<gfx::DrawTarget> StartRemoteDrawingInRegion(
|
|
+ const LayoutDeviceIntRegion& aInvalidRegion,
|
|
+ layers::BufferMode* aBufferMode) override;
|
|
|
|
uintptr_t GetWidgetKey() override;
|
|
|
|
@@ -42,9 +47,17 @@ class HeadlessCompositorWidget final : public CompositorWidget,
|
|
}
|
|
|
|
private:
|
|
+ void UpdateDrawTarget(const LayoutDeviceIntSize& aClientSize);
|
|
+ void PeriodicSnapshot();
|
|
+ void TakeSnapshot();
|
|
+
|
|
HeadlessWidget* mWidget;
|
|
+ mozilla::ReentrantMonitor mMon;
|
|
|
|
LayoutDeviceIntSize mClientSize;
|
|
+
|
|
+ HeadlessWidget::SnapshotListener mSnapshotListener;
|
|
+ RefPtr<gfx::DrawTarget> mDrawTarget;
|
|
};
|
|
|
|
} // namespace widget
|
|
diff --git a/widget/headless/HeadlessWidget.cpp b/widget/headless/HeadlessWidget.cpp
|
|
index 4cd7a8be322851f2710b4c60fbd6377f8cc4abfc..6bfb3da3e82ebfb453cd036c8b22921d506a3762 100644
|
|
--- a/widget/headless/HeadlessWidget.cpp
|
|
+++ b/widget/headless/HeadlessWidget.cpp
|
|
@@ -107,6 +107,8 @@ void HeadlessWidget::Destroy() {
|
|
}
|
|
}
|
|
|
|
+ SetSnapshotListener(nullptr);
|
|
+
|
|
nsBaseWidget::OnDestroy();
|
|
|
|
nsBaseWidget::Destroy();
|
|
@@ -561,5 +563,15 @@ nsresult HeadlessWidget::SynthesizeNativeTouchPadPinch(
|
|
DispatchPinchGestureInput(inputToDispatch);
|
|
return NS_OK;
|
|
}
|
|
+
|
|
+void HeadlessWidget::SetSnapshotListener(SnapshotListener&& listener) {
|
|
+ if (!mCompositorWidget) {
|
|
+ if (listener)
|
|
+ fprintf(stderr, "Trying to set SnapshotListener without compositor widget\n");
|
|
+ return;
|
|
+ }
|
|
+ mCompositorWidget->SetSnapshotListener(std::move(listener));
|
|
+}
|
|
+
|
|
} // namespace widget
|
|
} // namespace mozilla
|
|
diff --git a/widget/headless/HeadlessWidget.h b/widget/headless/HeadlessWidget.h
|
|
index 438456368c36f90e50ff1696456678b385da80c3..9f79c6af75b881a318b4beb6a4ef713db6b10c7f 100644
|
|
--- a/widget/headless/HeadlessWidget.h
|
|
+++ b/widget/headless/HeadlessWidget.h
|
|
@@ -134,6 +134,9 @@ class HeadlessWidget : public nsBaseWidget {
|
|
TouchpadGesturePhase aEventPhase, float aScale,
|
|
LayoutDeviceIntPoint aPoint, int32_t aModifierFlags) override;
|
|
|
|
+ using SnapshotListener = std::function<void(RefPtr<gfx::DataSourceSurface>&&)>;
|
|
+ void SetSnapshotListener(SnapshotListener&& listener);
|
|
+
|
|
private:
|
|
~HeadlessWidget();
|
|
bool mEnabled;
|
|
diff --git a/xpcom/reflect/xptinfo/xptinfo.h b/xpcom/reflect/xptinfo/xptinfo.h
|
|
index efee881c142175c29d15f7ceaaebf852f39e44cd..014bf4b39b99eaf2fba6fb08827e7d2f964bab33 100644
|
|
--- a/xpcom/reflect/xptinfo/xptinfo.h
|
|
+++ b/xpcom/reflect/xptinfo/xptinfo.h
|
|
@@ -514,7 +514,7 @@ static_assert(sizeof(nsXPTMethodInfo) == 8, "wrong size");
|
|
#if defined(MOZ_THUNDERBIRD) || defined(MOZ_SUITE)
|
|
# define PARAM_BUFFER_COUNT 18
|
|
#else
|
|
-# define PARAM_BUFFER_COUNT 14
|
|
+# define PARAM_BUFFER_COUNT 15
|
|
#endif
|
|
|
|
/**
|