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)]
|
#[derive(Clone, Copy, Debug, FromPrimitive, Parse, ToCss)]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
enum OverflowBlock {
|
enum OverflowBlock {
|
||||||
|
@ -548,7 +595,7 @@ macro_rules! system_metric_feature {
|
||||||
/// to support new types in these entries and (2) ensuring that either
|
/// to support new types in these entries and (2) ensuring that either
|
||||||
/// nsPresContext::MediaFeatureValuesChanged is called when the value that
|
/// nsPresContext::MediaFeatureValuesChanged is called when the value that
|
||||||
/// would be returned by the evaluator function could change.
|
/// would be returned by the evaluator function could change.
|
||||||
pub static MEDIA_FEATURES: [MediaFeatureDescription; 53] = [
|
pub static MEDIA_FEATURES: [MediaFeatureDescription; 54] = [
|
||||||
feature!(
|
feature!(
|
||||||
atom!("width"),
|
atom!("width"),
|
||||||
AllowsRanges::Yes,
|
AllowsRanges::Yes,
|
||||||
|
@ -666,6 +713,17 @@ pub static MEDIA_FEATURES: [MediaFeatureDescription; 53] = [
|
||||||
keyword_evaluator!(eval_prefers_reduced_motion, PrefersReducedMotion),
|
keyword_evaluator!(eval_prefers_reduced_motion, PrefersReducedMotion),
|
||||||
ParsingRequirements::empty(),
|
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!(
|
feature!(
|
||||||
atom!("overflow-block"),
|
atom!("overflow-block"),
|
||||||
AllowsRanges::No,
|
AllowsRanges::No,
|
||||||
|
|
|
@ -218,12 +218,18 @@ fn consume_operation_or_colon(input: &mut Parser) -> Result<Option<Operator>, ()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
fn disabled_by_pref(feature: &Atom) -> bool {
|
fn disabled_by_pref(feature: &Atom, context: &ParserContext) -> bool {
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
{
|
{
|
||||||
if *feature == atom!("-moz-touch-enabled") {
|
if *feature == atom!("-moz-touch-enabled") {
|
||||||
return !static_prefs::pref!("layout.css.moz-touch-enabled.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
|
false
|
||||||
}
|
}
|
||||||
|
@ -305,7 +311,7 @@ impl MediaFeatureExpression {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if disabled_by_pref(&feature.name) ||
|
if disabled_by_pref(&feature.name, context) ||
|
||||||
!requirements.contains(feature.requirements) ||
|
!requirements.contains(feature.requirements) ||
|
||||||
(range.is_some() && !feature.allows_ranges())
|
(range.is_some() && !feature.allows_ranges())
|
||||||
{
|
{
|
||||||
|
|
|
@ -2089,7 +2089,9 @@ pub fn assert_initial_values_match(data: &PerDocumentStyleData) {
|
||||||
let data = data.borrow();
|
let data = data.borrow();
|
||||||
let cv = data.stylist.device().default_computed_values();
|
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 = [
|
SKIPPED = [
|
||||||
"border-top-width",
|
"border-top-width",
|
||||||
"border-bottom-width",
|
"border-bottom-width",
|
||||||
|
@ -2098,6 +2100,7 @@ pub fn assert_initial_values_match(data: &PerDocumentStyleData) {
|
||||||
"font-family",
|
"font-family",
|
||||||
"font-size",
|
"font-size",
|
||||||
"outline-width",
|
"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]
|
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