FontFaceSet is now an EventTarget

Dispatch loading and loaddone events on load() call
This commit is contained in:
Pierre Tachoire
2026-03-11 22:16:35 +01:00
parent 7d835ef99d
commit bf07659dd5
3 changed files with 52 additions and 5 deletions

View File

@@ -56,3 +56,25 @@
testing.expectEqual('FontFaceSet', document.fonts.constructor.name); testing.expectEqual('FontFaceSet', document.fonts.constructor.name);
} }
</script> </script>
<script id="document_fonts_addEventListener">
{
let loading = false;
document.fonts.addEventListener('loading', function() {
loading = true;
});
let loadingdone = false;
document.fonts.addEventListener('loadingdone', function() {
loadingdone = true;
});
document.fonts.load("italic bold 16px Roboto");
testing.eventually(() => {
testing.expectEqual(true, loading);
testing.expectEqual(true, loadingdone);
});
testing.expectEqual(true, true);
}
</script>

View File

@@ -44,6 +44,7 @@ pub const Type = union(enum) {
screen_orientation: *@import("Screen.zig").Orientation, screen_orientation: *@import("Screen.zig").Orientation,
visual_viewport: *@import("VisualViewport.zig"), visual_viewport: *@import("VisualViewport.zig"),
file_reader: *@import("FileReader.zig"), file_reader: *@import("FileReader.zig"),
font_face_set: *@import("css/FontFaceSet.zig"),
}; };
pub fn init(page: *Page) !*EventTarget { pub fn init(page: *Page) !*EventTarget {
@@ -139,6 +140,7 @@ pub fn format(self: *EventTarget, writer: *std.Io.Writer) !void {
.screen_orientation => writer.writeAll("<ScreenOrientation>"), .screen_orientation => writer.writeAll("<ScreenOrientation>"),
.visual_viewport => writer.writeAll("<VisualViewport>"), .visual_viewport => writer.writeAll("<VisualViewport>"),
.file_reader => writer.writeAll("<FileReader>"), .file_reader => writer.writeAll("<FileReader>"),
.font_face_set => writer.writeAll("<FontFaceSet>"),
}; };
} }
@@ -157,6 +159,7 @@ pub fn toString(self: *EventTarget) []const u8 {
.screen_orientation => return "[object ScreenOrientation]", .screen_orientation => return "[object ScreenOrientation]",
.visual_viewport => return "[object VisualViewport]", .visual_viewport => return "[object VisualViewport]",
.file_reader => return "[object FileReader]", .file_reader => return "[object FileReader]",
.font_face_set => return "[object FontFaceSet]",
}; };
} }

View File

@@ -21,28 +21,34 @@ const js = @import("../../js/js.zig");
const Page = @import("../../Page.zig"); const Page = @import("../../Page.zig");
const Session = @import("../../Session.zig"); const Session = @import("../../Session.zig");
const FontFace = @import("FontFace.zig"); const FontFace = @import("FontFace.zig");
const EventTarget = @import("../EventTarget.zig");
const Event = @import("../Event.zig");
const Allocator = std.mem.Allocator; const Allocator = std.mem.Allocator;
const FontFaceSet = @This(); const FontFaceSet = @This();
_proto: *EventTarget,
_arena: Allocator, _arena: Allocator,
pub fn init(page: *Page) !*FontFaceSet { pub fn init(page: *Page) !*FontFaceSet {
const arena = try page.getArena(.{ .debug = "FontFaceSet" }); const arena = try page.getArena(.{ .debug = "FontFaceSet" });
errdefer page.releaseArena(arena); errdefer page.releaseArena(arena);
const self = try arena.create(FontFaceSet); return page._factory.eventTargetWithAllocator(arena, FontFaceSet{
self.* = .{ ._proto = undefined,
._arena = arena, ._arena = arena,
}; });
return self;
} }
pub fn deinit(self: *FontFaceSet, _: bool, session: *Session) void { pub fn deinit(self: *FontFaceSet, _: bool, session: *Session) void {
session.releaseArena(self._arena); session.releaseArena(self._arena);
} }
pub fn asEventTarget(self: *FontFaceSet) *EventTarget {
return self._proto;
}
// FontFaceSet.ready - returns an already-resolved Promise. // FontFaceSet.ready - returns an already-resolved Promise.
// In a headless browser there is no font loading, so fonts are always ready. // In a headless browser there is no font loading, so fonts are always ready.
pub fn getReady(_: *FontFaceSet, page: *Page) !js.Promise { pub fn getReady(_: *FontFaceSet, page: *Page) !js.Promise {
@@ -56,8 +62,24 @@ pub fn check(_: *const FontFaceSet, font: []const u8) bool {
} }
// load(font, text?) - resolves immediately with an empty array. // load(font, text?) - resolves immediately with an empty array.
pub fn load(_: *FontFaceSet, font: []const u8, page: *Page) !js.Promise { pub fn load(self: *FontFaceSet, font: []const u8, page: *Page) !js.Promise {
// TODO parse font to check if the font has been added before dispatching
// events.
_ = font; _ = font;
// Dispatch loading event
const target = self.asEventTarget();
if (page._event_manager.hasDirectListeners(target, "loading", null)) {
const event = try Event.initTrusted(comptime .wrap("loading"), .{}, page);
try page._event_manager.dispatchDirect(target, event, null, .{ .context = "load font face set" });
}
// Dispatch loadingdone event
if (page._event_manager.hasDirectListeners(target, "loadingdone", null)) {
const event = try Event.initTrusted(comptime .wrap("loadingdone"), .{}, page);
try page._event_manager.dispatchDirect(target, event, null, .{ .context = "load font face set" });
}
return page.js.local.?.resolvePromise({}); return page.js.local.?.resolvePromise({});
} }