style: Add system-ui boilerplate

Alias -apple-system to it, and put it behind a pref for now. This is
pretty boring (read: uncontroversial hopefully) code. The follow-up work
is modifying StaticPresData to look up the fonts using system APIs,
probably. Maybe a bit more work if on macOS they can't be named.

Differential Revision: https://phabricator.services.mozilla.com/D119984
This commit is contained in:
Emilio Cobos Álvarez 2023-05-22 10:26:26 +02:00 committed by Oriol Brufau
parent 9cf7df1f31
commit d86e449e8c
3 changed files with 31 additions and 25 deletions

View file

@ -137,7 +137,7 @@
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
} }
let family = FontFamily::parse_specified(input)?; let family = FontFamily::parse(context, input)?;
Ok(expanded! { Ok(expanded! {
% for name in "style weight stretch variant_caps".split(): % for name in "style weight stretch variant_caps".split():
font_${name}: unwrap_or_initial!(font_${name}, ${name}), font_${name}: unwrap_or_initial!(font_${name}, ${name}),

View file

@ -6,6 +6,7 @@
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
use crate::gecko_bindings::{bindings, structs}; use crate::gecko_bindings::{bindings, structs};
use crate::parser::{Parse, ParserContext};
use crate::values::animated::ToAnimatedValue; use crate::values::animated::ToAnimatedValue;
use crate::values::computed::{ use crate::values::computed::{
Angle, Context, Integer, Length, NonNegativeLength, NonNegativeNumber, NonNegativePercentage, Angle, Context, Integer, Length, NonNegativeLength, NonNegativeNumber, NonNegativePercentage,
@ -250,6 +251,7 @@ impl FontFamily {
generic_font_family!(FANTASY, Fantasy); generic_font_family!(FANTASY, Fantasy);
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
generic_font_family!(MOZ_EMOJI, MozEmoji); generic_font_family!(MOZ_EMOJI, MozEmoji);
generic_font_family!(SYSTEM_UI, SystemUi);
match generic { match generic {
GenericFontFamily::None => { GenericFontFamily::None => {
@ -263,6 +265,7 @@ impl FontFamily {
GenericFontFamily::Fantasy => &*FANTASY, GenericFontFamily::Fantasy => &*FANTASY,
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
GenericFontFamily::MozEmoji => &*MOZ_EMOJI, GenericFontFamily::MozEmoji => &*MOZ_EMOJI,
GenericFontFamily::SystemUi => &*SYSTEM_UI,
} }
} }
} }
@ -383,6 +386,10 @@ pub enum SingleFontFamily {
Generic(GenericFontFamily), Generic(GenericFontFamily),
} }
fn system_ui_enabled(_: &ParserContext) -> bool {
static_prefs::pref!("layout.css.system-ui.enabled")
}
/// A generic font-family name. /// A generic font-family name.
/// ///
/// The order here is important, if you change it make sure that /// The order here is important, if you change it make sure that
@ -417,15 +424,17 @@ pub enum GenericFontFamily {
Monospace, Monospace,
Cursive, Cursive,
Fantasy, Fantasy,
#[parse(aliases = "-apple-system", condition = "system_ui_enabled")]
SystemUi,
/// An internal value for emoji font selection. /// An internal value for emoji font selection.
#[css(skip)] #[css(skip)]
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
MozEmoji, MozEmoji,
} }
impl SingleFontFamily { impl Parse for SingleFontFamily {
/// Parse a font-family value. /// Parse a font-family value.
pub fn parse<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> { fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
if let Ok(value) = input.try_parse(|i| i.expect_string_cloned()) { if let Ok(value) = input.try_parse(|i| i.expect_string_cloned()) {
return Ok(SingleFontFamily::FamilyName(FamilyName { return Ok(SingleFontFamily::FamilyName(FamilyName {
name: Atom::from(&*value), name: Atom::from(&*value),
@ -433,11 +442,11 @@ impl SingleFontFamily {
})); }));
} }
let first_ident = input.expect_ident_cloned()?; if let Ok(generic) = input.try_parse(|i| GenericFontFamily::parse(context, i)) {
if let Ok(generic) = GenericFontFamily::from_ident(&first_ident) {
return Ok(SingleFontFamily::Generic(generic)); return Ok(SingleFontFamily::Generic(generic));
} }
let first_ident = input.expect_ident_cloned()?;
let reserved = match_ignore_ascii_case! { &first_ident, let reserved = match_ignore_ascii_case! { &first_ident,
// https://drafts.csswg.org/css-fonts/#propdef-font-family // https://drafts.csswg.org/css-fonts/#propdef-font-family
// "Font family names that happen to be the same as a keyword value // "Font family names that happen to be the same as a keyword value
@ -480,8 +489,10 @@ impl SingleFontFamily {
syntax, syntax,
})) }))
} }
}
#[cfg(feature = "servo")] #[cfg(feature = "servo")]
impl SingleFontFamily {
/// Get the corresponding font-family with Atom /// Get the corresponding font-family with Atom
pub fn from_atom(input: Atom) -> SingleFontFamily { pub fn from_atom(input: Atom) -> SingleFontFamily {
match input { match input {

View file

@ -681,19 +681,6 @@ pub enum FontFamily {
impl FontFamily { impl FontFamily {
system_font_methods!(FontFamily, font_family); system_font_methods!(FontFamily, font_family);
/// Parse a specified font-family value
pub fn parse_specified<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
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 { impl ToComputedValue for FontFamily {
@ -733,23 +720,31 @@ impl Parse for FontFamily {
/// <family-name> = <string> | [ <ident>+ ] /// <family-name> = <string> | [ <ident>+ ]
/// TODO: <generic-family> /// TODO: <generic-family>
fn parse<'i, 't>( fn parse<'i, 't>(
_: &ParserContext, context: &ParserContext,
input: &mut Parser<'i, 't>, input: &mut Parser<'i, 't>,
) -> Result<FontFamily, ParseError<'i>> { ) -> Result<FontFamily, ParseError<'i>> {
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 {} impl SpecifiedValueInfo for FontFamily {}
/// `FamilyName::parse` is based on `SingleFontFamily::parse` and not the other way around /// `FamilyName::parse` is based on `SingleFontFamily::parse` and not the other
/// because we want the former to exclude generic family keywords. /// way around because we want the former to exclude generic family keywords.
impl Parse for FamilyName { impl Parse for FamilyName {
fn parse<'i, 't>( fn parse<'i, 't>(
_: &ParserContext, context: &ParserContext,
input: &mut Parser<'i, 't>, input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> { ) -> Result<Self, ParseError<'i>> {
match SingleFontFamily::parse(input) { match SingleFontFamily::parse(context, input) {
Ok(SingleFontFamily::FamilyName(name)) => Ok(name), Ok(SingleFontFamily::FamilyName(name)) => Ok(name),
Ok(SingleFontFamily::Generic(_)) => { Ok(SingleFontFamily::Generic(_)) => {
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))