html: Parse a comma-separated list of faces in the <font> tag (#32622)

This change parses a comma-separated list of faces in the `<font>` tag
and also moves the parsing code from `stylo` to Servo. This means that
the servo-specific code can be removed from stylo decreasing the
differences between Gecko and Servo's version of `stylo`.
This commit is contained in:
Martin Robinson 2024-06-26 20:28:35 +02:00 committed by GitHub
parent 47678a61b9
commit da2de4fc68
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 89 additions and 4 deletions

View file

@ -751,19 +751,18 @@ impl<'dom> LayoutElementHelpers<'dom> for LayoutDom<'dom, Element> {
));
}
let font_family = if let Some(this) = self.downcast::<HTMLFontElement>() {
let font_face = if let Some(this) = self.downcast::<HTMLFontElement>() {
this.get_face()
} else {
None
};
if let Some(font_family) = font_family {
// FIXME(emilio): This in Gecko parses a whole family list.
if let Some(font_face) = font_face {
hints.push(from_declaration(
shared_lock,
PropertyDeclaration::FontFamily(font_family::SpecifiedValue::Values(
computed::font::FontFamilyList {
list: Box::new([computed::font::SingleFontFamily::from_atom(font_family)]),
list: HTMLFontElement::parse_face_attribute(font_face).into_boxed_slice(),
},
)),
));

View file

@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use cssparser::match_ignore_ascii_case;
use dom_struct::dom_struct;
use html5ever::{local_name, namespace_url, ns, LocalName, Prefix};
use js::rust::HandleObject;
@ -9,6 +10,9 @@ use servo_atoms::Atom;
use style::attr::AttrValue;
use style::color::AbsoluteColor;
use style::str::{read_numbers, HTML_SPACE_CHARACTERS};
use style::values::computed::font::{
FamilyName, FontFamilyNameSyntax, GenericFontFamily, SingleFontFamily,
};
use crate::dom::attr::Attr;
use crate::dom::bindings::codegen::Bindings::HTMLFontElementBinding::HTMLFontElementMethods;
@ -50,6 +54,38 @@ impl HTMLFontElement {
proto,
)
}
pub(crate) fn parse_face_attribute(face_value: Atom) -> Vec<SingleFontFamily> {
face_value
.to_string()
.split(",")
.map(|string| Self::parse_single_face_value_from_string(string.trim()))
.collect()
}
fn parse_single_face_value_from_string(string: &str) -> SingleFontFamily {
match_ignore_ascii_case! { string,
"serif" => return SingleFontFamily::Generic(GenericFontFamily::Serif),
"sans-serif" => return SingleFontFamily::Generic(GenericFontFamily::SansSerif),
"cursive" => return SingleFontFamily::Generic(GenericFontFamily::Cursive),
"fantasy" => return SingleFontFamily::Generic(GenericFontFamily::Fantasy),
"monospace" => return SingleFontFamily::Generic(GenericFontFamily::Monospace),
"system-ui" => return SingleFontFamily::Generic(GenericFontFamily::SystemUi),
_ => {}
}
let name = string.to_owned().replace(['\'', '"'], "");
let syntax = if name == string {
FontFamilyNameSyntax::Identifiers
} else {
FontFamilyNameSyntax::Quoted
};
SingleFontFamily::FamilyName(FamilyName {
name: name.into(),
syntax,
})
}
}
impl HTMLFontElementMethods for HTMLFontElement {