From c438bb2fbe5dbc709d066d64580c46ff42fcb3af Mon Sep 17 00:00:00 2001 From: Muki Kiboigo Date: Thu, 22 May 2025 12:51:00 -0700 Subject: [PATCH] fix style of MouseEvent interface --- src/browser/events/mouse_event.zig | 59 ++++++++++++++++++++++++------ 1 file changed, 47 insertions(+), 12 deletions(-) diff --git a/src/browser/events/mouse_event.zig b/src/browser/events/mouse_event.zig index c86b99f0..c74eef82 100644 --- a/src/browser/events/mouse_event.zig +++ b/src/browser/events/mouse_event.zig @@ -16,14 +16,29 @@ // 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 log = std.log.scoped(.mouse_event); + const parser = @import("../netsurf.zig"); const Event = @import("event.zig").Event; const JsObject = @import("../env.zig").JsObject; +// TODO: We currently don't have a UIEvent interface so we skip it in the prototype chain. +// https://developer.mozilla.org/en-US/docs/Web/API/UIEvent +const UIEvent = Event; + // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent pub const MouseEvent = struct { pub const Self = parser.MouseEvent; - pub const prototype = *Event; + pub const prototype = *UIEvent; + + const MouseButton = enum(u16) { + main_button = 0, + auxillary_button = 1, + secondary_button = 2, + fourth_button = 3, + fifth_button = 4, + }; const MouseEventInit = struct { screenX: i32 = 0, @@ -34,13 +49,14 @@ pub const MouseEvent = struct { shiftKey: bool = false, altKey: bool = false, metaKey: bool = false, - button: u16 = 0, + button: MouseButton = .main_button, }; - pub fn constructor(event_type: []const u8, opts_: ?MouseEventInit) !*Self { + pub fn constructor(event_type: []const u8, opts_: ?MouseEventInit) !*parser.MouseEvent { const opts = opts_ orelse MouseEventInit{}; - const mouse_event = try parser.mouseEventCreate(); + var mouse_event = try parser.mouseEventCreate(); + try parser.eventSetInternalType(@ptrCast(&mouse_event), .mouse_event); try parser.mouseEventInit(mouse_event, event_type, .{ .x = opts.clientX, @@ -49,35 +65,43 @@ pub const MouseEvent = struct { .shift = opts.shiftKey, .alt = opts.altKey, .meta = opts.metaKey, - .button = opts.button, + .button = @intFromEnum(opts.button), }); + if (!std.mem.eql(u8, event_type, "click")) { + log.warn("MouseEvent currently only supports listeners for 'click' events!", .{}); + } + return mouse_event; } + pub fn get_button(self: *parser.MouseEvent) u16 { + return self.button; + } + // These is just an alias for clientX. - pub fn get_x(self: *Self) !i32 { + pub fn get_x(self: *parser.MouseEvent) i32 { return self.cx; } // These is just an alias for clientY. - pub fn get_y(self: *Self) !i32 { + pub fn get_y(self: *parser.MouseEvent) i32 { return self.cy; } - pub fn get_clientX(self: *Self) !i32 { + pub fn get_clientX(self: *parser.MouseEvent) i32 { return self.cx; } - pub fn get_clientY(self: *Self) !i32 { + pub fn get_clientY(self: *parser.MouseEvent) i32 { return self.cy; } - pub fn get_screenX(self: *Self) !i32 { + pub fn get_screenX(self: *parser.MouseEvent) i32 { return self.sx; } - pub fn get_screenY(self: *Self) !i32 { + pub fn get_screenY(self: *parser.MouseEvent) i32 { return self.sy; } }; @@ -88,6 +112,7 @@ test "Browser.MouseEvent" { defer runner.deinit(); try runner.testCases(&.{ + // Default MouseEvent .{ "let event = new MouseEvent('click')", "undefined" }, .{ "event.type", "click" }, .{ "event instanceof MouseEvent", "true" }, @@ -96,10 +121,20 @@ test "Browser.MouseEvent" { .{ "event.clientY", "0" }, .{ "event.screenX", "0" }, .{ "event.screenY", "0" }, - .{ "let new_event = new MouseEvent('click2', { 'clientX': 10, 'clientY': 20 })", "undefined" }, + // MouseEvent with parameters + .{ "let new_event = new MouseEvent('click', { 'button': 0, 'clientX': 10, 'clientY': 20 })", "undefined" }, + .{ "new_event.button", "0" }, .{ "new_event.x", "10" }, .{ "new_event.y", "20" }, .{ "new_event.screenX", "10" }, .{ "new_event.screenY", "20" }, + // MouseEvent Listener + .{ "let me = new MouseEvent('click')", "undefined" }, + .{ "me instanceof Event", "true" }, + .{ "var eevt = null; function ccbk(event) { eevt = event; }", "undefined" }, + .{ "document.addEventListener('click', ccbk)", "undefined" }, + .{ "document.dispatchEvent(me)", "true" }, + .{ "eevt.type", "click" }, + .{ "eevt instanceof MouseEvent", "true" }, }, .{}); }