From f5d9f3e7378a461bca2c0aafbf478e2ce06d4eb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A0=20Arrufat?= Date: Wed, 23 Sep 2026 13:16:21 +0200 Subject: [PATCH 1/7] Give the document a height and clamp the viewport scroll to it html and body reported a fixed 100M px height and window.scrollTo never clamped. The document height is now the tallest of the synthetic node positions, body's stacked children and the viewport, and the window can't scroll past its bottom. --- src/browser/Frame.zig | 4 ++ src/browser/tests/element/position.html | 15 ++++--- src/browser/tests/mcp_actions.html | 2 + src/browser/tests/window_scroll.html | 25 +++++++++++ src/browser/webapi/Element.zig | 60 ++++++++++++++++++------- src/browser/webapi/Window.zig | 7 ++- 6 files changed, 92 insertions(+), 21 deletions(-) diff --git a/src/browser/Frame.zig b/src/browser/Frame.zig index 7298a2150..8c1d7bcad 100644 --- a/src/browser/Frame.zig +++ b/src/browser/Frame.zig @@ -154,6 +154,10 @@ _queued_events: *std.ArrayList(QueuedEvent) = undefined, _focus_fixup_pending: bool = false, _style_manager: StyleManager, + +// Element.documentHeight, valid while the style version and viewport height +// it was computed for hold. +_document_height: ?struct { version: usize, viewport: u32, value: f64 } = null, _script_manager: ScriptManager, _http_owner: HttpClient.Owner, diff --git a/src/browser/tests/element/position.html b/src/browser/tests/element/position.html index 17568d68c..eeeace6bc 100644 --- a/src/browser/tests/element/position.html +++ b/src/browser/tests/element/position.html @@ -337,17 +337,17 @@ testing.expectEqual(0, panel.clientHeight); testing.expectTrue(panel.scrollHeight > 0); - // The root containers keep their synthetic size rather than summing - // children. The root element's clientHeight is the viewport (CSSOM View): - // jstracker tiles clientWidth/10 cells over clientHeight and calls - // elementFromPoint per cell, which the 100M px box turned into ~5M walks. + // The root containers span the document rather than summing children. + // The root element's clientHeight is the viewport (CSSOM View): jstracker + // tiles clientWidth/10 cells over clientHeight and calls elementFromPoint + // per cell, which a document-sized box turned into ~5M walks. testing.expectEqual(document.body.clientHeight, document.body.scrollHeight); testing.expectEqual(window.innerHeight, document.documentElement.clientHeight); testing.expectEqual( document.documentElement.offsetHeight, document.documentElement.scrollHeight, ); - testing.expectTrue(document.documentElement.scrollHeight > document.documentElement.clientHeight); + testing.expectTrue(document.documentElement.scrollHeight >= document.documentElement.clientHeight); } @@ -578,6 +578,11 @@ deep.id = 'deep'; document.body.appendChild(deep); + // Room below it, or the viewport couldn't bring its top up + const room = document.createElement('div'); + room.style.height = '10000px'; + document.body.appendChild(room); + const targetY = deep.getBoundingClientRect().y; testing.expectTrue(targetY > 0); diff --git a/src/browser/tests/mcp_actions.html b/src/browser/tests/mcp_actions.html index c6e409ce5..75bda144f 100644 --- a/src/browser/tests/mcp_actions.html +++ b/src/browser/tests/mcp_actions.html @@ -70,5 +70,7 @@ document.getElementById('rad').addEventListener('click', function() { window.radClicked = true; }); document.getElementById('rad').addEventListener('change', function() { window.radChanged = true; }); + +
diff --git a/src/browser/tests/window_scroll.html b/src/browser/tests/window_scroll.html index 6d16dc0c3..dda8a1d51 100644 --- a/src/browser/tests/window_scroll.html +++ b/src/browser/tests/window_scroll.html @@ -1,6 +1,9 @@ + +
+ @@ -45,6 +48,28 @@ testing.expectEqual(0, window.scrollY); + + diff --git a/src/browser/tests/mcp_actions.html b/src/browser/tests/mcp_actions.html index 75bda144f..c407bffa6 100644 --- a/src/browser/tests/mcp_actions.html +++ b/src/browser/tests/mcp_actions.html @@ -71,6 +71,6 @@ document.getElementById('rad').addEventListener('change', function() { window.radChanged = true; }); -
+
diff --git a/src/browser/tests/window_scroll.html b/src/browser/tests/window_scroll.html index dda8a1d51..89c1fa498 100644 --- a/src/browser/tests/window_scroll.html +++ b/src/browser/tests/window_scroll.html @@ -2,7 +2,7 @@ -
+
- +
diff --git a/src/browser/tests/window_scroll.html b/src/browser/tests/window_scroll.html index 89c1fa498..a79508684 100644 --- a/src/browser/tests/window_scroll.html +++ b/src/browser/tests/window_scroll.html @@ -1,7 +1,7 @@ - +
+ +