LibWeb: Add additional padding to the end of the scrollable overflow

Adds additional padding to the end-side of the scrollable overflow
rectangle as necessary to enable a scroll position that satisfies
the requirements of `place-content: end` alignment.
This commit is contained in:
BenJilks 2024-08-01 14:29:09 +01:00 committed by Andreas Kling
parent 40b2d24d55
commit 963cf1c2c4
Notes: github-actions[bot] 2024-08-02 06:08:47 +00:00
7 changed files with 104 additions and 18 deletions

View file

@ -10,9 +10,9 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
TextNode <#text>
ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer<HTML>) [0,0 800x53] overflow: [0,0 800x68]
PaintableWithLines (BlockContainer<BODY>) [8,8 784x37] overflow: [8,8 784x60]
PaintableBox (Box<DIV>#flex-container) [8,8 784x37] overflow: [8,8 784x60]
PaintableWithLines (BlockContainer<HTML>) [0,0 800x53] overflow: [0,0 800x78]
PaintableWithLines (BlockContainer<BODY>) [8,8 784x37] overflow: [8,8 784x70]
PaintableBox (Box<DIV>#flex-container) [8,8 784x37] overflow: [8,8 784x70]
PaintableWithLines (BlockContainer<DIV>#absolute) [18,18 50x50]
PaintableWithLines (BlockContainer<DIV>#orange) [18,18 50x50]
PaintableWithLines (BlockContainer<DIV>#red) [18,18 9.703125x17]

View file

@ -47,8 +47,8 @@ ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer<DIV>) [11,10 196x22]
TextPaintable (TextNode<#text>)
TextPaintable (TextNode<#text>)
PaintableWithLines (BlockContainer<INPUT>) [220,8 202x26] overflow: [221,9 346.4375x24]
PaintableBox (Box<DIV>) [221,9 200x24] overflow: [221,9 346.4375x24]
PaintableWithLines (BlockContainer<INPUT>) [220,8 202x26] overflow: [221,9 346.4375x25]
PaintableBox (Box<DIV>) [221,9 200x24] overflow: [221,9 346.4375x25]
PaintableWithLines (BlockContainer<DIV>) [223,10 196x22] overflow: [223,10 344.4375x22]
TextPaintable (TextNode<#text>)
TextPaintable (TextNode<#text>)
@ -56,7 +56,7 @@ ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableBox (Box<DIV>) [433,9 200x24]
PaintableWithLines (BlockContainer<DIV>) [435,10 196x22]
TextPaintable (TextNode<#text>)
PaintableWithLines (BlockContainer<INPUT>#placeholder) [8,34 202x26] overflow: [9,35 409.71875x24]
PaintableBox (Box<DIV>) [9,35 200x24] overflow: [9,35 409.71875x24]
PaintableWithLines (BlockContainer<INPUT>#placeholder) [8,34 202x26] overflow: [9,35 409.71875x25]
PaintableBox (Box<DIV>) [9,35 200x24] overflow: [9,35 409.71875x25]
PaintableWithLines (BlockContainer<DIV>) [11,36 196x22] overflow: [11,36 407.71875x22]
TextPaintable (TextNode<#text>)

View file

@ -0,0 +1,57 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x260 [BFC] children: not-inline
BlockContainer <body> at (8,8) content-size 784x244 children: not-inline
BlockContainer <div.outer> at (34,34) content-size 400x70 [BFC] children: not-inline
BlockContainer <div.inner> at (35,35) content-size 400x100 children: inline
frag 0 from TextNode start: 0, length: 47, rect: [35,35 382.296875x17] baseline: 13.296875
"This should be scrollable vertically because of"
frag 1 from TextNode start: 48, length: 12, rect: [35,52 93.4375x17] baseline: 13.296875
"the padding."
TextNode <#text>
InlineNode <span>
BlockContainer <(anonymous)> at (8,130) content-size 784x0 children: inline
TextNode <#text>
BlockContainer <div.outer> at (34,156) content-size 400x70 [BFC] children: not-inline
BlockContainer <div.inner> at (35,157) content-size 400x100 children: inline
frag 0 from TextNode start: 0, length: 46, rect: [35,157 373.796875x17] baseline: 13.296875
"This padding represents, within the scrollable"
frag 1 from TextNode start: 47, length: 46, rect: [35,174 370.875x17] baseline: 13.296875
"overflow rectangle, the boxs own padding so"
frag 2 from TextNode start: 94, length: 45, rect: [35,191 366.578125x17] baseline: 13.296875
"that when its content is scrolled to the end,"
frag 3 from TextNode start: 140, length: 44, rect: [35,208 359.828125x17] baseline: 13.296875
"there is padding between the end-edge of its"
frag 4 from TextNode start: 185, length: 48, rect: [35,225 391.71875x17] baseline: 13.296875
"in-flow (or floated) content and the border edge"
frag 5 from TextNode start: 234, length: 50, rect: [35,242 395.328125x17] baseline: 13.296875
"of the box. It typically ends up being exactly the"
frag 6 from TextNode start: 285, length: 49, rect: [35,259 399.1875x17] baseline: 13.296875
"same size as the boxs own padding, except in a"
frag 7 from TextNode start: 335, length: 39, rect: [35,276 320.640625x17] baseline: 13.296875
"few cases—such as when an out-of-flow"
frag 8 from TextNode start: 375, length: 48, rect: [35,293 389.421875x17] baseline: 13.296875
"positioned element, or the visible overflow of a"
frag 9 from TextNode start: 424, length: 45, rect: [35,310 371.28125x17] baseline: 13.296875
"descendent, has already increased the size of"
frag 10 from TextNode start: 470, length: 45, rect: [35,327 366x17] baseline: 13.296875
"the scrollable overflow rectangle outside the"
frag 11 from TextNode start: 516, length: 43, rect: [35,344 319.109375x17] baseline: 13.296875
"conceptual “content edge” of the scroll"
frag 12 from TextNode start: 560, length: 22, rect: [35,361 165.21875x17] baseline: 13.296875
"containers content."
TextNode <#text>
BlockContainer <(anonymous)> at (8,252) content-size 784x0 children: inline
TextNode <#text>
ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer<HTML>) [0,0 800x260]
PaintableWithLines (BlockContainer<BODY>) [8,8 784x244]
PaintableWithLines (BlockContainer<DIV>.outer) [8,8 452x122] overflow: [9,9 450x152]
PaintableWithLines (BlockContainer<DIV>.inner) [34,34 402x102]
TextPaintable (TextNode<#text>)
InlinePaintable (InlineNode<SPAN>)
PaintableWithLines (BlockContainer(anonymous)) [8,130 784x0]
PaintableWithLines (BlockContainer<DIV>.outer) [8,130 452x122] overflow: [9,131 450x247]
PaintableWithLines (BlockContainer<DIV>.inner) [34,156 402x102] overflow: [35,157 400x221]
TextPaintable (TextNode<#text>)
PaintableWithLines (BlockContainer(anonymous)) [8,252 784x0]

View file

@ -9,5 +9,5 @@ ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer<HTML>) [0,0 800x216]
PaintableWithLines (BlockContainer<BODY>) [8,8 784x200]
PaintableWithLines (BlockContainer<DIV>#guide) [8,8 200x200]
PaintableWithLines (BlockContainer<DIV>#container) [8,8 20x20] overflow: [8,8 100x100]
PaintableWithLines (BlockContainer<DIV>#container) [8,8 20x20] overflow: [8,8 100x110]
PaintableWithLines (BlockContainer<DIV>#box) [8,8 100x100]

View file

@ -27,7 +27,7 @@ ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer<BODY>) [8,8 784x23]
PaintableWithLines (TableWrapper(anonymous)) [8,8 6x23] overflow: [8,8 17.265625x23]
PaintableBox (Box<TABLE>) [8,8 6x23] overflow: [8,8 17.265625x23]
PaintableBox (Box<TBODY>) [8,8 0x19] overflow: [10,10 15.265625x19]
PaintableBox (Box<TR>) [10,10 0x19] overflow: [10,10 15.265625x19]
PaintableWithLines (BlockContainer<TD>) [10,10 2x19] overflow: [10,10 15.265625x19]
PaintableBox (Box<TBODY>) [8,8 0x19] overflow: [10,10 15.265625x20]
PaintableBox (Box<TR>) [10,10 0x19] overflow: [10,10 15.265625x20]
PaintableWithLines (BlockContainer<TD>) [10,10 2x19] overflow: [10,10 15.265625x20]
TextPaintable (TextNode<#text>)

View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<style>
.outer {
border: 1px solid black;
padding: 25px;
width: 400px;
height: 70px;
overflow: auto;
}
.inner {
border: 1px solid black;
width: 400px;
height: 100px;
overflow: visable;
}
</style>
<div class="outer"><div class="inner">This should be scrollable vertically because of the padding.<span></span></div></div>
<div class="outer"><div class="inner">This padding represents, within the scrollable overflow rectangle, the boxs own padding so that when its content is scrolled to the end, there is padding between the end-edge of its in-flow (or floated) content and the border edge of the box. It typically ends up being exactly the same size as the boxs own padding, except in a few cases—such as when an out-of-flow positioned element, or the visible overflow of a descendent, has already increased the size of the scrollable overflow rectangle outside the conceptual “content edge” of the scroll containers content.</div></div>

View file

@ -94,18 +94,22 @@ static CSSPixelRect measure_scrollable_overflow(Box const& box)
}
}
auto content_overflow_rect = scrollable_overflow_rect;
// - The border boxes of all boxes for which it is the containing block
// and whose border boxes are positioned not wholly in the negative scrollable overflow region,
// FIXME: accounting for transforms by projecting each box onto the plane of the element that establishes its 3D rendering context. [CSS3-TRANSFORMS]
if (!box.children_are_inline()) {
box.for_each_child_of_type<Box>([&box, &scrollable_overflow_rect](Box const& child) {
box.for_each_child_of_type<Box>([&box, &scrollable_overflow_rect, &content_overflow_rect](Box const& child) {
if (!child.paintable_box())
return IterationDecision::Continue;
auto child_border_box = child.paintable_box()->absolute_border_box_rect();
// NOTE: Here we check that the child is not wholly in the negative scrollable overflow region.
if (child_border_box.bottom() > 0 && child_border_box.right() > 0)
if (child_border_box.bottom() > 0 && child_border_box.right() > 0) {
scrollable_overflow_rect = scrollable_overflow_rect.united(child_border_box);
content_overflow_rect = content_overflow_rect.united(child_border_box);
}
// - The scrollable overflow areas of all of the above boxes
// (including zero-area boxes and accounting for transforms as described above),
@ -122,10 +126,12 @@ static CSSPixelRect measure_scrollable_overflow(Box const& box)
return IterationDecision::Continue;
});
} else {
box.for_each_child([&scrollable_overflow_rect](Node const& child) {
box.for_each_child([&scrollable_overflow_rect, &content_overflow_rect](Node const& child) {
if (child.paintable() && child.paintable()->is_inline_paintable()) {
for (auto const& fragment : static_cast<Painting::InlinePaintable const&>(*child.paintable()).fragments())
for (auto const& fragment : static_cast<Painting::InlinePaintable const&>(*child.paintable()).fragments()) {
scrollable_overflow_rect = scrollable_overflow_rect.united(fragment.absolute_rect());
content_overflow_rect = content_overflow_rect.united(fragment.absolute_rect());
}
}
return IterationDecision::Continue;
@ -134,12 +140,16 @@ static CSSPixelRect measure_scrollable_overflow(Box const& box)
// FIXME: - The margin areas of grid item and flex item boxes for which the box establishes a containing block.
// FIXME: - Additional padding added to the end-side of the scrollable overflow rectangle as necessary
// to enable a scroll position that satisfies the requirements of place-content: end alignment.
// - Additional padding added to the end-side of the scrollable overflow rectangle as necessary
// to enable a scroll position that satisfies the requirements of place-content: end alignment.
auto has_scrollable_overflow = !paintable_box.absolute_padding_box_rect().contains(scrollable_overflow_rect);
if (has_scrollable_overflow) {
scrollable_overflow_rect.set_height(max(scrollable_overflow_rect.height(), content_overflow_rect.height() + box.box_model().padding.bottom));
}
paintable_box.set_overflow_data(Painting::PaintableBox::OverflowData {
.scrollable_overflow_rect = scrollable_overflow_rect,
.has_scrollable_overflow = !paintable_box.absolute_padding_box_rect().contains(scrollable_overflow_rect),
.has_scrollable_overflow = has_scrollable_overflow,
});
return scrollable_overflow_rect;