|
1 | 1 | #pragma once |
2 | 2 | #include "webscene_css_container_queries.h" |
3 | 3 | #include "webscene_css_matching.h" |
| 4 | +#include "webscene_accessibility_preferences.h" |
4 | 5 | #include <cstdlib> |
5 | 6 |
|
6 | 7 | namespace webscene_native::css { |
7 | | -struct media_environment { float width; float height; bool dark=false; bool reduced_motion=false; }; |
| 8 | +struct media_environment { |
| 9 | + float width{}; |
| 10 | + float height{}; |
| 11 | + bool dark{false}; |
| 12 | + bool reduced_motion{false}; |
| 13 | + bool forced_colors{false}; |
| 14 | + bool contrast_more{false}; |
| 15 | + |
| 16 | + media_environment() = default; |
| 17 | + media_environment(float width_value, float height_value) |
| 18 | + : media_environment(width_value, height_value, false) {} |
| 19 | + media_environment(float width_value, float height_value, bool dark_value) |
| 20 | + : width(width_value), height(height_value), dark(dark_value) |
| 21 | + { |
| 22 | + const auto preferences = get_active_accessibility_preferences(); |
| 23 | + reduced_motion = preferences.reduced_motion; |
| 24 | + forced_colors = preferences.forced_colors; |
| 25 | + contrast_more = preferences.contrast_more; |
| 26 | + } |
| 27 | + media_environment(float width_value, float height_value, bool dark_value, |
| 28 | + bool reduced_motion_value, bool forced_colors_value = false, |
| 29 | + bool contrast_more_value = false) |
| 30 | + : width(width_value), height(height_value), dark(dark_value), |
| 31 | + reduced_motion(reduced_motion_value), forced_colors(forced_colors_value), |
| 32 | + contrast_more(contrast_more_value) {} |
| 33 | +}; |
8 | 34 | inline bool media_matches(std::string query, const media_environment& environment) |
9 | 35 | { |
10 | 36 | if (is_container_query(query)) return true; |
@@ -85,6 +111,10 @@ inline bool media_matches(std::string query, const media_environment& environmen |
85 | 111 | environment.dark |
86 | 112 | ? "dark" |
87 | 113 | : "light"); |
| 114 | + } else if (feature == "forced-colors") { |
| 115 | + matches = value == (environment.forced_colors ? "active" : "none"); |
| 116 | + } else if (feature == "prefers-contrast") { |
| 117 | + matches = value == (environment.contrast_more ? "more" : "no-preference"); |
88 | 118 | } else { |
89 | 119 | matches = false; |
90 | 120 | } |
@@ -152,7 +182,8 @@ bool inventory_media(std::string query, Record&& record_feature) |
152 | 182 | static const std::unordered_set<std::string> supported_features{ |
153 | 183 | "max-width", "min-width", "max-height", "min-height", "orientation", |
154 | 184 | "hover", "any-hover", "pointer", "any-pointer", |
155 | | - "prefers-reduced-motion", "prefers-color-scheme"}; |
| 185 | + "prefers-reduced-motion", "prefers-color-scheme", |
| 186 | + "forced-colors", "prefers-contrast"}; |
156 | 187 | const auto known = range_syntax || (separator != std::string::npos |
157 | 188 | && supported_features.contains(feature)); |
158 | 189 | record_feature( |
|
0 commit comments