LibWeb/CSS: Only attempt to load valid @font-face fonts

These must have a `font-family` and `src` set to be included in
font-matching. Otherwise they should be ignored, but still exist in the
CSSOM.
This commit is contained in:
Sam Atkins 2025-04-03 12:15:11 +01:00
parent d42a5494d7
commit eea0f0932f
4 changed files with 17 additions and 2 deletions

View file

@ -34,6 +34,15 @@ void CSSFontFaceRule::initialize(JS::Realm& realm)
WEB_SET_PROTOTYPE_FOR_INTERFACE(CSSFontFaceRule);
}
bool CSSFontFaceRule::is_valid() const
{
// @font-face rules require a font-family and src descriptor; if either of these are missing, the @font-face rule
// must not be considered when performing the font matching algorithm.
// https://drafts.csswg.org/css-fonts-4/#font-face-rule
return !m_style->descriptor(DescriptorID::FontFamily).is_null()
&& !m_style->descriptor(DescriptorID::Src).is_null();
}
ParsedFontFace CSSFontFaceRule::font_face() const
{
return ParsedFontFace::from_descriptors(m_style);

View file

@ -22,6 +22,7 @@ public:
virtual ~CSSFontFaceRule() override = default;
bool is_valid() const;
ParsedFontFace font_face() const;
CSSStyleDeclaration* style() { return m_style; }

View file

@ -3061,8 +3061,10 @@ void StyleComputer::load_fonts_from_sheet(CSSStyleSheet& sheet)
for (auto const& rule : sheet.rules()) {
if (!is<CSSFontFaceRule>(*rule))
continue;
auto font_loader = load_font_face(static_cast<CSSFontFaceRule const&>(*rule).font_face());
if (font_loader.has_value()) {
auto const& font_face_rule = static_cast<CSSFontFaceRule const&>(*rule);
if (!font_face_rule.is_valid())
continue;
if (auto font_loader = load_font_face(font_face_rule.font_face()); font_loader.has_value()) {
sheet.add_associated_font_loader(font_loader.value());
}
}

View file

@ -702,6 +702,9 @@ void dump_rule(StringBuilder& builder, CSS::CSSRule const& rule, int indent_leve
void dump_font_face_rule(StringBuilder& builder, CSS::CSSFontFaceRule const& rule, int indent_levels)
{
auto const font_face = rule.font_face();
indent(builder, indent_levels + 1);
builder.appendff("VALID: {}\n", rule.is_valid());
indent(builder, indent_levels + 1);
builder.appendff("font-family: {}\n", font_face.font_family());