browser.actions: refactor click to use trusted MouseEvent

This commit is contained in:
Adrià Arrufat
2026-03-17 13:22:55 +09:00
parent 44a83c0e1c
commit 463aac9b59
3 changed files with 30 additions and 13 deletions

View File

@@ -62,6 +62,7 @@ const storage = @import("webapi/storage/storage.zig");
const PageTransitionEvent = @import("webapi/event/PageTransitionEvent.zig"); const PageTransitionEvent = @import("webapi/event/PageTransitionEvent.zig");
const NavigationKind = @import("webapi/navigation/root.zig").NavigationKind; const NavigationKind = @import("webapi/navigation/root.zig").NavigationKind;
const KeyboardEvent = @import("webapi/event/KeyboardEvent.zig"); const KeyboardEvent = @import("webapi/event/KeyboardEvent.zig");
const MouseEvent = @import("webapi/event/MouseEvent.zig");
const HttpClient = @import("HttpClient.zig"); const HttpClient = @import("HttpClient.zig");
const ArenaPool = App.ArenaPool; const ArenaPool = App.ArenaPool;
@@ -3255,14 +3256,14 @@ pub fn triggerMouseClick(self: *Page, x: f64, y: f64) !void {
.type = self._type, .type = self._type,
}); });
} }
const event = (try @import("webapi/event/MouseEvent.zig").init("click", .{ const mouse_event: *MouseEvent = try .initTrusted(comptime .wrap("click"), .{
.bubbles = true, .bubbles = true,
.cancelable = true, .cancelable = true,
.composed = true, .composed = true,
.clientX = x, .clientX = x,
.clientY = y, .clientY = y,
}, self)).asEvent(); }, self);
try self._event_manager.dispatch(target.asEventTarget(), event); try self._event_manager.dispatch(target.asEventTarget(), mouse_event.asEvent());
} }
// callback when the "click" event reaches the pages. // callback when the "click" event reaches the pages.

View File

@@ -21,17 +21,24 @@ const lp = @import("../lightpanda.zig");
const DOMNode = @import("webapi/Node.zig"); const DOMNode = @import("webapi/Node.zig");
const Element = @import("webapi/Element.zig"); const Element = @import("webapi/Element.zig");
const Event = @import("webapi/Event.zig"); const Event = @import("webapi/Event.zig");
const MouseEvent = @import("webapi/event/MouseEvent.zig");
const Page = @import("Page.zig"); const Page = @import("Page.zig");
pub fn click(node: *DOMNode, page: *Page) !void { pub fn click(node: *DOMNode, page: *Page) !void {
if (node.is(Element.Html)) |html_el| { const el = node.is(Element) orelse return error.InvalidNodeType;
html_el.click(page) catch |err| {
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 }); lp.log.err(.app, "click failed", .{ .err = err });
return error.ActionFailed; return error.ActionFailed;
}; };
} else {
return error.InvalidNodeType;
}
} }
pub fn fill(node: *DOMNode, text: []const u8, page: *Page) !void { pub fn fill(node: *DOMNode, text: []const u8, page: *Page) !void {

View File

@@ -83,12 +83,21 @@ pub fn init(typ: []const u8, _opts: ?Options, page: *Page) !*MouseEvent {
const arena = try page.getArena(.{ .debug = "MouseEvent" }); const arena = try page.getArena(.{ .debug = "MouseEvent" });
errdefer page.releaseArena(arena); errdefer page.releaseArena(arena);
const type_string = try String.init(arena, typ, .{}); 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 opts = _opts orelse Options{};
const event = try page._factory.uiEvent( const event = try page._factory.uiEvent(
arena, arena,
type_string, typ,
MouseEvent{ MouseEvent{
._type = .generic, ._type = .generic,
._proto = undefined, ._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; return event;
} }