Commit 7b7a6d29 authored by Morten Stenshorne's avatar Morten Stenshorne Committed by Commit Bot

[LayoutNG] Improve legacy write-back for nested multicol.

Create additional legacy fragmentainer groups when necessary, i.e. when
contiguous column content (i.e. without intervening spanners) is laid
out over multiple outer fragmentainers.

We also need to include block-size consumed in previous outer
fragmentainers, since the legacy engine expects everything to be in the
flow thread coordinate space.

Correct legacy write-back is necessary for position querying DOM APIs,
such as offsetLeft and offsetTop.

Bug: 829028
Change-Id: If6adaa0d6324376061e66a3fa73403c008559b1c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2450097
Commit-Queue: Morten Stenshorne <mstensho@chromium.org>
Reviewed-by: default avatarIan Kilpatrick <ikilpatrick@chromium.org>
Cr-Commit-Position: refs/heads/master@{#815564}
parent f37df86c
...@@ -717,16 +717,67 @@ void LayoutMultiColumnFlowThread::AppendNewFragmentainerGroupIfNeeded( ...@@ -717,16 +717,67 @@ void LayoutMultiColumnFlowThread::AppendNewFragmentainerGroupIfNeeded(
} }
} }
void LayoutMultiColumnFlowThread::UpdateFromNG() { void LayoutMultiColumnFlowThread::StartLayoutFromNG(unsigned column_count) {
NOT_DESTROYED();
column_count_ = column_count;
last_set_worked_on_ = ToLayoutMultiColumnSetOrNull(FirstMultiColumnBox());
}
LayoutMultiColumnSet* LayoutMultiColumnFlowThread::PendingColumnSetForNG()
const {
NOT_DESTROYED();
if (last_set_worked_on_ &&
!last_set_worked_on_->FirstFragmentainerGroup().IsLogicalHeightKnown()) {
DCHECK_EQ(last_set_worked_on_->FragmentainerGroups().size(), 1u);
return last_set_worked_on_;
}
return nullptr;
}
void LayoutMultiColumnFlowThread::AppendNewFragmentainerGroupFromNG() {
NOT_DESTROYED();
// TODO(mstensho): This nullptr check shouldn't be here, but we need it for
// now. If we have no column set at this point, something has gone wrong, but
// NG nested column balancing sometimes acts up when doubly nested (or more),
// making the legacy write-back machinery call FinishLayoutFromNG()
// prematurely. See e.g. fast/multicol/client-rect-nested.html
if (last_set_worked_on_)
last_set_worked_on_->AppendNewFragmentainerGroup();
}
void LayoutMultiColumnFlowThread::SetCurrentColumnBlockSizeFromNG(
LayoutUnit block_size) {
NOT_DESTROYED();
// There are cases where NG creates an empty column even if we don't create a
// column set.
if (!last_set_worked_on_)
return;
last_set_worked_on_->LastFragmentainerGroup().SetColumnBlockSizeFromNG(
block_size);
}
void LayoutMultiColumnFlowThread::FinishLayoutFromNG(
LayoutUnit flow_thread_offset) {
NOT_DESTROYED(); NOT_DESTROYED();
all_columns_have_known_height_ = true; all_columns_have_known_height_ = true;
for (LayoutBox* column_box = FirstMultiColumnBox(); column_box; for (LayoutBox* column_box = FirstMultiColumnBox(); column_box;
column_box = column_box->NextSiblingMultiColumnBox()) { column_box = column_box->NextSiblingMultiColumnBox()) {
if (column_box->IsLayoutMultiColumnSet())
ToLayoutMultiColumnSet(column_box)->UpdateFromNG();
column_box->ClearNeedsLayout(); column_box->ClearNeedsLayout();
column_box->UpdateAfterLayout(); column_box->UpdateAfterLayout();
} }
// If we have a trailing column set, finish it.
if (LayoutMultiColumnSet* last_column_set =
ToLayoutMultiColumnSetOrNull(LastMultiColumnBox())) {
last_column_set->EndFlow(flow_thread_offset);
last_column_set->FinishLayoutFromNG();
}
ValidateColumnSets();
SetLogicalHeight(flow_thread_offset);
UpdateAfterLayout();
ClearNeedsLayout();
last_set_worked_on_ = nullptr;
} }
bool LayoutMultiColumnFlowThread::IsFragmentainerLogicalHeightKnown() { bool LayoutMultiColumnFlowThread::IsFragmentainerLogicalHeightKnown() {
...@@ -991,10 +1042,19 @@ void LayoutMultiColumnFlowThread::WillBeRemovedFromTree() { ...@@ -991,10 +1042,19 @@ void LayoutMultiColumnFlowThread::WillBeRemovedFromTree() {
} }
void LayoutMultiColumnFlowThread::SkipColumnSpanner( void LayoutMultiColumnFlowThread::SkipColumnSpanner(
LayoutBox* layout_object, const LayoutBox* layout_object,
LayoutUnit logical_top_in_flow_thread) { LayoutUnit logical_top_in_flow_thread) {
NOT_DESTROYED(); NOT_DESTROYED();
DCHECK(layout_object->IsColumnSpanAll()); DCHECK(layout_object->IsColumnSpanAll());
// In legacy layout, |last_set_worked_on_| is only updated if we find a column
// set after the spanner. We don't want this in NG, since NG may have created
// empty columns after the spanner, without a column set being created, and
// then we want to leave the column set alone.
bool is_ng_layout = MultiColumnBlockFlow()->IsLayoutNGObject();
if (is_ng_layout)
last_set_worked_on_ = nullptr;
LayoutMultiColumnSpannerPlaceholder* placeholder = LayoutMultiColumnSpannerPlaceholder* placeholder =
layout_object->SpannerPlaceholder(); layout_object->SpannerPlaceholder();
LayoutBox* previous_column_box = placeholder->PreviousSiblingMultiColumnBox(); LayoutBox* previous_column_box = placeholder->PreviousSiblingMultiColumnBox();
...@@ -1008,6 +1068,9 @@ void LayoutMultiColumnFlowThread::SkipColumnSpanner( ...@@ -1008,6 +1068,9 @@ void LayoutMultiColumnFlowThread::SkipColumnSpanner(
next_set->BeginFlow(logical_top_in_flow_thread); next_set->BeginFlow(logical_top_in_flow_thread);
} }
if (is_ng_layout)
return;
// We'll lay out of spanners after flow thread layout has finished (during // We'll lay out of spanners after flow thread layout has finished (during
// layout of the spanner placeholders). There may be containing blocks for // layout of the spanner placeholders). There may be containing blocks for
// out-of-flow positioned descendants of the spanner in the flow thread, so // out-of-flow positioned descendants of the spanner in the flow thread, so
......
...@@ -255,7 +255,8 @@ class CORE_EXPORT LayoutMultiColumnFlowThread final ...@@ -255,7 +255,8 @@ class CORE_EXPORT LayoutMultiColumnFlowThread final
// out inside the flow thread, since the flow thread is not in a spanner's // out inside the flow thread, since the flow thread is not in a spanner's
// containing block chain (since the containing block is the multicol // containing block chain (since the containing block is the multicol
// container). // container).
void SkipColumnSpanner(LayoutBox*, LayoutUnit logical_top_in_flow_thread); void SkipColumnSpanner(const LayoutBox*,
LayoutUnit logical_top_in_flow_thread);
// Returns true if at least one column got a new height after flow thread // Returns true if at least one column got a new height after flow thread
// layout (during column set layout), in which case we need another layout // layout (during column set layout), in which case we need another layout
...@@ -303,7 +304,11 @@ class CORE_EXPORT LayoutMultiColumnFlowThread final ...@@ -303,7 +304,11 @@ class CORE_EXPORT LayoutMultiColumnFlowThread final
void AppendNewFragmentainerGroupIfNeeded(LayoutUnit offset_in_flow_thread, void AppendNewFragmentainerGroupIfNeeded(LayoutUnit offset_in_flow_thread,
PageBoundaryRule); PageBoundaryRule);
void UpdateFromNG(); void StartLayoutFromNG(unsigned column_count);
LayoutMultiColumnSet* PendingColumnSetForNG() const;
void AppendNewFragmentainerGroupFromNG();
void SetCurrentColumnBlockSizeFromNG(LayoutUnit);
void FinishLayoutFromNG(LayoutUnit flow_thread_offset);
// Implementing FragmentationContext: // Implementing FragmentationContext:
bool IsFragmentainerLogicalHeightKnown() final; bool IsFragmentainerLogicalHeightKnown() final;
......
...@@ -720,12 +720,15 @@ PhysicalRect LayoutMultiColumnSet::LocalVisualRectIgnoringVisibility() const { ...@@ -720,12 +720,15 @@ PhysicalRect LayoutMultiColumnSet::LocalVisualRectIgnoringVisibility() const {
return block_flow_bounds; return block_flow_bounds;
} }
void LayoutMultiColumnSet::UpdateFromNG() { void LayoutMultiColumnSet::FinishLayoutFromNG() {
NOT_DESTROYED(); NOT_DESTROYED();
DCHECK_EQ(fragmentainer_groups_.size(), 1U); // Calculate the block-size of all the fragmentainer groups combined.
auto& group = fragmentainer_groups_[0]; LogicalExtentComputedValues computed_values;
group.UpdateFromNG(LogicalHeight()); ComputeLogicalHeight(/* logical_height */ LayoutUnit(),
ComputeLayoutOverflow(LogicalHeight()); /* logical_top */ LayoutUnit(), computed_values);
SetLogicalHeight(computed_values.extent_);
ComputeLayoutOverflow(computed_values.extent_);
initial_height_calculated_ = false;
} }
} // namespace blink } // namespace blink
...@@ -77,6 +77,10 @@ class CORE_EXPORT LayoutMultiColumnSet final : public LayoutBlockFlow { ...@@ -77,6 +77,10 @@ class CORE_EXPORT LayoutMultiColumnSet final : public LayoutBlockFlow {
NOT_DESTROYED(); NOT_DESTROYED();
return fragmentainer_groups_.Last(); return fragmentainer_groups_.Last();
} }
MultiColumnFragmentainerGroup& LastFragmentainerGroup() {
NOT_DESTROYED();
return fragmentainer_groups_.Last();
}
unsigned FragmentainerGroupIndexAtFlowThreadOffset(LayoutUnit, unsigned FragmentainerGroupIndexAtFlowThreadOffset(LayoutUnit,
PageBoundaryRule) const; PageBoundaryRule) const;
MultiColumnFragmentainerGroup& FragmentainerGroupAtFlowThreadOffset( MultiColumnFragmentainerGroup& FragmentainerGroupAtFlowThreadOffset(
...@@ -264,7 +268,7 @@ class CORE_EXPORT LayoutMultiColumnSet final : public LayoutBlockFlow { ...@@ -264,7 +268,7 @@ class CORE_EXPORT LayoutMultiColumnSet final : public LayoutBlockFlow {
bool ComputeColumnRuleBounds(const LayoutPoint& paint_offset, bool ComputeColumnRuleBounds(const LayoutPoint& paint_offset,
Vector<LayoutRect>& column_rule_bounds) const; Vector<LayoutRect>& column_rule_bounds) const;
void UpdateFromNG(); void FinishLayoutFromNG();
protected: protected:
LayoutMultiColumnSet(LayoutFlowThread*); LayoutMultiColumnSet(LayoutFlowThread*);
......
...@@ -327,8 +327,10 @@ unsigned MultiColumnFragmentainerGroup::ActualColumnCount() const { ...@@ -327,8 +327,10 @@ unsigned MultiColumnFragmentainerGroup::ActualColumnCount() const {
return count; return count;
} }
void MultiColumnFragmentainerGroup::UpdateFromNG(LayoutUnit logical_height) { void MultiColumnFragmentainerGroup::SetColumnBlockSizeFromNG(
logical_height_ = logical_height; LayoutUnit block_size) {
DCHECK(!is_logical_height_known_ || logical_height_ == block_size);
logical_height_ = block_size;
is_logical_height_known_ = true; is_logical_height_known_ = true;
} }
......
...@@ -159,7 +159,7 @@ class CORE_EXPORT MultiColumnFragmentainerGroup { ...@@ -159,7 +159,7 @@ class CORE_EXPORT MultiColumnFragmentainerGroup {
// Returns 1 or greater, never 0. // Returns 1 or greater, never 0.
unsigned ActualColumnCount() const; unsigned ActualColumnCount() const;
void UpdateFromNG(LayoutUnit logical_height); void SetColumnBlockSizeFromNG(LayoutUnit);
private: private:
LayoutUnit HeightAdjustedForRowOffset(LayoutUnit height) const; LayoutUnit HeightAdjustedForRowOffset(LayoutUnit height) const;
......
...@@ -233,7 +233,11 @@ class CORE_EXPORT NGBlockNode final : public NGLayoutInputNode { ...@@ -233,7 +233,11 @@ class CORE_EXPORT NGBlockNode final : public NGLayoutInputNode {
void PlaceChildrenInLayoutBox( void PlaceChildrenInLayoutBox(
const NGPhysicalBoxFragment&, const NGPhysicalBoxFragment&,
const NGBlockBreakToken* previous_break_token) const; const NGBlockBreakToken* previous_break_token) const;
void PlaceChildrenInFlowThread(const NGPhysicalBoxFragment&) const; void PlaceChildrenInFlowThread(
LayoutMultiColumnFlowThread*,
const NGConstraintSpace&,
const NGPhysicalBoxFragment&,
const NGBlockBreakToken* previous_container_break_token) const;
void CopyChildFragmentPosition( void CopyChildFragmentPosition(
const NGPhysicalBoxFragment& child_fragment, const NGPhysicalBoxFragment& child_fragment,
PhysicalOffset, PhysicalOffset,
......
...@@ -1038,7 +1038,6 @@ crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/caret-range-anonymou ...@@ -1038,7 +1038,6 @@ crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/caret-range-anonymou
crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/caret-range-outside-columns.html [ Failure ] crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/caret-range-outside-columns.html [ Failure ]
crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/caret-range-outside-columns-rtl.html [ Failure ] crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/caret-range-outside-columns-rtl.html [ Failure ]
crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/client-rect-nested.html [ Failure ] crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/client-rect-nested.html [ Failure ]
crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/client-rects-crossing-boundaries-nested.html [ Failure ]
crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/client-rects.html [ Crash Failure ] crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/client-rects.html [ Crash Failure ]
crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/client-rects-rtl.html [ Crash Failure ] crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/client-rects-rtl.html [ Crash Failure ]
crbug.com/1058792 virtual/layout_ng_block_frag/fast/multicol/composited-layer-multiple-fragments-translated.html [ Failure Crash ] crbug.com/1058792 virtual/layout_ng_block_frag/fast/multicol/composited-layer-multiple-fragments-translated.html [ Failure Crash ]
...@@ -1054,7 +1053,6 @@ crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/dynamic/insert-spann ...@@ -1054,7 +1053,6 @@ crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/dynamic/insert-spann
crbug.com/1079031 virtual/layout_ng_block_frag/fast/multicol/dynamic/relpos-becomes-static-has-abspos.html [ Failure ] crbug.com/1079031 virtual/layout_ng_block_frag/fast/multicol/dynamic/relpos-becomes-static-has-abspos.html [ Failure ]
crbug.com/1079031 virtual/layout_ng_block_frag/fast/multicol/dynamic/remove-column-content-next-to-abspos-between-spanners.html [ Failure ] crbug.com/1079031 virtual/layout_ng_block_frag/fast/multicol/dynamic/remove-column-content-next-to-abspos-between-spanners.html [ Failure ]
crbug.com/1079031 virtual/layout_ng_block_frag/fast/multicol/dynamic/static-becomes-relpos-has-abspos.html [ Failure ] crbug.com/1079031 virtual/layout_ng_block_frag/fast/multicol/dynamic/static-becomes-relpos-has-abspos.html [ Failure ]
crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/event-offset-in-nested.html [ Failure ]
crbug.com/1061423 virtual/layout_ng_block_frag/fast/multicol/flipped-blocks-hit-test.html [ Failure ] crbug.com/1061423 virtual/layout_ng_block_frag/fast/multicol/flipped-blocks-hit-test.html [ Failure ]
crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/float-margin-at-row-boundary.html [ Failure ] crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/float-margin-at-row-boundary.html [ Failure ]
crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/float-margin-at-row-boundary-fixed-multicol-height.html [ Failure ] crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/float-margin-at-row-boundary-fixed-multicol-height.html [ Failure ]
...@@ -1107,27 +1105,20 @@ crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/static-child-becomes ...@@ -1107,27 +1105,20 @@ crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/static-child-becomes
crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/tall-content-in-inner-with-fixed-height.html [ Failure ] crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/tall-content-in-inner-with-fixed-height.html [ Failure ]
crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/tall-float1.html [ Failure ] crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/tall-float1.html [ Failure ]
crbug.com/1079031 virtual/layout_ng_block_frag/fast/multicol/tall-line-in-short-block.html [ Failure ] crbug.com/1079031 virtual/layout_ng_block_frag/fast/multicol/tall-line-in-short-block.html [ Failure ]
crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/three-inner-rows.html [ Failure ]
crbug.com/1079031 virtual/layout_ng_block_frag/fast/multicol/transform-with-fixedpos.html [ Failure ] crbug.com/1079031 virtual/layout_ng_block_frag/fast/multicol/transform-with-fixedpos.html [ Failure ]
crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/vertical-lr/caret-range-anonymous-block.html [ Failure ] crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/vertical-lr/caret-range-anonymous-block.html [ Failure ]
crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/vertical-lr/caret-range-anonymous-block-rtl.html [ Failure Crash ] crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/vertical-lr/caret-range-anonymous-block-rtl.html [ Failure Crash ]
crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/vertical-lr/caret-range-outside-columns.html [ Timeout Failure ] crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/vertical-lr/caret-range-outside-columns.html [ Timeout Failure ]
crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/vertical-lr/caret-range-outside-columns-rtl.html [ Failure ] crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/vertical-lr/caret-range-outside-columns-rtl.html [ Failure ]
crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/vertical-lr/client-rects-crossing-boundaries-nested.html [ Failure ]
crbug.com/1058792 virtual/layout_ng_block_frag/fast/multicol/vertical-lr/composited-relpos-overlapping-will-change.html [ Failure ] crbug.com/1058792 virtual/layout_ng_block_frag/fast/multicol/vertical-lr/composited-relpos-overlapping-will-change.html [ Failure ]
crbug.com/829028 [ Mac ] virtual/layout_ng_block_frag/fast/multicol/vertical-lr/nested-columns.html [ Failure ] crbug.com/829028 [ Mac ] virtual/layout_ng_block_frag/fast/multicol/vertical-lr/nested-columns.html [ Failure ]
crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/vertical-lr/offset-top-and-left-at-boundaries-nested.html [ Failure ]
crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/vertical-lr/offset-top-and-left-nested.html [ Failure ]
crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/vertical-rl/caret-range-anonymous-block.html [ Failure ] crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/vertical-rl/caret-range-anonymous-block.html [ Failure ]
crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/vertical-rl/caret-range-anonymous-block-rtl.html [ Failure ] crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/vertical-rl/caret-range-anonymous-block-rtl.html [ Failure ]
crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/vertical-rl/caret-range-outside-columns.html [ Crash Failure ] crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/vertical-rl/caret-range-outside-columns.html [ Crash Failure ]
crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/vertical-rl/caret-range-outside-columns-rtl.html [ Crash Failure ] crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/vertical-rl/caret-range-outside-columns-rtl.html [ Crash Failure ]
crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/vertical-rl/client-rects-crossing-boundaries-nested.html [ Failure ]
crbug.com/1058792 virtual/layout_ng_block_frag/fast/multicol/vertical-rl/composited-relpos-overlapping-will-change.html [ Failure ] crbug.com/1058792 virtual/layout_ng_block_frag/fast/multicol/vertical-rl/composited-relpos-overlapping-will-change.html [ Failure ]
crbug.com/1061423 virtual/layout_ng_block_frag/fast/multicol/vertical-rl/float-truncation.html [ Failure ] crbug.com/1061423 virtual/layout_ng_block_frag/fast/multicol/vertical-rl/float-truncation.html [ Failure ]
crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/vertical-rl/nested-columns.html [ Crash Failure ] crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/vertical-rl/nested-columns.html [ Crash Failure ]
crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/vertical-rl/offset-top-and-left-at-boundaries-nested.html [ Failure ]
crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/vertical-rl/offset-top-and-left-nested.html [ Failure ]
crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/widows-and-orphans.html [ Failure ] crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/widows-and-orphans.html [ Failure ]
crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/widows.html [ Failure ] crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/widows.html [ Failure ]
crbug.com/1079031 virtual/layout_ng_block_frag/fragmentation/abspos-after-forced-break.html [ Failure ] crbug.com/1079031 virtual/layout_ng_block_frag/fragmentation/abspos-after-forced-break.html [ 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