From bf07659dd57ccd45b3a027da42caacf6f1a8a0b1 Mon Sep 17 00:00:00 2001 From: Pierre Tachoire Date: Wed, 11 Mar 2026 22:16:35 +0100 Subject: [PATCH] FontFaceSet is now an EventTarget Dispatch loading and loaddone events on load() call --- src/browser/tests/css/font_face_set.html | 22 ++++++++++++++++ src/browser/webapi/EventTarget.zig | 3 +++ src/browser/webapi/css/FontFaceSet.zig | 32 ++++++++++++++++++++---- 3 files changed, 52 insertions(+), 5 deletions(-) diff --git a/src/browser/tests/css/font_face_set.html b/src/browser/tests/css/font_face_set.html index a860669e..c0248a74 100644 --- a/src/browser/tests/css/font_face_set.html +++ b/src/browser/tests/css/font_face_set.html @@ -56,3 +56,25 @@ testing.expectEqual('FontFaceSet', document.fonts.constructor.name); } + + diff --git a/src/browser/webapi/EventTarget.zig b/src/browser/webapi/EventTarget.zig index 715c209a..cfdf0872 100644 --- a/src/browser/webapi/EventTarget.zig +++ b/src/browser/webapi/EventTarget.zig @@ -44,6 +44,7 @@ pub const Type = union(enum) { screen_orientation: *@import("Screen.zig").Orientation, visual_viewport: *@import("VisualViewport.zig"), file_reader: *@import("FileReader.zig"), + font_face_set: *@import("css/FontFaceSet.zig"), }; pub fn init(page: *Page) !*EventTarget { @@ -139,6 +140,7 @@ pub fn format(self: *EventTarget, writer: *std.Io.Writer) !void { .screen_orientation => writer.writeAll(""), .visual_viewport => writer.writeAll(""), .file_reader => writer.writeAll(""), + .font_face_set => writer.writeAll(""), }; } @@ -157,6 +159,7 @@ pub fn toString(self: *EventTarget) []const u8 { .screen_orientation => return "[object ScreenOrientation]", .visual_viewport => return "[object VisualViewport]", .file_reader => return "[object FileReader]", + .font_face_set => return "[object FontFaceSet]", }; } diff --git a/src/browser/webapi/css/FontFaceSet.zig b/src/browser/webapi/css/FontFaceSet.zig index 2a4a000d..36c89570 100644 --- a/src/browser/webapi/css/FontFaceSet.zig +++ b/src/browser/webapi/css/FontFaceSet.zig @@ -21,28 +21,34 @@ const js = @import("../../js/js.zig"); const Page = @import("../../Page.zig"); const Session = @import("../../Session.zig"); const FontFace = @import("FontFace.zig"); +const EventTarget = @import("../EventTarget.zig"); +const Event = @import("../Event.zig"); const Allocator = std.mem.Allocator; const FontFaceSet = @This(); +_proto: *EventTarget, _arena: Allocator, pub fn init(page: *Page) !*FontFaceSet { const arena = try page.getArena(.{ .debug = "FontFaceSet" }); errdefer page.releaseArena(arena); - const self = try arena.create(FontFaceSet); - self.* = .{ + return page._factory.eventTargetWithAllocator(arena, FontFaceSet{ + ._proto = undefined, ._arena = arena, - }; - return self; + }); } pub fn deinit(self: *FontFaceSet, _: bool, session: *Session) void { session.releaseArena(self._arena); } +pub fn asEventTarget(self: *FontFaceSet) *EventTarget { + return self._proto; +} + // FontFaceSet.ready - returns an already-resolved Promise. // In a headless browser there is no font loading, so fonts are always ready. 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. -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; + + // 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({}); }