From 5123697afe35072ff3c041cd4fb8fa312b72bce3 Mon Sep 17 00:00:00 2001 From: sjorsdonkers <72333389+sjorsdonkers@users.noreply.github.com> Date: Fri, 11 Jul 2025 09:49:29 +0200 Subject: [PATCH] EventTarget internal type for all --- src/browser/dom/event_target.zig | 34 +++++++++++++-------------- src/browser/dom/performance.zig | 2 +- src/browser/events/event.zig | 4 ++-- src/browser/html/AbortController.zig | 3 +-- src/browser/html/media_query_list.zig | 2 +- src/browser/html/window.zig | 2 +- src/browser/netsurf.zig | 9 +++++-- src/browser/xhr/event_target.zig | 2 +- 8 files changed, 30 insertions(+), 28 deletions(-) diff --git a/src/browser/dom/event_target.zig b/src/browser/dom/event_target.zig index 21d93eda..bf59910a 100644 --- a/src/browser/dom/event_target.zig +++ b/src/browser/dom/event_target.zig @@ -16,6 +16,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . +const std = @import("std"); const Env = @import("../env.zig").Env; const parser = @import("../netsurf.zig"); const Page = @import("../page.zig").Page; @@ -39,33 +40,30 @@ pub const EventTarget = struct { // Extend libdom event target for pure zig struct. base: parser.EventTargetTBase = parser.EventTargetTBase{ .internal_target_type = .plain }, - pub fn toInterface(e: *parser.Event, et: *parser.EventTarget, page: *Page) !Union { + pub fn toInterface(et: *parser.EventTarget, page: *Page) !Union { // libdom assumes that all event targets are libdom nodes. They are not. - // The window is a common non-node target, but it's easy to handle as - // its a singleton. - if (@intFromPtr(et) == @intFromPtr(&page.window.base)) { - return .{ .node = .{ .Window = &page.window } }; - } - - if (try parser.eventTargetInternalType(et) == .plain) { - return .{ .plain = et }; - } - - // AbortSignal is another non-node target. It has a distinct usage though - // so we hijack the event internal type to identity if. - switch (try parser.eventGetInternalType(e)) { + switch (try parser.eventTargetInternalType(et)) { + .libdom_node => { + return .{ .node = try nod.Node.toInterface(@as(*parser.Node, @ptrCast(et))) }; + }, + .plain => return .{ .plain = et }, .abort_signal => { + // AbortSignal is a special case, it has its own internal type. + // We return it as a node, but we need to handle it differently. return .{ .node = .{ .AbortSignal = @fieldParentPtr("proto", @as(*parser.EventTargetTBase, @ptrCast(et))) } }; }, - .xhr_event => { + .window => { + // The window is a common non-node target, but it's easy to handle as its a singleton. + std.debug.assert(@intFromPtr(et) == @intFromPtr(&page.window.base)); + return .{ .node = .{ .Window = &page.window } }; + }, + .xhr => { const XMLHttpRequestEventTarget = @import("../xhr/event_target.zig").XMLHttpRequestEventTarget; const base: *XMLHttpRequestEventTarget = @fieldParentPtr("base", @as(*parser.EventTargetTBase, @ptrCast(et))); return .{ .xhr = @fieldParentPtr("proto", base) }; }, - else => { - return .{ .node = try nod.Node.toInterface(@as(*parser.Node, @ptrCast(et))) }; - }, + else => return error.MissingEventTargetType, } } diff --git a/src/browser/dom/performance.zig b/src/browser/dom/performance.zig index e45cff1b..aac2599a 100644 --- a/src/browser/dom/performance.zig +++ b/src/browser/dom/performance.zig @@ -39,7 +39,7 @@ pub const Performance = struct { pub const prototype = *EventTarget; // Extend libdom event target for pure zig struct. - base: parser.EventTargetTBase = parser.EventTargetTBase{}, + base: parser.EventTargetTBase = parser.EventTargetTBase{ .internal_target_type = .performance }, time_origin: std.time.Timer, // if (Window.crossOriginIsolated) -> Resolution in isolated contexts: 5 microseconds diff --git a/src/browser/events/event.zig b/src/browser/events/event.zig index f8e4d8c9..b9a5c297 100644 --- a/src/browser/events/event.zig +++ b/src/browser/events/event.zig @@ -78,13 +78,13 @@ pub const Event = struct { pub fn get_target(self: *parser.Event, page: *Page) !?EventTargetUnion { const et = try parser.eventTarget(self); if (et == null) return null; - return try EventTarget.toInterface(self, et.?, page); + return try EventTarget.toInterface(et.?, page); } pub fn get_currentTarget(self: *parser.Event, page: *Page) !?EventTargetUnion { const et = try parser.eventCurrentTarget(self); if (et == null) return null; - return try EventTarget.toInterface(self, et.?, page); + return try EventTarget.toInterface(et.?, page); } pub fn get_eventPhase(self: *parser.Event) !u8 { diff --git a/src/browser/html/AbortController.zig b/src/browser/html/AbortController.zig index bf7214a4..37f6eb5b 100644 --- a/src/browser/html/AbortController.zig +++ b/src/browser/html/AbortController.zig @@ -56,13 +56,12 @@ pub const AbortSignal = struct { const DEFAULT_REASON = "AbortError"; pub const prototype = *EventTarget; - proto: parser.EventTargetTBase = .{}, + proto: parser.EventTargetTBase = .{ .internal_target_type = .abort_signal }, aborted: bool, reason: ?[]const u8, pub const init: AbortSignal = .{ - .proto = .{}, .reason = null, .aborted = false, }; diff --git a/src/browser/html/media_query_list.zig b/src/browser/html/media_query_list.zig index 32ffc1d6..28216db3 100644 --- a/src/browser/html/media_query_list.zig +++ b/src/browser/html/media_query_list.zig @@ -26,7 +26,7 @@ pub const MediaQueryList = struct { // Extend libdom event target for pure zig struct. // This is not safe as it relies on a structure layout that isn't guaranteed - base: parser.EventTargetTBase = parser.EventTargetTBase{}, + base: parser.EventTargetTBase = parser.EventTargetTBase{ .internal_target_type = .media_query_list }, matches: bool, media: []const u8, diff --git a/src/browser/html/window.zig b/src/browser/html/window.zig index 78f57fd1..c1be58c6 100644 --- a/src/browser/html/window.zig +++ b/src/browser/html/window.zig @@ -45,7 +45,7 @@ pub const Window = struct { pub const prototype = *EventTarget; // Extend libdom event target for pure zig struct. - base: parser.EventTargetTBase = parser.EventTargetTBase{}, + base: parser.EventTargetTBase = parser.EventTargetTBase{ .internal_target_type = .window }, document: *parser.DocumentHTML, target: []const u8 = "", diff --git a/src/browser/netsurf.zig b/src/browser/netsurf.zig index e24ebc6a..f0af5280 100644 --- a/src/browser/netsurf.zig +++ b/src/browser/netsurf.zig @@ -779,8 +779,13 @@ pub fn eventTargetTBaseFieldName(comptime T: type) ?[]const u8 { pub const EventTargetTBase = extern struct { const Self = @This(); const InternalType = enum(u32) { - libdom = 0, + libdom_node = 0, plain = 1, + abort_signal = 2, + xhr = 3, + window = 4, + performance = 5, + media_query_list = 6, }; vtable: ?*const c.struct_dom_event_target_vtable = &c.struct_dom_event_target_vtable{ @@ -802,7 +807,7 @@ pub const EventTargetTBase = extern struct { refcnt: u32 = 0, eti: c.dom_event_target_internal = c.dom_event_target_internal{ .listeners = null }, - internal_target_type: InternalType = .libdom, + internal_target_type: InternalType, pub fn add_event_listener(et: [*c]c.dom_event_target, t: [*c]c.dom_string, l: ?*c.struct_dom_event_listener, capture: bool) callconv(.C) c.dom_exception { const self = @as(*Self, @ptrCast(et)); diff --git a/src/browser/xhr/event_target.zig b/src/browser/xhr/event_target.zig index f664a3a6..c74a1bf3 100644 --- a/src/browser/xhr/event_target.zig +++ b/src/browser/xhr/event_target.zig @@ -31,7 +31,7 @@ pub const XMLHttpRequestEventTarget = struct { pub const prototype = *EventTarget; // Extend libdom event target for pure zig struct. - base: parser.EventTargetTBase = parser.EventTargetTBase{}, + base: parser.EventTargetTBase = parser.EventTargetTBase{ .internal_target_type = .xhr }, onloadstart_cbk: ?Function = null, onprogress_cbk: ?Function = null,