Commit 3838d07c authored by Christian Biesinger's avatar Christian Biesinger Committed by Commit Bot

[css-flexbox] Only clear the override size if we're doing layout

And make ChildUnstretchedLogical{Width,Height} handle the case where
an override size is set (by clearing and re-setting).

The problem with clearing the override size, but not doing layout,
is that we may later do a simplified layout which will then
lay out as shrink-to-fit, which is undesired.

Bug: 992010
Change-Id: I18d3ae66f62cbdc9cdcf76810dc0eff6be915af6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1758940
Commit-Queue: Christian Biesinger <cbiesinger@chromium.org>
Auto-Submit: Christian Biesinger <cbiesinger@chromium.org>
Reviewed-by: default avatarDavid Grogan <dgrogan@chromium.org>
Reviewed-by: default avatarMorten Stenshorne <mstensho@chromium.org>
Reviewed-by: default avatarEmil A Eklund <eae@chromium.org>
Cr-Commit-Position: refs/heads/master@{#689485}
parent 91cdc184
...@@ -497,6 +497,12 @@ LayoutUnit LayoutFlexibleBox::ChildUnstretchedLogicalHeight( ...@@ -497,6 +497,12 @@ LayoutUnit LayoutFlexibleBox::ChildUnstretchedLogicalHeight(
// This should only be called if the logical height is the cross size // This should only be called if the logical height is the cross size
DCHECK(MainAxisIsInlineAxis(child)); DCHECK(MainAxisIsInlineAxis(child));
if (NeedToStretchChildLogicalHeight(child)) { if (NeedToStretchChildLogicalHeight(child)) {
LayoutUnit old_override_height = LayoutUnit(-1);
if (child.HasOverrideLogicalHeight()) {
old_override_height = child.OverrideLogicalHeight();
const_cast<LayoutBox&>(child).ClearOverrideLogicalHeight();
}
LayoutUnit child_intrinsic_content_logical_height; LayoutUnit child_intrinsic_content_logical_height;
if (!child.ShouldApplySizeContainment()) { if (!child.ShouldApplySizeContainment()) {
if (child.DisplayLockInducesSizeContainment()) { if (child.DisplayLockInducesSizeContainment()) {
...@@ -514,6 +520,10 @@ LayoutUnit LayoutFlexibleBox::ChildUnstretchedLogicalHeight( ...@@ -514,6 +520,10 @@ LayoutUnit LayoutFlexibleBox::ChildUnstretchedLogicalHeight(
LogicalExtentComputedValues values; LogicalExtentComputedValues values;
child.ComputeLogicalHeight(child_intrinsic_logical_height, LayoutUnit(), child.ComputeLogicalHeight(child_intrinsic_logical_height, LayoutUnit(),
values); values);
if (old_override_height != LayoutUnit(-1)) {
const_cast<LayoutBox&>(child).SetOverrideLogicalHeight(
old_override_height);
}
return values.extent_; return values.extent_;
} }
return child.LogicalHeight(); return child.LogicalHeight();
...@@ -524,14 +534,23 @@ LayoutUnit LayoutFlexibleBox::ChildUnstretchedLogicalWidth( ...@@ -524,14 +534,23 @@ LayoutUnit LayoutFlexibleBox::ChildUnstretchedLogicalWidth(
const LayoutBox& child) const { const LayoutBox& child) const {
// This should only be called if the logical width is the cross size // This should only be called if the logical width is the cross size
DCHECK(!MainAxisIsInlineAxis(child)); DCHECK(!MainAxisIsInlineAxis(child));
DCHECK(!child.HasOverrideLogicalWidth());
// We compute the width as if we were unstretched. Only the main axis // We compute the width as if we were unstretched. Only the main axis
// override size is set at this point. // override size is set at this point.
// However, if our cross axis length is definite we don't need to recompute // However, if our cross axis length is definite we don't need to recompute
// and can just return the already-set logical width. // and can just return the already-set logical width.
if (!CrossAxisLengthIsDefinite(child, child.StyleRef().LogicalWidth())) { if (!CrossAxisLengthIsDefinite(child, child.StyleRef().LogicalWidth())) {
LayoutUnit old_override_width = LayoutUnit(-1);
if (child.HasOverrideLogicalWidth()) {
old_override_width = child.OverrideLogicalWidth();
const_cast<LayoutBox&>(child).ClearOverrideLogicalWidth();
}
LogicalExtentComputedValues values; LogicalExtentComputedValues values;
child.ComputeLogicalWidth(values); child.ComputeLogicalWidth(values);
if (old_override_width != LayoutUnit(-1))
const_cast<LayoutBox&>(child).SetOverrideLogicalWidth(old_override_width);
return values.extent_; return values.extent_;
} }
...@@ -1142,8 +1161,6 @@ void LayoutFlexibleBox::ConstructAndAppendFlexItem( ...@@ -1142,8 +1161,6 @@ void LayoutFlexibleBox::ConstructAndAppendFlexItem(
FlexLayoutAlgorithm* algorithm, FlexLayoutAlgorithm* algorithm,
LayoutBox& child, LayoutBox& child,
ChildLayoutType layout_type) { ChildLayoutType layout_type) {
if (layout_type != kNeverLayout)
child.ClearOverrideSize();
if (layout_type != kNeverLayout && if (layout_type != kNeverLayout &&
ChildHasIntrinsicMainAxisSize(*algorithm, child)) { ChildHasIntrinsicMainAxisSize(*algorithm, child)) {
// If this condition is true, then ComputeMainAxisExtentForChild will call // If this condition is true, then ComputeMainAxisExtentForChild will call
...@@ -1158,6 +1175,7 @@ void LayoutFlexibleBox::ConstructAndAppendFlexItem( ...@@ -1158,6 +1175,7 @@ void LayoutFlexibleBox::ConstructAndAppendFlexItem(
UpdateBlockChildDirtyBitsBeforeLayout(layout_type == kForceLayout, child); UpdateBlockChildDirtyBitsBeforeLayout(layout_type == kForceLayout, child);
if (child.NeedsLayout() || layout_type == kForceLayout || if (child.NeedsLayout() || layout_type == kForceLayout ||
!intrinsic_size_along_main_axis_.Contains(&child)) { !intrinsic_size_along_main_axis_.Contains(&child)) {
child.ClearOverrideSize();
child.ForceLayout(); child.ForceLayout();
CacheChildMainSize(child); CacheChildMainSize(child);
} }
...@@ -1425,8 +1443,19 @@ void LayoutFlexibleBox::LayoutLineItems(FlexLine* current_line, ...@@ -1425,8 +1443,19 @@ void LayoutFlexibleBox::LayoutLineItems(FlexLine* current_line,
UpdateBlockChildDirtyBitsBeforeLayout(force_child_relayout, *child); UpdateBlockChildDirtyBitsBeforeLayout(force_child_relayout, *child);
if (!child->NeedsLayout()) if (!child->NeedsLayout())
MarkChildForPaginationRelayoutIfNeeded(*child, layout_scope); MarkChildForPaginationRelayoutIfNeeded(*child, layout_scope);
if (child->NeedsLayout()) if (child->NeedsLayout()) {
relaid_out_children_.insert(child); relaid_out_children_.insert(child);
// It is very important that we only clear the cross axis override size
// if we are in fact going to lay out the child. Otherwise, the cross
// axis size and the actual laid out size get out of sync, which will
// cause problems if we later lay out the child in simplified layout,
// which does not go through regular flex layout and therefore would
// not reset the cross axis size.
if (MainAxisIsInlineAxis(*child))
child->ClearOverrideLogicalHeight();
else
child->ClearOverrideLogicalWidth();
}
child->LayoutIfNeeded(); child->LayoutIfNeeded();
// This shouldn't be necessary, because we set the override size to be // This shouldn't be necessary, because we set the override size to be
......
<!DOCTYPE html>
<link rel="match" href="../reference/ref-filled-green-100px-square.xht" />
<link rel="author" title="Google LLC" href="http://www.google.com" />
<link rel="help" href="https://drafts.csswg.org/css-flexbox/#cross-sizing" />
<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=992010" />
<title>Tests that certain dynamic changes don't lead to a flex item being sized as shrink to fit when it should stretch in the cross axis</title>
<style>
#flex {
display: flex;
flex-direction: column;
flex-wrap: wrap;
position: absolute;
top: 20px;
width: 100px;
}
#it1 {
background: green;
flex: none;
height: 100px;
min-height: 0;
position: relative;
}
#child {
position: absolute;
top: 0;
left: 0;
}
</style>
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div style="position: relative;">
<div id="flex">
<div id="it1" style=""><div id="child"></div></div>
<div id="it2"></div>
</div>
</div>
<script>
var flex = document.getElementById("flex");
flex.offsetWidth;
var it2 = document.getElementById("it2");
it2.style.width = "50px";
flex.offsetWidth;
flex.style.top = "0px";
var child = document.getElementById("child");
child.style.top = "1px";
flex.offsetWidth;
</script>
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