# HG changeset patch
# User Matt A. Tobin <email@mattatobin.com>
# Date 1721847757 18000
# Node ID 8af210a884c8c3c677dbd92defe767ad6a5b8fc4
# Parent  781ba690d1c20d755331840f78c904d39362ef30
No Bug - Add support for CSS prefers-color-scheme media feature as a user preference.

Based on an nsStyle port of Bug 1494034 to UXP by athenian200 <athenian200@outlook.com>

diff --git a/dom/base/nsGkAtomList.h b/dom/base/nsGkAtomList.h
--- a/dom/base/nsGkAtomList.h
+++ b/dom/base/nsGkAtomList.h
@@ -2261,16 +2261,17 @@ GK_ATOM(forcemessagemanager, "forcemessa
 
 // Names for system metrics
 GK_ATOM(scrollbar_start_backward, "scrollbar-start-backward")
 GK_ATOM(scrollbar_start_forward, "scrollbar-start-forward")
 GK_ATOM(scrollbar_end_backward, "scrollbar-end-backward")
 GK_ATOM(scrollbar_end_forward, "scrollbar-end-forward")
 GK_ATOM(scrollbar_thumb_proportional, "scrollbar-thumb-proportional")
 GK_ATOM(overlay_scrollbars, "overlay-scrollbars")
+GK_ATOM(prefers_color_scheme, "prefers-color-scheme")
 GK_ATOM(windows_accent_color_in_titlebar, "windows-accent-color-in-titlebar")
 GK_ATOM(windows_default_theme, "windows-default-theme")
 GK_ATOM(mac_graphite_theme, "mac-graphite-theme")
 GK_ATOM(mac_yosemite_theme, "mac-yosemite-theme")
 GK_ATOM(windows_compositor, "windows-compositor")
 GK_ATOM(windows_glass, "windows-glass")
 GK_ATOM(touch_enabled, "touch-enabled")
 GK_ATOM(menubar_drag, "menubar-drag")
diff --git a/layout/style/nsCSSKeywordList.h b/layout/style/nsCSSKeywordList.h
--- a/layout/style/nsCSSKeywordList.h
+++ b/layout/style/nsCSSKeywordList.h
@@ -220,16 +220,17 @@ CSS_KEY(copy, copy)
 CSS_KEY(contextual, contextual)
 CSS_KEY(cover, cover)
 CSS_KEY(crop, crop)
 CSS_KEY(cross, cross)
 CSS_KEY(crosshair, crosshair)
 CSS_KEY(currentcolor, currentcolor)
 CSS_KEY(cursive, cursive)
 CSS_KEY(cyclic, cyclic)
+CSS_KEY(dark, dark)
 CSS_KEY(darken, darken)
 CSS_KEY(dashed, dashed)
 CSS_KEY(dense, dense)
 CSS_KEY(decimal, decimal)
 CSS_KEY(default, default)
 CSS_KEY(deg, deg)
 CSS_KEY(diagonal-fractions, diagonal_fractions)
 CSS_KEY(dialog, dialog)
@@ -355,16 +356,17 @@ CSS_KEY(khz, khz)
 CSS_KEY(landscape, landscape)
 CSS_KEY(large, large)
 CSS_KEY(larger, larger)
 CSS_KEY(last, last)
 CSS_KEY(last baseline, last_baseline) // only used for DevTools auto-completion
 CSS_KEY(layout, layout)
 CSS_KEY(left, left)
 CSS_KEY(legacy, legacy)
+CSS_KEY(light, light)
 CSS_KEY(lighten, lighten)
 CSS_KEY(lighter, lighter)
 CSS_KEY(line-through, line_through)
 CSS_KEY(linear, linear)
 CSS_KEY(lining-nums, lining_nums)
 CSS_KEY(list-item, list_item)
 CSS_KEY(local, local)
 CSS_KEY(logical, logical)
diff --git a/layout/style/nsMediaFeatures.cpp b/layout/style/nsMediaFeatures.cpp
--- a/layout/style/nsMediaFeatures.cpp
+++ b/layout/style/nsMediaFeatures.cpp
@@ -19,16 +19,17 @@
 #include "nsCSSRuleProcessor.h"
 #endif
 #include "nsDeviceContext.h"
 #include "nsIBaseWindow.h"
 #include "nsIDocShell.h"
 #include "nsIDocument.h"
 #include "nsIWidget.h"
 #include "nsContentUtils.h"
+#include "mozilla/Preferences.h"
 #include "mozilla/StyleSheet.h"
 #include "mozilla/StyleSheetInlines.h"
 
 using namespace mozilla;
 
 static const nsCSSProps::KTableEntry kOrientationKeywords[] = {
   { eCSSKeyword_portrait,                 NS_STYLE_ORIENTATION_PORTRAIT },
   { eCSSKeyword_landscape,                NS_STYLE_ORIENTATION_LANDSCAPE },
@@ -44,16 +45,22 @@ static const nsCSSProps::KTableEntry kSc
 static const nsCSSProps::KTableEntry kDisplayModeKeywords[] = {
   { eCSSKeyword_browser,                 NS_STYLE_DISPLAY_MODE_BROWSER },
   { eCSSKeyword_minimal_ui,              NS_STYLE_DISPLAY_MODE_MINIMAL_UI },
   { eCSSKeyword_standalone,              NS_STYLE_DISPLAY_MODE_STANDALONE },
   { eCSSKeyword_fullscreen,              NS_STYLE_DISPLAY_MODE_FULLSCREEN },
   { eCSSKeyword_UNKNOWN,                 -1 }
 };
 
+static const nsCSSProps::KTableEntry kPrefersColorSchemeKeywords[] = {
+  { eCSSKeyword_light,                  NS_STYLE_PREFERS_COLOR_SCHEME_LIGHT },
+  { eCSSKeyword_dark,                   NS_STYLE_PREFERS_COLOR_SCHEME_DARK },
+  { eCSSKeyword_UNKNOWN,                -1 },
+};
+
 #ifdef XP_WIN
 struct WindowsThemeName {
   LookAndFeel::WindowsTheme id;
   const wchar_t* name;
 };
 
 // Windows theme identities used in the -moz-windows-theme media query.
 const WindowsThemeName themeStrings[] = {
@@ -501,16 +508,34 @@ GetOperatingSystemVersion(nsIDocument* a
         break;
       }
     }
   }
 #endif
 }
 
 static void
+GetPrefersColorScheme(nsIDocument* aDocument, const nsMediaFeature* aFeature,
+                      nsCSSValue& aResult)
+{
+  switch(Preferences::GetInt("browser.display.prefers_color_scheme", 1)) {
+    case 1:
+      aResult.SetIntValue(NS_STYLE_PREFERS_COLOR_SCHEME_LIGHT,
+                          eCSSUnit_Enumerated);
+      break;
+    case 2:
+      aResult.SetIntValue(NS_STYLE_PREFERS_COLOR_SCHEME_DARK,
+                          eCSSUnit_Enumerated);
+      break;
+    default:
+      aResult.Reset();
+  }
+}
+
+static void
 GetIsGlyph(nsIDocument* aDocument, const nsMediaFeature* aFeature,
            nsCSSValue& aResult)
 {
   MOZ_ASSERT(aFeature->mReqFlags & nsMediaFeature::eUserAgentAndChromeOnly);
   aResult.SetIntValue(aDocument->IsSVGGlyphsDocument() ? 1 : 0, eCSSUnit_Integer);
 }
 
 /*
@@ -600,16 +625,24 @@ nsMediaFeatures::features[] = {
     &nsGkAtoms::monochrome,
     nsMediaFeature::eMinMaxAllowed,
     nsMediaFeature::eInteger,
     nsMediaFeature::eNoRequirements,
     { nullptr },
     GetMonochrome
   },
   {
+    &nsGkAtoms::prefers_color_scheme,
+    nsMediaFeature::eMinMaxNotAllowed,
+    nsMediaFeature::eEnumerated,
+    nsMediaFeature::eNoRequirements,
+    { kPrefersColorSchemeKeywords },
+    GetPrefersColorScheme
+  },
+  {
     &nsGkAtoms::resolution,
     nsMediaFeature::eMinMaxAllowed,
     nsMediaFeature::eResolution,
     nsMediaFeature::eNoRequirements,
     { nullptr },
     GetResolution
   },
   {
diff --git a/layout/style/nsStyleConsts.h b/layout/style/nsStyleConsts.h
--- a/layout/style/nsStyleConsts.h
+++ b/layout/style/nsStyleConsts.h
@@ -1216,11 +1216,15 @@ enum class StyleOverscrollBehavior : uin
 #define NS_STYLE_SCAN_INTERLACE                 1
 
 // display-mode
 #define NS_STYLE_DISPLAY_MODE_BROWSER           0
 #define NS_STYLE_DISPLAY_MODE_MINIMAL_UI        1
 #define NS_STYLE_DISPLAY_MODE_STANDALONE        2
 #define NS_STYLE_DISPLAY_MODE_FULLSCREEN        3
 
+// prefers-color-scheme
+#define NS_STYLE_PREFERS_COLOR_SCHEME_LIGHT     0
+#define NS_STYLE_PREFERS_COLOR_SCHEME_DARK      1
+
 } // namespace mozilla
 
 #endif /* nsStyleConsts_h___ */
diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -398,16 +398,20 @@ pref("ui.menu.incremental_search.timeout
 // If true, all popups won't hide automatically on blur
 pref("ui.popup.disable_autohide", false);
 
 pref("browser.display.use_document_fonts",  1);  // 0 = never, 1 = quick, 2 = always
 // 0 = default: always, except in high contrast mode
 // 1 = always
 // 2 = never
 pref("browser.display.document_color_use", 0);
+// 0 = feature disabled
+// 1 = default: light theme preferred
+// 2 = dark theme preferred
+pref("browser.display.prefers_color_scheme", 1);
 pref("browser.display.use_system_colors",   false);
 pref("browser.display.foreground_color",    "#000000");
 pref("browser.display.background_color",    "#FFFFFF");
 pref("browser.display.force_inline_alttext", false); // true = force ALT text for missing images to be layed out inline
 // 0 = no external leading,
 // 1 = use external leading only when font provides,
 // 2 = add extra leading both internal leading and external leading are zero
 pref("browser.display.normal_lineheight_calc_control", 2);
