mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-04-25 17:25:08 +02:00
LibWeb: Implement FontFaceSet.check()
This returns true if the given text can be rendered with the fonts in the set that are fully loaded.
This commit is contained in:
committed by
Sam Atkins
parent
14a0f00400
commit
657060ccc2
Notes:
github-actions[bot]
2026-03-27 15:30:12 +00:00
Author: https://github.com/tcl3 Commit: https://github.com/LadybirdBrowser/ladybird/commit/657060ccc26 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/8644 Reviewed-by: https://github.com/AtkinsSJ ✅
@@ -295,6 +295,35 @@ JS::ThrowCompletionOr<GC::Ref<WebIDL::Promise>> FontFaceSet::load(String const&
|
||||
return promise;
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/css-font-loading/#dom-fontfaceset-check
|
||||
WebIDL::ExceptionOr<bool> FontFaceSet::check(String const& font, String const& text)
|
||||
{
|
||||
// 1. Let font face set be the FontFaceSet object this method was called on.
|
||||
GC::Ref font_face_set = *this;
|
||||
|
||||
auto& realm = this->realm();
|
||||
|
||||
// 2. Find the matching font faces from font face set using the font and text arguments passed to the function, and
|
||||
// including system fonts, and let font face list be the returned list of font faces, and found faces be the
|
||||
// returned found faces flag. If a syntax error was returned, throw a SyntaxError exception and terminate these
|
||||
// steps.
|
||||
auto result = TRY(find_matching_font_faces(realm, font_face_set, font, text));
|
||||
|
||||
// 3. If font face list is empty, or all fonts in the font face list either have a status attribute of "loaded" or
|
||||
// are system fonts, return true. Otherwise, return false.
|
||||
if (result->set_size() == 0)
|
||||
return true;
|
||||
|
||||
for (auto font_face_value : *result) {
|
||||
auto& font_face = as<FontFace>(font_face_value.key.as_object());
|
||||
// FIXME: We should check if the font face is a system font here.
|
||||
if (font_face.status() != Bindings::FontFaceLoadStatus::Loaded)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/css-font-loading/#font-face-set-ready
|
||||
GC::Ref<WebIDL::Promise> FontFaceSet::ready() const
|
||||
{
|
||||
|
||||
@@ -40,6 +40,7 @@ public:
|
||||
WebIDL::CallbackType* onloadingerror();
|
||||
|
||||
JS::ThrowCompletionOr<GC::Ref<WebIDL::Promise>> load(String const& font, String const& text);
|
||||
WebIDL::ExceptionOr<bool> check(String const& font, String const& text);
|
||||
|
||||
Vector<GC::Ref<FontFace>>& loading_fonts() { return m_loading_fonts; }
|
||||
Vector<GC::Ref<FontFace>>& loaded_fonts() { return m_loaded_fonts; }
|
||||
|
||||
@@ -24,7 +24,7 @@ interface FontFaceSet : EventTarget {
|
||||
// return whether all fonts in the fontlist are loaded
|
||||
// (does not initiate load if not available)
|
||||
// FIXME: boolean check(CSSOMString font, optional CSSOMString text = " ");
|
||||
[FIXME] boolean check(CSSOMString font, optional CSSOMString text = "");
|
||||
boolean check(CSSOMString font, optional CSSOMString text = "");
|
||||
|
||||
// async notification that font loading and layout operations are done
|
||||
readonly attribute Promise<FontFaceSet> ready;
|
||||
|
||||
5
Tests/LibWeb/Text/expected/css/FontFaceSet-check.txt
Normal file
5
Tests/LibWeb/Text/expected/css/FontFaceSet-check.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
Check invalid font: PASS
|
||||
Check CSS keyword as font: PASS
|
||||
Check non-existent font: PASS
|
||||
Check unloaded font: PASS
|
||||
Check loaded font: PASS
|
||||
30
Tests/LibWeb/Text/input/css/FontFaceSet-check.html
Normal file
30
Tests/LibWeb/Text/input/css/FontFaceSet-check.html
Normal file
@@ -0,0 +1,30 @@
|
||||
<!DOCTYPE html>
|
||||
<script src="../include.js"></script>
|
||||
<script>
|
||||
promiseTest(async () => {
|
||||
const fontFaceSet = document.fonts;
|
||||
|
||||
try {
|
||||
fontFaceSet.check("invalid");
|
||||
println("Check invalid font: FAIL");
|
||||
} catch (e) {
|
||||
println(`Check invalid font: ${e.name === "SyntaxError" ? "PASS" : "FAIL"}`);
|
||||
}
|
||||
|
||||
try {
|
||||
fontFaceSet.check("revert");
|
||||
println("Check CSS keyword as font: FAIL");
|
||||
} catch (e) {
|
||||
println(`Check CSS keyword as font: ${e.name === "SyntaxError" ? "PASS" : "FAIL"}`);
|
||||
}
|
||||
|
||||
println(`Check non-existent font: ${fontFaceSet.check("10px NonExistentFont") === true ? "PASS" : "FAIL"}`);
|
||||
|
||||
const fontFace = new FontFace("Hash Sans", "url(../../../Assets/HashSans.woff)");
|
||||
fontFaceSet.add(fontFace);
|
||||
println(`Check unloaded font: ${fontFaceSet.check("1em Hash Sans") === false ? "PASS" : "FAIL"}`);
|
||||
|
||||
await fontFace.load();
|
||||
println(`Check loaded font: ${fontFaceSet.check("1em Hash Sans") === true ? "PASS" : "FAIL"}`);
|
||||
});
|
||||
</script>
|
||||
Reference in New Issue
Block a user