add window.scrollBy

This commit is contained in:
Pierre Tachoire
2026-02-27 16:19:27 +01:00
parent 3bf596c54c
commit 631ec70058
2 changed files with 59 additions and 0 deletions

View File

@@ -0,0 +1,36 @@
<!DOCTYPE html>
<script src="testing.js"></script>
<script id=scrollBy_exists>
testing.expectEqual('function', typeof window.scrollBy);
</script>
<script id=scrollBy_xy>
window.scrollTo(0, 0);
testing.expectEqual(0, window.scrollX);
testing.expectEqual(0, window.scrollY);
window.scrollBy(100, 200);
testing.expectEqual(100, window.scrollX);
testing.expectEqual(200, window.scrollY);
</script>
<script id=scrollBy_relative>
window.scrollTo(100, 100);
window.scrollBy(50, 50);
testing.expectEqual(150, window.scrollX);
testing.expectEqual(150, window.scrollY);
</script>
<script id=scrollBy_opts>
window.scrollTo(0, 0);
window.scrollBy({ left: 30, top: 40 });
testing.expectEqual(30, window.scrollX);
testing.expectEqual(40, window.scrollY);
</script>
<script id=scrollBy_negative_clamp>
window.scrollTo(10, 10);
window.scrollBy(-100, -100);
testing.expectEqual(0, window.scrollX);
testing.expectEqual(0, window.scrollY);
</script>

View File

@@ -515,6 +515,24 @@ pub fn scrollTo(self: *Window, opts: ScrollToOpts, y: ?i32, page: *Page) !void {
);
}
pub fn scrollBy(self: *Window, opts: ScrollToOpts, y: ?i32, page: *Page) !void {
// The scroll is relative to the current position. So compute to new
// absolute position.
var absx: i32 = undefined;
var absy: i32 = undefined;
switch (opts) {
.x => |x| {
absx = @as(i32, @intCast(self._scroll_pos.x)) + x;
absy = @as(i32, @intCast(self._scroll_pos.y)) + (y orelse 0);
},
.opts => |o| {
absx = @as(i32, @intCast(self._scroll_pos.x)) + o.left;
absy = @as(i32, @intCast(self._scroll_pos.y)) + o.top;
},
}
return self.scrollTo(.{ .x = absx }, absy, page);
}
pub fn unhandledPromiseRejection(self: *Window, rejection: js.PromiseRejection, page: *Page) !void {
if (comptime IS_DEBUG) {
log.debug(.js, "unhandled rejection", .{
@@ -784,6 +802,7 @@ pub const JsApi = struct {
pub const pageYOffset = bridge.accessor(Window.getScrollY, null, .{});
pub const scrollTo = bridge.function(Window.scrollTo, .{});
pub const scroll = bridge.function(Window.scrollTo, .{});
pub const scrollBy = bridge.function(Window.scrollBy, .{});
// Return false since we don't have secure-context-only APIs implemented
// (webcam, geolocation, clipboard, etc.)
@@ -818,3 +837,7 @@ const testing = @import("../../testing.zig");
test "WebApi: Window" {
try testing.htmlRunner("window", .{});
}
test "WebApi: Window scroll" {
try testing.htmlRunner("window_scroll.html", .{});
}