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 8b3ba8b0eb83fbdab73bc81f24824a65454df3a9..c01e43daa63e140b7357c6ccc2c4159ad28e62bf 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,15 +26,24 @@ 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) |
.SetIsShrinkToFit(shrink_to_fit) |
+ .SetFragmentainerSpaceAvailable(fragmentainer_space_available) |
+ .SetFragmentationType(block_fragmentation) |
.ToConstraintSpace(writing_mode); |
} |
@@ -2096,5 +2105,269 @@ TEST_F(NGBlockLayoutAlgorithmTest, PositionEmptyBlocksInNewBfc) { |
empty_block2->Offset()); |
} |
+// 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(getLayoutObjectByElementId("container"))); |
+ 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()->PhysicalFragment(); |
+ EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(200)), fragment->Size()); |
+ ASSERT_TRUE(fragment->BreakToken()->IsFinished()); |
+} |
+ |
+// Tests that a block child with fragment if it reaches the fragmentation line. |
mstensho (USE GERRIT)
2017/02/27 13:44:36
I don't think I can parse this sentence, but I thi
ikilpatrick
2017/02/27 18:50:09
s/with/will :P
|
+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(getLayoutObjectByElementId("container"))); |
+ auto* space = ConstructConstraintSpace( |
+ kHorizontalTopBottom, TextDirection::kLtr, |
+ NGLogicalSize(LayoutUnit(1000), NGSizeIndefinite), false, |
+ kFragmentainerSpaceAvailable); |
+ |
+ RefPtr<const NGPhysicalFragment> fragment = |
+ NGBlockLayoutAlgorithm(node, space).Layout()->PhysicalFragment(); |
+ EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(200)), fragment->Size()); |
+ ASSERT_FALSE(fragment->BreakToken()->IsFinished()); |
+ |
+ fragment = NGBlockLayoutAlgorithm(node, space, |
+ toNGBlockBreakToken(fragment->BreakToken())) |
+ .Layout() |
+ ->PhysicalFragment(); |
+ EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(100)), fragment->Size()); |
+ ASSERT_TRUE(fragment->BreakToken()->IsFinished()); |
+} |
+ |
+// Tests that children inside the same block formatting context fragment when |
+// reaching a fragmentation line. |
+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(getLayoutObjectByElementId("container"))); |
+ auto* space = ConstructConstraintSpace( |
+ kHorizontalTopBottom, TextDirection::kLtr, |
+ NGLogicalSize(LayoutUnit(1000), NGSizeIndefinite), false, |
+ kFragmentainerSpaceAvailable); |
+ |
+ RefPtr<const NGPhysicalFragment> fragment = |
+ NGBlockLayoutAlgorithm(node, space).Layout()->PhysicalFragment(); |
+ EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(200)), fragment->Size()); |
+ ASSERT_FALSE(fragment->BreakToken()->IsFinished()); |
+ |
+ FragmentChildIterator iterator(toNGPhysicalBoxFragment(fragment.get())); |
+ const NGPhysicalBoxFragment* child = iterator.NextChild(); |
+ EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(180)), child->Size()); |
+ EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(20)), child->Offset()); |
+ |
+ EXPECT_FALSE(iterator.NextChild()); |
+ |
+ fragment = NGBlockLayoutAlgorithm(node, space, |
+ toNGBlockBreakToken(fragment->BreakToken())) |
+ .Layout() |
+ ->PhysicalFragment(); |
+ EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(140)), fragment->Size()); |
+ ASSERT_TRUE(fragment->BreakToken()->IsFinished()); |
+ |
+ iterator.SetParent(toNGPhysicalBoxFragment(fragment.get())); |
+ child = iterator.NextChild(); |
+ EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(20)), child->Size()); |
+ EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(0)), child->Offset()); |
+ |
+ child = iterator.NextChild(); |
+ EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(100)), child->Size()); |
+ EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(40)), child->Offset()); |
+ |
+ EXPECT_FALSE(iterator.NextChild()); |
+} |
+ |
+// Tests that children inside which establish new formatting contexts fragment |
+// correctly. |
+TEST_F(NGBlockLayoutAlgorithmTest, |
+ InnerFormattingContextChildrenFragmentation) { |
+ setBodyInnerHTML(R"HTML( |
+ <!DOCTYPE html> |
+ <style> |
+ #container { |
+ width: 150px; |
+ padding-top: 20px; |
+ } |
+ #child1 { |
+ height: 200px; |
+ margin-bottom: 20px; |
+ contain: paint; |
+ } |
+ #child2 { |
+ height: 100px; |
+ margin-top: 20px; |
+ contain: paint; |
+ } |
+ </style> |
+ <div id='container'> |
+ <div id='child1'></div> |
+ <div id='child2'></div> |
+ </div> |
+ )HTML"); |
+ |
+ LayoutUnit kFragmentainerSpaceAvailable(200); |
+ |
+ NGBlockNode* node = new NGBlockNode( |
+ toLayoutBlockFlow(getLayoutObjectByElementId("container"))); |
+ auto* space = ConstructConstraintSpace( |
+ kHorizontalTopBottom, TextDirection::kLtr, |
+ NGLogicalSize(LayoutUnit(1000), NGSizeIndefinite), false, |
+ kFragmentainerSpaceAvailable); |
+ |
+ RefPtr<const NGPhysicalFragment> fragment = |
+ NGBlockLayoutAlgorithm(node, space).Layout()->PhysicalFragment(); |
+ EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(200)), fragment->Size()); |
+ ASSERT_FALSE(fragment->BreakToken()->IsFinished()); |
+ |
+ FragmentChildIterator iterator(toNGPhysicalBoxFragment(fragment.get())); |
+ const NGPhysicalBoxFragment* child = iterator.NextChild(); |
+ EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(180)), child->Size()); |
+ EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(20)), child->Offset()); |
+ |
+ EXPECT_FALSE(iterator.NextChild()); |
+ |
+ fragment = NGBlockLayoutAlgorithm(node, space, |
+ toNGBlockBreakToken(fragment->BreakToken())) |
+ .Layout() |
+ ->PhysicalFragment(); |
+ EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(140)), fragment->Size()); |
+ ASSERT_TRUE(fragment->BreakToken()->IsFinished()); |
+ |
+ iterator.SetParent(toNGPhysicalBoxFragment(fragment.get())); |
+ child = iterator.NextChild(); |
+ EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(20)), child->Size()); |
+ EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(0)), child->Offset()); |
+ |
+ child = iterator.NextChild(); |
+ EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(100)), child->Size()); |
+ EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(40)), child->Offset()); |
+ |
+ EXPECT_FALSE(iterator.NextChild()); |
+} |
+ |
+// Tests that children inside which establish new formatting contexts fragment |
mstensho (USE GERRIT)
2017/02/27 13:44:36
Comment is the same as the one before the previous
ikilpatrick
2017/02/27 18:50:09
Done.
|
+// correctly. |
+TEST_F(NGBlockLayoutAlgorithmTest, InnerChildrenFragmentationSmallHeight) { |
+ setBodyInnerHTML(R"HTML( |
+ <!DOCTYPE html> |
+ <style> |
+ #container { |
+ width: 150px; |
+ padding-top: 20px; |
+ height: 50px; |
+ } |
+ #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(getLayoutObjectByElementId("container"))); |
+ auto* space = ConstructConstraintSpace( |
+ kHorizontalTopBottom, TextDirection::kLtr, |
+ NGLogicalSize(LayoutUnit(1000), NGSizeIndefinite), false, |
+ kFragmentainerSpaceAvailable); |
+ |
+ RefPtr<const NGPhysicalFragment> fragment = |
+ NGBlockLayoutAlgorithm(node, space).Layout()->PhysicalFragment(); |
+ EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(70)), fragment->Size()); |
+ ASSERT_FALSE(fragment->BreakToken()->IsFinished()); |
+ |
+ FragmentChildIterator iterator(toNGPhysicalBoxFragment(fragment.get())); |
+ const NGPhysicalBoxFragment* child = iterator.NextChild(); |
+ EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(180)), child->Size()); |
+ EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(20)), child->Offset()); |
+ |
+ EXPECT_FALSE(iterator.NextChild()); |
+ |
+ fragment = NGBlockLayoutAlgorithm(node, space, |
+ toNGBlockBreakToken(fragment->BreakToken())) |
+ .Layout() |
+ ->PhysicalFragment(); |
+ EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(0)), fragment->Size()); |
+ ASSERT_TRUE(fragment->BreakToken()->IsFinished()); |
+ |
+ iterator.SetParent(toNGPhysicalBoxFragment(fragment.get())); |
+ child = iterator.NextChild(); |
+ EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(20)), child->Size()); |
+ EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(0)), child->Offset()); |
+ |
+ child = iterator.NextChild(); |
+ EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(100)), child->Size()); |
+ EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(40)), child->Offset()); |
+ |
+ EXPECT_FALSE(iterator.NextChild()); |
+} |
+ |
} // namespace |
} // namespace blink |