From 2a2a9d7941d6920ac2546cfa09070359b2e373b2 Mon Sep 17 00:00:00 2001 From: sjorsdonkers <72333389+sjorsdonkers@users.noreply.github.com> Date: Thu, 10 Jul 2025 14:21:02 +0200 Subject: [PATCH] EventTarget InternalType --- src/browser/dom/event_target.zig | 7 ++++++- src/browser/netsurf.zig | 19 +++++++++++++++++++ vendor/netsurf/libdom | 2 +- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/browser/dom/event_target.zig b/src/browser/dom/event_target.zig index e3ddaa0f..21d93eda 100644 --- a/src/browser/dom/event_target.zig +++ b/src/browser/dom/event_target.zig @@ -28,6 +28,7 @@ const nod = @import("node.zig"); pub const Union = union(enum) { node: nod.Union, xhr: *@import("../xhr/xhr.zig").XMLHttpRequest, + plain: *parser.EventTarget, }; // EventTarget implementation @@ -36,7 +37,7 @@ pub const EventTarget = struct { pub const Exception = DOMException; // Extend libdom event target for pure zig struct. - base: parser.EventTargetTBase = parser.EventTargetTBase{}, + base: parser.EventTargetTBase = parser.EventTargetTBase{ .internal_target_type = .plain }, pub fn toInterface(e: *parser.Event, et: *parser.EventTarget, page: *Page) !Union { // libdom assumes that all event targets are libdom nodes. They are not. @@ -47,6 +48,10 @@ pub const EventTarget = struct { 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)) { diff --git a/src/browser/netsurf.zig b/src/browser/netsurf.zig index 0b11a1dd..e24ebc6a 100644 --- a/src/browser/netsurf.zig +++ b/src/browser/netsurf.zig @@ -749,6 +749,13 @@ pub fn eventTargetDispatchEvent(et: *EventTarget, event: *Event) !bool { return res; } +pub fn eventTargetInternalType(et: *EventTarget) !EventTargetTBase.InternalType { + var res: u32 = undefined; + const err = eventTargetVtable(et).internal_type.?(et, &res); + try DOMErr(err); + return @enumFromInt(res); +} + pub fn elementDispatchEvent(element: *Element, event: *Event) !bool { const et: *EventTarget = toEventTarget(Element, element); return eventTargetDispatchEvent(et, @ptrCast(event)); @@ -771,12 +778,17 @@ pub fn eventTargetTBaseFieldName(comptime T: type) ?[]const u8 { // EventTargetBase is used to implement EventTarget for pure zig struct. pub const EventTargetTBase = extern struct { const Self = @This(); + const InternalType = enum(u32) { + libdom = 0, + plain = 1, + }; vtable: ?*const c.struct_dom_event_target_vtable = &c.struct_dom_event_target_vtable{ .dispatch_event = dispatch_event, .remove_event_listener = remove_event_listener, .add_event_listener = add_event_listener, .iter_event_listener = iter_event_listener, + .internal_type = internal_type, }, // When we dispatch the event, we need to provide a target. In reality, the @@ -790,6 +802,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, 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)); @@ -822,6 +835,12 @@ pub const EventTargetTBase = extern struct { const self = @as(*Self, @ptrCast(et)); return c._dom_event_target_iter_event_listener(self.eti, t, capture, cur, next, l); } + + pub fn internal_type(et: [*c]c.dom_event_target, internal_type_: [*c]u32) callconv(.C) c.dom_exception { + const self = @as(*Self, @ptrCast(et)); + internal_type_.* = @intFromEnum(self.internal_target_type); + return c.DOM_NO_ERR; + } }; // MouseEvent diff --git a/vendor/netsurf/libdom b/vendor/netsurf/libdom index 614187b0..84723c5b 160000 --- a/vendor/netsurf/libdom +++ b/vendor/netsurf/libdom @@ -1 +1 @@ -Subproject commit 614187b0aa6305ff992b4e0cb24af2e3ca0c4bfc +Subproject commit 84723c5be588db1d8a7777eba528d1976f394012