actions: make scroll coordinates optional

Updates the scroll action to accept optional x and y coordinates. This
allows scrolling on a single axis without resetting the other to zero.
This commit is contained in:
Adrià Arrufat
2026-03-16 22:44:37 +09:00
parent f5bc7310b1
commit a74e46debf
3 changed files with 8 additions and 14 deletions

View File

@@ -63,21 +63,21 @@ pub fn fill(node: *DOMNode, text: []const u8, page: *Page) !void {
_ = page._event_manager.dispatch(el.asEventTarget(), change_evt) catch {}; _ = page._event_manager.dispatch(el.asEventTarget(), change_evt) catch {};
} }
pub fn scroll(node: ?*DOMNode, x: i32, y: i32, page: *Page) !void { pub fn scroll(node: ?*DOMNode, x: ?i32, y: ?i32, page: *Page) !void {
if (node) |n| { if (node) |n| {
const el = n.is(Element) orelse return error.InvalidNodeType; const el = n.is(Element) orelse return error.InvalidNodeType;
if (x != 0) { if (x) |val| {
el.setScrollLeft(x, page) catch {}; el.setScrollLeft(val, page) catch {};
} }
if (y != 0) { if (y) |val| {
el.setScrollTop(y, page) catch {}; el.setScrollTop(val, page) catch {};
} }
const scroll_evt = try Event.initTrusted(comptime lp.String.wrap("scroll"), .{ .bubbles = true }, page); const scroll_evt = try Event.initTrusted(comptime lp.String.wrap("scroll"), .{ .bubbles = true }, page);
_ = page._event_manager.dispatch(el.asEventTarget(), scroll_evt) catch {}; _ = page._event_manager.dispatch(el.asEventTarget(), scroll_evt) catch {};
} else { } else {
page.window.scrollTo(.{ .x = x }, y, page) catch |err| { page.window.scrollTo(.{ .x = x orelse 0 }, y, page) catch |err| {
lp.log.err(.app, "scroll failed", .{ .err = err }); lp.log.err(.app, "scroll failed", .{ .err = err });
return error.ActionFailed; return error.ActionFailed;
}; };

View File

@@ -207,9 +207,6 @@ fn scrollNode(cmd: anytype) !void {
const bc = cmd.browser_context orelse return error.NoBrowserContext; const bc = cmd.browser_context orelse return error.NoBrowserContext;
const page = bc.session.currentPage() orelse return error.PageNotLoaded; const page = bc.session.currentPage() orelse return error.PageNotLoaded;
const x = params.x orelse 0;
const y = params.y orelse 0;
const input_node_id = params.nodeId orelse params.backendNodeId; const input_node_id = params.nodeId orelse params.backendNodeId;
var target_node: ?*DOMNode = null; var target_node: ?*DOMNode = null;
@@ -218,7 +215,7 @@ fn scrollNode(cmd: anytype) !void {
target_node = node.dom; target_node = node.dom;
} }
lp.actions.scroll(target_node, x, y, page) catch |err| { lp.actions.scroll(target_node, params.x, params.y, page) catch |err| {
if (err == error.InvalidNodeType) return error.InvalidParam; if (err == error.InvalidNodeType) return error.InvalidParam;
return error.InternalError; return error.InternalError;
}; };

View File

@@ -494,9 +494,6 @@ fn handleScroll(server: *Server, arena: std.mem.Allocator, id: std.json.Value, a
return server.sendError(id, .PageNotLoaded, "Page not loaded"); return server.sendError(id, .PageNotLoaded, "Page not loaded");
}; };
const x = args.x orelse 0;
const y = args.y orelse 0;
var target_node: ?*DOMNode = null; var target_node: ?*DOMNode = null;
if (args.backendNodeId) |node_id| { if (args.backendNodeId) |node_id| {
const node = server.node_registry.lookup_by_id.get(node_id) orelse { const node = server.node_registry.lookup_by_id.get(node_id) orelse {
@@ -505,7 +502,7 @@ fn handleScroll(server: *Server, arena: std.mem.Allocator, id: std.json.Value, a
target_node = node.dom; target_node = node.dom;
} }
lp.actions.scroll(target_node, x, y, page) catch |err| { lp.actions.scroll(target_node, args.x, args.y, page) catch |err| {
if (err == error.InvalidNodeType) { if (err == error.InvalidNodeType) {
return server.sendError(id, .InvalidParams, "Node is not an element"); return server.sendError(id, .InvalidParams, "Node is not an element");
} }