|
@@ -386,12 +386,12 @@ void FormattingContext::compute_width_for_absolutely_positioned_element(Box cons
|
|
|
compute_width_for_absolutely_positioned_non_replaced_element(box, available_space);
|
|
|
}
|
|
|
|
|
|
-void FormattingContext::compute_height_for_absolutely_positioned_element(Box const& box, AvailableSpace const& available_space)
|
|
|
+void FormattingContext::compute_height_for_absolutely_positioned_element(Box const& box, AvailableSpace const& available_space, BeforeOrAfterInsideLayout before_or_after_inside_layout)
|
|
|
{
|
|
|
if (is<ReplacedBox>(box))
|
|
|
- compute_height_for_absolutely_positioned_replaced_element(static_cast<ReplacedBox const&>(box), available_space);
|
|
|
+ compute_height_for_absolutely_positioned_replaced_element(static_cast<ReplacedBox const&>(box), available_space, before_or_after_inside_layout);
|
|
|
else
|
|
|
- compute_height_for_absolutely_positioned_non_replaced_element(box, available_space);
|
|
|
+ compute_height_for_absolutely_positioned_non_replaced_element(box, available_space, before_or_after_inside_layout);
|
|
|
}
|
|
|
|
|
|
CSSPixels FormattingContext::compute_width_for_replaced_element(LayoutState const& state, ReplacedBox const& box, AvailableSpace const& available_space)
|
|
@@ -636,13 +636,17 @@ void FormattingContext::compute_width_for_absolutely_positioned_replaced_element
|
|
|
}
|
|
|
|
|
|
// https://drafts.csswg.org/css-position-3/#abs-non-replaced-height
|
|
|
-void FormattingContext::compute_height_for_absolutely_positioned_non_replaced_element(Box const& box, AvailableSpace const& available_space)
|
|
|
+void FormattingContext::compute_height_for_absolutely_positioned_non_replaced_element(Box const& box, AvailableSpace const& available_space, BeforeOrAfterInsideLayout before_or_after_inside_layout)
|
|
|
{
|
|
|
// 5.3. The Height Of Absolutely Positioned, Non-Replaced Elements
|
|
|
|
|
|
// For absolutely positioned elements, the used values of the vertical dimensions must satisfy this constraint:
|
|
|
// top + margin-top + border-top-width + padding-top + height + padding-bottom + border-bottom-width + margin-bottom + bottom = height of containing block
|
|
|
|
|
|
+ // NOTE: This function is called twice: both before and after inside layout.
|
|
|
+ // In the before pass, if it turns out we need the automatic height of the box, we abort these steps.
|
|
|
+ // This allows the box to retain an indefinite height from the perspective of inside layout.
|
|
|
+
|
|
|
auto margin_top = box.computed_values().margin().top();
|
|
|
auto margin_bottom = box.computed_values().margin().bottom();
|
|
|
auto top = box.computed_values().inset().top();
|
|
@@ -697,6 +701,10 @@ void FormattingContext::compute_height_for_absolutely_positioned_non_replaced_el
|
|
|
|
|
|
// If all three of top, height, and bottom are auto:
|
|
|
if (top.is_auto() && height.is_auto() && bottom.is_auto()) {
|
|
|
+ // (If we haven't done inside layout yet, we can't compute the auto height.)
|
|
|
+ if (before_or_after_inside_layout == BeforeOrAfterInsideLayout::Before)
|
|
|
+ return;
|
|
|
+
|
|
|
// First set any auto values for margin-top and margin-bottom to 0,
|
|
|
if (margin_top.is_auto())
|
|
|
margin_top = CSS::Length::make_px(0);
|
|
@@ -748,6 +756,10 @@ void FormattingContext::compute_height_for_absolutely_positioned_non_replaced_el
|
|
|
|
|
|
// 1. If top and height are auto and bottom is not auto,
|
|
|
if (top.is_auto() && height.is_auto() && !bottom.is_auto()) {
|
|
|
+ // (If we haven't done inside layout yet, we can't compute the auto height.)
|
|
|
+ if (before_or_after_inside_layout == BeforeOrAfterInsideLayout::Before)
|
|
|
+ return;
|
|
|
+
|
|
|
// then the height is based on the Auto heights for block formatting context roots,
|
|
|
height = CSS::Size::make_px(compute_auto_height_for_block_formatting_context_root(verify_cast<BlockContainer>(box)));
|
|
|
|
|
@@ -766,6 +778,10 @@ void FormattingContext::compute_height_for_absolutely_positioned_non_replaced_el
|
|
|
|
|
|
// 3. If height and bottom are auto and top is not auto,
|
|
|
else if (height.is_auto() && bottom.is_auto() && !top.is_auto()) {
|
|
|
+ // (If we haven't done inside layout yet, we can't compute the auto height.)
|
|
|
+ if (before_or_after_inside_layout == BeforeOrAfterInsideLayout::Before)
|
|
|
+ return;
|
|
|
+
|
|
|
// then the height is based on the Auto heights for block formatting context roots,
|
|
|
height = CSS::Size::make_px(compute_auto_height_for_block_formatting_context_root(verify_cast<BlockContainer>(box)));
|
|
|
|
|
@@ -893,10 +909,11 @@ void FormattingContext::layout_absolutely_positioned_element(Box const& box, Ava
|
|
|
// NOTE: We compute height before *and* after doing inside layout.
|
|
|
// This is done so that inside layout can resolve percentage heights.
|
|
|
// In some situations, e.g with non-auto top & bottom values, the height can be determined early.
|
|
|
- compute_height_for_absolutely_positioned_element(box, available_space);
|
|
|
+ compute_height_for_absolutely_positioned_element(box, available_space, BeforeOrAfterInsideLayout::Before);
|
|
|
|
|
|
auto independent_formatting_context = layout_inside(box, LayoutMode::Normal, box_state.available_inner_space_or_constraints_from(available_space));
|
|
|
- compute_height_for_absolutely_positioned_element(box, available_space);
|
|
|
+
|
|
|
+ compute_height_for_absolutely_positioned_element(box, available_space, BeforeOrAfterInsideLayout::After);
|
|
|
|
|
|
box_state.margin_left = box.computed_values().margin().left().resolved(box, width_of_containing_block_as_length).to_px(box);
|
|
|
box_state.margin_top = box.computed_values().margin().top().resolved(box, width_of_containing_block_as_length).to_px(box);
|
|
@@ -966,7 +983,7 @@ void FormattingContext::layout_absolutely_positioned_element(Box const& box, Ava
|
|
|
independent_formatting_context->parent_context_did_dimension_child_root_box();
|
|
|
}
|
|
|
|
|
|
-void FormattingContext::compute_height_for_absolutely_positioned_replaced_element(ReplacedBox const& box, AvailableSpace const& available_space)
|
|
|
+void FormattingContext::compute_height_for_absolutely_positioned_replaced_element(ReplacedBox const& box, AvailableSpace const& available_space, BeforeOrAfterInsideLayout)
|
|
|
{
|
|
|
// 10.6.5 Absolutely positioned, replaced elements
|
|
|
// The used value of 'height' is determined as for inline replaced elements.
|