Commit fc70bf9e authored by Kent Tamura's avatar Kent Tamura Committed by Commit Bot

LayoutNG for buttons: Implement baseline handling, and enable the feature as "experimental"

This CL ports LayoutButton::BaselinePosition() to
ng_flex_layout_algorithm.cc.

FlexNG's children don't have the last-line baseline values. So we set
BaselineAlgorithmType in NGFlexLayoutAlgorithm::Layout() so that
children provide the last-line baseline as well as the first-line
baseline. PropagateBaselineFromChild() needs to call |NGBoxFragment::
FirstBaseline()| explicitly because button children's Baseline() is
the last-line baselines.

* text-overflow-ellipsis-button-expected.html
  Ellipsis processing in LayoutNG keeps the first letter.

Bug: 1040826
Change-Id: I36402b4fc291d2989c45fb1764202f4fcea91fda
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2300902
Commit-Queue: Kent Tamura <tkent@chromium.org>
Reviewed-by: default avatarIan Kilpatrick <ikilpatrick@chromium.org>
Cr-Commit-Position: refs/heads/master@{#795798}
parent 803be6f2
......@@ -76,6 +76,8 @@ bool BaseButtonInputType::ShouldSaveAndRestoreFormControlState() const {
void BaseButtonInputType::AppendToFormData(FormData&) const {}
bool BaseButtonInputType::TypeShouldForceLegacyLayout() const {
if (RuntimeEnabledFeatures::LayoutNGForControlsEnabled())
return false;
UseCounter::Count(GetElement().GetDocument(),
WebFeature::kLegacyLayoutByButton);
return true;
......
......@@ -47,6 +47,8 @@ void HTMLButtonElement::setType(const AtomicString& type) {
}
bool HTMLButtonElement::TypeShouldForceLegacyLayout() const {
if (RuntimeEnabledFeatures::LayoutNGForControlsEnabled())
return false;
UseCounter::Count(GetDocument(), WebFeature::kLegacyLayoutByButton);
return true;
}
......
......@@ -941,6 +941,15 @@ scoped_refptr<const NGLayoutResult> NGFlexLayoutAlgorithm::LayoutInternal() {
if (ShouldItemShrinkToFit(flex_item.ng_input_node))
space_builder.SetIsShrinkToFit(true);
// For a button child, we need the baseline type same as the container's
// baseline type for UseCounter. For example, if the container's display
// property is 'inline-block', we need the last-line baseline of the
// child. See the bottom of GiveLinesAndItemsFinalPositionAndSize().
if (Node().IsButton()) {
space_builder.SetBaselineAlgorithmType(
ConstraintSpace().BaselineAlgorithmType());
}
NGConstraintSpace child_space = space_builder.ToConstraintSpace();
flex_item.layout_result =
flex_item.ng_input_node.Layout(child_space, nullptr /*break token*/);
......@@ -961,8 +970,7 @@ scoped_refptr<const NGLayoutResult> NGFlexLayoutAlgorithm::LayoutInternal() {
LayoutUnit intrinsic_block_size = BorderScrollbarPadding().BlockSum();
if (algorithm_->FlexLines().IsEmpty() &&
To<LayoutBlock>(Node().GetLayoutBox())->HasLineIfEmpty()) {
if (algorithm_->FlexLines().IsEmpty() && Node().HasLineIfEmpty()) {
intrinsic_block_size += Node().GetLayoutBox()->LogicalHeightForEmptyLine();
} else {
intrinsic_block_size += algorithm_->IntrinsicContentBlockSize();
......@@ -1122,10 +1130,54 @@ bool NGFlexLayoutAlgorithm::GiveLinesAndItemsFinalPositionAndSize() {
if (!container_builder_.Baseline() && fallback_baseline)
container_builder_.SetBaseline(*fallback_baseline);
if (Node().IsButton())
AdjustButtonBaseline(final_content_cross_size);
// Signal if we need to relayout with new child scrollbar information.
return success;
}
void NGFlexLayoutAlgorithm::AdjustButtonBaseline(
LayoutUnit final_content_cross_size) {
// See LayoutButton::BaselinePosition()
if (!Node().HasLineIfEmpty() && !Node().ShouldApplyLayoutContainment() &&
!container_builder_.Baseline()) {
// To ensure that we have a consistent baseline when we have no children,
// even when we have the anonymous LayoutBlock child, we calculate the
// baseline for the empty case manually here.
container_builder_.SetBaseline(BorderScrollbarPadding().block_start +
final_content_cross_size);
return;
}
// Apply flexbox's baseline as is. That is to say, the baseline of the
// first line.
// However, we count the differences between it and the last-line baseline
// of the anonymous block. crbug.com/690036.
// The button should have at most one child.
const NGContainerFragmentBuilder::ChildrenVector& children =
container_builder_.Children();
if (children.size() < 1)
return;
DCHECK_EQ(children.size(), 1u);
const NGContainerFragmentBuilder::ChildWithOffset& child = children[0];
DCHECK(!child.fragment->IsLineBox());
const NGConstraintSpace& space = ConstraintSpace();
NGBoxFragment fragment(space.GetWritingMode(), space.Direction(),
To<NGPhysicalBoxFragment>(*child.fragment));
base::Optional<LayoutUnit> child_baseline =
space.BaselineAlgorithmType() == NGBaselineAlgorithmType::kFirstLine
? fragment.FirstBaseline()
: fragment.Baseline();
if (child_baseline)
child_baseline = *child_baseline + child.offset.block_offset;
if (container_builder_.Baseline() != child_baseline) {
UseCounter::Count(Node().GetDocument(),
WebFeature::kWrongBaselineOfButtonElement);
}
}
void NGFlexLayoutAlgorithm::PropagateBaselineFromChild(
const FlexItem& flex_item,
const NGBoxFragment& fragment,
......@@ -1136,7 +1188,9 @@ void NGFlexLayoutAlgorithm::PropagateBaselineFromChild(
return;
LayoutUnit baseline_offset =
block_offset + fragment.Baseline().value_or(fragment.BlockSize());
block_offset +
(Node().IsButton() ? fragment.FirstBaseline() : fragment.Baseline())
.value_or(fragment.BlockSize());
// We prefer a baseline from a child with baseline alignment, and no
// auto-margins in the cross axis (even if we have to synthesize the
......
......@@ -73,6 +73,8 @@ class CORE_EXPORT NGFlexLayoutAlgorithm
void HandleOutOfFlowPositioned(NGBlockNode child);
void AdjustButtonBaseline(LayoutUnit final_content_cross_size);
// Propagates the baseline from the given flex-item if needed.
void PropagateBaselineFromChild(
const FlexItem&,
......
......@@ -161,6 +161,16 @@ class CORE_EXPORT NGBlockNode final : public NGLayoutInputNode {
static bool CanUseNewLayout(const LayoutBox&);
bool CanUseNewLayout() const;
bool ShouldApplyLayoutContainment() const {
return box_->ShouldApplyLayoutContainment();
}
bool HasLineIfEmpty() const {
if (const auto* block = DynamicTo<LayoutBlock>(box_))
return block->HasLineIfEmpty();
return false;
}
String ToString() const;
private:
......
......@@ -128,6 +128,7 @@ class CORE_EXPORT NGLayoutInputNode {
DCHECK(IsListMarker());
return ToLayoutNGOutsideListMarker(box_)->NeedsOccupyWholeLine();
}
bool IsButton() const { return IsBlock() && box_->IsLayoutNGButton(); }
bool IsFieldsetContainer() const {
return IsBlock() && box_->IsLayoutNGFieldset();
}
......
......@@ -404,6 +404,7 @@ crbug.com/591099 external/wpt/quirks/line-height-trailing-collapsable-whitespace
### fast/css/
crbug.com/591099 fast/css/absolute-inline-alignment-2.html [ Failure ]
crbug.com/591099 fast/css/text-overflow-ellipsis-button.html [ Failure ]
### fast/writing-mode/
crbug.com/591099 fast/writing-mode/flipped-blocks-inline-map-local-to-container.html [ Failure ]
......
......@@ -1123,6 +1123,7 @@ crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/dynamic/remove-colum
crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/dynamic/static-becomes-relpos-has-abspos.html [ Crash Failure ]
crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/event-offset-in-nested.html [ Failure ]
crbug.com/875235 virtual/layout_ng_block_frag/fast/multicol/fieldset-as-multicol.html [ Failure ]
crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/file-upload-as-multicol.html [ Failure ]
crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/float-after-break-after.html [ Failure ]
crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/float-avoidance.html [ Failure ]
crbug.com/591099 virtual/layout_ng_block_frag/fast/multicol/float-margin-at-row-boundary.html [ Failure ]
......@@ -1501,7 +1502,6 @@ crbug.com/1053725 [ Mac ] virtual/web-components-v0-disabled/fast/dom/title-text
# Needs triage:
crbug.com/1053725 [ Mac ] fast/css/button-height.html [ Skip ]
crbug.com/1053725 [ Mac ] fast/css-grid-layout/preferred-width-computed-after-layout.html [ Skip ]
crbug.com/1053725 [ Mac ] fast/css/text-overflow-ellipsis-button.html [ Skip ]
crbug.com/1053725 [ Mac ] editing/selection/replaced-boundaries-3.html [ Skip ]
......@@ -4355,6 +4355,7 @@ crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-model/co
crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-model/display-grid.html [ Failure ]
crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-model/display-inline-grid.html [ Failure ]
crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-model/grid-box-sizing-001.html [ Failure ]
crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-model/grid-button-001.html [ Failure ]
crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-model/grid-container-ignores-first-letter-001.html [ Failure ]
crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-model/grid-container-scrollbar-001.html [ Failure ]
crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-model/grid-container-scrollbar-vertical-lr-001.html [ Failure ]
......
......@@ -11,6 +11,6 @@
</style>
</head>
<body>
<button type="button">&#x2026;</button>
<button type="button">L&#x2026;</button>
</body>
</html>
......@@ -7,7 +7,7 @@
"backgroundColor": "#FFFFFF"
},
{
"name": "LayoutButton INPUT id='control' class='composited'",
"name": "LayoutNGButton INPUT id='control' class='composited'",
"bounds": [127, 22],
"backgroundColor": "#EFEFEF",
"transform": 1
......
{
"layers": [
{
"name": "Scrolling Contents Layer",
"bounds": [800, 600],
"contentsOpaque": true,
"backgroundColor": "#FFFFFF"
},
{
"name": "LayoutButton INPUT id='control' class='composited'",
"bounds": [127, 22],
"backgroundColor": "#EFEFEF",
"transform": 1
}
],
"transforms": [
{
"id": 1,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[8, 8, 0, 1]
]
}
]
}
......@@ -92,7 +92,7 @@ button{
"isKeyboardFocusable": true,
"accessibleName": "click",
"accessibleRole": "button",
"layoutObjectName": "LayoutButton",
"layoutObjectName": "LayoutNGButton",
"showAccessibilityInfo": true
}
}
......
......@@ -7,7 +7,7 @@
"backgroundColor": "#FFFFFF"
},
{
"name": "LayoutButton INPUT id='control' class='composited'",
"name": "LayoutNGButton INPUT id='control' class='composited'",
"bounds": [129, 21],
"backgroundColor": "#EFEFEF",
"transform": 1
......
This is a testharness.js-based test.
FAIL abspos button with auto width, non-auto left/right (rtl) assert_equals: offsetLeft expected 663 but got 100
PASS abspos button with auto width, non-auto left/right (ltr)
Harness: the test ran to completion.
......@@ -92,7 +92,7 @@ button{
"isKeyboardFocusable": true,
"accessibleName": "click",
"accessibleRole": "button",
"layoutObjectName": "LayoutButton",
"layoutObjectName": "LayoutNGButton",
"showAccessibilityInfo": true
}
}
......
......@@ -6,7 +6,7 @@
"contentsOpaque": true,
"backgroundColor": "#FFFFFF",
"invalidations": [
[75, 113, 66, 16],
[75, 114, 66, 15],
[9, 84, 65, 15]
]
}
......
......@@ -7,7 +7,7 @@
"backgroundColor": "#FFFFFF"
},
{
"name": "LayoutButton INPUT id='control' class='composited'",
"name": "LayoutNGButton INPUT id='control' class='composited'",
"bounds": [127, 22],
"backgroundColor": "#EFEFEF",
"transform": 1
......
......@@ -92,7 +92,7 @@ button{
"isKeyboardFocusable": true,
"accessibleName": "click",
"accessibleRole": "button",
"layoutObjectName": "LayoutButton",
"layoutObjectName": "LayoutNGButton",
"showAccessibilityInfo": true
}
}
......
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