Commit da3d3705 authored by David Grogan's avatar David Grogan Committed by Commit Bot

[FlexNG] Subtract inline margins from available size

When laying out items in a column container for flex basis calculation,
we have to subtract inline margins from the container width to get the
right available width for the items.

This also fixes the browser test
PrintPreviewPagesSettingsTest.InvalidPageRanges
which used to crash.

Bug: 845235
Change-Id: Ie9382c0e6cfa89333fc92c2bc4eb8e95c592c923
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2106821
Commit-Queue: David Grogan <dgrogan@chromium.org>
Reviewed-by: default avatarIan Kilpatrick <ikilpatrick@chromium.org>
Cr-Commit-Position: refs/heads/master@{#751205}
parent a69aa65f
...@@ -325,7 +325,8 @@ double NGFlexLayoutAlgorithm::GetMainOverCrossAspectRatio( ...@@ -325,7 +325,8 @@ double NGFlexLayoutAlgorithm::GetMainOverCrossAspectRatio(
} }
NGConstraintSpace NGFlexLayoutAlgorithm::BuildSpaceForIntrinsicBlockSize( NGConstraintSpace NGFlexLayoutAlgorithm::BuildSpaceForIntrinsicBlockSize(
const NGBlockNode& flex_item) const { const NGBlockNode& flex_item,
const NGPhysicalBoxStrut& physical_margins) const {
const ComputedStyle& child_style = flex_item.Style(); const ComputedStyle& child_style = flex_item.Style();
NGConstraintSpaceBuilder space_builder(ConstraintSpace(), NGConstraintSpaceBuilder space_builder(ConstraintSpace(),
child_style.GetWritingMode(), child_style.GetWritingMode(),
...@@ -334,16 +335,25 @@ NGConstraintSpace NGFlexLayoutAlgorithm::BuildSpaceForIntrinsicBlockSize( ...@@ -334,16 +335,25 @@ NGConstraintSpace NGFlexLayoutAlgorithm::BuildSpaceForIntrinsicBlockSize(
space_builder.SetCacheSlot(NGCacheSlot::kMeasure); space_builder.SetCacheSlot(NGCacheSlot::kMeasure);
space_builder.SetIsPaintedAtomically(true); space_builder.SetIsPaintedAtomically(true);
if (ShouldItemShrinkToFit(flex_item)) NGBoxStrut margins = physical_margins.ConvertToLogical(
ConstraintSpace().GetWritingMode(), Style().Direction());
LogicalSize child_available_size = content_box_size_;
if (ShouldItemShrinkToFit(flex_item)) {
space_builder.SetIsShrinkToFit(true); space_builder.SetIsShrinkToFit(true);
// TODO(dgrogan): Do you need to account for item's min and max cross sizes } else if (WillChildCrossSizeBeContainerCrossSize(flex_item)) {
// before SetIsFixed{Inline,Block}Size(true) ? // TODO(dgrogan): Do you need to further adjust available size by item's min
if (WillChildCrossSizeBeContainerCrossSize(flex_item)) { // and max cross sizes before SetIsFixed{Inline,Block}Size(true) ?
if (is_column_) { if (is_column_) {
space_builder.SetIsFixedInlineSize(true); space_builder.SetIsFixedInlineSize(true);
child_available_size.inline_size =
(child_available_size.inline_size - margins.InlineSum())
.ClampNegativeToZero();
} else { } else {
space_builder.SetIsFixedBlockSize(true); space_builder.SetIsFixedBlockSize(true);
DCHECK_NE(content_box_size_.block_size, kIndefiniteSize); DCHECK_NE(content_box_size_.block_size, kIndefiniteSize);
child_available_size.block_size =
(child_available_size.block_size - margins.BlockSum())
.ClampNegativeToZero();
} }
} }
...@@ -358,10 +368,10 @@ NGConstraintSpace NGFlexLayoutAlgorithm::BuildSpaceForIntrinsicBlockSize( ...@@ -358,10 +368,10 @@ NGConstraintSpace NGFlexLayoutAlgorithm::BuildSpaceForIntrinsicBlockSize(
if (is_column_) if (is_column_)
child_percentage_size.block_size = kIndefiniteSize; child_percentage_size.block_size = kIndefiniteSize;
space_builder.SetAvailableSize(child_available_size);
space_builder.SetPercentageResolutionSize(child_percentage_size);
// TODO(dgrogan): The SetReplacedPercentageResolutionSize calls in this file // TODO(dgrogan): The SetReplacedPercentageResolutionSize calls in this file
// may be untested. Write a test or determine why they're unnecessary. // may be untested. Write a test or determine why they're unnecessary.
space_builder.SetAvailableSize(content_box_size_);
space_builder.SetPercentageResolutionSize(child_percentage_size);
space_builder.SetReplacedPercentageResolutionSize(child_percentage_size); space_builder.SetReplacedPercentageResolutionSize(child_percentage_size);
space_builder.SetTextDirection(child_style.Direction()); space_builder.SetTextDirection(child_style.Direction());
return space_builder.ToConstraintSpace(); return space_builder.ToConstraintSpace();
...@@ -394,6 +404,9 @@ void NGFlexLayoutAlgorithm::ConstructAndAppendFlexItems() { ...@@ -394,6 +404,9 @@ void NGFlexLayoutAlgorithm::ConstructAndAppendFlexItems() {
const ComputedStyle& child_style = child.Style(); const ComputedStyle& child_style = child.Style();
NGConstraintSpace flex_basis_space = BuildSpaceForFlexBasis(child); NGConstraintSpace flex_basis_space = BuildSpaceForFlexBasis(child);
NGPhysicalBoxStrut physical_child_margins =
ComputePhysicalMargins(flex_basis_space, child_style);
NGBoxStrut border_padding_in_child_writing_mode = NGBoxStrut border_padding_in_child_writing_mode =
ComputeBorders(flex_basis_space, child_style) + ComputeBorders(flex_basis_space, child_style) +
ComputePadding(flex_basis_space, child_style); ComputePadding(flex_basis_space, child_style);
...@@ -412,7 +425,8 @@ void NGFlexLayoutAlgorithm::ConstructAndAppendFlexItems() { ...@@ -412,7 +425,8 @@ void NGFlexLayoutAlgorithm::ConstructAndAppendFlexItems() {
base::Optional<LayoutUnit> intrinsic_block_size; base::Optional<LayoutUnit> intrinsic_block_size;
auto IntrinsicBlockSizeFunc = [&]() -> LayoutUnit { auto IntrinsicBlockSizeFunc = [&]() -> LayoutUnit {
if (!intrinsic_block_size) { if (!intrinsic_block_size) {
NGConstraintSpace child_space = BuildSpaceForIntrinsicBlockSize(child); NGConstraintSpace child_space =
BuildSpaceForIntrinsicBlockSize(child, physical_child_margins);
intrinsic_block_size = intrinsic_block_size =
child.Layout(child_space, /* break_token */ nullptr) child.Layout(child_space, /* break_token */ nullptr)
->IntrinsicBlockSize(); ->IntrinsicBlockSize();
...@@ -423,14 +437,15 @@ void NGFlexLayoutAlgorithm::ConstructAndAppendFlexItems() { ...@@ -423,14 +437,15 @@ void NGFlexLayoutAlgorithm::ConstructAndAppendFlexItems() {
base::Optional<MinMaxSizes> min_max_size; base::Optional<MinMaxSizes> min_max_size;
auto MinMaxSizesFunc = [&]() -> MinMaxSizes { auto MinMaxSizesFunc = [&]() -> MinMaxSizes {
if (!min_max_size) { if (!min_max_size) {
// We want the child's min/max size in its writing mode, not ours. NGConstraintSpace child_space =
// We'll only ever use it if the child's inline axis is our main axis. BuildSpaceForIntrinsicBlockSize(child, physical_child_margins);
NGConstraintSpace child_space = BuildSpaceForIntrinsicBlockSize(child);
if (child.Style().OverflowBlockDirection() == EOverflow::kAuto) { if (child.Style().OverflowBlockDirection() == EOverflow::kAuto) {
// Ensure this child has been laid out so its auto scrollbars are // Ensure this child has been laid out so its auto scrollbars are
// included in its intrinsic sizes. // included in its intrinsic sizes.
IntrinsicBlockSizeFunc(); IntrinsicBlockSizeFunc();
} }
// We want the child's min/max size in its writing mode, not ours.
// We'll only ever use it if the child's inline axis is our main axis.
min_max_size = child.ComputeMinMaxSizes( min_max_size = child.ComputeMinMaxSizes(
child_style.GetWritingMode(), child_style.GetWritingMode(),
MinMaxSizesInput(content_box_size_.block_size), &child_space); MinMaxSizesInput(content_box_size_.block_size), &child_space);
...@@ -690,8 +705,6 @@ void NGFlexLayoutAlgorithm::ConstructAndAppendFlexItems() { ...@@ -690,8 +705,6 @@ void NGFlexLayoutAlgorithm::ConstructAndAppendFlexItems() {
// TODO(dgrogan): Should min_max_sizes_in_cross_axis_direction include // TODO(dgrogan): Should min_max_sizes_in_cross_axis_direction include
// cross_axis_border_padding? // cross_axis_border_padding?
NGPhysicalBoxStrut physical_child_margins =
ComputePhysicalMargins(flex_basis_space, child_style);
algorithm_ algorithm_
->emplace_back(nullptr, child.Style(), flex_base_content_size, ->emplace_back(nullptr, child.Style(), flex_base_content_size,
min_max_sizes_in_main_axis_direction, min_max_sizes_in_main_axis_direction,
......
...@@ -52,7 +52,8 @@ class CORE_EXPORT NGFlexLayoutAlgorithm ...@@ -52,7 +52,8 @@ class CORE_EXPORT NGFlexLayoutAlgorithm
NGConstraintSpace BuildSpaceForFlexBasis(const NGBlockNode& flex_item) const; NGConstraintSpace BuildSpaceForFlexBasis(const NGBlockNode& flex_item) const;
NGConstraintSpace BuildSpaceForIntrinsicBlockSize( NGConstraintSpace BuildSpaceForIntrinsicBlockSize(
const NGBlockNode& flex_item) const; const NGBlockNode& flex_item,
const NGPhysicalBoxStrut& physical_margins) const;
void ConstructAndAppendFlexItems(); void ConstructAndAppendFlexItems();
void ApplyStretchAlignmentToChild(FlexItem& flex_item); void ApplyStretchAlignmentToChild(FlexItem& flex_item);
void GiveLinesAndItemsFinalPositionAndSize(); void GiveLinesAndItemsFinalPositionAndSize();
......
<!DOCTYPE html>
<title>Flexbox: margins and available space</title>
<link rel="author" title="David Grogan" href="mailto:dgrogan@chromium.org">
<link rel="help" href="https://drafts.csswg.org/css-flexbox/#algo-main-item" title="Case E">
<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
<meta name="flags" content="" />
<meta name="assert" content="An item's inline margins are subtracted from available space when laying out to determine flex-basis in a column container." />
<style>
.inline-block {
display: inline-block;
width: 40px;
height: 50px;
}
#reference-overlapped-red {
position: absolute;
background-color: red;
width: 100px;
height: 100px;
z-index: -1;
}
</style>
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div id="reference-overlapped-red"></div>
<div style="display: flex; flex-direction: column; width: 100px; background: green;">
<!-- 21px makes the inline-blocks wrap -->
<div style="margin-right: 21px; flex: 0 0 auto; line-height: 0px;">
<div class="inline-block"></div><div class="inline-block"></div>
</div>
</div>
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