mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-10-08 12:21:44 -04:00
Extend the document to nested declared heights
A spacer inside an auto-height wrapper, as virtualized lists build, counted as 5px, so the viewport clamp stopped short of it.
This commit is contained in:
1 parent
03fee916fd
commit
51b9ee8125
3 files changed
+39
-6
No files matched your search
@@ -71,6 +71,20 @@
|
||||
window.scrollTo(0, 0);
|
||||
</script>
|
||||
|
||||
<script id=scrollTo_reaches_nested_spacer>
|
||||
// Virtualized lists size an inner spacer inside an auto-height wrapper
|
||||
const outer = document.createElement('div');
|
||||
const spacer = document.createElement('div');
|
||||
spacer.style.height = '20000px';
|
||||
outer.appendChild(spacer);
|
||||
document.body.appendChild(outer);
|
||||
window.scrollTo(0, 99999999);
|
||||
testing.expectTrue(window.scrollY + window.innerHeight >= 20000);
|
||||
testing.expectEqual(document.documentElement.scrollHeight - window.innerHeight, window.scrollY);
|
||||
outer.remove();
|
||||
window.scrollTo(0, 0);
|
||||
</script>
|
||||
|
||||
<script id=element_scroll_events_coalesce_and_preserve_reentrancy type=module>
|
||||
const state = await testing.async();
|
||||
const element = document.createElement('div');
|
||||
|
||||
@@ -505,9 +505,10 @@ pub fn getDocumentElement(self: *Document) ?*Element {
|
||||
pub const Extent = struct { width: f64, height: f64 };
|
||||
|
||||
/// The document's size. Height: enough for every synthetic position (5px per
|
||||
/// node) and body's stacked children. Width: body's widest child. An inline
|
||||
/// size on body stretches both. A document without a frame isn't rendered,
|
||||
/// so it has no size.
|
||||
/// node), the bottom of every element with a declared height, and body's
|
||||
/// stacked children. Width: body's widest child. An inline size on body
|
||||
/// stretches both. A document without a frame isn't rendered, so it has no
|
||||
/// size.
|
||||
pub fn extent(self: *Document) Extent {
|
||||
const frame = self._frame orelse return .{ .width = 0, .height = 0 };
|
||||
const version = frame.page.style_version;
|
||||
@@ -518,11 +519,29 @@ pub fn extent(self: *Document) Extent {
|
||||
}
|
||||
}
|
||||
|
||||
var size: Extent = .{ .width = 0, .height = Element.countSubtreeNodes(self.asNode()) * 5.0 };
|
||||
const style_manager = &frame._style_manager;
|
||||
var size: Extent = .{ .width = 0, .height = 0 };
|
||||
|
||||
// A nested spacer (virtualized lists) must extend the document even when
|
||||
// its auto-height ancestors count as 5px each. Body's own children are
|
||||
// stacked below instead.
|
||||
var index: f64 = 0;
|
||||
var tw = @import("TreeWalker.zig").Full.init(self.asNode(), .{});
|
||||
while (tw.next()) |node| : (index += 1) {
|
||||
const el = node.is(Element) orelse continue;
|
||||
const parent = el.parentElement() orelse continue;
|
||||
if (parent.getTag() == .html or parent.getTag() == .body) {
|
||||
continue;
|
||||
}
|
||||
if (style_manager.declaredSize(el, .height)) |height| {
|
||||
size.height = @max(size.height, index * 5.0 + height);
|
||||
}
|
||||
}
|
||||
size.height = @max(size.height, index * 5.0);
|
||||
|
||||
if (self.is(HTMLDocument)) |html_doc| {
|
||||
if (html_doc.getBody()) |html_body| {
|
||||
const body = html_body.asElement();
|
||||
const style_manager = &frame._style_manager;
|
||||
size.height = @max(size.height, body.contentAxis(frame, .height), style_manager.inlineSize(body, .height) orelse 0);
|
||||
size.width = style_manager.inlineSize(body, .width) orelse 0;
|
||||
var child = body.asNode().firstChild();
|
||||
|
||||
@@ -1917,7 +1917,7 @@ fn calculateDocumentPosition(node: *Node) f64 {
|
||||
}
|
||||
|
||||
// Counts total nodes in a subtree (node + all descendants)
|
||||
pub fn countSubtreeNodes(node: *Node) f64 {
|
||||
fn countSubtreeNodes(node: *Node) f64 {
|
||||
var count: f64 = 0;
|
||||
var tw = TreeWalker.Full.init(node, .{});
|
||||
while (tw.next()) |_| {
|
||||
|
||||
Reference in new issue
Block a user