style: Implement the prefers-contrast media-query.

Differential Revision: https://phabricator.services.mozilla.com/D79553
This commit is contained in:
Zeke Medley 2020-06-29 17:46:12 +00:00 committed by Emilio Cobos Álvarez
parent 46df06b3e2
commit 8ff565c86b
3 changed files with 71 additions and 4 deletions

View file

@ -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,