Commit 66ac041a authored by Ian Kilpatrick's avatar Ian Kilpatrick Committed by Commit Bot

[LayoutNG] Handle 'auto' for new formatting contexts within a BFC.

This implements our current behaviour for 'auto' sized FCs within a BFC.

We need to perform layout twice under two scenarios:
 1. 'auto' inline size child. In this case we need to perform layout
    once, and if the child doesn't fit, we perform layout a second time
    with an "open" layout opportunity, so we can guarantee it will fit.

 2. Non-adjoining margin strut and unpositioned floats/current layout.
    In this case we need to perform a relayout as the BFCOffset where
    floats will be positioned will change. This happens if the child
    doesn't fit on the "top" of the exclusion space.

This also adds more TODOs everywhere which we can handle later.
I kept this as small as possible to keep sanity. :)

Bug: 635619
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_layout_tests_layout_ng
Change-Id: I499dc9722fac47f43694f35c507e9d2742d317db
Reviewed-on: https://chromium-review.googlesource.com/680176
Commit-Queue: Ian Kilpatrick <ikilpatrick@chromium.org>
Reviewed-by: default avatarEmil A Eklund <eae@chromium.org>
Cr-Commit-Position: refs/heads/master@{#506963}
parent 41032806
...@@ -1232,6 +1232,7 @@ crbug.com/591099 css3/flexbox/flexbox-baseline.html [ Failure ] ...@@ -1232,6 +1232,7 @@ crbug.com/591099 css3/flexbox/flexbox-baseline.html [ Failure ]
crbug.com/591099 css3/flexbox/floated-flexbox.html [ Failure ] crbug.com/591099 css3/flexbox/floated-flexbox.html [ Failure ]
crbug.com/591099 css3/flexbox/intrinsic-width-orthogonal-writing-mode.html [ Failure ] crbug.com/591099 css3/flexbox/intrinsic-width-orthogonal-writing-mode.html [ Failure ]
crbug.com/591099 css3/flexbox/line-wrapping.html [ Failure ] crbug.com/591099 css3/flexbox/line-wrapping.html [ Failure ]
crbug.com/591099 css3/flexbox/nested-orthogonal-flexbox-relayout.html [ Failure ]
crbug.com/591099 css3/flexbox/overflow-auto-dynamic-changes.html [ Failure ] crbug.com/591099 css3/flexbox/overflow-auto-dynamic-changes.html [ Failure ]
crbug.com/591099 css3/flexbox/position-absolute-child-with-contenteditable.html [ Failure ] crbug.com/591099 css3/flexbox/position-absolute-child-with-contenteditable.html [ Failure ]
crbug.com/591099 css3/flexbox/scrollbars-auto.html [ Failure ] crbug.com/591099 css3/flexbox/scrollbars-auto.html [ Failure ]
...@@ -2570,6 +2571,8 @@ crbug.com/591099 external/wpt/css/CSS2/floats-clear/margin-collapse-157.xht [ Fa ...@@ -2570,6 +2571,8 @@ crbug.com/591099 external/wpt/css/CSS2/floats-clear/margin-collapse-157.xht [ Fa
crbug.com/591099 external/wpt/css/CSS2/floats-clear/margin-collapse-clear-008.xht [ Failure ] crbug.com/591099 external/wpt/css/CSS2/floats-clear/margin-collapse-clear-008.xht [ Failure ]
crbug.com/591099 external/wpt/css/CSS2/floats/floats-wrap-bfc-001-left-overflow.xht [ Crash Failure ] crbug.com/591099 external/wpt/css/CSS2/floats/floats-wrap-bfc-001-left-overflow.xht [ Crash Failure ]
crbug.com/591099 external/wpt/css/CSS2/floats/floats-wrap-bfc-002-left-overflow.xht [ Failure ] crbug.com/591099 external/wpt/css/CSS2/floats/floats-wrap-bfc-002-left-overflow.xht [ Failure ]
crbug.com/591099 external/wpt/css/CSS2/floats/floats-wrap-bfc-002-left-table.xht [ Failure ]
crbug.com/591099 external/wpt/css/CSS2/floats/floats-wrap-bfc-002-right-table.xht [ Failure ]
crbug.com/591099 external/wpt/css/CSS2/floats/floats-wrap-bfc-003-left-overflow.xht [ Failure ] crbug.com/591099 external/wpt/css/CSS2/floats/floats-wrap-bfc-003-left-overflow.xht [ Failure ]
crbug.com/591099 external/wpt/css/CSS2/floats/floats-wrap-bfc-003-right-overflow.xht [ Failure ] crbug.com/591099 external/wpt/css/CSS2/floats/floats-wrap-bfc-003-right-overflow.xht [ Failure ]
crbug.com/591099 external/wpt/css/CSS2/floats/floats-wrap-bfc-004.xht [ Failure ] crbug.com/591099 external/wpt/css/CSS2/floats/floats-wrap-bfc-004.xht [ Failure ]
...@@ -3447,6 +3450,7 @@ crbug.com/591099 fast/block/basic/quirk-height.html [ Failure ] ...@@ -3447,6 +3450,7 @@ crbug.com/591099 fast/block/basic/quirk-height.html [ Failure ]
crbug.com/591099 fast/block/basic/quirk-percent-height-grandchild.html [ Failure ] crbug.com/591099 fast/block/basic/quirk-percent-height-grandchild.html [ Failure ]
crbug.com/591099 fast/block/block-add-child-crash.html [ Failure Pass ] crbug.com/591099 fast/block/block-add-child-crash.html [ Failure Pass ]
crbug.com/591099 fast/block/block-width-recalc-with-relative-height.html [ Crash Failure ] crbug.com/591099 fast/block/block-width-recalc-with-relative-height.html [ Crash Failure ]
crbug.com/591099 fast/block/containing-block-negative-margins.html [ Failure ]
crbug.com/591099 fast/block/float-avoids-padding-inline-ancestors.html [ Failure ] crbug.com/591099 fast/block/float-avoids-padding-inline-ancestors.html [ Failure ]
crbug.com/591099 fast/block/float/002.html [ Crash Failure ] crbug.com/591099 fast/block/float/002.html [ Crash Failure ]
crbug.com/591099 fast/block/float/003.html [ Failure ] crbug.com/591099 fast/block/float/003.html [ Failure ]
...@@ -7954,6 +7958,7 @@ crbug.com/591099 tables/mozilla/bugs/bug133948.html [ Failure ] ...@@ -7954,6 +7958,7 @@ crbug.com/591099 tables/mozilla/bugs/bug133948.html [ Failure ]
crbug.com/591099 tables/mozilla/bugs/bug137388-3.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug137388-3.html [ Failure ]
crbug.com/591099 tables/mozilla/bugs/bug149275-1.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug149275-1.html [ Failure ]
crbug.com/591099 tables/mozilla/bugs/bug149275-2.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug149275-2.html [ Failure ]
crbug.com/591099 tables/mozilla/bugs/bug15247.html [ Failure ]
crbug.com/591099 tables/mozilla/bugs/bug154780.html [ Crash Failure ] crbug.com/591099 tables/mozilla/bugs/bug154780.html [ Crash Failure ]
crbug.com/591099 tables/mozilla/bugs/bug16252.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug16252.html [ Failure ]
crbug.com/591099 tables/mozilla/bugs/bug18440.html [ Failure ] crbug.com/591099 tables/mozilla/bugs/bug18440.html [ Failure ]
......
...@@ -298,6 +298,8 @@ crbug.com/711704 virtual/layout_ng/external/wpt/css/CSS2/floats/floats-rule7-out ...@@ -298,6 +298,8 @@ crbug.com/711704 virtual/layout_ng/external/wpt/css/CSS2/floats/floats-rule7-out
crbug.com/711704 virtual/layout_ng/external/wpt/css/CSS2/floats/floats-rule7-outside-right-001.xht [ Failure ] crbug.com/711704 virtual/layout_ng/external/wpt/css/CSS2/floats/floats-rule7-outside-right-001.xht [ Failure ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats/floats-wrap-bfc-001-left-overflow.xht [ Failure ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats/floats-wrap-bfc-001-left-overflow.xht [ Failure ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats/floats-wrap-bfc-002-left-overflow.xht [ Failure ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats/floats-wrap-bfc-002-left-overflow.xht [ Failure ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats/floats-wrap-bfc-002-left-table.xht [ Failure ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats/floats-wrap-bfc-002-right-table.xht [ Failure ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats/floats-wrap-bfc-003-left-overflow.xht [ Failure ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats/floats-wrap-bfc-003-left-overflow.xht [ Failure ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats/floats-wrap-bfc-003-right-overflow.xht [ Failure ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats/floats-wrap-bfc-003-right-overflow.xht [ Failure ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats/floats-wrap-bfc-004.xht [ Failure ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats/floats-wrap-bfc-004.xht [ Failure ]
...@@ -332,7 +334,6 @@ crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/floats-131 ...@@ -332,7 +334,6 @@ crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/floats-131
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/floats-137.xht [ Skip ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/floats-137.xht [ Skip ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/floats-143.xht [ Failure ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/floats-143.xht [ Failure ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/margin-collapse-157.xht [ Failure ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/margin-collapse-157.xht [ Failure ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/margin-collapse-clear-008.xht [ Failure ]
# Regressions while changing zero-block-size float behaviour. # Regressions while changing zero-block-size float behaviour.
crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/001.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/001.html [ Failure ]
...@@ -471,15 +472,12 @@ crbug.com/635619 virtual/layout_ng/fast/block/float/017.html [ Failure ] ...@@ -471,15 +472,12 @@ crbug.com/635619 virtual/layout_ng/fast/block/float/017.html [ Failure ]
crbug.com/635619 virtual/layout_ng/fast/block/float/018.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/float/018.html [ Failure ]
crbug.com/635619 [ Mac ] virtual/layout_ng/fast/block/float/020.html [ Failure ] crbug.com/635619 [ Mac ] virtual/layout_ng/fast/block/float/020.html [ Failure ]
crbug.com/635619 virtual/layout_ng/fast/block/float/022.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/float/022.html [ Failure ]
crbug.com/635619 virtual/layout_ng/fast/block/float/025.html [ Failure ]
crbug.com/635619 virtual/layout_ng/fast/block/float/026.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/float/026.html [ Failure ]
crbug.com/635619 virtual/layout_ng/fast/block/float/027.html [ Failure ]
crbug.com/635619 virtual/layout_ng/fast/block/float/028.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/float/028.html [ Failure ]
crbug.com/635619 virtual/layout_ng/fast/block/float/031.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/float/031.html [ Failure ]
crbug.com/635619 virtual/layout_ng/fast/block/float/035.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/float/035.html [ Failure ]
crbug.com/635619 virtual/layout_ng/fast/block/float/assert-when-moving-float.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/float/assert-when-moving-float.html [ Failure ]
crbug.com/635619 virtual/layout_ng/fast/block/float/assert-when-moving-float-2.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/float/assert-when-moving-float-2.html [ Failure ]
crbug.com/635619 virtual/layout_ng/fast/block/float/avoiding-float-centered.html [ Failure ]
crbug.com/635619 virtual/layout_ng/fast/block/float/block-with-negative-margin-clears-float.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/float/block-with-negative-margin-clears-float.html [ Failure ]
crbug.com/635619 virtual/layout_ng/fast/block/float/br-with-clear-2.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/float/br-with-clear-2.html [ Failure ]
crbug.com/635619 virtual/layout_ng/fast/block/float/centered-float-avoidance-complexity.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/float/centered-float-avoidance-complexity.html [ Failure ]
...@@ -531,14 +529,12 @@ crbug.com/635619 virtual/layout_ng/fast/block/float/rubybase-children-moved-cras ...@@ -531,14 +529,12 @@ crbug.com/635619 virtual/layout_ng/fast/block/float/rubybase-children-moved-cras
crbug.com/635619 virtual/layout_ng/fast/block/float/rubybase-children-moved-crash.html [ Crash Pass ] crbug.com/635619 virtual/layout_ng/fast/block/float/rubybase-children-moved-crash.html [ Crash Pass ]
crbug.com/635619 virtual/layout_ng/fast/block/float/shrink-to-avoid-float-complexity.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/float/shrink-to-avoid-float-complexity.html [ Failure ]
crbug.com/635619 virtual/layout_ng/fast/block/float/trailing-float-with-columns.html [ Crash Failure ] crbug.com/635619 virtual/layout_ng/fast/block/float/trailing-float-with-columns.html [ Crash Failure ]
crbug.com/635619 virtual/layout_ng/fast/block/float/width-update-after-clear.html [ Failure ]
### virtual/layout_ng/fast/block/margin-collapse ### virtual/layout_ng/fast/block/margin-collapse
crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/032.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/032.html [ Failure ]
crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/033.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/033.html [ Failure ]
crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/057.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/057.html [ Failure ]
crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/103.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/103.html [ Failure ]
crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/bfc-beside-float-complex-margin-collapsing.html [ Failure ]
crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/self-collapsing-cols-creates-block-formatting-context.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/self-collapsing-cols-creates-block-formatting-context.html [ Failure ]
### virtual/layout_ng/fast/block/margin-collapse/block-inside-inline ### virtual/layout_ng/fast/block/margin-collapse/block-inside-inline
...@@ -550,7 +546,6 @@ crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/block-inside-inlin ...@@ -550,7 +546,6 @@ crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/block-inside-inlin
### virtual/layout_ng/fast/block/margin-collapse ### virtual/layout_ng/fast/block/margin-collapse
crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/clear-nested-float-more-than-one-previous-sibling-away.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/clear-nested-float-more-than-one-previous-sibling-away.html [ Failure ]
crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/empty-clear-blocks.html [ Failure ]
crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/webkit-margin-collapse-container.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/webkit-margin-collapse-container.html [ Failure ]
crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/webkit-margin-collapse-separate-position.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/webkit-margin-collapse-separate-position.html [ Failure ]
crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/webkit-margin-collapse-siblings.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/webkit-margin-collapse-siblings.html [ Failure ]
......
...@@ -304,7 +304,9 @@ void LayoutTable::UpdateLogicalWidth() { ...@@ -304,7 +304,9 @@ void LayoutTable::UpdateLogicalWidth() {
MinimumValueForLength(Style()->MarginStart(), available_logical_width); MinimumValueForLength(Style()->MarginStart(), available_logical_width);
LayoutUnit margin_end = LayoutUnit margin_end =
MinimumValueForLength(Style()->MarginEnd(), available_logical_width); MinimumValueForLength(Style()->MarginEnd(), available_logical_width);
LayoutUnit margin_total = margin_start + margin_end; LayoutUnit margin_total = RuntimeEnabledFeatures::LayoutNGEnabled()
? LayoutUnit()
: margin_start + margin_end;
// Subtract out our margins to get the available content width. // Subtract out our margins to get the available content width.
LayoutUnit available_content_logical_width = LayoutUnit available_content_logical_width =
...@@ -312,7 +314,8 @@ void LayoutTable::UpdateLogicalWidth() { ...@@ -312,7 +314,8 @@ void LayoutTable::UpdateLogicalWidth() {
.ClampNegativeToZero(); .ClampNegativeToZero();
if (ShrinkToAvoidFloats() && cb->IsLayoutBlockFlow() && if (ShrinkToAvoidFloats() && cb->IsLayoutBlockFlow() &&
ToLayoutBlockFlow(cb)->ContainsFloats() && ToLayoutBlockFlow(cb)->ContainsFloats() &&
!has_perpendicular_containing_block) !has_perpendicular_containing_block &&
!RuntimeEnabledFeatures::LayoutNGEnabled())
available_content_logical_width = ShrinkLogicalWidthToAvoidFloats( available_content_logical_width = ShrinkLogicalWidthToAvoidFloats(
margin_start, margin_end, ToLayoutBlockFlow(cb)); margin_start, margin_end, ToLayoutBlockFlow(cb));
......
...@@ -59,6 +59,7 @@ bool ClearanceMayAffectLayout( ...@@ -59,6 +59,7 @@ bool ClearanceMayAffectLayout(
// through", etc. // through", etc.
bool IsEmptyBlock(const NGLayoutInputNode child, bool IsEmptyBlock(const NGLayoutInputNode child,
const NGLayoutResult& layout_result) { const NGLayoutResult& layout_result) {
// TODO(ikilpatrick): This should be a DCHECK.
if (child.CreatesNewFormattingContext()) if (child.CreatesNewFormattingContext())
return false; return false;
...@@ -491,82 +492,74 @@ bool NGBlockLayoutAlgorithm::HandleNewFormattingContext( ...@@ -491,82 +492,74 @@ bool NGBlockLayoutAlgorithm::HandleNewFormattingContext(
DCHECK(child.CreatesNewFormattingContext()); DCHECK(child.CreatesNewFormattingContext());
const ComputedStyle& child_style = child.Style(); const ComputedStyle& child_style = child.Style();
const EClear child_clear = child_style.Clear();
const TextDirection direction = ConstraintSpace().Direction(); const TextDirection direction = ConstraintSpace().Direction();
// Perform layout on the child. bool is_fixed_inline_size =
(IsHorizontalWritingMode(ConstraintSpace().WritingMode())
? child_style.Width().IsAuto()
: child_style.Height().IsAuto()) &&
IsParallelWritingMode(
ConstraintSpace().WritingMode(),
FromPlatformWritingMode(child_style.GetWritingMode())) &&
!child.ShouldBeConsideredAsReplaced();
NGInflowChildData child_data = NGInflowChildData child_data =
ComputeChildData(*previous_inflow_position, child, child_break_token); ComputeChildData(*previous_inflow_position, child, child_break_token);
RefPtr<NGConstraintSpace> child_space =
CreateConstraintSpaceForChild(child, child_data);
RefPtr<NGLayoutResult> layout_result =
child.Layout(*child_space, child_break_token);
// We must have an actual fragment at this stage. NGMarginStrut adjoining_margin_strut(previous_inflow_position->margin_strut);
DCHECK(layout_result->PhysicalFragment()); adjoining_margin_strut.Append(child_data.margins.block_start,
const auto& physical_fragment = *layout_result->PhysicalFragment(); child_style.HasMarginBeforeQuirk());
NGFragment fragment(ConstraintSpace().WritingMode(), physical_fragment);
LayoutUnit child_bfc_offset_estimate = LayoutUnit child_bfc_offset_estimate =
child_data.bfc_offset_estimate.block_offset; child_data.bfc_offset_estimate.block_offset +
adjoining_margin_strut.Sum();
// 1. Position all pending floats to a temporary space, which is a copy of
// the current exclusion space.
NGExclusionSpace tmp_exclusion_space(*exclusion_space_);
PositionFloats(child_bfc_offset_estimate, child_bfc_offset_estimate,
unpositioned_floats_, ConstraintSpace(),
container_builder_.Size().inline_size, &tmp_exclusion_space);
NGBfcOffset origin_offset = {
ConstraintSpace().BfcOffset().line_offset +
border_scrollbar_padding_.LineLeft(direction) +
child_data.margins.LineLeft(direction),
child_bfc_offset_estimate};
AdjustToClearance(tmp_exclusion_space.ClearanceOffset(child_clear),
&origin_offset);
// 2. Find an estimated layout opportunity for our fragment.
NGLogicalSize fragment_size(fragment.InlineSize(), fragment.BlockSize());
// TODO(ikilpatrick): child_space.AvailableSize() is probably wrong as the
// area we need to search shrinks by the origin_offset and LineRight margin.
NGLayoutOpportunity opportunity = tmp_exclusion_space.FindLayoutOpportunity(
origin_offset, child_space->AvailableSize(), fragment_size);
NGMarginStrut margin_strut = previous_inflow_position->margin_strut; NGLayoutOpportunity opportunity;
RefPtr<NGLayoutResult> layout_result;
std::tie(layout_result, opportunity) =
LayoutNewFormattingContext(child, child_break_token, is_fixed_inline_size,
child_data, child_bfc_offset_estimate);
// 3. If the found opportunity lies on the same line with our estimated DCHECK(layout_result->PhysicalFragment());
// child's BFC offset then merge fragment's margins with the current LayoutUnit fragment_block_size =
// MarginStrut. NGFragment(ConstraintSpace().WritingMode(),
if (opportunity.offset.block_offset == child_bfc_offset_estimate) *layout_result->PhysicalFragment())
margin_strut.Append(child_data.margins.block_start, .BlockSize();
child_style.HasMarginBeforeQuirk());
child_bfc_offset_estimate += margin_strut.Sum(); // We allow a single re-layout for new formatting contexts. If the first
// layout doesn't produce which fragment which sends up at the top of the
// exclusion space, or it just doesn't fit, we relayout with a
// *non*-adjoining margin strut.
//
// This re-layout *must* produce a fragment and opportunity which fits within
// the exclusion space.
if (opportunity.offset.block_offset != child_bfc_offset_estimate ||
(is_fixed_inline_size && fragment_block_size > opportunity.BlockSize())) {
NGMarginStrut non_adjoining_margin_strut(
previous_inflow_position->margin_strut);
child_bfc_offset_estimate = child_data.bfc_offset_estimate.block_offset +
non_adjoining_margin_strut.Sum();
std::tie(layout_result, opportunity) = LayoutNewFormattingContext(
child, child_break_token, is_fixed_inline_size, child_data,
child_bfc_offset_estimate);
}
// 4. The child's BFC block offset is known here. // We now know the childs BFC offset, try and update our own if needed.
bool updated = MaybeUpdateFragmentBfcOffset( bool updated = MaybeUpdateFragmentBfcOffset(
ConstraintSpace(), child_bfc_offset_estimate, &container_builder_); ConstraintSpace(), child_bfc_offset_estimate, &container_builder_);
if (updated && abort_when_bfc_resolved_) if (updated && abort_when_bfc_resolved_)
return false; return false;
// Position any pending floats if we've just updated our BFC offset.
PositionPendingFloats(ConstraintSpace(), child_bfc_offset_estimate, PositionPendingFloats(ConstraintSpace(), child_bfc_offset_estimate,
&container_builder_, &unpositioned_floats_, &container_builder_, &unpositioned_floats_,
exclusion_space_.get()); exclusion_space_.get());
origin_offset = {ConstraintSpace().BfcOffset().line_offset + DCHECK(layout_result->PhysicalFragment());
border_scrollbar_padding_.LineLeft(direction) + const auto& physical_fragment = *layout_result->PhysicalFragment();
child_data.margins.LineLeft(direction), NGFragment fragment(ConstraintSpace().WritingMode(), physical_fragment);
child_bfc_offset_estimate};
AdjustToClearance(exclusion_space_->ClearanceOffset(child_clear),
&origin_offset);
// 5. Find the final layout opportunity for the fragment after all pending
// floats are positioned at the correct BFC block's offset.
// TODO(ikilpatrick): child_space.AvailableSize() is probably wrong as the
// area we need to search shrinks by the origin_offset and LineRight margin.
opportunity = exclusion_space_->FindLayoutOpportunity(
origin_offset, child_space->AvailableSize(), fragment_size);
// Auto-margins are applied within the layout opportunity which fits. // Auto-margins are applied within the layout opportunity which fits.
// TODO(ikilpatrick): Some of these calculations should be pulled into // TODO(ikilpatrick): Some of these calculations should be pulled into
...@@ -585,9 +578,6 @@ bool NGBlockLayoutAlgorithm::HandleNewFormattingContext( ...@@ -585,9 +578,6 @@ bool NGBlockLayoutAlgorithm::HandleNewFormattingContext(
LayoutUnit line_left_auto_margin = LayoutUnit line_left_auto_margin =
is_line_left_auto_margin ? margins.LineLeft(direction) : LayoutUnit(); is_line_left_auto_margin ? margins.LineLeft(direction) : LayoutUnit();
// We try and position the child within the block formatting context. This
// may cause our BFC offset to be resolved, in which case we should abort our
// layout if needed.
NGBfcOffset child_bfc_offset( NGBfcOffset child_bfc_offset(
opportunity.offset.line_offset + line_left_auto_margin, opportunity.offset.line_offset + line_left_auto_margin,
opportunity.offset.block_offset); opportunity.offset.block_offset);
...@@ -627,9 +617,116 @@ bool NGBlockLayoutAlgorithm::HandleNewFormattingContext( ...@@ -627,9 +617,116 @@ bool NGBlockLayoutAlgorithm::HandleNewFormattingContext(
*previous_inflow_position, child, child_data, child_bfc_offset, *previous_inflow_position, child, child_data, child_bfc_offset,
logical_offset, *layout_result, fragment, logical_offset, *layout_result, fragment,
/* empty_block_affected_by_clearance */ false); /* empty_block_affected_by_clearance */ false);
return true; return true;
} }
std::pair<RefPtr<NGLayoutResult>, NGLayoutOpportunity>
NGBlockLayoutAlgorithm::LayoutNewFormattingContext(
NGLayoutInputNode child,
NGBreakToken* child_break_token,
bool is_fixed_inline_size,
const NGInflowChildData& child_data,
LayoutUnit child_origin_block_offset) {
const ComputedStyle& child_style = child.Style();
const EClear child_clear = child_style.Clear();
const TextDirection direction = ConstraintSpace().Direction();
LayoutUnit child_bfc_line_offset =
ConstraintSpace().BfcOffset().line_offset +
border_scrollbar_padding_.LineLeft(direction) +
child_data.margins.LineLeft(direction);
// Position all the pending floats into a temporary exclusion space. This
// *doesn't* place them into our output exclusion space yet, as we don't know
// where the child will be positioned, and hence what *out* BFC offset is.
// If we already know our BFC offset, this won't have any affect.
NGExclusionSpace tmp_exclusion_space(*exclusion_space_);
PositionFloats(child_origin_block_offset, child_origin_block_offset,
unpositioned_floats_, ConstraintSpace(),
container_builder_.Size().inline_size, &tmp_exclusion_space);
// The origin offset is where we should start looking for layout
// opportunities. It needs to be adjusted by the child's clearance, in
// addition to the parent's (if we don't know our BFC offset yet).
NGBfcOffset origin_offset = {child_bfc_line_offset,
child_origin_block_offset};
AdjustToClearance(tmp_exclusion_space.ClearanceOffset(child_clear),
&origin_offset);
if (!container_builder_.BfcOffset())
AdjustToClearance(ConstraintSpace().ClearanceOffset(), &origin_offset);
// TODO(ikilpatrick): min_max_size, max_inline_size, min_inline_size,
// is_fixed_inline_size, should be computed in ComputeChildData. This will
// allow us to handle 'auto' in the parent by assigning a fixed size to our
// children. This will require us to remove the requirement that
// ResolveInlineLength to take a constraint space, instead taking a
// {writing_mode, available_size, percentage_size} struct.
RefPtr<NGConstraintSpace> child_space =
CreateConstraintSpaceForChild(child, child_data);
WTF::Optional<MinMaxSize> min_max_size;
if (NeedMinMaxSize(*child_space, child_style))
min_max_size = child.ComputeMinMaxSize();
Optional<LayoutUnit> max_inline_size;
if (!child_style.LogicalMaxWidth().IsMaxSizeNone()) {
max_inline_size = ResolveInlineLength(
*child_space, child_style, min_max_size, child_style.LogicalMaxWidth(),
LengthResolveType::kMaxSize);
}
Optional<LayoutUnit> min_inline_size = ResolveInlineLength(
*child_space, child_style, min_max_size, child_style.LogicalMinWidth(),
LengthResolveType::kMinSize);
// Adjust the area we search for layout opportunities by the child's margins.
LayoutUnit child_available_inline_size =
std::max(LayoutUnit(), child_available_size_.inline_size -
child_data.margins.InlineSum());
NGLogicalSize child_available_size(child_available_inline_size,
LayoutUnit(-1));
// If we have should have a fixed inline size, we find a layout opportunity
// before layout, then fixed our child to that size.
WTF::Optional<NGLayoutOpportunity> opportunity;
WTF::Optional<LayoutUnit> fixed_inline_size;
if (is_fixed_inline_size) {
// TODO(ikilpatrick): This actually needs to take into account the border
// and padding of the child for the minimum layout opportunity size.
// TODO(ikilpatrick): min_inline_size should be applied before finding the
// layout opportunity.
// TODO(ikilpatrick): During the second layout pass of new formatting
// contexts, we actually need to find the first "open" layout opportunity.
// TODO(ikilpatrick): Investigate tables 'auto' size as this is subtly
// different to normal 'auto' sizing behaviour.
opportunity = tmp_exclusion_space.FindLayoutOpportunity(
origin_offset, child_available_size, NGLogicalSize());
fixed_inline_size = ConstrainByMinMax(opportunity->InlineSize(),
min_inline_size, max_inline_size);
}
child_space = CreateConstraintSpaceForChild(child, child_data, WTF::nullopt,
fixed_inline_size);
RefPtr<NGLayoutResult> layout_result =
child.Layout(*child_space, child_break_token);
DCHECK(layout_result->PhysicalFragment());
// If we didn't have a fixed inline size, we now search for the layout
// opportunity we fit into.
if (!opportunity) {
NGFragment fragment(ConstraintSpace().WritingMode(),
*layout_result->PhysicalFragment());
// TODO(ikilpatrick): child_available_size is probably wrong as the area we
// need to search shrinks by the origin_offset and LineRight margin.
opportunity = tmp_exclusion_space.FindLayoutOpportunity(
origin_offset, child_available_size,
NGLogicalSize{fragment.InlineSize(), fragment.BlockSize()});
}
return std::make_pair(std::move(layout_result), opportunity.value());
}
bool NGBlockLayoutAlgorithm::HandleInflow( bool NGBlockLayoutAlgorithm::HandleInflow(
NGLayoutInputNode child, NGLayoutInputNode child,
NGBreakToken* child_break_token, NGBreakToken* child_break_token,
...@@ -637,6 +734,7 @@ bool NGBlockLayoutAlgorithm::HandleInflow( ...@@ -637,6 +734,7 @@ bool NGBlockLayoutAlgorithm::HandleInflow(
DCHECK(child); DCHECK(child);
DCHECK(!child.IsFloating()); DCHECK(!child.IsFloating());
DCHECK(!child.IsOutOfFlowPositioned()); DCHECK(!child.IsOutOfFlowPositioned());
DCHECK(!child.CreatesNewFormattingContext());
// TODO(ikilpatrick): We may only want to position pending floats if there is // TODO(ikilpatrick): We may only want to position pending floats if there is
// something that we *might* clear in the unpositioned list. E.g. we may // something that we *might* clear in the unpositioned list. E.g. we may
...@@ -1128,10 +1226,19 @@ NGBoxStrut NGBlockLayoutAlgorithm::CalculateMargins( ...@@ -1128,10 +1226,19 @@ NGBoxStrut NGBlockLayoutAlgorithm::CalculateMargins(
RefPtr<NGConstraintSpace> NGBlockLayoutAlgorithm::CreateConstraintSpaceForChild( RefPtr<NGConstraintSpace> NGBlockLayoutAlgorithm::CreateConstraintSpaceForChild(
const NGLayoutInputNode child, const NGLayoutInputNode child,
const NGInflowChildData& child_data, const NGInflowChildData& child_data,
const WTF::Optional<NGBfcOffset> floats_bfc_offset) { const WTF::Optional<NGBfcOffset> floats_bfc_offset,
const WTF::Optional<LayoutUnit> fixed_inline_size) {
NGConstraintSpaceBuilder space_builder(ConstraintSpace()); NGConstraintSpaceBuilder space_builder(ConstraintSpace());
space_builder.SetAvailableSize(child_available_size_)
.SetPercentageResolutionSize(child_percentage_size_); NGLogicalSize available_size(child_available_size_);
NGLogicalSize percentage_size(child_percentage_size_);
if (fixed_inline_size) {
space_builder.SetIsFixedSizeInline(true);
available_size.inline_size = fixed_inline_size.value();
percentage_size.inline_size = fixed_inline_size.value();
}
space_builder.SetAvailableSize(available_size)
.SetPercentageResolutionSize(percentage_size);
if (NGBaseline::ShouldPropagateBaselines(child)) if (NGBaseline::ShouldPropagateBaselines(child))
space_builder.AddBaselineRequests(ConstraintSpace().BaselineRequests()); space_builder.AddBaselineRequests(ConstraintSpace().BaselineRequests());
......
...@@ -74,7 +74,8 @@ class CORE_EXPORT NGBlockLayoutAlgorithm ...@@ -74,7 +74,8 @@ class CORE_EXPORT NGBlockLayoutAlgorithm
RefPtr<NGConstraintSpace> CreateConstraintSpaceForChild( RefPtr<NGConstraintSpace> CreateConstraintSpaceForChild(
const NGLayoutInputNode child, const NGLayoutInputNode child,
const NGInflowChildData& child_data, const NGInflowChildData& child_data,
const WTF::Optional<NGBfcOffset> floats_bfc_offset = WTF::nullopt); const WTF::Optional<NGBfcOffset> floats_bfc_offset = WTF::nullopt,
const WTF::Optional<LayoutUnit> fixed_inline_size = WTF::nullopt);
// @return Estimated BFC offset for the "to be layout" child. // @return Estimated BFC offset for the "to be layout" child.
NGInflowChildData ComputeChildData(const NGPreviousInflowPosition&, NGInflowChildData ComputeChildData(const NGPreviousInflowPosition&,
...@@ -91,7 +92,6 @@ class CORE_EXPORT NGBlockLayoutAlgorithm ...@@ -91,7 +92,6 @@ class CORE_EXPORT NGBlockLayoutAlgorithm
const NGFragment& fragment, const NGFragment& fragment,
bool empty_block_affected_by_clearance); bool empty_block_affected_by_clearance);
// Positions the fragment that knows its BFC offset. // Positions the fragment that knows its BFC offset.
WTF::Optional<NGBfcOffset> PositionWithBfcOffset( WTF::Optional<NGBfcOffset> PositionWithBfcOffset(
const NGBfcOffset& bfc_offset); const NGBfcOffset& bfc_offset);
...@@ -137,6 +137,15 @@ class CORE_EXPORT NGBlockLayoutAlgorithm ...@@ -137,6 +137,15 @@ class CORE_EXPORT NGBlockLayoutAlgorithm
NGBreakToken* child_break_token, NGBreakToken* child_break_token,
NGPreviousInflowPosition*); NGPreviousInflowPosition*);
// Performs the actual layout of a new formatting context. This may be called
// multiple times from HandleNewFormattingContext.
std::pair<RefPtr<NGLayoutResult>, NGLayoutOpportunity>
LayoutNewFormattingContext(NGLayoutInputNode child,
NGBreakToken* child_break_token,
bool is_auto_inline_size,
const NGInflowChildData&,
LayoutUnit child_origin_block_offset);
// Handle an in-flow child. // Handle an in-flow child.
// Returns false if we need to abort layout, because a previously unknown BFC // Returns false if we need to abort layout, because a previously unknown BFC
// offset has now been resolved. (Same as HandleNewFormattingContext). // offset has now been resolved. (Same as HandleNewFormattingContext).
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "core/layout/LayoutBlockFlow.h" #include "core/layout/LayoutBlockFlow.h"
#include "core/layout/LayoutMultiColumnFlowThread.h" #include "core/layout/LayoutMultiColumnFlowThread.h"
#include "core/layout/LayoutMultiColumnSet.h" #include "core/layout/LayoutMultiColumnSet.h"
#include "core/layout/LayoutTable.h"
#include "core/layout/MinMaxSize.h" #include "core/layout/MinMaxSize.h"
#include "core/layout/ng/inline/ng_inline_node.h" #include "core/layout/ng/inline/ng_inline_node.h"
#include "core/layout/ng/layout_ng_block_flow.h" #include "core/layout/ng/layout_ng_block_flow.h"
...@@ -488,16 +489,19 @@ RefPtr<NGLayoutResult> NGBlockNode::RunOldLayout( ...@@ -488,16 +489,19 @@ RefPtr<NGLayoutResult> NGBlockNode::RunOldLayout(
box_->SetOverrideContainingBlockContentLogicalHeight( box_->SetOverrideContainingBlockContentLogicalHeight(
available_size.inline_size); available_size.inline_size);
} }
// TODO(layout-ng): Does this handle scrollbars correctly? // TODO(layout-ng): Does this handle scrollbars correctly?
if (constraint_space.IsFixedSizeInline()) { if (constraint_space.IsFixedSizeInline()) {
box_->SetOverrideLogicalContentWidth( box_->SetOverrideLogicalContentWidth(
constraint_space.AvailableSize().inline_size - (constraint_space.AvailableSize().inline_size -
box_->BorderAndPaddingLogicalWidth()); box_->BorderAndPaddingLogicalWidth())
.ClampNegativeToZero());
} }
if (constraint_space.IsFixedSizeBlock()) { if (constraint_space.IsFixedSizeBlock()) {
box_->SetOverrideLogicalContentHeight( box_->SetOverrideLogicalContentHeight(
constraint_space.AvailableSize().block_size - (constraint_space.AvailableSize().block_size -
box_->BorderAndPaddingLogicalHeight()); box_->BorderAndPaddingLogicalHeight())
.ClampNegativeToZero());
} }
if (box_->IsLayoutNGBlockFlow() && box_->NeedsLayout()) { if (box_->IsLayoutNGBlockFlow() && box_->NeedsLayout()) {
......
...@@ -77,6 +77,10 @@ bool NGLayoutInputNode::IsReplaced() const { ...@@ -77,6 +77,10 @@ bool NGLayoutInputNode::IsReplaced() const {
return box_->IsLayoutReplaced(); return box_->IsLayoutReplaced();
} }
bool NGLayoutInputNode::ShouldBeConsideredAsReplaced() const {
return box_->ShouldBeConsideredAsReplaced();
}
bool NGLayoutInputNode::IsQuirkyContainer() const { bool NGLayoutInputNode::IsQuirkyContainer() const {
return box_->GetDocument().InQuirksMode() && return box_->GetDocument().InQuirksMode() &&
(box_->IsBody() || box_->IsTableCell()); (box_->IsBody() || box_->IsTableCell());
......
...@@ -42,6 +42,7 @@ class CORE_EXPORT NGLayoutInputNode { ...@@ -42,6 +42,7 @@ class CORE_EXPORT NGLayoutInputNode {
bool IsReplaced() const; bool IsReplaced() const;
bool IsAbsoluteContainer() const; bool IsAbsoluteContainer() const;
bool IsFixedContainer() const; bool IsFixedContainer() const;
bool ShouldBeConsideredAsReplaced() const;
// If the node is a quirky container for margin collapsing, see: // If the node is a quirky container for margin collapsing, see:
// https://html.spec.whatwg.org/#margin-collapsing-quirks // https://html.spec.whatwg.org/#margin-collapsing-quirks
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment