diff --git a/src/browser/Page.zig b/src/browser/Page.zig index cb62cb31..0fa5bba3 100644 --- a/src/browser/Page.zig +++ b/src/browser/Page.zig @@ -62,6 +62,7 @@ const storage = @import("webapi/storage/storage.zig"); const PageTransitionEvent = @import("webapi/event/PageTransitionEvent.zig"); const NavigationKind = @import("webapi/navigation/root.zig").NavigationKind; const KeyboardEvent = @import("webapi/event/KeyboardEvent.zig"); +const MouseEvent = @import("webapi/event/MouseEvent.zig"); const HttpClient = @import("HttpClient.zig"); const ArenaPool = App.ArenaPool; @@ -3255,14 +3256,14 @@ pub fn triggerMouseClick(self: *Page, x: f64, y: f64) !void { .type = self._type, }); } - const event = (try @import("webapi/event/MouseEvent.zig").init("click", .{ + const mouse_event: *MouseEvent = try .initTrusted(comptime .wrap("click"), .{ .bubbles = true, .cancelable = true, .composed = true, .clientX = x, .clientY = y, - }, self)).asEvent(); - try self._event_manager.dispatch(target.asEventTarget(), event); + }, self); + try self._event_manager.dispatch(target.asEventTarget(), mouse_event.asEvent()); } // callback when the "click" event reaches the pages. diff --git a/src/browser/actions.zig b/src/browser/actions.zig index 9b4025e8..951f2b1e 100644 --- a/src/browser/actions.zig +++ b/src/browser/actions.zig @@ -21,17 +21,24 @@ const lp = @import("../lightpanda.zig"); const DOMNode = @import("webapi/Node.zig"); const Element = @import("webapi/Element.zig"); const Event = @import("webapi/Event.zig"); +const MouseEvent = @import("webapi/event/MouseEvent.zig"); const Page = @import("Page.zig"); pub fn click(node: *DOMNode, page: *Page) !void { - if (node.is(Element.Html)) |html_el| { - html_el.click(page) catch |err| { - lp.log.err(.app, "click failed", .{ .err = err }); - return error.ActionFailed; - }; - } else { - return error.InvalidNodeType; - } + const el = node.is(Element) orelse return error.InvalidNodeType; + + const mouse_event: *MouseEvent = try .initTrusted(comptime .wrap("click"), .{ + .bubbles = true, + .cancelable = true, + .composed = true, + .clientX = 0, + .clientY = 0, + }, page); + + page._event_manager.dispatch(el.asEventTarget(), mouse_event.asEvent()) catch |err| { + lp.log.err(.app, "click failed", .{ .err = err }); + return error.ActionFailed; + }; } pub fn fill(node: *DOMNode, text: []const u8, page: *Page) !void { diff --git a/src/browser/webapi/event/MouseEvent.zig b/src/browser/webapi/event/MouseEvent.zig index 6b032433..cae21509 100644 --- a/src/browser/webapi/event/MouseEvent.zig +++ b/src/browser/webapi/event/MouseEvent.zig @@ -83,12 +83,21 @@ pub fn init(typ: []const u8, _opts: ?Options, page: *Page) !*MouseEvent { const arena = try page.getArena(.{ .debug = "MouseEvent" }); errdefer page.releaseArena(arena); const type_string = try String.init(arena, typ, .{}); + return initWithTrusted(arena, type_string, _opts, false, page); +} +pub fn initTrusted(typ: String, _opts: ?Options, page: *Page) !*MouseEvent { + const arena = try page.getArena(.{ .debug = "MouseEvent.trusted" }); + errdefer page.releaseArena(arena); + return initWithTrusted(arena, typ, _opts, true, page); +} + +fn initWithTrusted(arena: std.mem.Allocator, typ: String, _opts: ?Options, trusted: bool, page: *Page) !*MouseEvent { const opts = _opts orelse Options{}; const event = try page._factory.uiEvent( arena, - type_string, + typ, MouseEvent{ ._type = .generic, ._proto = undefined, @@ -106,7 +115,7 @@ pub fn init(typ: []const u8, _opts: ?Options, page: *Page) !*MouseEvent { }, ); - Event.populatePrototypes(event, opts, false); + Event.populatePrototypes(event, opts, trusted); return event; }