Commit 6cc4c310 authored by David Grogan's avatar David Grogan Committed by Commit Bot

[LayoutNG] Don't always make a post-flexed main size definite

It should only be definite if the element already had a definite main
size or if the container has a definite main size.

This is #2 from https://drafts.csswg.org/css-flexbox/#definite-sizes

Bug: 845235
Change-Id: I0230080d22ada93ebc8bae09aeda629d87cf5b6d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1797442Reviewed-by: default avatarChristian Biesinger <cbiesinger@chromium.org>
Commit-Queue: David Grogan <dgrogan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#698790}
parent 2afc1cd0
...@@ -61,6 +61,18 @@ void NGFlexLayoutAlgorithm::HandleOutOfFlowPositioned(NGBlockNode child) { ...@@ -61,6 +61,18 @@ void NGFlexLayoutAlgorithm::HandleOutOfFlowPositioned(NGBlockNode child) {
border_scrollbar_padding_.block_start}); border_scrollbar_padding_.block_start});
} }
bool NGFlexLayoutAlgorithm::IsColumnContainerMainSizeDefinite() const {
DCHECK(is_column_);
// If this flex container is also a flex item, it might have a definite size
// imposed on it by its parent flex container.
if (ConstraintSpace().IsFixedBlockSize() &&
!ConstraintSpace().IsFixedBlockSizeIndefinite())
return true;
Length main_size = Style().LogicalHeight();
return !BlockLengthUnresolvable(ConstraintSpace(), main_size,
LengthResolvePhase::kLayout);
}
bool NGFlexLayoutAlgorithm::IsContainerCrossSizeDefinite() const { bool NGFlexLayoutAlgorithm::IsContainerCrossSizeDefinite() const {
// A column flexbox's cross axis is an inline size, so is definite. // A column flexbox's cross axis is an inline size, so is definite.
if (is_column_) if (is_column_)
...@@ -92,6 +104,28 @@ bool NGFlexLayoutAlgorithm::DoesItemStretch(const NGBlockNode& child) const { ...@@ -92,6 +104,28 @@ bool NGFlexLayoutAlgorithm::DoesItemStretch(const NGBlockNode& child) const {
ItemPosition::kStretch; ItemPosition::kStretch;
} }
// This behavior is under discussion: the item's pre-flexing main size
// definiteness may no longer imply post-flexing definiteness.
// TODO(dgrogan): Have https://crbug.com/1003506 and
// https://github.com/w3c/csswg-drafts/issues/4305 been resolved yet?
bool NGFlexLayoutAlgorithm::IsItemMainSizeDefinite(
const NGBlockNode& child) const {
DCHECK(is_column_);
// Inline sizes are always definite.
// TODO(dgrogan): The relevant tests, the last two cases in
// css/css-flexbox/percentage-heights-003.html passed even without this, so it
// may be untested or unnecessary.
if (MainAxisIsInlineAxis(child))
return true;
// We need a constraint space for the child to determine resolvability and the
// space for flex-basis is sufficient, even though it has some unnecessary
// stuff (ShrinkToFit and fixed cross sizes).
NGConstraintSpace child_space =
BuildConstraintSpaceForDeterminingFlexBasis(child);
return !BlockLengthUnresolvable(child_space, child.Style().LogicalHeight(),
LengthResolvePhase::kLayout);
}
bool NGFlexLayoutAlgorithm::DoesItemCrossSizeComputeToAuto( bool NGFlexLayoutAlgorithm::DoesItemCrossSizeComputeToAuto(
const NGBlockNode& child) const { const NGBlockNode& child) const {
const ComputedStyle& child_style = child.Style(); const ComputedStyle& child_style = child.Style();
...@@ -145,6 +179,33 @@ bool NGFlexLayoutAlgorithm::WillChildCrossSizeBeContainerCrossSize( ...@@ -145,6 +179,33 @@ bool NGFlexLayoutAlgorithm::WillChildCrossSizeBeContainerCrossSize(
DoesItemStretch(child); DoesItemStretch(child);
} }
NGConstraintSpace
NGFlexLayoutAlgorithm::BuildConstraintSpaceForDeterminingFlexBasis(
const NGBlockNode& flex_item) const {
const ComputedStyle& child_style = flex_item.Style();
NGConstraintSpaceBuilder space_builder(ConstraintSpace(),
child_style.GetWritingMode(),
/* is_new_fc */ true);
SetOrthogonalFallbackInlineSizeIfNeeded(Style(), flex_item, &space_builder);
if (ShouldItemShrinkToFit(flex_item))
space_builder.SetIsShrinkToFit(true);
if (WillChildCrossSizeBeContainerCrossSize(flex_item)) {
if (is_column_) {
space_builder.SetIsFixedInlineSize(true);
} else {
space_builder.SetIsFixedBlockSize(true);
DCHECK_NE(content_box_size_.block_size, kIndefiniteSize);
}
}
// TODO(dgrogan): Change SetPercentageResolutionSize everywhere in this file
// to use CalculateChildPercentageSize.
space_builder.SetAvailableSize(content_box_size_);
space_builder.SetPercentageResolutionSize(content_box_size_);
return space_builder.ToConstraintSpace();
}
void NGFlexLayoutAlgorithm::ConstructAndAppendFlexItems() { void NGFlexLayoutAlgorithm::ConstructAndAppendFlexItems() {
for (NGLayoutInputNode generic_child = Node().FirstChild(); generic_child; for (NGLayoutInputNode generic_child = Node().FirstChild(); generic_child;
generic_child = generic_child.NextSibling()) { generic_child = generic_child.NextSibling()) {
...@@ -155,27 +216,8 @@ void NGFlexLayoutAlgorithm::ConstructAndAppendFlexItems() { ...@@ -155,27 +216,8 @@ void NGFlexLayoutAlgorithm::ConstructAndAppendFlexItems() {
} }
const ComputedStyle& child_style = child.Style(); const ComputedStyle& child_style = child.Style();
NGConstraintSpaceBuilder space_builder(ConstraintSpace(), NGConstraintSpace child_space =
child_style.GetWritingMode(), BuildConstraintSpaceForDeterminingFlexBasis(child);
/* is_new_fc */ true);
SetOrthogonalFallbackInlineSizeIfNeeded(Style(), child, &space_builder);
if (ShouldItemShrinkToFit(child))
space_builder.SetIsShrinkToFit(true);
if (WillChildCrossSizeBeContainerCrossSize(child)) {
if (is_column_) {
space_builder.SetIsFixedInlineSize(true);
} else {
space_builder.SetIsFixedBlockSize(true);
DCHECK_NE(content_box_size_.block_size, kIndefiniteSize);
}
}
// TODO(dgrogan): Change SetPercentageResolutionSize everywhere in this file
// to use CalculateChildPercentageSize.
space_builder.SetAvailableSize(content_box_size_);
space_builder.SetPercentageResolutionSize(content_box_size_);
NGConstraintSpace child_space = space_builder.ToConstraintSpace();
NGBoxStrut border_padding_in_child_writing_mode = NGBoxStrut border_padding_in_child_writing_mode =
ComputeBorders(child_space, child) + ComputeBorders(child_space, child) +
...@@ -424,9 +466,14 @@ scoped_refptr<const NGLayoutResult> NGFlexLayoutAlgorithm::Layout() { ...@@ -424,9 +466,14 @@ scoped_refptr<const NGLayoutResult> NGFlexLayoutAlgorithm::Layout() {
available_size.block_size = available_size.block_size =
flex_item.flexed_content_size + flex_item.main_axis_border_padding; flex_item.flexed_content_size + flex_item.main_axis_border_padding;
space_builder.SetIsFixedBlockSize(true); space_builder.SetIsFixedBlockSize(true);
// TODO(dgrogan): Set IsFixedBlockSizeIndefinite if neither the item's // https://drafts.csswg.org/css-flexbox/#definite-sizes
// nor container's main size is definite. (The latter being exception 2 // If the flex container has a definite main size, a flex item's
// from https://drafts.csswg.org/css-flexbox/#definite-sizes ) // post-flexing main size is treated as definite, even though it can
// rely on the indefinite sizes of any flex items in the same line.
if (!IsColumnContainerMainSizeDefinite() &&
!IsItemMainSizeDefinite(flex_item.ng_input_node)) {
space_builder.SetIsFixedBlockSizeIndefinite(true);
}
} else { } else {
available_size.inline_size = available_size.inline_size =
flex_item.flexed_content_size + flex_item.main_axis_border_padding; flex_item.flexed_content_size + flex_item.main_axis_border_padding;
...@@ -519,9 +566,10 @@ void NGFlexLayoutAlgorithm::GiveLinesAndItemsFinalPositionAndSize() { ...@@ -519,9 +566,10 @@ void NGFlexLayoutAlgorithm::GiveLinesAndItemsFinalPositionAndSize() {
flex_item.cross_axis_size); flex_item.cross_axis_size);
if (is_column_) { if (is_column_) {
available_size.Transpose(); available_size.Transpose();
// TODO(dgrogan): Set IsFixedBlockSizeIndefinite if neither the item's if (!IsColumnContainerMainSizeDefinite() &&
// nor container's main size is definite. (The latter being exception !IsItemMainSizeDefinite(flex_item.ng_input_node)) {
// 2 from https://drafts.csswg.org/css-flexbox/#definite-sizes ) space_builder.SetIsFixedBlockSizeIndefinite(true);
}
} }
space_builder.SetAvailableSize(available_size); space_builder.SetAvailableSize(available_size);
space_builder.SetPercentageResolutionSize(content_box_size_); space_builder.SetPercentageResolutionSize(content_box_size_);
......
...@@ -29,6 +29,7 @@ class CORE_EXPORT NGFlexLayoutAlgorithm ...@@ -29,6 +29,7 @@ class CORE_EXPORT NGFlexLayoutAlgorithm
private: private:
bool DoesItemCrossSizeComputeToAuto(const NGBlockNode& child) const; bool DoesItemCrossSizeComputeToAuto(const NGBlockNode& child) const;
bool IsItemMainSizeDefinite(const NGBlockNode& child) const;
bool ShouldItemShrinkToFit(const NGBlockNode& child) const; bool ShouldItemShrinkToFit(const NGBlockNode& child) const;
bool DoesItemStretch(const NGBlockNode& child) const; bool DoesItemStretch(const NGBlockNode& child) const;
// This implements the first of the additional scenarios where a flex item // This implements the first of the additional scenarios where a flex item
...@@ -39,6 +40,8 @@ class CORE_EXPORT NGFlexLayoutAlgorithm ...@@ -39,6 +40,8 @@ class CORE_EXPORT NGFlexLayoutAlgorithm
bool IsColumnContainerMainSizeDefinite() const; bool IsColumnContainerMainSizeDefinite() const;
bool IsContainerCrossSizeDefinite() const; bool IsContainerCrossSizeDefinite() const;
NGConstraintSpace BuildConstraintSpaceForDeterminingFlexBasis(
const NGBlockNode& flex_item) const;
void ConstructAndAppendFlexItems(); void ConstructAndAppendFlexItems();
void GiveLinesAndItemsFinalPositionAndSize(); void GiveLinesAndItemsFinalPositionAndSize();
// This is same method as FlexItem but we need that logic before FlexItem is // This is same method as FlexItem but we need that logic before FlexItem is
......
...@@ -96,6 +96,9 @@ bool BlockLengthUnresolvable( ...@@ -96,6 +96,9 @@ bool BlockLengthUnresolvable(
if (phase == LengthResolvePhase::kIntrinsic) if (phase == LengthResolvePhase::kIntrinsic)
return true; return true;
// TODO(dgrogan): Make this account for constraint_space.IsFixedSizeBlock &&
// constraint_space.IsFixedBlockSizeIndefinite?
LayoutUnit percentage_resolution_block_size = LayoutUnit percentage_resolution_block_size =
opt_percentage_resolution_block_size_for_min_max opt_percentage_resolution_block_size_for_min_max
? *opt_percentage_resolution_block_size_for_min_max ? *opt_percentage_resolution_block_size_for_min_max
......
...@@ -1982,7 +1982,7 @@ crbug.com/591099 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/fle ...@@ -1982,7 +1982,7 @@ crbug.com/591099 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/fle
crbug.com/467127 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/negative-margins-001.html [ Failure ] crbug.com/467127 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/negative-margins-001.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/order_value.html [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/order_value.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/overflow-top-left.html [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/overflow-top-left.html [ Failure ]
crbug.com/467127 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/percentage-heights-003.html [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/percentage-heights-007.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/percentage-heights-quirks-node.html [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/percentage-heights-quirks-node.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/position-absolute-001.html [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/position-absolute-001.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/position-absolute-002.html [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/position-absolute-002.html [ Failure ]
......
...@@ -76,6 +76,15 @@ ...@@ -76,6 +76,15 @@
</div> </div>
</div> </div>
<!-- indefinite unwrapped column flexbox where item doesn't stretch -->
<div style="height: 100px;">
<div class="flexbox column">
<div style="align-self: flex-start">
<span data-expected-height="0"></span>
</div>
</div>
</div>
<!-- indefinite wrapped column flexbox --> <!-- indefinite wrapped column flexbox -->
<div style="height: 100px;"> <div style="height: 100px;">
<div class="flexbox column-wrap"> <div class="flexbox column-wrap">
......
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