| // Copyright 2015 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "core/layout/LayoutBlockFlow.h" |
| #include "core/layout/LayoutMultiColumnFlowThread.h" |
| |
| #include "core/layout/LayoutTestHelper.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace blink { |
| |
| class PaginationStrutTest : public RenderingTest { |
| public: |
| int StrutForBox(const char* block_id) { |
| LayoutObject* layout_object = GetLayoutObjectByElementId(block_id); |
| if (!layout_object || !layout_object->IsBox()) |
| return std::numeric_limits<int>::min(); |
| LayoutBox* box = ToLayoutBox(layout_object); |
| return box->PaginationStrut().ToInt(); |
| } |
| |
| int StrutForLine(const char* container_id, int line_index) { |
| LayoutObject* layout_object = GetLayoutObjectByElementId(container_id); |
| if (!layout_object || !layout_object->IsLayoutBlockFlow()) |
| return std::numeric_limits<int>::min(); |
| LayoutBlockFlow* block = ToLayoutBlockFlow(layout_object); |
| if (block->MultiColumnFlowThread()) |
| block = block->MultiColumnFlowThread(); |
| for (RootInlineBox *line = block->FirstRootBox(); line; |
| line = line->NextRootBox(), line_index--) { |
| if (line_index) |
| continue; |
| return line->PaginationStrut().ToInt(); |
| } |
| return std::numeric_limits<int>::min(); |
| } |
| }; |
| |
| TEST_F(PaginationStrutTest, LineWithStrut) { |
| SetBodyInnerHTML( |
| "<div id='paged' style='overflow:-webkit-paged-y; height:200px; " |
| "line-height:150px;'>" |
| " line1<br>" |
| " line2<br>" |
| "</div>"); |
| EXPECT_EQ(0, StrutForLine("paged", 0)); |
| EXPECT_EQ(50, StrutForLine("paged", 1)); |
| } |
| |
| TEST_F(PaginationStrutTest, BlockWithStrut) { |
| SetBodyInnerHTML( |
| "<div style='overflow:-webkit-paged-y; height:200px; line-height:150px;'>" |
| " <div id='block1'>line1</div>" |
| " <div id='block2'>line2</div>" |
| "</div>"); |
| EXPECT_EQ(0, StrutForBox("block1")); |
| EXPECT_EQ(0, StrutForLine("block1", 0)); |
| EXPECT_EQ(50, StrutForBox("block2")); |
| EXPECT_EQ(0, StrutForLine("block2", 0)); |
| } |
| |
| TEST_F(PaginationStrutTest, FloatWithStrut) { |
| SetBodyInnerHTML( |
| "<div style='overflow:-webkit-paged-y; height:200px; line-height:150px;'>" |
| " <div style='height:120px;'></div>" |
| " <div id='float' style='float:left;'>line</div>" |
| "</div>"); |
| EXPECT_EQ(80, StrutForBox("float")); |
| EXPECT_EQ(0, StrutForLine("float", 0)); |
| } |
| |
| TEST_F(PaginationStrutTest, UnbreakableBlockWithStrut) { |
| SetBodyInnerHTML( |
| "<style>img { display:block; width:100px; height:150px; outline:4px " |
| "solid blue; padding:0; border:none; margin:0; }</style>" |
| "<div style='overflow:-webkit-paged-y; height:200px;'>" |
| " <img id='img1'>" |
| " <img id='img2'>" |
| "</div>"); |
| EXPECT_EQ(0, StrutForBox("img1")); |
| EXPECT_EQ(50, StrutForBox("img2")); |
| } |
| |
| TEST_F(PaginationStrutTest, BreakBefore) { |
| SetBodyInnerHTML( |
| "<div style='overflow:-webkit-paged-y; height:400px; line-height:50px;'>" |
| " <div id='block1'>line1</div>" |
| " <div id='block2' style='break-before:page;'>line2</div>" |
| "</div>"); |
| EXPECT_EQ(0, StrutForBox("block1")); |
| EXPECT_EQ(0, StrutForLine("block1", 0)); |
| EXPECT_EQ(350, StrutForBox("block2")); |
| EXPECT_EQ(0, StrutForLine("block2", 0)); |
| } |
| |
| TEST_F(PaginationStrutTest, BlockWithStrutPropagatedFromInnerBlock) { |
| SetBodyInnerHTML( |
| "<div style='overflow:-webkit-paged-y; height:200px; line-height:150px;'>" |
| " <div id='block1'>line1</div>" |
| " <div id='block2' style='padding-top:2px;'>" |
| " <div id='innerBlock' style='padding-top:2px;'>line2</div>" |
| " </div>" |
| "</div>"); |
| EXPECT_EQ(0, StrutForBox("block1")); |
| EXPECT_EQ(0, StrutForLine("block1", 0)); |
| EXPECT_EQ(50, StrutForBox("block2")); |
| EXPECT_EQ(0, StrutForBox("innerBlock")); |
| EXPECT_EQ(0, StrutForLine("innerBlock", 0)); |
| } |
| |
| TEST_F(PaginationStrutTest, BlockWithStrutPropagatedFromUnbreakableInnerBlock) { |
| SetBodyInnerHTML( |
| "<div style='overflow:-webkit-paged-y; height:400px; line-height:150px;'>" |
| " <div id='block1'>line1</div>" |
| " <div id='block2' style='padding-top:2px;'>" |
| " <div id='innerBlock' style='padding-top:2px; " |
| "break-inside:avoid;'>" |
| " line2<br>" |
| " line3<br>" |
| " </div>" |
| " </div>" |
| "</div>"); |
| EXPECT_EQ(0, StrutForBox("block1")); |
| EXPECT_EQ(0, StrutForLine("block1", 0)); |
| EXPECT_EQ(250, StrutForBox("block2")); |
| EXPECT_EQ(0, StrutForBox("innerBlock")); |
| EXPECT_EQ(0, StrutForLine("innerBlock", 0)); |
| EXPECT_EQ(0, StrutForLine("innerBlock", 1)); |
| } |
| |
| TEST_F(PaginationStrutTest, InnerBlockWithBreakBefore) { |
| SetBodyInnerHTML( |
| "<div style='overflow:-webkit-paged-y; height:200px; line-height:150px;'>" |
| " <div id='block1'>line1</div>" |
| " <div id='block2' style='padding-top:2px;'>" |
| " <div id='innerBlock' style='padding-top:2px; " |
| "break-before:page;'>line2</div>" |
| " </div>" |
| "</div>"); |
| EXPECT_EQ(0, StrutForBox("block1")); |
| EXPECT_EQ(0, StrutForLine("block1", 0)); |
| // There's no class A break point before #innerBlock (they only exist |
| // *between* siblings), so the break is propagated and applied before #block2. |
| EXPECT_EQ(50, StrutForBox("block2")); |
| EXPECT_EQ(0, StrutForBox("innerBlock")); |
| EXPECT_EQ(0, StrutForLine("innerBlock", 0)); |
| } |
| |
| } // namespace blink |