mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 05:07:45 +00:00
LibWeb: Compute content width before static position for abspos elements
In some scenarios, correctly computing the static position may depend on the content width having been calculated beforehand.
This commit is contained in:
parent
18fe86adc3
commit
e3b1d4a141
3 changed files with 72 additions and 4 deletions
|
@ -0,0 +1,34 @@
|
||||||
|
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
||||||
|
BlockContainer <html> at (0,0) content-size 800x116 [BFC] children: not-inline
|
||||||
|
BlockContainer <body> at (8,8) content-size 784x100 children: not-inline
|
||||||
|
BlockContainer <div#containing-block> at (8,8) content-size 200x100 children: not-inline
|
||||||
|
BlockContainer <(anonymous)> at (8,8) content-size 200x0 children: inline
|
||||||
|
TextNode <#text>
|
||||||
|
Box <div#inner-flex> at (8,8) content-size 200x0 flex-container(row) [FFC] children: not-inline
|
||||||
|
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
|
||||||
|
TextNode <#text>
|
||||||
|
BlockContainer <div> at (83,8) content-size 50x100 positioned [BFC] children: not-inline
|
||||||
|
BlockContainer <(anonymous)> at (83,8) content-size 50x0 children: inline
|
||||||
|
TextNode <#text>
|
||||||
|
BlockContainer <span> at (83,8) content-size 50x0 children: not-inline
|
||||||
|
BlockContainer <(anonymous)> at (83,8) content-size 50x0 children: inline
|
||||||
|
TextNode <#text>
|
||||||
|
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
|
||||||
|
TextNode <#text>
|
||||||
|
BlockContainer <(anonymous)> at (8,8) content-size 200x0 children: inline
|
||||||
|
TextNode <#text>
|
||||||
|
BlockContainer <(anonymous)> at (8,108) content-size 784x0 children: inline
|
||||||
|
TextNode <#text>
|
||||||
|
|
||||||
|
ViewportPaintable (Viewport<#document>) [0,0 800x600]
|
||||||
|
PaintableWithLines (BlockContainer<HTML>) [0,0 800x116]
|
||||||
|
PaintableWithLines (BlockContainer<BODY>) [8,8 784x100]
|
||||||
|
PaintableWithLines (BlockContainer<DIV>#containing-block) [8,8 200x100]
|
||||||
|
PaintableWithLines (BlockContainer(anonymous)) [8,8 200x0]
|
||||||
|
PaintableBox (Box<DIV>#inner-flex) [8,8 200x0] overflow: [83,8 50x100]
|
||||||
|
PaintableWithLines (BlockContainer<DIV>) [83,8 50x100]
|
||||||
|
PaintableWithLines (BlockContainer(anonymous)) [83,8 50x0]
|
||||||
|
PaintableWithLines (BlockContainer<SPAN>) [83,8 50x0]
|
||||||
|
PaintableWithLines (BlockContainer(anonymous)) [83,8 50x0]
|
||||||
|
PaintableWithLines (BlockContainer(anonymous)) [8,8 200x0]
|
||||||
|
PaintableWithLines (BlockContainer(anonymous)) [8,108 784x0]
|
|
@ -0,0 +1,25 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<style>
|
||||||
|
#containing-block {
|
||||||
|
width: 200px;
|
||||||
|
height: 100px;
|
||||||
|
background: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
#inner-flex {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
display: block;
|
||||||
|
width: 50px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div id="containing-block">
|
||||||
|
<div id="inner-flex">
|
||||||
|
<div style="position: absolute; height: 100px; background: green;">
|
||||||
|
<span></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -656,7 +656,7 @@ CSSPixels FormattingContext::compute_height_for_replaced_element(Box const& box,
|
||||||
void FormattingContext::compute_width_for_absolutely_positioned_non_replaced_element(Box const& box, AvailableSpace const& available_space)
|
void FormattingContext::compute_width_for_absolutely_positioned_non_replaced_element(Box const& box, AvailableSpace const& available_space)
|
||||||
{
|
{
|
||||||
auto width_of_containing_block = available_space.width.to_px_or_zero();
|
auto width_of_containing_block = available_space.width.to_px_or_zero();
|
||||||
auto& computed_values = box.computed_values();
|
auto const& computed_values = box.computed_values();
|
||||||
auto zero_value = CSS::Length::make_px(0);
|
auto zero_value = CSS::Length::make_px(0);
|
||||||
|
|
||||||
auto margin_left = CSS::Length::make_auto();
|
auto margin_left = CSS::Length::make_auto();
|
||||||
|
@ -699,10 +699,20 @@ void FormattingContext::compute_width_for_absolutely_positioned_non_replaced_ele
|
||||||
// Then, if the 'direction' property of the element establishing the static-position containing block
|
// Then, if the 'direction' property of the element establishing the static-position containing block
|
||||||
// is 'ltr' set 'left' to the static position and apply rule number three below;
|
// is 'ltr' set 'left' to the static position and apply rule number three below;
|
||||||
// otherwise, set 'right' to the static position and apply rule number one below.
|
// otherwise, set 'right' to the static position and apply rule number one below.
|
||||||
// FIXME: This is very hackish.
|
|
||||||
|
// NOTE: As with compute_height_for_absolutely_positioned_non_replaced_element, we actually apply these
|
||||||
|
// steps in the opposite order since the static position may depend on the width of the box.
|
||||||
|
|
||||||
|
auto result = calculate_shrink_to_fit_widths(box);
|
||||||
|
auto available_width = solve_for_width();
|
||||||
|
CSSPixels content_width = min(max(result.preferred_minimum_width, available_width.to_px(box)), result.preferred_width);
|
||||||
|
width = CSS::Length::make_px(content_width);
|
||||||
|
m_state.get_mutable(box).set_content_width(content_width);
|
||||||
|
|
||||||
auto static_position = calculate_static_position(box);
|
auto static_position = calculate_static_position(box);
|
||||||
|
|
||||||
left = static_position.x();
|
left = static_position.x();
|
||||||
goto Rule3;
|
right = solve_for_right();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If none of the three is auto:
|
// If none of the three is auto:
|
||||||
|
@ -765,7 +775,6 @@ void FormattingContext::compute_width_for_absolutely_positioned_non_replaced_ele
|
||||||
// 3. 'width' and 'right' are 'auto' and 'left' is not 'auto',
|
// 3. 'width' and 'right' are 'auto' and 'left' is not 'auto',
|
||||||
// then the width is shrink-to-fit. Then solve for 'right'
|
// then the width is shrink-to-fit. Then solve for 'right'
|
||||||
else if (width.is_auto() && computed_right.is_auto() && !computed_left.is_auto()) {
|
else if (width.is_auto() && computed_right.is_auto() && !computed_left.is_auto()) {
|
||||||
Rule3:
|
|
||||||
auto result = calculate_shrink_to_fit_widths(box);
|
auto result = calculate_shrink_to_fit_widths(box);
|
||||||
auto available_width = solve_for_width();
|
auto available_width = solve_for_width();
|
||||||
width = CSS::Length::make_px(min(max(result.preferred_minimum_width, available_width.to_px(box)), result.preferred_width));
|
width = CSS::Length::make_px(min(max(result.preferred_minimum_width, available_width.to_px(box)), result.preferred_width));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue