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

diff --git a/dom/base/nsGkAtomList.h b/dom/base/nsGkAtomList.h
--- a/dom/base/nsGkAtomList.h
+++ b/dom/base/nsGkAtomList.h
@@ -2262,16 +2262,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(prefers_contrast, "prefers-contrast")
 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
@@ -219,16 +219,17 @@ CSS_KEY(contrast, contrast)
 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(custom, custom)
 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)
@@ -356,16 +357,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(less, less)
 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)
@@ -393,16 +395,17 @@ CSS_KEY(menutext, menutext)
 CSS_KEY(message-box, message_box)
 CSS_KEY(middle, middle)
 CSS_KEY(min-content, min_content)
 CSS_KEY(minmax, minmax)
 CSS_KEY(mix, mix)
 CSS_KEY(mixed, mixed)
 CSS_KEY(mm, mm)
 CSS_KEY(monospace, monospace)
+CSS_KEY(more, more)
 CSS_KEY(move, move)
 CSS_KEY(ms, ms)
 CSS_KEY(multiply, multiply)
 CSS_KEY(n-resize, n_resize)
 CSS_KEY(narrower, narrower)
 CSS_KEY(ne-resize, ne_resize)
 CSS_KEY(nesw-resize, nesw_resize)
 CSS_KEY(no-clip, no_clip)
@@ -410,16 +413,17 @@ CSS_KEY(no-close-quote, no_close_quote)
 CSS_KEY(no-common-ligatures, no_common_ligatures)
 CSS_KEY(no-contextual, no_contextual)
 CSS_KEY(no-discretionary-ligatures, no_discretionary_ligatures)
 CSS_KEY(no-drag, no_drag)
 CSS_KEY(no-drop, no_drop)
 CSS_KEY(no-historical-ligatures, no_historical_ligatures)
 CSS_KEY(no-open-quote, no_open_quote)
 CSS_KEY(no-repeat, no_repeat)
+CSS_KEY(no-preference, no_preference)
 CSS_KEY(none, none)
 CSS_KEY(normal, normal)
 CSS_KEY(not-allowed, not_allowed)
 CSS_KEY(nowrap, nowrap)
 CSS_KEY(numeric, numeric)
 CSS_KEY(ns-resize, ns_resize)
 CSS_KEY(nw-resize, nw_resize)
 CSS_KEY(nwse-resize, nwse_resize)
diff --git a/layout/style/nsMediaFeatures.cpp b/layout/style/nsMediaFeatures.cpp
--- a/layout/style/nsMediaFeatures.cpp
+++ b/layout/style/nsMediaFeatures.cpp
@@ -51,16 +51,24 @@ static const nsCSSProps::KTableEntry kDi
 };
 
 static const nsCSSProps::KTableEntry kPrefersColorSchemeKeywords[] = {
   { eCSSKeyword_light,                  NS_STYLE_PREFERS_COLOR_SCHEME_LIGHT },
   { eCSSKeyword_dark,                   NS_STYLE_PREFERS_COLOR_SCHEME_DARK },
   { eCSSKeyword_UNKNOWN,                -1 },
 };
 
+static const nsCSSProps::KTableEntry kPrefersContrastKeywords[] = {
+  { eCSSKeyword_no_preference,          NS_STYLE_PREFERS_CONTRAST_NO_PREFERENCE },
+  { eCSSKeyword_less,                   NS_STYLE_PREFERS_CONTRAST_LESS },
+  { eCSSKeyword_more,                   NS_STYLE_PREFERS_CONTRAST_MORE },
+  { eCSSKeyword_custom,                 NS_STYLE_PREFERS_CONTRAST_CUSTOM },
+  { 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[] = {
@@ -526,16 +534,48 @@ GetPrefersColorScheme(nsIDocument* aDocu
                           eCSSUnit_Enumerated);
       break;
     default:
       aResult.Reset();
   }
 }
 
 static void
+GetPrefersContrast(nsIDocument* aDocument, const nsMediaFeature* aFeature,
+                   nsCSSValue& aResult)
+{
+  if (Preferences::GetInt("browser.display.document_color_use", 0) == 2 ||
+      LookAndFeel::GetInt(LookAndFeel::eIntID_UseAccessibilityTheme, 0)) {
+    aResult.SetIntValue(NS_STYLE_PREFERS_CONTRAST_CUSTOM, eCSSUnit_Enumerated);
+  }
+  else {
+    switch(Preferences::GetInt("browser.display.prefers_contrast", 0)) {
+      case 0:
+        aResult.SetIntValue(NS_STYLE_PREFERS_CONTRAST_NO_PREFERENCE,
+                            eCSSUnit_Enumerated);
+        break;
+      case 1:
+        aResult.SetIntValue(NS_STYLE_PREFERS_CONTRAST_LESS,
+                            eCSSUnit_Enumerated);
+        break;
+      case 2:
+        aResult.SetIntValue(NS_STYLE_PREFERS_CONTRAST_MORE,
+                            eCSSUnit_Enumerated);
+        break;
+      case 3:
+        aResult.SetIntValue(NS_STYLE_PREFERS_CONTRAST_CUSTOM,
+                            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);
 }
 
 /*
@@ -633,16 +673,24 @@ nsMediaFeatures::features[] = {
     &nsGkAtoms::prefers_color_scheme,
     nsMediaFeature::eMinMaxNotAllowed,
     nsMediaFeature::eEnumerated,
     nsMediaFeature::eNoRequirements,
     { kPrefersColorSchemeKeywords },
     GetPrefersColorScheme
   },
   {
+    &nsGkAtoms::prefers_contrast,
+    nsMediaFeature::eMinMaxNotAllowed,
+    nsMediaFeature::eEnumerated,
+    nsMediaFeature::eNoRequirements,
+    { kPrefersContrastKeywords },
+    GetPrefersContrast
+  },
+  {
     &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
@@ -1220,11 +1220,17 @@ enum class StyleOverscrollBehavior : uin
 #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
 
+// prefers-contrast
+#define NS_STYLE_PREFERS_CONTRAST_NO_PREFERENCE 0
+#define NS_STYLE_PREFERS_CONTRAST_LESS          1
+#define NS_STYLE_PREFERS_CONTRAST_MORE          2
+#define NS_STYLE_PREFERS_CONTRAST_CUSTOM        3
+
 } // 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
@@ -402,16 +402,24 @@ pref("browser.display.use_document_fonts
 // 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);
+// 0 = default: no-preference
+// 1 = less
+// 2 = more
+// 3 = custom;
+// NOTE: If browser.display.document_color_use is 2 or
+// LookAndFeel::eIntID_UseAccessibilityTheme evaluates to true 'custom' will return
+// unconditionally.
+pref("browser.display.prefers_contrast", 0);
 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);
