Skip to content

Commit 13e2ca6

Browse files
committed
LibWeb: Parse src: local(...) in CSS @font-face rules
Note that we don't load the local font as specified, but at least we no longer reject such src properties in the CSS parser. This makes the custom fonts used on http://apple.com/ actually load. :^)
1 parent e924ea0 commit 13e2ca6

File tree

7 files changed

+32
-6
lines changed

7 files changed

+32
-6
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@font-face { font-family: "a1"; src: local("xyz"); unicode-range: "U+0-10ffff"; }
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<script src="../include.js"></script>
2+
<script>
3+
test(() => {
4+
let style = document.createElement("style");
5+
style.innerText = "@font-face { font-family: 'a1'; src: local('xyz'); }";
6+
document.head.appendChild(style);
7+
let sheet = style.sheet;
8+
println(sheet.cssRules[0].cssText);
9+
});
10+
</script>

Userland/Libraries/LibWeb/CSS/CSSFontFaceRule.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,11 @@ DeprecatedString CSSFontFaceRule::serialized() const
6262

6363
// 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.
6464
serialize_a_comma_separated_list(builder, m_font_face.sources(), [&](StringBuilder& builder, FontFace::Source source) -> void {
65-
// FIXME: Serialize locals once we support those
66-
serialize_a_url(builder, source.url.to_deprecated_string());
65+
if (source.local_or_url.has<AK::URL>()) {
66+
serialize_a_url(builder, source.local_or_url.get<AK::URL>().to_deprecated_string());
67+
} else {
68+
builder.appendff("local({})", source.local_or_url.get<String>());
69+
}
6770

6871
// NOTE: No spec currently exists for format()
6972
if (source.format.has_value()) {

Userland/Libraries/LibWeb/CSS/FontFace.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ namespace Web::CSS {
1616
class FontFace {
1717
public:
1818
struct Source {
19-
AK::URL url;
19+
Variant<String, AK::URL> local_or_url;
2020
// FIXME: Do we need to keep this around, or is it only needed to discard unwanted formats during parsing?
2121
Optional<FlyString> format;
2222
};

Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4453,7 +4453,14 @@ Vector<FontFace::Source> Parser::parse_font_face_src(TokenStream<ComponentValue>
44534453
continue;
44544454
}
44554455

4456-
// FIXME: Implement `local()`.
4456+
if (first.is_function() && first.function().name().equals_ignoring_ascii_case("local"sv)) {
4457+
if (first.function().values().is_empty()) {
4458+
continue;
4459+
}
4460+
supported_sources.empend(first.function().values().first().to_string(), Optional<FlyString> {});
4461+
continue;
4462+
}
4463+
44574464
dbgln_if(CSS_PARSER_DEBUG, "CSSParser: @font-face src invalid (failed to parse url from: {}); discarding.", first.to_debug_string());
44584465
return {};
44594466
}

Userland/Libraries/LibWeb/CSS/StyleComputer.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2827,7 +2827,9 @@ void StyleComputer::load_fonts_from_sheet(CSSStyleSheet const& sheet)
28272827
Vector<AK::URL> urls;
28282828
for (auto& source : font_face.sources()) {
28292829
// FIXME: These should be loaded relative to the stylesheet URL instead of the document URL.
2830-
urls.append(m_document->parse_url(source.url.to_deprecated_string()));
2830+
if (source.local_or_url.has<AK::URL>())
2831+
urls.append(m_document->parse_url(source.local_or_url.get<AK::URL>().to_deprecated_string()));
2832+
// FIXME: Handle local()
28312833
}
28322834

28332835
if (urls.is_empty())

Userland/Libraries/LibWeb/Dump.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -654,7 +654,10 @@ void dump_font_face_rule(StringBuilder& builder, CSS::CSSFontFaceRule const& rul
654654
builder.append("sources:\n"sv);
655655
for (auto const& source : font_face.sources()) {
656656
indent(builder, indent_levels + 2);
657-
builder.appendff("url={}, format={}\n", source.url, source.format.value_or("???"_string));
657+
if (source.local_or_url.has<AK::URL>())
658+
builder.appendff("url={}, format={}\n", source.local_or_url.get<AK::URL>(), source.format.value_or("???"_string));
659+
else
660+
builder.appendff("local={}\n", source.local_or_url.get<AK::String>());
658661
}
659662

660663
indent(builder, indent_levels + 1);

0 commit comments

Comments
 (0)