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

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

Issue 2714803002: [LayoutNG] Allow block-flow layout to be fragmented using new approach. (Closed)
Patch Set: silly me... Created 3 years, 9 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 unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/layout/ng/ng_block_layout_algorithm.h" 5 #include "core/layout/ng/ng_block_layout_algorithm.h"
6 6
7 #include "core/dom/NodeComputedStyle.h" 7 #include "core/dom/NodeComputedStyle.h"
8 #include "core/dom/TagCollection.h" 8 #include "core/dom/TagCollection.h"
9 #include "core/layout/ng/layout_ng_block_flow.h" 9 #include "core/layout/ng/layout_ng_block_flow.h"
10 #include "core/layout/ng/ng_block_node.h" 10 #include "core/layout/ng/ng_block_node.h"
11 #include "core/layout/ng/ng_constraint_space.h" 11 #include "core/layout/ng/ng_constraint_space.h"
12 #include "core/layout/ng/ng_constraint_space_builder.h" 12 #include "core/layout/ng/ng_constraint_space_builder.h"
13 #include "core/layout/ng/ng_floating_object.h" 13 #include "core/layout/ng/ng_floating_object.h"
14 #include "core/layout/ng/ng_length_utils.h" 14 #include "core/layout/ng/ng_length_utils.h"
15 #include "core/layout/LayoutTestHelper.h" 15 #include "core/layout/LayoutTestHelper.h"
16 #include "core/layout/ng/ng_physical_box_fragment.h" 16 #include "core/layout/ng/ng_physical_box_fragment.h"
17 #include "core/layout/ng/ng_physical_fragment.h" 17 #include "core/layout/ng/ng_physical_fragment.h"
18 #include "core/layout/ng/ng_units.h" 18 #include "core/layout/ng/ng_units.h"
19 #include "core/style/ComputedStyle.h" 19 #include "core/style/ComputedStyle.h"
20 #include "testing/gmock/include/gmock/gmock.h" 20 #include "testing/gmock/include/gmock/gmock.h"
21 #include "testing/gtest/include/gtest/gtest.h" 21 #include "testing/gtest/include/gtest/gtest.h"
22 22
23 namespace blink { 23 namespace blink {
24 namespace { 24 namespace {
25 25
26 using testing::ElementsAre; 26 using testing::ElementsAre;
27 using testing::Pointee; 27 using testing::Pointee;
28 28
29 NGConstraintSpace* ConstructConstraintSpace(NGWritingMode writing_mode, 29 NGConstraintSpace* ConstructConstraintSpace(
30 TextDirection direction, 30 NGWritingMode writing_mode,
31 NGLogicalSize size, 31 TextDirection direction,
32 bool shrink_to_fit = false) { 32 NGLogicalSize size,
33 bool shrink_to_fit = false,
34 LayoutUnit fragmentainer_space_available = LayoutUnit()) {
35 NGFragmentationType block_fragmentation =
36 fragmentainer_space_available != LayoutUnit()
37 ? NGFragmentationType::kFragmentColumn
38 : NGFragmentationType::kFragmentNone;
39
33 return NGConstraintSpaceBuilder(writing_mode) 40 return NGConstraintSpaceBuilder(writing_mode)
34 .SetAvailableSize(size) 41 .SetAvailableSize(size)
35 .SetPercentageResolutionSize(size) 42 .SetPercentageResolutionSize(size)
36 .SetTextDirection(direction) 43 .SetTextDirection(direction)
37 .SetIsShrinkToFit(shrink_to_fit) 44 .SetIsShrinkToFit(shrink_to_fit)
45 .SetFragmentainerSpaceAvailable(fragmentainer_space_available)
46 .SetFragmentationType(block_fragmentation)
38 .ToConstraintSpace(writing_mode); 47 .ToConstraintSpace(writing_mode);
39 } 48 }
40 49
41 typedef bool TestParamLayoutNG; 50 typedef bool TestParamLayoutNG;
42 class NGBlockLayoutAlgorithmTest 51 class NGBlockLayoutAlgorithmTest
43 : public ::testing::WithParamInterface<TestParamLayoutNG>, 52 : public ::testing::WithParamInterface<TestParamLayoutNG>,
44 public RenderingTest { 53 public RenderingTest {
45 public: 54 public:
46 NGBlockLayoutAlgorithmTest() { 55 NGBlockLayoutAlgorithmTest() {
47 RuntimeEnabledFeatures::setLayoutNGEnabled(true); 56 RuntimeEnabledFeatures::setLayoutNGEnabled(true);
(...skipping 2041 matching lines...) Expand 10 before | Expand all | Expand 10 after
2089 EXPECT_THAT(NGPhysicalOffset(LayoutUnit(8), LayoutUnit(8)), 2098 EXPECT_THAT(NGPhysicalOffset(LayoutUnit(8), LayoutUnit(8)),
2090 empty_block1->Offset()); 2099 empty_block1->Offset());
2091 2100
2092 auto* empty_block2 = 2101 auto* empty_block2 =
2093 toNGPhysicalBoxFragment(container_fragment->Children()[1].get()); 2102 toNGPhysicalBoxFragment(container_fragment->Children()[1].get());
2094 // empty-block2's margin == 50 2103 // empty-block2's margin == 50
2095 EXPECT_THAT(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(50)), 2104 EXPECT_THAT(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(50)),
2096 empty_block2->Offset()); 2105 empty_block2->Offset());
2097 } 2106 }
2098 2107
2108 // Tests that a block child won't fragment if it doesn't reach the fragmentation
2109 // line.
2110 TEST_F(NGBlockLayoutAlgorithmTest, NoFragmentation) {
2111 setBodyInnerHTML(R"HTML(
2112 <!DOCTYPE html>
2113 <style>
2114 #container {
2115 width: 150px;
2116 height: 200px;
2117 }
2118 </style>
2119 <div id='container'></div>
2120 )HTML");
2121
2122 LayoutUnit kFragmentainerSpaceAvailable(200);
2123
2124 NGBlockNode* node = new NGBlockNode(
2125 toLayoutBlockFlow(getLayoutObjectByElementId("container")));
2126 auto* space = ConstructConstraintSpace(
2127 kHorizontalTopBottom, TextDirection::kLtr,
2128 NGLogicalSize(LayoutUnit(1000), NGSizeIndefinite), false,
2129 kFragmentainerSpaceAvailable);
2130
2131 // We should only have one 150x200 fragment with no fragmentation.
2132 RefPtr<const NGPhysicalFragment> fragment =
2133 NGBlockLayoutAlgorithm(node, space).Layout()->PhysicalFragment();
2134 EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(200)), fragment->Size());
2135 ASSERT_TRUE(fragment->BreakToken()->IsFinished());
2136 }
2137
2138 // 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
2139 TEST_F(NGBlockLayoutAlgorithmTest, SimpleFragmentation) {
2140 setBodyInnerHTML(R"HTML(
2141 <!DOCTYPE html>
2142 <style>
2143 #container {
2144 width: 150px;
2145 height: 300px;
2146 }
2147 </style>
2148 <div id='container'></div>
2149 )HTML");
2150
2151 LayoutUnit kFragmentainerSpaceAvailable(200);
2152
2153 NGBlockNode* node = new NGBlockNode(
2154 toLayoutBlockFlow(getLayoutObjectByElementId("container")));
2155 auto* space = ConstructConstraintSpace(
2156 kHorizontalTopBottom, TextDirection::kLtr,
2157 NGLogicalSize(LayoutUnit(1000), NGSizeIndefinite), false,
2158 kFragmentainerSpaceAvailable);
2159
2160 RefPtr<const NGPhysicalFragment> fragment =
2161 NGBlockLayoutAlgorithm(node, space).Layout()->PhysicalFragment();
2162 EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(200)), fragment->Size());
2163 ASSERT_FALSE(fragment->BreakToken()->IsFinished());
2164
2165 fragment = NGBlockLayoutAlgorithm(node, space,
2166 toNGBlockBreakToken(fragment->BreakToken()))
2167 .Layout()
2168 ->PhysicalFragment();
2169 EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(100)), fragment->Size());
2170 ASSERT_TRUE(fragment->BreakToken()->IsFinished());
2171 }
2172
2173 // Tests that children inside the same block formatting context fragment when
2174 // reaching a fragmentation line.
2175 TEST_F(NGBlockLayoutAlgorithmTest, InnerChildrenFragmentation) {
2176 setBodyInnerHTML(R"HTML(
2177 <!DOCTYPE html>
2178 <style>
2179 #container {
2180 width: 150px;
2181 padding-top: 20px;
2182 }
2183 #child1 {
2184 height: 200px;
2185 margin-bottom: 20px;
2186 }
2187 #child2 {
2188 height: 100px;
2189 margin-top: 20px;
2190 }
2191 </style>
2192 <div id='container'>
2193 <div id='child1'></div>
2194 <div id='child2'></div>
2195 </div>
2196 )HTML");
2197
2198 LayoutUnit kFragmentainerSpaceAvailable(200);
2199
2200 NGBlockNode* node = new NGBlockNode(
2201 toLayoutBlockFlow(getLayoutObjectByElementId("container")));
2202 auto* space = ConstructConstraintSpace(
2203 kHorizontalTopBottom, TextDirection::kLtr,
2204 NGLogicalSize(LayoutUnit(1000), NGSizeIndefinite), false,
2205 kFragmentainerSpaceAvailable);
2206
2207 RefPtr<const NGPhysicalFragment> fragment =
2208 NGBlockLayoutAlgorithm(node, space).Layout()->PhysicalFragment();
2209 EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(200)), fragment->Size());
2210 ASSERT_FALSE(fragment->BreakToken()->IsFinished());
2211
2212 FragmentChildIterator iterator(toNGPhysicalBoxFragment(fragment.get()));
2213 const NGPhysicalBoxFragment* child = iterator.NextChild();
2214 EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(180)), child->Size());
2215 EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(20)), child->Offset());
2216
2217 EXPECT_FALSE(iterator.NextChild());
2218
2219 fragment = NGBlockLayoutAlgorithm(node, space,
2220 toNGBlockBreakToken(fragment->BreakToken()))
2221 .Layout()
2222 ->PhysicalFragment();
2223 EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(140)), fragment->Size());
2224 ASSERT_TRUE(fragment->BreakToken()->IsFinished());
2225
2226 iterator.SetParent(toNGPhysicalBoxFragment(fragment.get()));
2227 child = iterator.NextChild();
2228 EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(20)), child->Size());
2229 EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(0)), child->Offset());
2230
2231 child = iterator.NextChild();
2232 EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(100)), child->Size());
2233 EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(40)), child->Offset());
2234
2235 EXPECT_FALSE(iterator.NextChild());
2236 }
2237
2238 // Tests that children inside which establish new formatting contexts fragment
2239 // correctly.
2240 TEST_F(NGBlockLayoutAlgorithmTest,
2241 InnerFormattingContextChildrenFragmentation) {
2242 setBodyInnerHTML(R"HTML(
2243 <!DOCTYPE html>
2244 <style>
2245 #container {
2246 width: 150px;
2247 padding-top: 20px;
2248 }
2249 #child1 {
2250 height: 200px;
2251 margin-bottom: 20px;
2252 contain: paint;
2253 }
2254 #child2 {
2255 height: 100px;
2256 margin-top: 20px;
2257 contain: paint;
2258 }
2259 </style>
2260 <div id='container'>
2261 <div id='child1'></div>
2262 <div id='child2'></div>
2263 </div>
2264 )HTML");
2265
2266 LayoutUnit kFragmentainerSpaceAvailable(200);
2267
2268 NGBlockNode* node = new NGBlockNode(
2269 toLayoutBlockFlow(getLayoutObjectByElementId("container")));
2270 auto* space = ConstructConstraintSpace(
2271 kHorizontalTopBottom, TextDirection::kLtr,
2272 NGLogicalSize(LayoutUnit(1000), NGSizeIndefinite), false,
2273 kFragmentainerSpaceAvailable);
2274
2275 RefPtr<const NGPhysicalFragment> fragment =
2276 NGBlockLayoutAlgorithm(node, space).Layout()->PhysicalFragment();
2277 EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(200)), fragment->Size());
2278 ASSERT_FALSE(fragment->BreakToken()->IsFinished());
2279
2280 FragmentChildIterator iterator(toNGPhysicalBoxFragment(fragment.get()));
2281 const NGPhysicalBoxFragment* child = iterator.NextChild();
2282 EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(180)), child->Size());
2283 EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(20)), child->Offset());
2284
2285 EXPECT_FALSE(iterator.NextChild());
2286
2287 fragment = NGBlockLayoutAlgorithm(node, space,
2288 toNGBlockBreakToken(fragment->BreakToken()))
2289 .Layout()
2290 ->PhysicalFragment();
2291 EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(140)), fragment->Size());
2292 ASSERT_TRUE(fragment->BreakToken()->IsFinished());
2293
2294 iterator.SetParent(toNGPhysicalBoxFragment(fragment.get()));
2295 child = iterator.NextChild();
2296 EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(20)), child->Size());
2297 EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(0)), child->Offset());
2298
2299 child = iterator.NextChild();
2300 EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(100)), child->Size());
2301 EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(40)), child->Offset());
2302
2303 EXPECT_FALSE(iterator.NextChild());
2304 }
2305
2306 // 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.
2307 // correctly.
2308 TEST_F(NGBlockLayoutAlgorithmTest, InnerChildrenFragmentationSmallHeight) {
2309 setBodyInnerHTML(R"HTML(
2310 <!DOCTYPE html>
2311 <style>
2312 #container {
2313 width: 150px;
2314 padding-top: 20px;
2315 height: 50px;
2316 }
2317 #child1 {
2318 height: 200px;
2319 margin-bottom: 20px;
2320 }
2321 #child2 {
2322 height: 100px;
2323 margin-top: 20px;
2324 }
2325 </style>
2326 <div id='container'>
2327 <div id='child1'></div>
2328 <div id='child2'></div>
2329 </div>
2330 )HTML");
2331
2332 LayoutUnit kFragmentainerSpaceAvailable(200);
2333
2334 NGBlockNode* node = new NGBlockNode(
2335 toLayoutBlockFlow(getLayoutObjectByElementId("container")));
2336 auto* space = ConstructConstraintSpace(
2337 kHorizontalTopBottom, TextDirection::kLtr,
2338 NGLogicalSize(LayoutUnit(1000), NGSizeIndefinite), false,
2339 kFragmentainerSpaceAvailable);
2340
2341 RefPtr<const NGPhysicalFragment> fragment =
2342 NGBlockLayoutAlgorithm(node, space).Layout()->PhysicalFragment();
2343 EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(70)), fragment->Size());
2344 ASSERT_FALSE(fragment->BreakToken()->IsFinished());
2345
2346 FragmentChildIterator iterator(toNGPhysicalBoxFragment(fragment.get()));
2347 const NGPhysicalBoxFragment* child = iterator.NextChild();
2348 EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(180)), child->Size());
2349 EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(20)), child->Offset());
2350
2351 EXPECT_FALSE(iterator.NextChild());
2352
2353 fragment = NGBlockLayoutAlgorithm(node, space,
2354 toNGBlockBreakToken(fragment->BreakToken()))
2355 .Layout()
2356 ->PhysicalFragment();
2357 EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(0)), fragment->Size());
2358 ASSERT_TRUE(fragment->BreakToken()->IsFinished());
2359
2360 iterator.SetParent(toNGPhysicalBoxFragment(fragment.get()));
2361 child = iterator.NextChild();
2362 EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(20)), child->Size());
2363 EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(0)), child->Offset());
2364
2365 child = iterator.NextChild();
2366 EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(100)), child->Size());
2367 EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(40)), child->Offset());
2368
2369 EXPECT_FALSE(iterator.NextChild());
2370 }
2371
2099 } // namespace 2372 } // namespace
2100 } // namespace blink 2373 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698