diff --git a/components/style/properties/shorthands/font.mako.rs b/components/style/properties/shorthands/font.mako.rs index 26205c2ea9c..b24711b4aed 100644 --- a/components/style/properties/shorthands/font.mako.rs +++ b/components/style/properties/shorthands/font.mako.rs @@ -137,7 +137,7 @@ return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } - let family = FontFamily::parse_specified(input)?; + let family = FontFamily::parse(context, input)?; Ok(expanded! { % for name in "style weight stretch variant_caps".split(): font_${name}: unwrap_or_initial!(font_${name}, ${name}), diff --git a/components/style/values/computed/font.rs b/components/style/values/computed/font.rs index b944640d8e7..9d7ba40c0bd 100644 --- a/components/style/values/computed/font.rs +++ b/components/style/values/computed/font.rs @@ -6,6 +6,7 @@ #[cfg(feature = "gecko")] use crate::gecko_bindings::{bindings, structs}; +use crate::parser::{Parse, ParserContext}; use crate::values::animated::ToAnimatedValue; use crate::values::computed::{ Angle, Context, Integer, Length, NonNegativeLength, NonNegativeNumber, NonNegativePercentage, @@ -250,6 +251,7 @@ impl FontFamily { generic_font_family!(FANTASY, Fantasy); #[cfg(feature = "gecko")] generic_font_family!(MOZ_EMOJI, MozEmoji); + generic_font_family!(SYSTEM_UI, SystemUi); match generic { GenericFontFamily::None => { @@ -263,6 +265,7 @@ impl FontFamily { GenericFontFamily::Fantasy => &*FANTASY, #[cfg(feature = "gecko")] GenericFontFamily::MozEmoji => &*MOZ_EMOJI, + GenericFontFamily::SystemUi => &*SYSTEM_UI, } } } @@ -383,6 +386,10 @@ pub enum SingleFontFamily { Generic(GenericFontFamily), } +fn system_ui_enabled(_: &ParserContext) -> bool { + static_prefs::pref!("layout.css.system-ui.enabled") +} + /// A generic font-family name. /// /// The order here is important, if you change it make sure that @@ -417,15 +424,17 @@ pub enum GenericFontFamily { Monospace, Cursive, Fantasy, + #[parse(aliases = "-apple-system", condition = "system_ui_enabled")] + SystemUi, /// An internal value for emoji font selection. #[css(skip)] #[cfg(feature = "gecko")] MozEmoji, } -impl SingleFontFamily { +impl Parse for SingleFontFamily { /// Parse a font-family value. - pub fn parse<'i, 't>(input: &mut Parser<'i, 't>) -> Result> { + fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { if let Ok(value) = input.try_parse(|i| i.expect_string_cloned()) { return Ok(SingleFontFamily::FamilyName(FamilyName { name: Atom::from(&*value), @@ -433,11 +442,11 @@ impl SingleFontFamily { })); } - let first_ident = input.expect_ident_cloned()?; - if let Ok(generic) = GenericFontFamily::from_ident(&first_ident) { + if let Ok(generic) = input.try_parse(|i| GenericFontFamily::parse(context, i)) { return Ok(SingleFontFamily::Generic(generic)); } + let first_ident = input.expect_ident_cloned()?; let reserved = match_ignore_ascii_case! { &first_ident, // https://drafts.csswg.org/css-fonts/#propdef-font-family // "Font family names that happen to be the same as a keyword value @@ -480,8 +489,10 @@ impl SingleFontFamily { syntax, })) } +} - #[cfg(feature = "servo")] +#[cfg(feature = "servo")] +impl SingleFontFamily { /// Get the corresponding font-family with Atom pub fn from_atom(input: Atom) -> SingleFontFamily { match input { diff --git a/components/style/values/specified/font.rs b/components/style/values/specified/font.rs index 9b417a410c6..22859d1af1b 100644 --- a/components/style/values/specified/font.rs +++ b/components/style/values/specified/font.rs @@ -681,19 +681,6 @@ pub enum FontFamily { impl FontFamily { system_font_methods!(FontFamily, font_family); - - /// Parse a specified font-family value - pub fn parse_specified<'i, 't>(input: &mut Parser<'i, 't>) -> Result> { - let values = input.parse_comma_separated(SingleFontFamily::parse)?; - Ok(FontFamily::Values(FontFamilyList { - #[cfg(feature = "gecko")] - list: crate::ArcSlice::from_iter(values.into_iter()), - #[cfg(feature = "servo")] - list: values.into_boxed_slice(), - #[cfg(feature = "gecko")] - fallback: computed::GenericFontFamily::None, - })) - } } impl ToComputedValue for FontFamily { @@ -733,23 +720,31 @@ impl Parse for FontFamily { /// = | [ + ] /// TODO: fn parse<'i, 't>( - _: &ParserContext, + context: &ParserContext, input: &mut Parser<'i, 't>, ) -> Result> { - FontFamily::parse_specified(input) + let values = input.parse_comma_separated(|input| SingleFontFamily::parse(context, input))?; + Ok(FontFamily::Values(FontFamilyList { + #[cfg(feature = "gecko")] + list: crate::ArcSlice::from_iter(values.into_iter()), + #[cfg(feature = "servo")] + list: values.into_boxed_slice(), + #[cfg(feature = "gecko")] + fallback: computed::GenericFontFamily::None, + })) } } impl SpecifiedValueInfo for FontFamily {} -/// `FamilyName::parse` is based on `SingleFontFamily::parse` and not the other way around -/// because we want the former to exclude generic family keywords. +/// `FamilyName::parse` is based on `SingleFontFamily::parse` and not the other +/// way around because we want the former to exclude generic family keywords. impl Parse for FamilyName { fn parse<'i, 't>( - _: &ParserContext, + context: &ParserContext, input: &mut Parser<'i, 't>, ) -> Result> { - match SingleFontFamily::parse(input) { + match SingleFontFamily::parse(context, input) { Ok(SingleFontFamily::FamilyName(name)) => Ok(name), Ok(SingleFontFamily::Generic(_)) => { Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))