Commit 593748ae authored by Morten Stenshorne's avatar Morten Stenshorne Committed by Commit Bot

[LayoutNG] Don't break inside a child that's past the fragmentainer.

This may happen for column-span:all, and possibly in other cases, too.
If we're inside a block that has a spanner, we'll create a break inside
the block, before the next sibling to resume at (after the spanner).
However, at this point we may already be past the end of the column. If
this happens, we need to make sure that we don't allow the break inside,
but rather break before the parent of the spanner, and then try again in
the next column.

Bug: 829028
Change-Id: Ie7e121679bbeb7b3dfe88567e1ad7229e104b6dd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1944495Reviewed-by: default avatarIan Kilpatrick <ikilpatrick@chromium.org>
Commit-Queue: Morten Stenshorne <mstensho@chromium.org>
Cr-Commit-Position: refs/heads/master@{#720921}
parent dabc5a78
...@@ -4897,6 +4897,47 @@ TEST_F(NGColumnLayoutAlgorithmTest, FixedSizeMulticolWithSpanner) { ...@@ -4897,6 +4897,47 @@ TEST_F(NGColumnLayoutAlgorithmTest, FixedSizeMulticolWithSpanner) {
EXPECT_EQ(expectation, dump); EXPECT_EQ(expectation, dump);
} }
TEST_F(NGColumnLayoutAlgorithmTest, MarginAndBorderTopWithSpanner) {
SetBodyInnerHTML(R"HTML(
<style>
#parent {
columns: 3;
column-fill: auto;
column-gap: 10px;
width: 320px;
height: 300px;
}
</style>
<div id="container">
<div id="parent">
<div style="width:22px; margin-top:200px; border-top:100px solid;">
<div style="column-span:all; width:33px; height:100px;"></div>
<div style="width:44px; height:300px;"></div>
</div>
</div>
)HTML");
String dump = DumpFragmentTree(GetElementById("container"));
String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
offset:unplaced size:1000x300
offset:0,0 size:320x300
offset:0,0 size:100x100
offset:110,0 size:100x100
offset:0,0 size:22x100
offset:0,100 size:33x100
offset:0,200 size:100x100
offset:0,0 size:22x100
offset:0,0 size:44x100
offset:110,200 size:100x100
offset:0,0 size:22x100
offset:0,0 size:44x100
offset:220,200 size:100x100
offset:0,0 size:22x100
offset:0,0 size:44x100
)DUMP";
EXPECT_EQ(expectation, dump);
}
TEST_F(NGColumnLayoutAlgorithmTest, BreakInsideSpannerWithMargins) { TEST_F(NGColumnLayoutAlgorithmTest, BreakInsideSpannerWithMargins) {
SetBodyInnerHTML(R"HTML( SetBodyInnerHTML(R"HTML(
<style> <style>
......
...@@ -363,6 +363,14 @@ bool MovePastBreakpoint(const NGConstraintSpace& space, ...@@ -363,6 +363,14 @@ bool MovePastBreakpoint(const NGConstraintSpace& space,
// infinite number of fragmentainers without putting any content into them. // infinite number of fragmentainers without putting any content into them.
bool refuse_break = space_left >= space.FragmentainerBlockSize(); bool refuse_break = space_left >= space.FragmentainerBlockSize();
// If the child starts past the end of the fragmentainer (probably due to a
// block-start margin), we must break before it.
bool must_break_before = space_left < LayoutUnit();
if (must_break_before) {
DCHECK(!refuse_break);
return false;
}
if (IsA<NGBlockBreakToken>(physical_fragment.BreakToken())) { if (IsA<NGBlockBreakToken>(physical_fragment.BreakToken())) {
// The block child broke inside. We now need to decide whether to keep that // The block child broke inside. We now need to decide whether to keep that
// break, or if it would be better to break before it. // break, or if it would be better to break before it.
...@@ -370,7 +378,7 @@ bool MovePastBreakpoint(const NGConstraintSpace& space, ...@@ -370,7 +378,7 @@ bool MovePastBreakpoint(const NGConstraintSpace& space,
space, To<NGBlockNode>(child), layout_result); space, To<NGBlockNode>(child), layout_result);
// Allow breaking inside if it has the same appeal or higher than breaking // Allow breaking inside if it has the same appeal or higher than breaking
// before or breaking earlier. Also, if breaking before is impossible, break // before or breaking earlier. Also, if breaking before is impossible, break
// inside regardless of appeal, . // inside regardless of appeal.
if (refuse_break || (appeal_inside >= appeal_before && if (refuse_break || (appeal_inside >= appeal_before &&
(!builder->HasEarlyBreak() || (!builder->HasEarlyBreak() ||
appeal_inside >= builder->BreakAppeal()))) { appeal_inside >= builder->BreakAppeal()))) {
......
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