# HG changeset patch
# User Matt A. Tobin <email@mattatobin.com>
# Date 1722040388 18000
# Node ID 7b6db858e3d2729fc17560e9b82393a3430160be
# Parent  fbaa12c835063bf6bb02f78d6a447145bbf870de
No Bug - Add support for CSS prefers-reduced-motion 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
@@ -2263,16 +2263,17 @@ GK_ATOM(forcemessagemanager, "forcemessa
 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(prefers_reduced_motion, "prefers-reduced-motion")
 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
@@ -463,16 +463,17 @@ CSS_KEY(progressive, progressive)
 CSS_KEY(proportional-nums, proportional_nums)
 CSS_KEY(proportional-width, proportional_width)
 CSS_KEY(proximity, proximity)
 CSS_KEY(pt, pt)
 CSS_KEY(px, px)
 CSS_KEY(rad, rad)
 CSS_KEY(read-only, read_only)
 CSS_KEY(read-write, read_write)
+CSS_KEY(reduce, reduce)
 CSS_KEY(relative, relative)
 CSS_KEY(repeat, repeat)
 CSS_KEY(repeat-x, repeat_x)
 CSS_KEY(repeat-y, repeat_y)
 CSS_KEY(reverse, reverse)
 CSS_KEY(ridge, ridge)
 CSS_KEY(right, right)
 CSS_KEY(rl, rl)
diff --git a/layout/style/nsMediaFeatures.cpp b/layout/style/nsMediaFeatures.cpp
--- a/layout/style/nsMediaFeatures.cpp
+++ b/layout/style/nsMediaFeatures.cpp
@@ -59,16 +59,22 @@ static const nsCSSProps::KTableEntry kPr
 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 },
 };
 
+static const nsCSSProps::KTableEntry kPrefersReducedMotionKeywords[] = {
+  { eCSSKeyword_no_preference,          NS_STYLE_PREFERS_REDUCED_MOTION_NO_PREFERENCE },
+  { eCSSKeyword_reduce,                 NS_STYLE_PREFERS_REDUCED_MOTION_REDUCE },
+  { 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[] = {
@@ -566,16 +572,30 @@ GetPrefersContrast(nsIDocument* aDocumen
         break;
       default:
         aResult.Reset();
     }
   }
 }
 
 static void
+GetPrefersReducedMotion(nsIDocument* aDocument, const nsMediaFeature* aFeature,
+                        nsCSSValue& aResult)
+{
+  if (Preferences::GetInt("browser.display.prefers_reduced_motion", 0) == 1) {
+      aResult.SetIntValue(NS_STYLE_PREFERS_REDUCED_MOTION_REDUCE,
+                          eCSSUnit_Enumerated);
+  }
+  else {
+      aResult.SetIntValue(NS_STYLE_PREFERS_REDUCED_MOTION_NO_PREFERENCE,
+                          eCSSUnit_Enumerated);
+  }
+}
+
+static void
 GetIsGlyph(nsIDocument* aDocument, const nsMediaFeature* aFeature,
            nsCSSValue& aResult)
 {
   MOZ_ASSERT(aFeature->mReqFlags & nsMediaFeature::eUserAgentAndChromeOnly);
   aResult.SetIntValue(aDocument->IsSVGGlyphsDocument() ? 1 : 0, eCSSUnit_Integer);
 }
 
 /*
@@ -681,16 +701,24 @@ nsMediaFeatures::features[] = {
     &nsGkAtoms::prefers_contrast,
     nsMediaFeature::eMinMaxNotAllowed,
     nsMediaFeature::eEnumerated,
     nsMediaFeature::eNoRequirements,
     { kPrefersContrastKeywords },
     GetPrefersContrast
   },
   {
+    &nsGkAtoms::prefers_reduced_motion,
+    nsMediaFeature::eMinMaxNotAllowed,
+    nsMediaFeature::eEnumerated,
+    nsMediaFeature::eNoRequirements,
+    { kPrefersReducedMotionKeywords },
+    GetPrefersReducedMotion
+  },
+  {
     &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
@@ -1226,11 +1226,15 @@ enum class StyleOverscrollBehavior : uin
 #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
 
+// prefers-reduced-motion
+#define NS_STYLE_PREFERS_REDUCED_MOTION_NO_PREFERENCE   0
+#define NS_STYLE_PREFERS_REDUCED_MOTION_REDUCE          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
@@ -410,16 +410,19 @@ pref("browser.display.prefers_color_sche
 // 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);
+// 0 = default; no-preference
+// 1 = reduce
+pref("browser.display.prefers_reduced_motion", 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);
