mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
style: Implement the prefers-contrast media-query.
Differential Revision: https://phabricator.services.mozilla.com/D79553
This commit is contained in:
parent
46df06b3e2
commit
8ff565c86b
3 changed files with 71 additions and 4 deletions
|
@ -308,6 +308,53 @@ fn eval_prefers_reduced_motion(device: &Device, query_value: Option<PrefersReduc
|
|||
}
|
||||
}
|
||||
|
||||
/// Possible values for prefers-contrast media query.
|
||||
/// https://drafts.csswg.org/mediaqueries-5/#prefers-contrast
|
||||
#[derive(Clone, Copy, Debug, FromPrimitive, PartialEq, Parse, ToCss)]
|
||||
#[repr(u8)]
|
||||
#[allow(missing_docs)]
|
||||
enum PrefersContrast {
|
||||
High,
|
||||
Low,
|
||||
NoPreference,
|
||||
Forced,
|
||||
}
|
||||
|
||||
/// Represents the parts of prefers-contrast that explicitly deal with
|
||||
/// contrast. Used in combination with information about rather or not
|
||||
/// forced colors are active this allows for evaluation of the
|
||||
/// prefers-contrast media query.
|
||||
#[derive(Clone, Copy, Debug, FromPrimitive, PartialEq)]
|
||||
#[repr(u8)]
|
||||
pub enum ContrastPref {
|
||||
/// High contrast is prefered. Corresponds to an accessibility theme
|
||||
/// being enabled or firefox forcing high contrast colors.
|
||||
High,
|
||||
/// Low contrast is prefered. Corresponds to the
|
||||
/// browser.display.prefers_low_contrast pref being true.
|
||||
Low,
|
||||
/// The default value if neither high or low contrast is enabled.
|
||||
NoPreference,
|
||||
}
|
||||
|
||||
/// https://drafts.csswg.org/mediaqueries-5/#prefers-contrast
|
||||
fn eval_prefers_contrast(device: &Device, query_value: Option<PrefersContrast>) -> bool {
|
||||
let forced_colors = !device.use_document_colors();
|
||||
let contrast_pref =
|
||||
unsafe { bindings::Gecko_MediaFeatures_PrefersContrast(device.document(), forced_colors) };
|
||||
if let Some(query_value) = query_value {
|
||||
match query_value {
|
||||
PrefersContrast::Forced => forced_colors,
|
||||
PrefersContrast::High => contrast_pref == ContrastPref::High,
|
||||
PrefersContrast::Low => contrast_pref == ContrastPref::Low,
|
||||
PrefersContrast::NoPreference => contrast_pref == ContrastPref::NoPreference,
|
||||
}
|
||||
} else {
|
||||
// Only prefers-contrast: no-preference evaluates to false.
|
||||
forced_colors || (contrast_pref != ContrastPref::NoPreference)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, FromPrimitive, Parse, ToCss)]
|
||||
#[repr(u8)]
|
||||
enum OverflowBlock {
|
||||
|
@ -548,7 +595,7 @@ macro_rules! system_metric_feature {
|
|||
/// to support new types in these entries and (2) ensuring that either
|
||||
/// nsPresContext::MediaFeatureValuesChanged is called when the value that
|
||||
/// would be returned by the evaluator function could change.
|
||||
pub static MEDIA_FEATURES: [MediaFeatureDescription; 53] = [
|
||||
pub static MEDIA_FEATURES: [MediaFeatureDescription; 54] = [
|
||||
feature!(
|
||||
atom!("width"),
|
||||
AllowsRanges::Yes,
|
||||
|
@ -666,6 +713,17 @@ pub static MEDIA_FEATURES: [MediaFeatureDescription; 53] = [
|
|||
keyword_evaluator!(eval_prefers_reduced_motion, PrefersReducedMotion),
|
||||
ParsingRequirements::empty(),
|
||||
),
|
||||
feature!(
|
||||
atom!("prefers-contrast"),
|
||||
AllowsRanges::No,
|
||||
keyword_evaluator!(eval_prefers_contrast, PrefersContrast),
|
||||
// Note: by default this is only enabled in browser chrome and
|
||||
// ua. It can be enabled on the web via the
|
||||
// layout.css.prefers-contrast.enabled preference. See
|
||||
// disabed_by_pref in media_feature_expression.rs for how that
|
||||
// is done.
|
||||
ParsingRequirements::empty(),
|
||||
),
|
||||
feature!(
|
||||
atom!("overflow-block"),
|
||||
AllowsRanges::No,
|
||||
|
|
|
@ -218,12 +218,18 @@ fn consume_operation_or_colon(input: &mut Parser) -> Result<Option<Operator>, ()
|
|||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn disabled_by_pref(feature: &Atom) -> bool {
|
||||
fn disabled_by_pref(feature: &Atom, context: &ParserContext) -> bool {
|
||||
#[cfg(feature = "gecko")]
|
||||
{
|
||||
if *feature == atom!("-moz-touch-enabled") {
|
||||
return !static_prefs::pref!("layout.css.moz-touch-enabled.enabled");
|
||||
}
|
||||
// prefers-contrast is always enabled in the ua and chrome. On
|
||||
// the web it is hidden behind a preference.
|
||||
if *feature == atom!("prefers-contrast") {
|
||||
return !context.in_ua_or_chrome_sheet() &&
|
||||
!static_prefs::pref!("layout.css.prefers-contrast.enabled");
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
@ -305,7 +311,7 @@ impl MediaFeatureExpression {
|
|||
},
|
||||
};
|
||||
|
||||
if disabled_by_pref(&feature.name) ||
|
||||
if disabled_by_pref(&feature.name, context) ||
|
||||
!requirements.contains(feature.requirements) ||
|
||||
(range.is_some() && !feature.allows_ranges())
|
||||
{
|
||||
|
|
|
@ -2089,7 +2089,9 @@ pub fn assert_initial_values_match(data: &PerDocumentStyleData) {
|
|||
let data = data.borrow();
|
||||
let cv = data.stylist.device().default_computed_values();
|
||||
<%
|
||||
# Skip properties with initial values that change at computed value time.
|
||||
# Skip properties with initial values that change at computed
|
||||
# value time, or whose initial value depends on the document
|
||||
# / other prefs.
|
||||
SKIPPED = [
|
||||
"border-top-width",
|
||||
"border-bottom-width",
|
||||
|
@ -2098,6 +2100,7 @@ pub fn assert_initial_values_match(data: &PerDocumentStyleData) {
|
|||
"font-family",
|
||||
"font-size",
|
||||
"outline-width",
|
||||
"color",
|
||||
]
|
||||
TO_TEST = [p for p in data.longhands if p.enabled_in != "" and not p.logical and not p.name in SKIPPED]
|
||||
%>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue