commit 64841b5dc9c79632d3321efe74fe2fc4631a0d16
parent af4baca06e2a8299a31a4a9fc74fa988d9ce0686
Author: Emilio Cobos Álvarez <emilio@crisal.io>
Date: Mon, 15 Dec 2025 22:18:27 +0000
Bug 2006091 - Only use preferred-color-scheme override explicitly on our browsing context. r=jwatt
Otherwise let the embedder propagate the right information, which
matches how the page would render with the system setting without the
override.
Differential Revision: https://phabricator.services.mozilla.com/D276470
Diffstat:
3 files changed, 38 insertions(+), 15 deletions(-)
diff --git a/layout/base/nsPresContext.cpp b/layout/base/nsPresContext.cpp
@@ -917,13 +917,10 @@ void nsPresContext::RecomputeBrowsingContextDependentData() {
auto* top = browsingContext->Top();
SetColorSchemeOverride([&] {
auto overriden = top->PrefersColorSchemeOverride();
- if (overriden != PrefersColorSchemeOverride::None) {
+ if (browsingContext == top &&
+ overriden != PrefersColorSchemeOverride::None) {
return overriden;
}
- if (!StaticPrefs::
- layout_css_iframe_embedder_prefers_color_scheme_content_enabled()) {
- return top->GetEmbedderColorSchemes().mPreferred;
- }
return browsingContext->GetEmbedderColorSchemes().mPreferred;
}());
diff --git a/layout/base/tests/test_emulate_color_scheme.html b/layout/base/tests/test_emulate_color_scheme.html
@@ -12,6 +12,8 @@
}
</style>
<div id="test"></div>
+<iframe id="light-iframe" style="color-scheme: light"></iframe>
+<iframe id="dark-iframe" style="color-scheme: dark"></iframe>
<script>
function colorId() {
// Gets the middle number of the rgb(0, x, 0) color.
@@ -21,20 +23,51 @@ function colorId() {
return id;
}
-{
+function iframeIsDark(id) {
+ return document.getElementById(id).contentWindow.matchMedia("(prefers-color-scheme: dark)").matches;
+}
+
+// Color-scheme switches should happen synchronously if we're the top window,
+// but if we're not (e.g., in the xorigin tests) we need IPC to go through
+// the embedder color-scheme mechanism, so we gotta wait.
+function maybeWaitForColorScheme(scheme) {
+ if (window.top == window) {
+ return;
+ }
+ let media = matchMedia(`(prefers-color-scheme: ${scheme})`);
+ if (media.matches) {
+ return;
+ }
+ return new Promise(r => {
+ media.addEventListener("change", r, { once: true });
+ });
+}
+
+add_task(async function() {
let bc = SpecialPowers.wrap(window).browsingContext.top;
ok('prefersColorSchemeOverride' in bc, "API should exist");
is(bc.prefersColorSchemeOverride, "none", "Override shouldn't be active.");
+ ok(iframeIsDark("dark-iframe"), "Dark iframe is dark");
+ ok(!iframeIsDark("light-iframe"), "Light iframe is light");
let originalColor = colorId();
bc.prefersColorSchemeOverride = "light";
+ await maybeWaitForColorScheme("light");
is(colorId(), 1, "Light emulation works");
+ ok(iframeIsDark("dark-iframe"), "Dark iframe still dark");
+ ok(!iframeIsDark("light-iframe"), "Light iframe still light");
+
bc.prefersColorSchemeOverride = "dark";
- is(colorId(), 2, "Dark emulation works");
+ await maybeWaitForColorScheme("dark");
+ is(colorId(), 2, "Dark emulation works as expected");
+
+ ok(iframeIsDark("dark-iframe"), "Dark iframe still dark");
+ ok(!iframeIsDark("light-iframe"), "Light iframe still light");
bc.prefersColorSchemeOverride = "none";
+ await maybeWaitForColorScheme(originalColor == 1 ? "light" : "dark");
is(colorId(), originalColor, "Clearing the override works");
-}
+});
</script>
diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml
@@ -10003,13 +10003,6 @@
value: false
mirror: always
-# This pref controls whether the `prefers-color-scheme` value of iframes images
-# reacts to the embedder `color-scheme` in content.
-- name: layout.css.iframe-embedder-prefers-color-scheme.content.enabled
- type: RelaxedAtomicBool
- value: true
- mirror: always
-
# Controls the transparency of the initial about:blank document. Generally you
# don't ever want a white flash in dark mode, but due to backwards compat we
# have some extra control over this, for now at least.