Commit 906e303a authored by David Grogan's avatar David Grogan Committed by Commit Bot

[LayoutNG] Support all types of flex base sizes

Old code only supported auto and fixed flex bases. This makes 3 more
tests pass.

Also added a ton of comments.

From spot checking, it seems many non-crash failures are due to not
setting the flex container's height correctly, e.g.
external/wpt/css/css-flexbox/align-content-001.htm
css3/flexbox/relpos-with-percentage-top.html

Bug: 845235
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_layout_tests_layout_ng
Change-Id: I06a3d8f4b8923c8acb1d6fb07826da66d55826a5
Reviewed-on: https://chromium-review.googlesource.com/1088229
Commit-Queue: David Grogan <dgrogan@chromium.org>
Reviewed-by: default avatarMorten Stenshorne <mstensho@chromium.org>
Reviewed-by: default avatarChristian Biesinger <cbiesinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#565084}
parent b5cbafdb
...@@ -19,6 +19,9 @@ LayoutNGFlexibleBox::LayoutNGFlexibleBox(Element* element) ...@@ -19,6 +19,9 @@ LayoutNGFlexibleBox::LayoutNGFlexibleBox(Element* element)
void LayoutNGFlexibleBox::UpdateBlockLayout(bool relayout_children) { void LayoutNGFlexibleBox::UpdateBlockLayout(bool relayout_children) {
LayoutAnalyzer::BlockScope analyzer(*this); LayoutAnalyzer::BlockScope analyzer(*this);
// TODO(dgrogan): Reuse logic from LayoutNGBlockFlow's
// UpdateOutOfFlowBlockLayout when this flexbox is out of flow.
scoped_refptr<NGConstraintSpace> constraint_space = scoped_refptr<NGConstraintSpace> constraint_space =
NGConstraintSpace::CreateFromLayoutObject(*this); NGConstraintSpace::CreateFromLayoutObject(*this);
......
...@@ -46,6 +46,17 @@ scoped_refptr<NGLayoutResult> NGFlexLayoutAlgorithm::Layout() { ...@@ -46,6 +46,17 @@ scoped_refptr<NGLayoutResult> NGFlexLayoutAlgorithm::Layout() {
MinMaxSize min_max_sizes = MinMaxSize min_max_sizes =
child.ComputeMinMaxSize(ConstraintSpace().GetWritingMode(), zero_input); child.ComputeMinMaxSize(ConstraintSpace().GetWritingMode(), zero_input);
NGConstraintSpaceBuilder space_builder(ConstraintSpace());
// TODO(dgrogan): Set the percentage size also, which is possibly same as
// container_logical_width. Also change NGSizeIndefinite to container size
// if it's definite.
space_builder.SetAvailableSize(
NGLogicalSize{container_logical_width, NGSizeIndefinite});
scoped_refptr<NGConstraintSpace> child_space =
space_builder.ToConstraintSpace(child.Style().GetWritingMode());
// Spec calls this "flex base size"
// https://www.w3.org/TR/css-flexbox-1/#algo-main-item
LayoutUnit flex_base_content_size; LayoutUnit flex_base_content_size;
if (child.Style().FlexBasis().IsAuto() && child.Style().Width().IsAuto()) { if (child.Style().FlexBasis().IsAuto() && child.Style().Width().IsAuto()) {
flex_base_content_size = min_max_sizes.max_size; flex_base_content_size = min_max_sizes.max_size;
...@@ -55,18 +66,12 @@ scoped_refptr<NGLayoutResult> NGFlexLayoutAlgorithm::Layout() { ...@@ -55,18 +66,12 @@ scoped_refptr<NGLayoutResult> NGFlexLayoutAlgorithm::Layout() {
length_to_resolve = child.Style().Width(); length_to_resolve = child.Style().Width();
DCHECK(!length_to_resolve.IsAuto()); DCHECK(!length_to_resolve.IsAuto());
// TODO(dgrogan): ResolveInlineLength will handle all the types? // TODO(dgrogan): Use ResolveBlockLength here for column flex boxes.
DCHECK(length_to_resolve.IsFixed())
<< "We only support auto and fixed flex base sizes";
flex_base_content_size = LayoutUnit(length_to_resolve.Value());
}
NGConstraintSpaceBuilder space_builder(ConstraintSpace()); flex_base_content_size = ResolveInlineLength(
// TODO(dgrogan): Set the percentage size also. *child_space, child.Style(), min_max_sizes, length_to_resolve,
space_builder.SetAvailableSize( LengthResolveType::kContentSize, LengthResolvePhase::kLayout);
NGLogicalSize{container_logical_width, NGSizeIndefinite}); }
scoped_refptr<NGConstraintSpace> child_space =
space_builder.ToConstraintSpace(child.Style().GetWritingMode());
LayoutUnit main_axis_border_and_padding = LayoutUnit main_axis_border_and_padding =
ComputeBorders(*child_space, child.Style()).InlineSum() + ComputeBorders(*child_space, child.Style()).InlineSum() +
...@@ -76,7 +81,11 @@ scoped_refptr<NGLayoutResult> NGFlexLayoutAlgorithm::Layout() { ...@@ -76,7 +81,11 @@ scoped_refptr<NGLayoutResult> NGFlexLayoutAlgorithm::Layout() {
// TODO(dgrogan): When child has a min/max-{width,height} set, call // TODO(dgrogan): When child has a min/max-{width,height} set, call
// Resolve{Inline,Block}Length here with child's style and constraint space. // Resolve{Inline,Block}Length here with child's style and constraint space.
// Fill this in with the results. // Pass kMinSize, kMaxSize as appropriate.
// Further, min-width:auto has special meaning for flex items. We'll need to
// calculate that here by either extracting the logic from legacy or
// reimplementing. When resolved, pass it here.
// https://www.w3.org/TR/css-flexbox-1/#min-size-auto
MinMaxSize min_max_sizes_in_main_axis_direction{LayoutUnit(), MinMaxSize min_max_sizes_in_main_axis_direction{LayoutUnit(),
LayoutUnit::Max()}; LayoutUnit::Max()};
flex_items.emplace_back(ToLayoutBox(Node().GetLayoutObject()), flex_items.emplace_back(ToLayoutBox(Node().GetLayoutObject()),
...@@ -124,6 +133,9 @@ scoped_refptr<NGLayoutResult> NGFlexLayoutAlgorithm::Layout() { ...@@ -124,6 +133,9 @@ scoped_refptr<NGLayoutResult> NGFlexLayoutAlgorithm::Layout() {
flex_item.layout_result, flex_item.layout_result,
{flex_item.desired_location.X(), flex_item.desired_location.Y()}); {flex_item.desired_location.X(), flex_item.desired_location.Y()});
} }
// TODO(dgrogan): For column flex containers, keep track of tallest flex
// line and pass to ComputeBlockSizeForFragment as content_size.
} }
return container_builder_.ToBoxFragment(); return container_builder_.ToBoxFragment();
} }
......
...@@ -50,8 +50,10 @@ CORE_EXPORT bool NeedMinMaxSize(const ComputedStyle&); ...@@ -50,8 +50,10 @@ CORE_EXPORT bool NeedMinMaxSize(const ComputedStyle&);
CORE_EXPORT bool NeedMinMaxSizeForContentContribution(WritingMode mode, CORE_EXPORT bool NeedMinMaxSizeForContentContribution(WritingMode mode,
const ComputedStyle&); const ComputedStyle&);
// Convert an inline-axis length to a layout unit using the given constraint // Resolve means translate a Length to a LayoutUnit, using parent info
// space. // (represented by ConstraintSpace) as necessary for things like percents.
//
// MinMaxSize is used only when the length is intrinsic (fit-content, etc)
CORE_EXPORT LayoutUnit ResolveInlineLength(const NGConstraintSpace&, CORE_EXPORT LayoutUnit ResolveInlineLength(const NGConstraintSpace&,
const ComputedStyle&, const ComputedStyle&,
const base::Optional<MinMaxSize>&, const base::Optional<MinMaxSize>&,
...@@ -59,8 +61,8 @@ CORE_EXPORT LayoutUnit ResolveInlineLength(const NGConstraintSpace&, ...@@ -59,8 +61,8 @@ CORE_EXPORT LayoutUnit ResolveInlineLength(const NGConstraintSpace&,
LengthResolveType, LengthResolveType,
LengthResolvePhase); LengthResolvePhase);
// Convert a block-axis length to a layout unit using the given constraint // Same as ResolveInlineLength, except here content_size roughly plays the part
// space and content size. // of MinMaxSize.
CORE_EXPORT LayoutUnit ResolveBlockLength(const NGConstraintSpace&, CORE_EXPORT LayoutUnit ResolveBlockLength(const NGConstraintSpace&,
const ComputedStyle&, const ComputedStyle&,
const Length&, const Length&,
...@@ -103,17 +105,15 @@ MinMaxSize ComputeMinAndMaxContentContribution( ...@@ -103,17 +105,15 @@ MinMaxSize ComputeMinAndMaxContentContribution(
const MinMaxSizeInput& input, const MinMaxSizeInput& input,
const NGConstraintSpace* space = nullptr); const NGConstraintSpace* space = nullptr);
// Resolves the given length to a layout unit, constraining it by the min // Resolves the computed value in style.logicalWidth (Length) to a layout unit,
// logical width and max logical width properties from the ComputedStyle // then constrains the result by the resolved min logical width and max logical
// object. // width from the ComputedStyle object.
CORE_EXPORT LayoutUnit CORE_EXPORT LayoutUnit
ComputeInlineSizeForFragment(const NGConstraintSpace&, ComputeInlineSizeForFragment(const NGConstraintSpace&,
const ComputedStyle&, const ComputedStyle&,
const base::Optional<MinMaxSize>&); const base::Optional<MinMaxSize>&);
// Resolves the given length to a layout unit, constraining it by the min // Same as ComputeInlineSizeForFragment, but uses height instead of width.
// logical height and max logical height properties from the ComputedStyle
// object.
CORE_EXPORT LayoutUnit ComputeBlockSizeForFragment(const NGConstraintSpace&, CORE_EXPORT LayoutUnit ComputeBlockSizeForFragment(const NGConstraintSpace&,
const ComputedStyle&, const ComputedStyle&,
LayoutUnit content_size); LayoutUnit content_size);
......
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