From 903168b3a64f81bfe7e22e924d5ac88422736693 Mon Sep 17 00:00:00 2001 From: Karl Seguin Date: Wed, 14 May 2025 18:23:26 +0800 Subject: [PATCH 1/2] Support the capture field of the addEventListener option addEventListener can take a boolean (capture, already supported) or an object of options. This adds union support for the two, but only supports the `capture` field of the options object. The other fields are not supported by netsurf. --- src/browser/dom/event_target.zig | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/browser/dom/event_target.zig b/src/browser/dom/event_target.zig index d768937a..7a8d21b5 100644 --- a/src/browser/dom/event_target.zig +++ b/src/browser/dom/event_target.zig @@ -42,20 +42,38 @@ pub const EventTarget = struct { // JS funcs // -------- + const AddEventListenerOpts = union(enum) { + opts: Opts, + capture: bool, + + const Opts = struct { + capture: ?bool, + once: ?bool, // currently does nothing + passive: ?bool, // currently does nothing + signal: ?bool, // currently does nothing + }; + }; + pub fn _addEventListener( self: *parser.EventTarget, typ: []const u8, cbk: Env.Callback, - capture: ?bool, + opts_: ?AddEventListenerOpts, state: *SessionState, - // TODO: hanle EventListenerOptions - // see #https://github.com/lightpanda-io/jsruntime-lib/issues/114 ) !void { + var capture = false; + if (opts_) |opts| { + switch (opts) { + .capture => |c| capture = c, + .opts => |o| capture = o.capture orelse false, + } + } + // check if event target has already this listener const lst = try parser.eventTargetHasListener( self, typ, - capture orelse false, + capture, cbk.id, ); if (lst != null) { @@ -68,7 +86,7 @@ pub const EventTarget = struct { self, typ, &eh.node, - capture orelse false, + capture, ); } @@ -172,7 +190,7 @@ test "Browser.DOM.EventTarget" { try runner.testCases(&.{ .{ "nb = 0", "0" }, - .{ "content.removeEventListener('basic', cbk, true)", "undefined" }, + .{ "content.removeEventListener('basic', cbk, {capture: true})", "undefined" }, .{ "content.dispatchEvent(new Event('basic'))", "true" }, .{ "nb", "0" }, }, .{}); From 206e34ac803bebbe1957c65a4d571194db8d3dfa Mon Sep 17 00:00:00 2001 From: Karl Seguin Date: Thu, 15 May 2025 13:09:16 +0800 Subject: [PATCH 2/2] Explicit error if an AddEventListenerOption flag is set that we dont' support --- src/browser/dom/event_target.zig | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/browser/dom/event_target.zig b/src/browser/dom/event_target.zig index 7a8d21b5..33f61395 100644 --- a/src/browser/dom/event_target.zig +++ b/src/browser/dom/event_target.zig @@ -65,7 +65,18 @@ pub const EventTarget = struct { if (opts_) |opts| { switch (opts) { .capture => |c| capture = c, - .opts => |o| capture = o.capture orelse false, + .opts => |o| { + // Done this way so that, for common cases that _only_ set + // capture, i.e. {captrue: true}, it works. + // But for any case that sets any of the other flags, we + // error. If we don't error, this function call would succeed + // but the behavior might be wrong. At this point, it's + // better to be explicit and error. + if (o.once orelse false) return error.NotImplemented; + if (o.signal orelse false) return error.NotImplemented; + if (o.passive orelse false) return error.NotImplemented; + capture = o.capture orelse false; + }, } }