Chromium Code Reviews| 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 |