mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-30 04:39:06 +00:00
LibWeb: Only apply box offset if the box is not already the ancestor
When determining the content/margin box rects within their ancestor's coordinate space, we were returning early if the passed in values already belonged to the requested ancestor. Unfortunately, we had already applied the used values' offset to the rect, which is the offset to the ancestor's ancestor. This simplifies the logic to always apply the rect offset after checking if we've reached the ancestor. Fixes determining float intrusions inside block elements with `margin: auto` set. Fixes #4083.
This commit is contained in:
parent
28d5d982ce
commit
99df80f81e
Notes:
github-actions[bot]
2025-04-04 13:36:19 +00:00
Author: https://github.com/gmta
Commit: 99df80f81e
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4219
5 changed files with 57 additions and 16 deletions
|
@ -1182,10 +1182,9 @@ void FormattingContext::compute_height_for_absolutely_positioned_non_replaced_el
|
|||
|
||||
CSSPixelRect FormattingContext::content_box_rect_in_static_position_ancestor_coordinate_space(Box const& box, Box const& ancestor_box) const
|
||||
{
|
||||
auto rect = content_box_rect(box);
|
||||
if (&box == &ancestor_box)
|
||||
return rect;
|
||||
for (auto const* current = box.static_position_containing_block(); current; current = current->static_position_containing_block()) {
|
||||
auto box_used_values = m_state.get(box);
|
||||
CSSPixelRect rect = { { 0, 0 }, box_used_values.content_size() };
|
||||
for (auto const* current = &box; current; current = current->static_position_containing_block()) {
|
||||
if (current == &ancestor_box)
|
||||
return rect;
|
||||
auto const& current_state = m_state.get(*current);
|
||||
|
@ -1761,7 +1760,7 @@ bool FormattingContext::can_skip_is_anonymous_text_run(Box& box)
|
|||
CSSPixelRect FormattingContext::absolute_content_rect(Box const& box) const
|
||||
{
|
||||
auto const& box_state = m_state.get(box);
|
||||
CSSPixelRect rect { box_state.offset, { box_state.content_width(), box_state.content_height() } };
|
||||
CSSPixelRect rect { box_state.offset, box_state.content_size() };
|
||||
for (auto* block = box_state.containing_block_used_values(); block; block = block->containing_block_used_values())
|
||||
rect.translate_by(block->offset);
|
||||
return rect;
|
||||
|
@ -1825,10 +1824,13 @@ CSSPixels FormattingContext::box_baseline(Box const& box) const
|
|||
return box_state.margin_box_height();
|
||||
}
|
||||
|
||||
CSSPixelRect FormattingContext::margin_box_rect(LayoutState::UsedValues const& used_values) const
|
||||
[[nodiscard]] static CSSPixelRect margin_box_rect(LayoutState::UsedValues const& used_values)
|
||||
{
|
||||
return {
|
||||
used_values.offset.translated(-used_values.margin_box_left(), -used_values.margin_box_top()),
|
||||
{
|
||||
-used_values.margin_box_left(),
|
||||
-used_values.margin_box_top(),
|
||||
},
|
||||
{
|
||||
used_values.margin_box_left() + used_values.content_width() + used_values.margin_box_right(),
|
||||
used_values.margin_box_top() + used_values.content_height() + used_values.margin_box_bottom(),
|
||||
|
@ -1843,15 +1845,13 @@ CSSPixelRect FormattingContext::content_box_rect(Box const& box) const
|
|||
|
||||
CSSPixelRect FormattingContext::content_box_rect(LayoutState::UsedValues const& used_values) const
|
||||
{
|
||||
return CSSPixelRect { used_values.offset, { used_values.content_width(), used_values.content_height() } };
|
||||
return CSSPixelRect { used_values.offset, used_values.content_size() };
|
||||
}
|
||||
|
||||
CSSPixelRect FormattingContext::content_box_rect_in_ancestor_coordinate_space(LayoutState::UsedValues const& used_values, Box const& ancestor_box) const
|
||||
{
|
||||
auto rect = content_box_rect(used_values);
|
||||
if (&used_values.node() == &ancestor_box)
|
||||
return rect;
|
||||
for (auto const* current = used_values.containing_block_used_values(); current; current = current->containing_block_used_values()) {
|
||||
CSSPixelRect rect = { { 0, 0 }, used_values.content_size() };
|
||||
for (auto const* current = &used_values; current; current = current->containing_block_used_values()) {
|
||||
if (¤t->node() == &ancestor_box)
|
||||
return rect;
|
||||
rect.translate_by(current->offset);
|
||||
|
@ -1863,9 +1863,7 @@ CSSPixelRect FormattingContext::content_box_rect_in_ancestor_coordinate_space(La
|
|||
CSSPixelRect FormattingContext::margin_box_rect_in_ancestor_coordinate_space(LayoutState::UsedValues const& used_values, Box const& ancestor_box) const
|
||||
{
|
||||
auto rect = margin_box_rect(used_values);
|
||||
if (&used_values.node() == &ancestor_box)
|
||||
return rect;
|
||||
for (auto const* current = used_values.containing_block_used_values(); current; current = current->containing_block_used_values()) {
|
||||
for (auto const* current = &used_values; current; current = current->containing_block_used_values()) {
|
||||
if (¤t->node() == &ancestor_box)
|
||||
return rect;
|
||||
rect.translate_by(current->offset);
|
||||
|
|
|
@ -82,7 +82,6 @@ public:
|
|||
|
||||
[[nodiscard]] CSSPixelRect absolute_content_rect(Box const&) const;
|
||||
[[nodiscard]] CSSPixelRect margin_box_rect_in_ancestor_coordinate_space(Box const&, Box const& ancestor_box) const;
|
||||
[[nodiscard]] CSSPixelRect margin_box_rect(LayoutState::UsedValues const&) const;
|
||||
[[nodiscard]] CSSPixelRect margin_box_rect_in_ancestor_coordinate_space(LayoutState::UsedValues const&, Box const& ancestor_box) const;
|
||||
[[nodiscard]] CSSPixelRect content_box_rect(Box const&) const;
|
||||
[[nodiscard]] CSSPixelRect content_box_rect(LayoutState::UsedValues const&) const;
|
||||
|
|
|
@ -67,6 +67,8 @@ struct LayoutState {
|
|||
void set_content_width(CSSPixels);
|
||||
void set_content_height(CSSPixels);
|
||||
|
||||
CSSPixelSize content_size() const { return { content_width(), content_height() }; }
|
||||
|
||||
void set_indefinite_content_width();
|
||||
void set_indefinite_content_height();
|
||||
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
||||
BlockContainer <html> at (0,0) content-size 800x316 [BFC] children: not-inline
|
||||
BlockContainer <body> at (8,8) content-size 784x300 children: not-inline
|
||||
BlockContainer <div.a> at (300,8) content-size 200x300 [BFC] children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <div.b.g> at (300,8) content-size 150x150 floating [BFC] children: not-inline
|
||||
TextNode <#text>
|
||||
BlockContainer <div.b.r> at (300,158) content-size 150x150 floating [BFC] children: not-inline
|
||||
TextNode <#text>
|
||||
BlockContainer <(anonymous)> at (8,308) content-size 784x0 children: inline
|
||||
TextNode <#text>
|
||||
|
||||
ViewportPaintable (Viewport<#document>) [0,0 800x600]
|
||||
PaintableWithLines (BlockContainer<HTML>) [0,0 800x316]
|
||||
PaintableWithLines (BlockContainer<BODY>) [8,8 784x300]
|
||||
PaintableWithLines (BlockContainer<DIV>.a) [300,8 200x300]
|
||||
PaintableWithLines (BlockContainer<DIV>.b.g) [300,8 150x150]
|
||||
PaintableWithLines (BlockContainer<DIV>.b.r) [300,158 150x150]
|
||||
PaintableWithLines (BlockContainer(anonymous)) [8,308 784x0]
|
|
@ -0,0 +1,23 @@
|
|||
<!DOCTYPE html>
|
||||
<style>
|
||||
.a {
|
||||
margin: auto;
|
||||
overflow: auto;
|
||||
width: 200px;
|
||||
}
|
||||
.b {
|
||||
height: 150px;
|
||||
float: left;
|
||||
width: 150px;
|
||||
}
|
||||
.g {
|
||||
background-color: green;
|
||||
}
|
||||
.r {
|
||||
background-color: red;
|
||||
}
|
||||
</style>
|
||||
<div class="a">
|
||||
<div class="b g"></div>
|
||||
<div class="b r"></div>
|
||||
</div>
|
Loading…
Add table
Add a link
Reference in a new issue