diff --git a/Tests/LibWeb/Text/expected/css/font-face-src-local-serialization.txt b/Tests/LibWeb/Text/expected/css/font-face-src-local-serialization.txt new file mode 100644 index 00000000000..491578a7596 --- /dev/null +++ b/Tests/LibWeb/Text/expected/css/font-face-src-local-serialization.txt @@ -0,0 +1 @@ +@font-face { font-family: "a1"; src: local("xyz"); unicode-range: "U+0-10ffff"; } diff --git a/Tests/LibWeb/Text/input/css/font-face-src-local-serialization.html b/Tests/LibWeb/Text/input/css/font-face-src-local-serialization.html new file mode 100644 index 00000000000..6e1505b29ab --- /dev/null +++ b/Tests/LibWeb/Text/input/css/font-face-src-local-serialization.html @@ -0,0 +1,10 @@ + + diff --git a/Userland/Libraries/LibWeb/CSS/CSSFontFaceRule.cpp b/Userland/Libraries/LibWeb/CSS/CSSFontFaceRule.cpp index 9e486ab9046..4fa5945cbdf 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSFontFaceRule.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSFontFaceRule.cpp @@ -62,8 +62,11 @@ DeprecatedString CSSFontFaceRule::serialized() const // 2. The result of invoking serialize a comma-separated list on performing serialize a URL or serialize a LOCAL for each source on the source list. serialize_a_comma_separated_list(builder, m_font_face.sources(), [&](StringBuilder& builder, FontFace::Source source) -> void { - // FIXME: Serialize locals once we support those - serialize_a_url(builder, source.url.to_deprecated_string()); + if (source.local_or_url.has()) { + serialize_a_url(builder, source.local_or_url.get().to_deprecated_string()); + } else { + builder.appendff("local({})", source.local_or_url.get()); + } // NOTE: No spec currently exists for format() if (source.format.has_value()) { diff --git a/Userland/Libraries/LibWeb/CSS/FontFace.h b/Userland/Libraries/LibWeb/CSS/FontFace.h index 04a112a2d01..eb46b3de307 100644 --- a/Userland/Libraries/LibWeb/CSS/FontFace.h +++ b/Userland/Libraries/LibWeb/CSS/FontFace.h @@ -16,7 +16,7 @@ namespace Web::CSS { class FontFace { public: struct Source { - AK::URL url; + Variant local_or_url; // FIXME: Do we need to keep this around, or is it only needed to discard unwanted formats during parsing? Optional format; }; diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index 5f76228272b..384a02f4e40 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -4453,7 +4453,14 @@ Vector Parser::parse_font_face_src(TokenStream continue; } - // FIXME: Implement `local()`. + if (first.is_function() && first.function().name().equals_ignoring_ascii_case("local"sv)) { + if (first.function().values().is_empty()) { + continue; + } + supported_sources.empend(first.function().values().first().to_string(), Optional {}); + continue; + } + dbgln_if(CSS_PARSER_DEBUG, "CSSParser: @font-face src invalid (failed to parse url from: {}); discarding.", first.to_debug_string()); return {}; } diff --git a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp index 64128d288ba..253fbef348d 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp @@ -2827,7 +2827,9 @@ void StyleComputer::load_fonts_from_sheet(CSSStyleSheet const& sheet) Vector urls; for (auto& source : font_face.sources()) { // FIXME: These should be loaded relative to the stylesheet URL instead of the document URL. - urls.append(m_document->parse_url(source.url.to_deprecated_string())); + if (source.local_or_url.has()) + urls.append(m_document->parse_url(source.local_or_url.get().to_deprecated_string())); + // FIXME: Handle local() } if (urls.is_empty()) diff --git a/Userland/Libraries/LibWeb/Dump.cpp b/Userland/Libraries/LibWeb/Dump.cpp index e7164462122..023d7468c71 100644 --- a/Userland/Libraries/LibWeb/Dump.cpp +++ b/Userland/Libraries/LibWeb/Dump.cpp @@ -654,7 +654,10 @@ void dump_font_face_rule(StringBuilder& builder, CSS::CSSFontFaceRule const& rul builder.append("sources:\n"sv); for (auto const& source : font_face.sources()) { indent(builder, indent_levels + 2); - builder.appendff("url={}, format={}\n", source.url, source.format.value_or("???"_string)); + if (source.local_or_url.has()) + builder.appendff("url={}, format={}\n", source.local_or_url.get(), source.format.value_or("???"_string)); + else + builder.appendff("local={}\n", source.local_or_url.get()); } indent(builder, indent_levels + 1);