Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1079)

Unified Diff: third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc

Issue 2693193002: [LayoutNG] A different approach to multi-col. (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc
index 4e2bf337d2204074f826676ea8677d6e1e853d5a..9ca6be40dee5d66a6a996a565203d08476667dd9 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc
@@ -26,16 +26,25 @@ namespace {
using testing::ElementsAre;
using testing::Pointee;
-NGConstraintSpace* ConstructConstraintSpace(NGWritingMode writing_mode,
- TextDirection direction,
- NGLogicalSize size,
- bool shrink_to_fit = false) {
+NGConstraintSpace* ConstructConstraintSpace(
+ NGWritingMode writing_mode,
+ TextDirection direction,
+ NGLogicalSize size,
+ bool shrink_to_fit = false,
+ LayoutUnit fragmentainer_space_available = LayoutUnit()) {
+ NGFragmentationType block_fragmentation =
+ fragmentainer_space_available != LayoutUnit()
+ ? NGFragmentationType::kFragmentColumn
+ : NGFragmentationType::kFragmentNone;
+
return NGConstraintSpaceBuilder(writing_mode)
.SetAvailableSize(size)
.SetPercentageResolutionSize(size)
.SetTextDirection(direction)
.SetWritingMode(writing_mode)
.SetIsShrinkToFit(shrink_to_fit)
+ .SetFragmentainerSpaceAvailable(fragmentainer_space_available)
+ .SetFragmentationType(block_fragmentation)
.ToConstraintSpace();
}
@@ -60,14 +69,13 @@ class NGBlockLayoutAlgorithmTest
RefPtr<NGPhysicalBoxFragment> RunBlockLayoutAlgorithm(
NGConstraintSpace* space,
- NGBlockNode* first_child) {
- NGBlockNode parent(style_.get());
- parent.SetFirstChild(first_child);
+ NGBlockNode* first_child,
+ NGBreakToken* break_token = nullptr) {
+ NGBlockNode* parent = new NGBlockNode(style_.get());
+ parent->SetFirstChild(first_child);
RefPtr<NGPhysicalFragment> fragment =
- NGBlockLayoutAlgorithm(/* layout_object */ nullptr, style_.get(),
- first_child, space)
- .Layout();
+ NGBlockLayoutAlgorithm(parent, space).Layout();
return toNGPhysicalBoxFragment(fragment.get());
}
@@ -86,11 +94,13 @@ class NGBlockLayoutAlgorithmTest
MinAndMaxContentSizes RunComputeMinAndMax(NGBlockNode* first_child) {
// The constraint space is not used for min/max computation, but we need
// it to create the algorithm.
+ NGBlockNode* node = new NGBlockNode(style_.get());
+ node->SetFirstChild(first_child);
+
NGConstraintSpace* space =
ConstructConstraintSpace(kHorizontalTopBottom, TextDirection::kLtr,
NGLogicalSize(LayoutUnit(), LayoutUnit()));
- NGBlockLayoutAlgorithm algorithm(/* layout_object */ nullptr, style_.get(),
- first_child, space);
+ NGBlockLayoutAlgorithm algorithm(node, space);
EXPECT_TRUE(algorithm.ComputeMinAndMaxContentSizes().has_value());
return *algorithm.ComputeMinAndMaxContentSizes();
}
@@ -1293,7 +1303,7 @@ class FragmentChildIterator {
// </div>
// TODO(glebl): reenable multicol after new margin collapsing/floats algorithm
// is checked in.
-TEST_F(NGBlockLayoutAlgorithmTest, DISABLED_EmptyMulticol) {
+/*TEST_F(NGBlockLayoutAlgorithmTest, EmptyMulticol) {
// parent
RefPtr<ComputedStyle> parent_style = ComputedStyle::create();
parent_style->setColumnCount(2);
@@ -1317,7 +1327,7 @@ TEST_F(NGBlockLayoutAlgorithmTest, DISABLED_EmptyMulticol) {
// There should be nothing inside the multicol container.
EXPECT_FALSE(FragmentChildIterator(fragment).NextChild());
-}
+}*/
// Test case's HTML representation:
// <div id="parent" style="columns:2; column-fill:auto; column-gap:10px;
@@ -1326,7 +1336,7 @@ TEST_F(NGBlockLayoutAlgorithmTest, DISABLED_EmptyMulticol) {
// </div>
// TODO(glebl): reenable multicol after new margin collapsing/floats algorithm
// is checked in.
-TEST_F(NGBlockLayoutAlgorithmTest, DISABLED_EmptyBlock) {
+/*TEST_F(NGBlockLayoutAlgorithmTest, EmptyBlock) {
// parent
RefPtr<ComputedStyle> parent_style = ComputedStyle::create();
parent_style->setColumnCount(2);
@@ -1364,8 +1374,306 @@ TEST_F(NGBlockLayoutAlgorithmTest, DISABLED_EmptyBlock) {
EXPECT_EQ(LayoutUnit(), fragment->Height());
EXPECT_EQ(0UL, fragment->Children().size());
EXPECT_FALSE(iterator.NextChild());
+}*/
+
+// Tests that a block child won't fragment if it doesn't reach the fragmentation
+// line.
+TEST_F(NGBlockLayoutAlgorithmTest, NoFragmentation) {
+ setBodyInnerHTML(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ #container {
+ width: 150px;
+ height: 200px;
+ }
+ </style>
+ <div id='container'></div>
+ )HTML");
+
+ LayoutUnit kFragmentainerSpaceAvailable(200);
+
+ NGBlockNode* node = new NGBlockNode(toLayoutBlockFlow(
+ document().getElementById("container")->layoutObject()));
+ auto* space = ConstructConstraintSpace(
+ kHorizontalTopBottom, TextDirection::kLtr,
+ NGLogicalSize(LayoutUnit(1000), NGSizeIndefinite), false,
+ kFragmentainerSpaceAvailable);
+
+ // We should only have one 150x200 fragment with no fragmentation.
+ RefPtr<const NGPhysicalFragment> fragment =
+ NGBlockLayoutAlgorithm(node, space).Layout();
+ EXPECT_EQ(LayoutUnit(150), fragment->Width());
+ EXPECT_EQ(LayoutUnit(200), fragment->Height());
+ ASSERT_TRUE(fragment->BreakToken()->IsFinished());
+}
+
+TEST_F(NGBlockLayoutAlgorithmTest, SimpleFragmentation) {
+ setBodyInnerHTML(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ #container {
+ width: 150px;
+ height: 300px;
+ }
+ </style>
+ <div id='container'></div>
+ )HTML");
+
+ LayoutUnit kFragmentainerSpaceAvailable(200);
+
+ NGBlockNode* node = new NGBlockNode(toLayoutBlockFlow(
+ document().getElementById("container")->layoutObject()));
+ auto* space = ConstructConstraintSpace(
+ kHorizontalTopBottom, TextDirection::kLtr,
+ NGLogicalSize(LayoutUnit(1000), NGSizeIndefinite), false,
+ kFragmentainerSpaceAvailable);
+
+ // The first fragment should have ...
+ RefPtr<const NGPhysicalFragment> fragment =
+ NGBlockLayoutAlgorithm(node, space).Layout();
+ EXPECT_EQ(LayoutUnit(150), fragment->Width());
+ EXPECT_EQ(LayoutUnit(200), fragment->Height());
+ ASSERT_FALSE(fragment->BreakToken()->IsFinished());
+
+ fragment = NGBlockLayoutAlgorithm(node, space,
+ toNGBlockBreakToken(fragment->BreakToken()))
+ .Layout();
+ EXPECT_EQ(LayoutUnit(150), fragment->Width());
+ EXPECT_EQ(LayoutUnit(100), fragment->Height());
+ ASSERT_TRUE(fragment->BreakToken()->IsFinished());
+}
+
+TEST_F(NGBlockLayoutAlgorithmTest, InnerChildrenFragmentation) {
+ setBodyInnerHTML(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ #container {
+ width: 150px;
+ padding-top: 20px;
+ }
+ #child1 {
+ height: 200px;
+ margin-bottom: 20px;
+ }
+ #child2 {
+ height: 100px;
+ margin-top: 20px;
+ }
+ </style>
+ <div id='container'>
+ <div id='child1'></div>
+ <div id='child2'></div>
+ </div>
+ )HTML");
+
+ LayoutUnit kFragmentainerSpaceAvailable(200);
+
+ NGBlockNode* node = new NGBlockNode(toLayoutBlockFlow(
+ document().getElementById("container")->layoutObject()));
+ auto* space = ConstructConstraintSpace(
+ kHorizontalTopBottom, TextDirection::kLtr,
+ NGLogicalSize(LayoutUnit(1000), NGSizeIndefinite), false,
+ kFragmentainerSpaceAvailable);
+
+ // The first fragment should have ...
+ RefPtr<const NGPhysicalFragment> fragment =
+ NGBlockLayoutAlgorithm(node, space).Layout();
+ EXPECT_EQ(LayoutUnit(150), fragment->Width());
+ EXPECT_EQ(LayoutUnit(200), fragment->Height());
+ ASSERT_FALSE(fragment->BreakToken()->IsFinished());
+
+ FragmentChildIterator iterator(toNGPhysicalBoxFragment(fragment.get()));
+ const NGPhysicalBoxFragment* child = iterator.NextChild();
+ EXPECT_EQ(LayoutUnit(150), child->Width());
+ EXPECT_EQ(LayoutUnit(180), child->Height());
+ EXPECT_EQ(LayoutUnit(0), child->LeftOffset());
+ EXPECT_EQ(LayoutUnit(20), child->TopOffset());
+
+ EXPECT_FALSE(iterator.NextChild());
+
+ fragment = NGBlockLayoutAlgorithm(node, space,
+ toNGBlockBreakToken(fragment->BreakToken()))
+ .Layout();
+ EXPECT_EQ(LayoutUnit(150), fragment->Width());
+ EXPECT_EQ(LayoutUnit(140), fragment->Height());
+ ASSERT_TRUE(fragment->BreakToken()->IsFinished());
+
+ iterator.SetParent(toNGPhysicalBoxFragment(fragment.get()));
+ child = iterator.NextChild();
+ EXPECT_EQ(LayoutUnit(150), child->Width());
+ EXPECT_EQ(LayoutUnit(20), child->Height());
+ EXPECT_EQ(LayoutUnit(0), child->LeftOffset());
+ EXPECT_EQ(LayoutUnit(0), child->TopOffset());
+
+ child = iterator.NextChild();
+ EXPECT_EQ(LayoutUnit(150), child->Width());
+ EXPECT_EQ(LayoutUnit(100), child->Height());
+ EXPECT_EQ(LayoutUnit(0), child->LeftOffset());
+ EXPECT_EQ(LayoutUnit(40), child->TopOffset());
+
+ EXPECT_FALSE(iterator.NextChild());
}
+TEST_F(NGBlockLayoutAlgorithmTest, ParallelFlowFragmentation) {
+ setBodyInnerHTML(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ #container {
+ width: 150px;
+ }
+ #float_left {
+ float: left;
+ width: 20px;
+ height: 300px;
+ }
+ #float_right {
+ float: right;
+ width: 50px;
+ height: 500px;
+ }
+ #in_flow {
+ height: 550px;
+ }
+ </style>
+ <div id='container'>
+ <div id='float_left'></div>
+ <div id='float_right'></div>
+ <div id='in_flow'></div>
+ </div>
+ )HTML");
+
+ LayoutUnit kFragmentainerSpaceAvailable(200);
+
+ NGBlockNode* node = new NGBlockNode(toLayoutBlockFlow(
+ document().getElementById("container")->layoutObject()));
+ auto* space = ConstructConstraintSpace(
+ kHorizontalTopBottom, TextDirection::kLtr,
+ NGLogicalSize(LayoutUnit(1000), NGSizeIndefinite), false,
+ kFragmentainerSpaceAvailable);
+
+ // The first fragment should have ...
+ RefPtr<const NGPhysicalFragment> fragment =
+ NGBlockLayoutAlgorithm(node, space).Layout();
+ EXPECT_EQ(LayoutUnit(150), fragment->Width());
+ EXPECT_EQ(LayoutUnit(200), fragment->Height());
+ ASSERT_FALSE(fragment->BreakToken()->IsFinished());
+
+ FragmentChildIterator iterator(toNGPhysicalBoxFragment(fragment.get()));
+
+ // #float_left child.
+ const NGPhysicalBoxFragment* child = iterator.NextChild();
+ EXPECT_EQ(LayoutUnit(20), child->Width());
+ EXPECT_EQ(LayoutUnit(200), child->Height());
+ EXPECT_EQ(LayoutUnit(0), child->LeftOffset());
+ EXPECT_EQ(LayoutUnit(0), child->TopOffset());
+
+ // #float_right child.
+ child = iterator.NextChild();
+ EXPECT_EQ(LayoutUnit(50), child->Width());
+ EXPECT_EQ(LayoutUnit(200), child->Height());
+ EXPECT_EQ(LayoutUnit(100), child->LeftOffset());
+ EXPECT_EQ(LayoutUnit(0), child->TopOffset());
+
+ // #in_flow child.
+ child = iterator.NextChild();
+ EXPECT_EQ(LayoutUnit(150), child->Width());
+ EXPECT_EQ(LayoutUnit(200), child->Height());
+ EXPECT_EQ(LayoutUnit(0), child->LeftOffset());
+ EXPECT_EQ(LayoutUnit(0), child->TopOffset());
+
+ EXPECT_FALSE(iterator.NextChild());
+
+ fragment = NGBlockLayoutAlgorithm(node, space,
+ toNGBlockBreakToken(fragment->BreakToken()))
+ .Layout();
+ EXPECT_EQ(LayoutUnit(150), fragment->Width());
+ EXPECT_EQ(LayoutUnit(200), fragment->Height());
+ ASSERT_FALSE(fragment->BreakToken()->IsFinished());
+
+ iterator.SetParent(toNGPhysicalBoxFragment(fragment.get()));
+
+ // #float_left child.
+ child = iterator.NextChild();
+ EXPECT_EQ(LayoutUnit(20), child->Width());
+ EXPECT_EQ(LayoutUnit(100), child->Height());
+ EXPECT_EQ(LayoutUnit(0), child->LeftOffset());
+ EXPECT_EQ(LayoutUnit(0), child->TopOffset());
+ EXPECT_TRUE(child->BreakToken()->IsFinished());
+
+ // #float_right child.
+ child = iterator.NextChild();
+ EXPECT_EQ(LayoutUnit(50), child->Width());
+ EXPECT_EQ(LayoutUnit(200), child->Height());
+ EXPECT_EQ(LayoutUnit(100), child->LeftOffset());
+ EXPECT_EQ(LayoutUnit(0), child->TopOffset());
+
+ // #in_flow child.
+ child = iterator.NextChild();
+ EXPECT_EQ(LayoutUnit(150), child->Width());
+ EXPECT_EQ(LayoutUnit(200), child->Height());
+ EXPECT_EQ(LayoutUnit(0), child->LeftOffset());
+ EXPECT_EQ(LayoutUnit(0), child->TopOffset());
+
+ EXPECT_FALSE(iterator.NextChild());
+
+ fragment = NGBlockLayoutAlgorithm(node, space,
+ toNGBlockBreakToken(fragment->BreakToken()))
+ .Layout();
+
+ EXPECT_EQ(LayoutUnit(150), fragment->Width());
+ EXPECT_EQ(LayoutUnit(150), fragment->Height());
+ ASSERT_FALSE(fragment->BreakToken()->IsFinished());
+
+ iterator.SetParent(toNGPhysicalBoxFragment(fragment.get()));
+
+ // #float_right child.
+ child = iterator.NextChild();
+ EXPECT_EQ(LayoutUnit(50), child->Width());
+ EXPECT_EQ(LayoutUnit(100), child->Height());
+ EXPECT_EQ(LayoutUnit(100), child->LeftOffset());
+ EXPECT_EQ(LayoutUnit(0), child->TopOffset());
+
+ // #in_flow child.
+ child = iterator.NextChild();
+ EXPECT_EQ(LayoutUnit(150), child->Width());
+ EXPECT_EQ(LayoutUnit(150), child->Height());
+ EXPECT_EQ(LayoutUnit(0), child->LeftOffset());
+ EXPECT_EQ(LayoutUnit(0), child->TopOffset());
+
+ EXPECT_FALSE(iterator.NextChild());
+}
+
+// Tests that a block child will fragment if it reaches it's fragmentation line.
+/*TEST_F(NGBlockLayoutAlgorithmTest, NoFragmentation) {
+ setBodyInnerHTML(
+ "<!DOCTYPE html>"
+ "<style>"
+ " #container {"
+ " height: 200px;"
+ " width: 150px;"
+ " }"
+ "</style>"
+ "<div id='container'>"
+ "</div>");
+
+ LayoutUnit kFragmentainerSpaceAvailable(200);
+
+ NGBlockNode* node = new NGBlockNode(
+ toLayoutBlockFlow(document().getElementById("container")->layoutObject()));
+ auto* space = ConstructConstraintSpace(
+ kHorizontalTopBottom, TextDirection::kLtr,
+ NGLogicalSize(LayoutUnit(1000), NGSizeIndefinite), false,
+kFragmentainerSpaceAvailable);
+
+ RefPtr<const NGPhysicalBoxFragment> fragment = RunBlockLayoutAlgorithm(space,
+node);
+
+ // We should only have one 150x200 fragment with no fragmentation.
+ EXPECT_EQ(LayoutUnit(150), fragment->Width());
+ EXPECT_EQ(LayoutUnit(200), fragment->Height());
+ ASSERT_TRUE(fragment->BreakToken()->IsFinished());
+}*/
+
// Test case's HTML representation:
// <div id="parent" style="columns:2; column-fill:auto; column-gap:10px;
// width:310px; height:100px;">
@@ -1373,7 +1681,7 @@ TEST_F(NGBlockLayoutAlgorithmTest, DISABLED_EmptyBlock) {
// </div>
// TODO(glebl): reenable multicol after new margin collapsing/floats algorithm
// is checked in.
-TEST_F(NGBlockLayoutAlgorithmTest, DISABLED_BlockInOneColumn) {
+TEST_F(NGBlockLayoutAlgorithmTest, BlockInOneColumn) {
// parent
RefPtr<ComputedStyle> parent_style = ComputedStyle::create();
parent_style->setColumnCount(2);
@@ -1423,7 +1731,7 @@ TEST_F(NGBlockLayoutAlgorithmTest, DISABLED_BlockInOneColumn) {
// </div>
// TODO(glebl): reenable multicol after new margin collapsing/floats algorithm
// is checked in.
-TEST_F(NGBlockLayoutAlgorithmTest, DISABLED_BlockInTwoColumns) {
+TEST_F(NGBlockLayoutAlgorithmTest, BlockInTwoColumns) {
// parent
RefPtr<ComputedStyle> parent_style = ComputedStyle::create();
parent_style->setColumnCount(2);
@@ -1482,7 +1790,7 @@ TEST_F(NGBlockLayoutAlgorithmTest, DISABLED_BlockInTwoColumns) {
// </div>
// TODO(glebl): reenable multicol after new margin collapsing/floats algorithm
// is checked in.
-TEST_F(NGBlockLayoutAlgorithmTest, DISABLED_BlockInThreeColumns) {
+TEST_F(NGBlockLayoutAlgorithmTest, BlockInThreeColumns) {
// parent
RefPtr<ComputedStyle> parent_style = ComputedStyle::create();
parent_style->setColumnCount(3);
@@ -1550,8 +1858,7 @@ TEST_F(NGBlockLayoutAlgorithmTest, DISABLED_BlockInThreeColumns) {
// </div>
// TODO(glebl): reenable multicol after new margin collapsing/floats algorithm
// is checked in.
-TEST_F(NGBlockLayoutAlgorithmTest,
- DISABLED_ActualColumnCountGreaterThanSpecified) {
+TEST_F(NGBlockLayoutAlgorithmTest, ActualColumnCountGreaterThanSpecified) {
// parent
RefPtr<ComputedStyle> parent_style = ComputedStyle::create();
parent_style->setColumnCount(2);
@@ -1620,7 +1927,7 @@ TEST_F(NGBlockLayoutAlgorithmTest,
// </div>
// TODO(glebl): reenable multicol after new margin collapsing/floats algorithm
// is checked in.
-TEST_F(NGBlockLayoutAlgorithmTest, DISABLED_TwoBlocksInTwoColumns) {
+TEST_F(NGBlockLayoutAlgorithmTest, TwoBlocksInTwoColumns) {
// parent
RefPtr<ComputedStyle> parent_style = ComputedStyle::create();
parent_style->setColumnCount(3);
@@ -1698,7 +2005,7 @@ TEST_F(NGBlockLayoutAlgorithmTest, DISABLED_TwoBlocksInTwoColumns) {
// </div>
// TODO(glebl): reenable multicol after new margin collapsing/floats algorithm
// is checked in.
-TEST_F(NGBlockLayoutAlgorithmTest, DISABLED_OverflowedBlock) {
+TEST_F(NGBlockLayoutAlgorithmTest, OverflowedBlock) {
// parent
RefPtr<ComputedStyle> parent_style = ComputedStyle::create();
parent_style->setColumnCount(3);
@@ -1809,7 +2116,7 @@ TEST_F(NGBlockLayoutAlgorithmTest, DISABLED_OverflowedBlock) {
// </div>
// TODO(glebl): reenable multicol after new margin collapsing/floats algorithm
// is checked in.
-TEST_F(NGBlockLayoutAlgorithmTest, DISABLED_FloatInOneColumn) {
+TEST_F(NGBlockLayoutAlgorithmTest, FloatInOneColumn) {
// parent
RefPtr<ComputedStyle> parent_style = ComputedStyle::create();
parent_style->setColumnCount(3);
@@ -1861,7 +2168,7 @@ TEST_F(NGBlockLayoutAlgorithmTest, DISABLED_FloatInOneColumn) {
// </div>
// TODO(glebl): reenable multicol after new margin collapsing/floats algorithm
// is checked in.
-TEST_F(NGBlockLayoutAlgorithmTest, DISABLED_TwoFloatsInOneColumn) {
+TEST_F(NGBlockLayoutAlgorithmTest, TwoFloatsInOneColumn) {
// parent
RefPtr<ComputedStyle> parent_style = ComputedStyle::create();
parent_style->setColumnCount(3);
@@ -1929,7 +2236,7 @@ TEST_F(NGBlockLayoutAlgorithmTest, DISABLED_TwoFloatsInOneColumn) {
// </div>
// TODO(glebl): reenable multicol after new margin collapsing/floats algorithm
// is checked in.
-TEST_F(NGBlockLayoutAlgorithmTest, DISABLED_TwoFloatsInTwoColumns) {
+TEST_F(NGBlockLayoutAlgorithmTest, TwoFloatsInTwoColumns) {
// parent
RefPtr<ComputedStyle> parent_style = ComputedStyle::create();
parent_style->setColumnCount(3);

Powered by Google App Engine
This is Rietveld 408576698