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

[FlexNG] Fix abspos legacy flex sandwich

Previously, if a legacy abspos child of an NG flexbox had a legacy
containing block, it could be positioned incorrectly.

This CL copies the staticpos logic from legacy flex, with a few minor
simplifications.

There's little refactoring of legacy to share code. Legacy continues to
mostly rely on methods in LayoutFlexibleBox that the new code can't use.
I don't want to risk altering legacy's behavior here, especially
considering this might be merged to 84.

Bug: 845235, 1066859
Change-Id: Ic07ed9e3fe5febe72981b47b0bacbc2b33691c71
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2222112Reviewed-by: default avatarChristian Biesinger <cbiesinger@chromium.org>
Commit-Queue: David Grogan <dgrogan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#778008}
parent f5a774c9
...@@ -901,12 +901,13 @@ void LayoutBlock::LayoutPositionedObject(LayoutBox* positioned_object, ...@@ -901,12 +901,13 @@ void LayoutBlock::LayoutPositionedObject(LayoutBox* positioned_object,
LayoutObject* parent = positioned_object->Parent(); LayoutObject* parent = positioned_object->Parent();
bool layout_changed = false; bool layout_changed = false;
// TODO(dgrogan): The NG flexbox implementation doesn't have an analogous if ((parent->IsLayoutNGFlexibleBox() &&
// method yet, so abspos children of NG flexboxes that have a legacy !positioned_object->IsLayoutNGMixin() &&
// containing block will not be positioned correctly. LayoutFlexibleBox::SetStaticPositionForChildInFlexNGContainer(
if (parent->IsFlexibleBox() && *positioned_object, To<LayoutBlock>(parent))) ||
ToLayoutFlexibleBox(parent)->SetStaticPositionForPositionedLayout( (parent->IsFlexibleBox() &&
*positioned_object)) { ToLayoutFlexibleBox(parent)->SetStaticPositionForPositionedLayout(
*positioned_object))) {
// The static position of an abspos child of a flexbox depends on its size // The static position of an abspos child of a flexbox depends on its size
// (for example, they can be centered). So we may have to reposition the // (for example, they can be centered). So we may have to reposition the
// item after layout. // item after layout.
......
...@@ -1268,31 +1268,112 @@ void LayoutFlexibleBox::SetOverrideMainAxisContentSizeForChild(FlexItem& item) { ...@@ -1268,31 +1268,112 @@ void LayoutFlexibleBox::SetOverrideMainAxisContentSizeForChild(FlexItem& item) {
} }
} }
namespace {
LayoutUnit MainAxisStaticPositionCommon(const LayoutBox& child,
LayoutBox* parent,
LayoutUnit available_space) {
LayoutUnit offset = FlexLayoutAlgorithm::InitialContentPositionOffset(
parent->StyleRef(), available_space,
FlexLayoutAlgorithm::ResolvedJustifyContent(parent->StyleRef()), 1);
if (parent->StyleRef().ResolvedIsRowReverseFlexDirection() ||
parent->StyleRef().ResolvedIsColumnReverseFlexDirection())
offset = available_space - offset;
return offset;
}
LayoutUnit StaticMainAxisPositionForNGPositionedChild(const LayoutBox& child,
LayoutBox* parent) {
const LayoutUnit available_space =
FlexLayoutAlgorithm::IsHorizontalFlow(parent->StyleRef())
? parent->ContentWidth() - child.Size().Width()
: parent->ContentHeight() - child.Size().Height();
return MainAxisStaticPositionCommon(child, parent, available_space);
}
LayoutUnit CrossAxisStaticPositionCommon(const LayoutBox& child,
LayoutBox* parent,
LayoutUnit available_space) {
return FlexItem::AlignmentOffset(
available_space,
FlexLayoutAlgorithm::AlignmentForChild(parent->StyleRef(),
child.StyleRef()),
LayoutUnit(), LayoutUnit(),
parent->StyleRef().FlexWrap() == EFlexWrap::kWrapReverse,
parent->StyleRef().IsDeprecatedWebkitBox());
}
LayoutUnit StaticCrossAxisPositionForNGPositionedChild(const LayoutBox& child,
LayoutBox* parent) {
const LayoutUnit available_space =
FlexLayoutAlgorithm::IsHorizontalFlow(parent->StyleRef())
? parent->ContentHeight() - child.Size().Height()
: parent->ContentWidth() - child.Size().Width();
return CrossAxisStaticPositionCommon(child, parent, available_space);
}
LayoutUnit StaticInlinePositionForNGPositionedChild(const LayoutBox& child,
LayoutBlock* parent) {
const LayoutUnit start_offset = parent->StartOffsetForContent();
if (parent->StyleRef().IsDeprecatedWebkitBox())
return start_offset;
return start_offset +
(parent->StyleRef().ResolvedIsColumnFlexDirection()
? StaticCrossAxisPositionForNGPositionedChild(child, parent)
: StaticMainAxisPositionForNGPositionedChild(child, parent));
}
LayoutUnit StaticBlockPositionForNGPositionedChild(const LayoutBox& child,
LayoutBlock* parent) {
return parent->BorderAndPaddingBefore() +
(parent->StyleRef().ResolvedIsColumnFlexDirection()
? StaticMainAxisPositionForNGPositionedChild(child, parent)
: StaticCrossAxisPositionForNGPositionedChild(child, parent));
}
} // namespace
bool LayoutFlexibleBox::SetStaticPositionForChildInFlexNGContainer(
LayoutBox& child,
LayoutBlock* parent) {
const ComputedStyle& style = parent->StyleRef();
bool position_changed = false;
PaintLayer* child_layer = child.Layer();
if (child.StyleRef().HasStaticInlinePosition(
style.IsHorizontalWritingMode())) {
LayoutUnit inline_position =
StaticInlinePositionForNGPositionedChild(child, parent);
if (child_layer->StaticInlinePosition() != inline_position) {
child_layer->SetStaticInlinePosition(inline_position);
position_changed = true;
}
}
if (child.StyleRef().HasStaticBlockPosition(
style.IsHorizontalWritingMode())) {
LayoutUnit block_position =
StaticBlockPositionForNGPositionedChild(child, parent);
if (child_layer->StaticBlockPosition() != block_position) {
child_layer->SetStaticBlockPosition(block_position);
position_changed = true;
}
}
return position_changed;
}
LayoutUnit LayoutFlexibleBox::StaticMainAxisPositionForPositionedChild( LayoutUnit LayoutFlexibleBox::StaticMainAxisPositionForPositionedChild(
const LayoutBox& child) { const LayoutBox& child) {
const LayoutUnit available_space = const LayoutUnit available_space =
MainAxisContentExtent(ContentLogicalHeight()) - MainAxisContentExtent(ContentLogicalHeight()) -
MainAxisExtentForChild(child); MainAxisExtentForChild(child);
LayoutUnit offset = FlexLayoutAlgorithm::InitialContentPositionOffset( return MainAxisStaticPositionCommon(child, this, available_space);
StyleRef(), available_space,
FlexLayoutAlgorithm::ResolvedJustifyContent(StyleRef()), 1);
if (StyleRef().ResolvedIsRowReverseFlexDirection() ||
StyleRef().ResolvedIsColumnReverseFlexDirection())
offset = available_space - offset;
return offset;
} }
LayoutUnit LayoutFlexibleBox::StaticCrossAxisPositionForPositionedChild( LayoutUnit LayoutFlexibleBox::StaticCrossAxisPositionForPositionedChild(
const LayoutBox& child) { const LayoutBox& child) {
LayoutUnit available_space = LayoutUnit available_space =
CrossAxisContentExtent() - CrossAxisExtentForChild(child); CrossAxisContentExtent() - CrossAxisExtentForChild(child);
return FlexItem::AlignmentOffset( return CrossAxisStaticPositionCommon(child, this, available_space);
available_space,
FlexLayoutAlgorithm::AlignmentForChild(StyleRef(), child.StyleRef()),
LayoutUnit(), LayoutUnit(),
StyleRef().FlexWrap() == EFlexWrap::kWrapReverse,
StyleRef().IsDeprecatedWebkitBox());
} }
LayoutUnit LayoutFlexibleBox::StaticInlinePositionForPositionedChild( LayoutUnit LayoutFlexibleBox::StaticInlinePositionForPositionedChild(
......
...@@ -98,6 +98,8 @@ class CORE_EXPORT LayoutFlexibleBox : public LayoutBlock { ...@@ -98,6 +98,8 @@ class CORE_EXPORT LayoutFlexibleBox : public LayoutBlock {
// Returns true if the position changed. In that case, the child will have to // Returns true if the position changed. In that case, the child will have to
// be laid out again. // be laid out again.
bool SetStaticPositionForPositionedLayout(LayoutBox& child); bool SetStaticPositionForPositionedLayout(LayoutBox& child);
static bool SetStaticPositionForChildInFlexNGContainer(LayoutBox& child,
LayoutBlock* parent);
LayoutUnit CrossAxisContentExtent() const; LayoutUnit CrossAxisContentExtent() const;
protected: protected:
......
...@@ -1183,7 +1183,6 @@ virtual/layout_ng_fragment_traversal/external/wpt/css/CSS2/text/* [ Skip ] ...@@ -1183,7 +1183,6 @@ virtual/layout_ng_fragment_traversal/external/wpt/css/CSS2/text/* [ Skip ]
# Fail in NG flex, pass in legacy flex. # Fail in NG flex, pass in legacy flex.
crbug.com/845235 virtual/layout_ng_flex_box/external/wpt/css/css-flexbox/quirks-auto-block-size-with-percentage-item.html [ Pass Failure ] crbug.com/845235 virtual/layout_ng_flex_box/external/wpt/css/css-flexbox/quirks-auto-block-size-with-percentage-item.html [ Pass Failure ]
crbug.com/846557 [ Mac ] virtual/layout_ng_flex_box/css3/flexbox/button.html [ Failure ] crbug.com/846557 [ Mac ] virtual/layout_ng_flex_box/css3/flexbox/button.html [ Failure ]
crbug.com/1066859 external/wpt/css/css-flexbox/position-absolute-009.html [ Failure ]
# Fail in both legacy flex and NG flex # Fail in both legacy flex and NG flex
crbug.com/626703 virtual/layout_ng_flex_box/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-baseline-horiz-008.xhtml [ Failure ] crbug.com/626703 virtual/layout_ng_flex_box/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-baseline-horiz-008.xhtml [ Failure ]
......
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