From de71b97b1ff3450aa8cc8fc118349c6b48652d95 Mon Sep 17 00:00:00 2001 From: Karl Seguin Date: Sun, 2 Nov 2025 00:17:45 +0800 Subject: [PATCH] optional listener, or object listener --- src/browser/tests/events.html | 62 ++++++++++++++++++++++++++++++ src/browser/webapi/EventTarget.zig | 31 ++++++++++++--- 2 files changed, 87 insertions(+), 6 deletions(-) diff --git a/src/browser/tests/events.html b/src/browser/tests/events.html index e85a474f..a0459f40 100644 --- a/src/browser/tests/events.html +++ b/src/browser/tests/events.html @@ -285,3 +285,65 @@ testing.expectEqual('window-capture', non_bubble_calls[0]); testing.expectEqual('child', non_bubble_calls[1]); + + + + + + + + diff --git a/src/browser/webapi/EventTarget.zig b/src/browser/webapi/EventTarget.zig index 6d31515e..a313bc73 100644 --- a/src/browser/webapi/EventTarget.zig +++ b/src/browser/webapi/EventTarget.zig @@ -23,11 +23,23 @@ pub fn dispatchEvent(self: *EventTarget, event: *Event, page: *Page) !bool { return !event._cancelable or !event._prevent_default; } -const addEventListenerOptions = union(enum) { +const AddEventListenerOptions = union(enum) { capture: bool, options: RegisterOptions, }; -pub fn addEventListener(self: *EventTarget, typ: []const u8, callback: js.Function, opts_: ?addEventListenerOptions, page: *Page) !void { + +pub const EventListenerCallback = union(enum) { + function: js.Function, + object: js.Object, +}; +pub fn addEventListener(self: *EventTarget, typ: []const u8, callback_: ?EventListenerCallback, opts_: ?AddEventListenerOptions, page: *Page) !void { + const callback = callback_ orelse return; + + const actual_callback = switch (callback) { + .function => |func| func, + .object => |obj| (try obj.getFunction("handleEvent")) orelse return, + }; + const options = blk: { const o = opts_ orelse break :blk RegisterOptions{}; break :blk switch (o) { @@ -35,10 +47,10 @@ pub fn addEventListener(self: *EventTarget, typ: []const u8, callback: js.Functi .capture => |capture| RegisterOptions{ .capture = capture }, }; }; - return page._event_manager.register(self, typ, callback, options); + return page._event_manager.register(self, typ, actual_callback, options); } -const removeEventListenerOptions = union(enum) { +const RemoveEventListenerOptions = union(enum) { capture: bool, options: Options, @@ -46,7 +58,14 @@ const removeEventListenerOptions = union(enum) { useCapture: bool = false, }; }; -pub fn removeEventListener(self: *EventTarget, typ: []const u8, callback: js.Function, opts_: ?removeEventListenerOptions, page: *Page) !void { +pub fn removeEventListener(self: *EventTarget, typ: []const u8, callback_: ?EventListenerCallback, opts_: ?RemoveEventListenerOptions, page: *Page) !void { + const callback = callback_ orelse return; + + const actual_callback = switch (callback) { + .function => |func| func, + .object => |obj| (try obj.getFunction("handleEvent")) orelse return, + }; + const use_capture = blk: { const o = opts_ orelse break :blk false; break :blk switch (o) { @@ -54,7 +73,7 @@ pub fn removeEventListener(self: *EventTarget, typ: []const u8, callback: js.Fun .options => |opts| opts.useCapture, }; }; - return page._event_manager.remove(self, typ, callback, use_capture); + return page._event_manager.remove(self, typ, actual_callback, use_capture); } pub fn format(self: *EventTarget, writer: *std.Io.Writer) !void {