Commit 2ede55d0 authored by David Grogan's avatar David Grogan Committed by Commit Bot

[LayoutNG] Give flex items their stretched size earlier.

Force the cross size on stretchy items when they are laid out for
flex base sizing or cross size determination.

Bug: 845235
Change-Id: I49c6b9a9ef1d2e86aa02c47841075ed2726d5619
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1762816
Commit-Queue: David Grogan <dgrogan@chromium.org>
Reviewed-by: default avatarChristian Biesinger <cbiesinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#689303}
parent aa79fe80
......@@ -81,7 +81,8 @@ bool NGFlexLayoutAlgorithm::IsContainerCrossSizeDefinite() const {
}
bool NGFlexLayoutAlgorithm::DoesItemStretch(const NGBlockNode& child) const {
DCHECK(IsItemCrossSizeAuto(child));
if (!DoesItemCrossSizeComputeToAuto(child))
return false;
const ComputedStyle& child_style = child.Style();
// https://drafts.csswg.org/css-flexbox/#valdef-align-items-stretch
// If the cross size property of the flex item computes to auto, and neither
......@@ -96,18 +97,12 @@ bool NGFlexLayoutAlgorithm::DoesItemStretch(const NGBlockNode& child) const {
ItemPosition::kStretch;
}
bool NGFlexLayoutAlgorithm::IsItemCrossSizeAuto(
bool NGFlexLayoutAlgorithm::DoesItemCrossSizeComputeToAuto(
const NGBlockNode& child) const {
const ComputedStyle& child_style = child.Style();
Length cross_size =
is_horizontal_flow_ ? child_style.Height() : child_style.Width();
// The following DCHECK assures that the container's cross axis is the
// same direction as the inline axis of the item, so the cross axis is never
// the item's block axis. That absolves this function of having to check for
// the cross axis being auto due to being a block-size percent without a
// definite block size to resolve against.
DCHECK(!MainAxisIsInlineAxis(child));
return cross_size.IsAuto();
if (is_horizontal_flow_)
return child_style.Height().IsAuto();
return child_style.Width().IsAuto();
}
// This function is used to handle two requirements from the spec.
......@@ -124,26 +119,37 @@ bool NGFlexLayoutAlgorithm::IsItemCrossSizeAuto(
bool NGFlexLayoutAlgorithm::ShouldItemShrinkToFit(
const NGBlockNode& child) const {
if (MainAxisIsInlineAxis(child)) {
// The cross size isn't needed to determine main size, so don't use
// In this case, the cross size is in the item's block axis. The item's
// block size is never needed to determine its inline size so don't use
// fit-content.
return false;
}
if (!IsItemCrossSizeAuto(child)) {
// The cross size is already specified, so don't use fit-content.
if (!child.Style().LogicalWidth().IsAuto()) {
DCHECK(!DoesItemCrossSizeComputeToAuto(child));
// The cross size (item's inline size) is already specified, so don't use
// fit-content.
return false;
}
// We also don't use fit-content if the item qualifies for the first case in
DCHECK(DoesItemCrossSizeComputeToAuto(child));
// If execution reaches here, the item's inline size is its cross size and
// computes to auto. In that situation, we only don't use fit-content if the
// item qualifies for the first case in
// https://drafts.csswg.org/css-flexbox/#definite-sizes :
// 1. If a single-line flex container has a definite cross size, the outer
// cross size of any stretched flex items is the flex container’s inner cross
// size (clamped to the flex item’s min and max cross size) and is considered
// definite.
if (!algorithm_->IsMultiline() && IsContainerCrossSizeDefinite() &&
DoesItemStretch(child))
if (WillChildCrossSizeBeContainerCrossSize(child))
return false;
return true;
}
bool NGFlexLayoutAlgorithm::WillChildCrossSizeBeContainerCrossSize(
const NGBlockNode& child) const {
return !algorithm_->IsMultiline() && IsContainerCrossSizeDefinite() &&
DoesItemStretch(child);
}
void NGFlexLayoutAlgorithm::ConstructAndAppendFlexItems() {
for (NGLayoutInputNode generic_child = Node().FirstChild(); generic_child;
generic_child = generic_child.NextSibling()) {
......@@ -161,6 +167,14 @@ void NGFlexLayoutAlgorithm::ConstructAndAppendFlexItems() {
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.
......@@ -425,6 +439,13 @@ scoped_refptr<const NGLayoutResult> NGFlexLayoutAlgorithm::Layout() {
available_size.block_size = content_box_size_.block_size;
space_builder.SetIsFixedInlineSize(true);
}
if (WillChildCrossSizeBeContainerCrossSize(flex_item.ng_input_node)) {
if (is_column_)
space_builder.SetIsFixedInlineSize(true);
else
space_builder.SetIsFixedBlockSize(true);
}
space_builder.SetAvailableSize(available_size);
// https://drafts.csswg.org/css-flexbox/#algo-cross-item
// Determine the hypothetical cross size of each item by performing layout
......
......@@ -28,9 +28,14 @@ class CORE_EXPORT NGFlexLayoutAlgorithm
const MinMaxSizeInput&) const override;
private:
bool IsItemCrossSizeAuto(const NGBlockNode& child) const;
bool DoesItemCrossSizeComputeToAuto(const NGBlockNode& child) const;
bool ShouldItemShrinkToFit(const NGBlockNode& child) const;
bool DoesItemStretch(const NGBlockNode& child) const;
// This implements the first of the additional scenarios where a flex item
// has definite sizes when it would not if it weren't a flex item.
// https://drafts.csswg.org/css-flexbox/#definite-sizes
bool WillChildCrossSizeBeContainerCrossSize(const NGBlockNode& child) const;
bool IsColumnContainerMainSizeDefinite() const;
bool IsContainerCrossSizeDefinite() const;
......
......@@ -327,6 +327,7 @@ crbug.com/591099 virtual/prefer_compositing_to_lcd_text/compositing/overflow/scr
crbug.com/591099 paint/invalidation/scroll/sticky/invalidate-after-composited-scroll-with-sticky.html [ Failure ]
crbug.com/591099 virtual/compositor_threaded_scrollbar_scrolling/paint/invalidation/scroll/sticky/invalidate-after-composited-scroll-with-sticky.html [ Failure ]
crbug.com/591099 external/wpt/css/css-flexbox/flexbox_align-items-stretch-3.html [ Failure ]
crbug.com/591099 external/wpt/css/css-flexbox/percentage-heights-006.html [ Failure ]
# These would need a rebaseline back from LayoutNGBlockFlow to LayoutBlockFlow
......
......@@ -1876,6 +1876,9 @@ Bug(none) virtual/layout_ng_experimental/fragmentation/scrolling-contents-scroll
# Flexbox in NG
#
# Fails in [NG block + legacy flex]
crbug.com/591099 external/wpt/css/css-flexbox/flexbox_align-items-stretch-3.html [ Failure ]
### virtual/layout_ng_experimental/css3/flexbox/
crbug.com/591099 virtual/layout_ng_experimental/css3/flexbox/auto-height-column-with-border-and-padding.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/css3/flexbox/box-sizing-min-max-sizes.html [ Failure ]
......@@ -1911,7 +1914,6 @@ crbug.com/591099 virtual/layout_ng_experimental/css3/flexbox/multiline.html [ Fa
crbug.com/591099 virtual/layout_ng_experimental/css3/flexbox/negative-overflow.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/css3/flexbox/order-painting.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/css3/flexbox/overflow-auto-resizes-correctly.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/css3/flexbox/overflow-keep-scrollpos.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/css3/flexbox/percentage-height-replaced-element.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/css3/flexbox/position-absolute-child.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/css3/flexbox/relayout-align-items.html [ Failure ]
......@@ -1956,6 +1958,7 @@ crbug.com/249112 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/fle
crbug.com/467127 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/flex-minimum-height-flex-items-006.xht [ Failure ]
crbug.com/249112 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/flex-minimum-height-flex-items-007.xht [ Failure ]
crbug.com/467127 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/flex-minimum-height-flex-items-008.xht [ Failure ]
crbug.com/996474 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/flex-minimum-height-flex-items-009.html [ Pass Failure ]
crbug.com/591099 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/flex-minimum-height-flex-items-015.html [ Failure ]
crbug.com/249112 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/flex-minimum-width-flex-items-005.xht [ Failure ]
crbug.com/249112 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/flex-minimum-width-flex-items-007.xht [ Failure ]
......
<!DOCTYPE html>
<title>flex base size and stretched items</title>
<link rel="author" title="David Grogan" href="mailto:dgrogan@chromium.org">
<link rel="help" href="https://drafts.csswg.org/css-flexbox/#definite-sizes" title="bullet #1">
<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
<meta name="flags" content="" />
<meta name="assert" content="Item's stretched size is used for laying out descendants when determining flex base size." />
<style>
x-flexbox {
display: flex;
height: 100px;
}
x-item {
background: green;
writing-mode: vertical-lr;
}
x-item > div {
padding-right: 70%;
width: 30px;
}
</style>
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<x-flexbox>
<x-item>
<div></div>
</x-item>
</x-flexbox>
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