OLD | NEW |
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" |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 child = static_cast<const NGPhysicalBoxFragment*>(child)->Children()[0].get(); | 188 child = static_cast<const NGPhysicalBoxFragment*>(child)->Children()[0].get(); |
189 | 189 |
190 EXPECT_EQ(kHeight, child->Height()); | 190 EXPECT_EQ(kHeight, child->Height()); |
191 EXPECT_EQ(0, child->TopOffset()); | 191 EXPECT_EQ(0, child->TopOffset()); |
192 EXPECT_EQ(kMarginLeft, child->LeftOffset()); | 192 EXPECT_EQ(kMarginLeft, child->LeftOffset()); |
193 } | 193 } |
194 | 194 |
195 // Verifies that floats are positioned at the top of the first child that can | 195 // Verifies that floats are positioned at the top of the first child that can |
196 // determine its position after margins collapsed. | 196 // determine its position after margins collapsed. |
197 TEST_F(NGBlockLayoutAlgorithmTest, CollapsingMarginsCase1WithFloats) { | 197 TEST_F(NGBlockLayoutAlgorithmTest, CollapsingMarginsCase1WithFloats) { |
198 setBodyInnerHTML( | 198 setBodyInnerHTML(R"HTML( |
199 "<style>" | 199 <style> |
200 " #container {" | 200 #container { |
201 " height: 200px;" | 201 height: 200px; |
202 " width: 200px;" | 202 width: 200px; |
203 " margin-top: 10px;" | 203 margin-top: 10px; |
204 " padding: 0 7px;" | 204 padding: 0 7px; |
205 " background-color: red;" | 205 background-color: red; |
206 " }" | 206 } |
207 " #first-child {" | 207 #first-child { |
208 " margin-top: 20px;" | 208 margin-top: 20px; |
209 " height: 10px;" | 209 height: 10px; |
210 " background-color: blue;" | 210 background-color: blue; |
211 " }" | 211 } |
212 " #float-child-left {" | 212 #float-child-left { |
213 " float: left;" | 213 float: left; |
214 " height: 10px;" | 214 height: 10px; |
215 " width: 10px;" | 215 width: 10px; |
216 " padding: 10px;" | 216 padding: 10px; |
217 " margin: 10px;" | 217 margin: 10px; |
218 " background-color: green;" | 218 background-color: green; |
219 " }" | 219 } |
220 " #float-child-right {" | 220 #float-child-right { |
221 " float: right;" | 221 float: right; |
222 " height: 30px;" | 222 height: 30px; |
223 " width: 30px;" | 223 width: 30px; |
224 " background-color: pink;" | 224 background-color: pink; |
225 " }" | 225 } |
226 "</style>" | 226 </style> |
227 "<div id='container'>" | 227 <div id='container'> |
228 " <div id='float-child-left'></div>" | 228 <div id='float-child-left'></div> |
229 " <div id='float-child-right'></div>" | 229 <div id='float-child-right'></div> |
230 " <div id='first-child'></div>" | 230 <div id='first-child'></div> |
231 "</div>"); | 231 </div> |
| 232 )HTML"); |
232 | 233 |
233 // ** Run LayoutNG algorithm ** | 234 // ** Run LayoutNG algorithm ** |
234 NGConstraintSpace* space; | 235 NGConstraintSpace* space; |
235 RefPtr<NGPhysicalBoxFragment> fragment; | 236 RefPtr<NGPhysicalBoxFragment> fragment; |
236 std::tie(fragment, space) = RunBlockLayoutAlgorithmForElement( | 237 std::tie(fragment, space) = RunBlockLayoutAlgorithmForElement( |
237 document().getElementsByTagName("html")->item(0)); | 238 document().getElementsByTagName("html")->item(0)); |
238 ASSERT_EQ(fragment->Children().size(), 1UL); | 239 ASSERT_EQ(fragment->Children().size(), 1UL); |
239 auto* body_fragment = toNGPhysicalBoxFragment(fragment->Children()[0].get()); | 240 auto* body_fragment = toNGPhysicalBoxFragment(fragment->Children()[0].get()); |
240 // 20 = max(first child's margin top, containers's margin top) | 241 // 20 = max(first child's margin top, containers's margin top) |
241 int body_top_offset = 20; | 242 int body_top_offset = 20; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 (ElementsAre(Pointee(expected_exclusion1), | 298 (ElementsAre(Pointee(expected_exclusion1), |
298 Pointee(expected_exclusion2)))); | 299 Pointee(expected_exclusion2)))); |
299 } | 300 } |
300 | 301 |
301 // Verifies the collapsing margins case for the next pairs: | 302 // Verifies the collapsing margins case for the next pairs: |
302 // - bottom margin of box and top margin of its next in-flow following sibling. | 303 // - bottom margin of box and top margin of its next in-flow following sibling. |
303 // - top and bottom margins of a box that does not establish a new block | 304 // - top and bottom margins of a box that does not establish a new block |
304 // formatting context and that has zero computed 'min-height', zero or 'auto' | 305 // formatting context and that has zero computed 'min-height', zero or 'auto' |
305 // computed 'height', and no in-flow children | 306 // computed 'height', and no in-flow children |
306 TEST_F(NGBlockLayoutAlgorithmTest, CollapsingMarginsCase2WithFloats) { | 307 TEST_F(NGBlockLayoutAlgorithmTest, CollapsingMarginsCase2WithFloats) { |
307 setBodyInnerHTML( | 308 setBodyInnerHTML(R"HTML( |
308 "<style>" | 309 <style> |
309 "#first-child {" | 310 #first-child { |
310 " background-color: red;" | 311 background-color: red; |
311 " height: 50px;" | 312 height: 50px; |
312 " margin-bottom: 20px;" | 313 margin-bottom: 20px; |
313 "}" | 314 } |
314 "#float-between-empties {" | 315 #float-between-empties { |
315 " background-color: green;" | 316 background-color: green; |
316 " float: left;" | 317 float: left; |
317 " height: 30px;" | 318 height: 30px; |
318 " width: 30px;" | 319 width: 30px; |
319 "}" | 320 } |
320 "#float-between-nonempties {" | 321 #float-between-nonempties { |
321 " background-color: lightgreen;" | 322 background-color: lightgreen; |
322 " float: left;" | 323 float: left; |
323 " height: 40px;" | 324 height: 40px; |
324 " width: 40px;" | 325 width: 40px; |
325 "}" | 326 } |
326 "#float-top-align {" | 327 #float-top-align { |
327 " background-color: seagreen;" | 328 background-color: seagreen; |
328 " float: left;" | 329 float: left; |
329 " height: 50px;" | 330 height: 50px; |
330 " width: 50px;" | 331 width: 50px; |
331 "}" | 332 } |
332 "#second-child {" | 333 #second-child { |
333 " background-color: blue;" | 334 background-color: blue; |
334 " height: 50px;" | 335 height: 50px; |
335 " margin-top: 10px;" | 336 margin-top: 10px; |
336 "}" | 337 } |
337 "</style>" | 338 </style> |
338 "<div id='first-child'>" | 339 <div id='first-child'> |
339 " <div id='empty1' style='margin-bottom: -15px'></div>" | 340 <div id='empty1' style='margin-bottom: -15px'></div> |
340 " <div id='float-between-empties'></div>" | 341 <div id='float-between-empties'></div> |
341 " <div id='empty2'></div>" | 342 <div id='empty2'></div> |
342 "</div>" | 343 </div> |
343 "<div id='float-between-nonempties'></div>" | 344 <div id='float-between-nonempties'></div> |
344 "<div id='second-child'>" | 345 <div id='second-child'> |
345 " <div id='float-top-align'></div>" | 346 <div id='float-top-align'></div> |
346 " <div id='empty3'></div>" | 347 <div id='empty3'></div> |
347 " <div id='empty4' style='margin-top: -30px'></div>" | 348 <div id='empty4' style='margin-top: -30px'></div> |
348 "</div>" | 349 </div> |
349 "<div id='empty5'></div>"); | 350 <div id='empty5'></div> |
| 351 )HTML"); |
350 | 352 |
351 // ** Run LayoutNG algorithm ** | 353 // ** Run LayoutNG algorithm ** |
352 NGConstraintSpace* space; | 354 NGConstraintSpace* space; |
353 RefPtr<NGPhysicalBoxFragment> fragment; | 355 RefPtr<NGPhysicalBoxFragment> fragment; |
354 std::tie(fragment, space) = RunBlockLayoutAlgorithmForElement( | 356 std::tie(fragment, space) = RunBlockLayoutAlgorithmForElement( |
355 document().getElementsByTagName("html")->item(0)); | 357 document().getElementsByTagName("html")->item(0)); |
356 | 358 |
357 auto* body_fragment = toNGPhysicalBoxFragment(fragment->Children()[0].get()); | 359 auto* body_fragment = toNGPhysicalBoxFragment(fragment->Children()[0].get()); |
358 // -7 = empty1's margin(-15) + body's margin(8) | 360 // -7 = empty1's margin(-15) + body's margin(8) |
359 int body_top_offset = -7; | 361 int body_top_offset = -7; |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
428 EXPECT_THAT(space->Exclusions()->storage, | 430 EXPECT_THAT(space->Exclusions()->storage, |
429 (ElementsAre(Pointee(float_empties_exclusion), | 431 (ElementsAre(Pointee(float_empties_exclusion), |
430 Pointee(float_nonempties_exclusion), | 432 Pointee(float_nonempties_exclusion), |
431 Pointee(float_top_align_exclusion)))); | 433 Pointee(float_top_align_exclusion)))); |
432 } | 434 } |
433 | 435 |
434 // Verifies the collapsing margins case for the next pair: | 436 // Verifies the collapsing margins case for the next pair: |
435 // - bottom margin of a last in-flow child and bottom margin of its parent if | 437 // - bottom margin of a last in-flow child and bottom margin of its parent if |
436 // the parent has 'auto' computed height | 438 // the parent has 'auto' computed height |
437 TEST_F(NGBlockLayoutAlgorithmTest, CollapsingMarginsCase3) { | 439 TEST_F(NGBlockLayoutAlgorithmTest, CollapsingMarginsCase3) { |
438 setBodyInnerHTML( | 440 setBodyInnerHTML(R"HTML( |
439 "<style>" | 441 <style> |
440 " #container {" | 442 #container { |
441 " margin-bottom: 20px;" | 443 margin-bottom: 20px; |
442 " }" | 444 } |
443 " #child {" | 445 #child { |
444 " margin-bottom: 200px;" | 446 margin-bottom: 200px; |
445 " height: 50px;" | 447 height: 50px; |
446 " }" | 448 } |
447 "</style>" | 449 </style> |
448 "<div id='container'>" | 450 <div id='container'> |
449 " <div id='child'></div>" | 451 <div id='child'></div> |
450 "</div>"); | 452 </div> |
| 453 )HTML"); |
451 | 454 |
452 const NGPhysicalBoxFragment* body_fragment; | 455 const NGPhysicalBoxFragment* body_fragment; |
453 const NGPhysicalBoxFragment* container_fragment; | 456 const NGPhysicalBoxFragment* container_fragment; |
454 const NGPhysicalBoxFragment* child_fragment; | 457 const NGPhysicalBoxFragment* child_fragment; |
455 RefPtr<const NGPhysicalBoxFragment> fragment; | 458 RefPtr<const NGPhysicalBoxFragment> fragment; |
456 auto run_test = [&](const Length& container_height) { | 459 auto run_test = [&](const Length& container_height) { |
457 Element* container = document().getElementById("container"); | 460 Element* container = document().getElementById("container"); |
458 container->mutableComputedStyle()->setHeight(container_height); | 461 container->mutableComputedStyle()->setHeight(container_height); |
459 std::tie(fragment, std::ignore) = RunBlockLayoutAlgorithmForElement( | 462 std::tie(fragment, std::ignore) = RunBlockLayoutAlgorithmForElement( |
460 document().getElementsByTagName("html")->item(0)); | 463 document().getElementsByTagName("html")->item(0)); |
(...skipping 18 matching lines...) Expand all Loading... |
479 run_test(Length(50, Fixed)); | 482 run_test(Length(50, Fixed)); |
480 // Margins are not collapsed, so fragment still has margins == 20. | 483 // Margins are not collapsed, so fragment still has margins == 20. |
481 // The fragment size 78 == body's margin 8 + child's height 50 + 20 | 484 // The fragment size 78 == body's margin 8 + child's height 50 + 20 |
482 EXPECT_EQ(NGPhysicalSize(LayoutUnit(800), LayoutUnit(78)), fragment->Size()); | 485 EXPECT_EQ(NGPhysicalSize(LayoutUnit(800), LayoutUnit(78)), fragment->Size()); |
483 EXPECT_EQ(NGMarginStrut(), container_fragment->EndMarginStrut()); | 486 EXPECT_EQ(NGMarginStrut(), container_fragment->EndMarginStrut()); |
484 } | 487 } |
485 | 488 |
486 // Verifies that 2 adjoining margins are not collapsed if there is padding or | 489 // Verifies that 2 adjoining margins are not collapsed if there is padding or |
487 // border that separates them. | 490 // border that separates them. |
488 TEST_F(NGBlockLayoutAlgorithmTest, CollapsingMarginsCase4) { | 491 TEST_F(NGBlockLayoutAlgorithmTest, CollapsingMarginsCase4) { |
489 setBodyInnerHTML( | 492 setBodyInnerHTML(R"HTML( |
490 "<style>" | 493 <style> |
491 " #container {" | 494 #container { |
492 " margin: 30px 0px;" | 495 margin: 30px 0px; |
493 " width: 200px;" | 496 width: 200px; |
494 " }" | 497 } |
495 " #child {" | 498 #child { |
496 " margin: 200px 0px;" | 499 margin: 200px 0px; |
497 " height: 50px;" | 500 height: 50px; |
498 " background-color: blue;" | 501 background-color: blue; |
499 " }" | 502 } |
500 "</style>" | 503 </style> |
501 "<div id='container'>" | 504 <div id='container'> |
502 " <div id='child'></div>" | 505 <div id='child'></div> |
503 "</div>"); | 506 </div> |
| 507 )HTML"); |
504 | 508 |
505 const NGPhysicalBoxFragment* body_fragment; | 509 const NGPhysicalBoxFragment* body_fragment; |
506 const NGPhysicalBoxFragment* container_fragment; | 510 const NGPhysicalBoxFragment* container_fragment; |
507 const NGPhysicalBoxFragment* child_fragment; | 511 const NGPhysicalBoxFragment* child_fragment; |
508 RefPtr<const NGPhysicalBoxFragment> fragment; | 512 RefPtr<const NGPhysicalBoxFragment> fragment; |
509 auto run_test = [&](const Length& container_padding_top) { | 513 auto run_test = [&](const Length& container_padding_top) { |
510 Element* container = document().getElementById("container"); | 514 Element* container = document().getElementById("container"); |
511 container->mutableComputedStyle()->setPaddingTop(container_padding_top); | 515 container->mutableComputedStyle()->setPaddingTop(container_padding_top); |
512 std::tie(fragment, std::ignore) = RunBlockLayoutAlgorithmForElement( | 516 std::tie(fragment, std::ignore) = RunBlockLayoutAlgorithmForElement( |
513 document().getElementsByTagName("html")->item(0)); | 517 document().getElementsByTagName("html")->item(0)); |
(...skipping 23 matching lines...) Expand all Loading... |
537 EXPECT_EQ(NGPhysicalSize(LayoutUnit(800), LayoutUnit(450)), fragment->Size()); | 541 EXPECT_EQ(NGPhysicalSize(LayoutUnit(800), LayoutUnit(450)), fragment->Size()); |
538 // 200 = (body's margin 8, container's margin 30, child's margin 200) | 542 // 200 = (body's margin 8, container's margin 30, child's margin 200) |
539 EXPECT_EQ(LayoutUnit(200), body_fragment->TopOffset()); | 543 EXPECT_EQ(LayoutUnit(200), body_fragment->TopOffset()); |
540 // 0 = collapsed margins | 544 // 0 = collapsed margins |
541 EXPECT_EQ(LayoutUnit(0), child_fragment->TopOffset()); | 545 EXPECT_EQ(LayoutUnit(0), child_fragment->TopOffset()); |
542 } | 546 } |
543 | 547 |
544 // Verifies that margins of 2 adjoining blocks with different writing modes | 548 // Verifies that margins of 2 adjoining blocks with different writing modes |
545 // get collapsed. | 549 // get collapsed. |
546 TEST_F(NGBlockLayoutAlgorithmTest, CollapsingMarginsCase5) { | 550 TEST_F(NGBlockLayoutAlgorithmTest, CollapsingMarginsCase5) { |
547 setBodyInnerHTML( | 551 setBodyInnerHTML(R"HTML( |
548 "<style>" | 552 <style> |
549 // TODO(glebl): Remove the fixed height | 553 #container { |
550 // Fix this once min/max algorithm handles orthogonal children. | 554 margin-top: 10px; |
551 " body {" | 555 writing-mode: vertical-lr; |
552 " height: 500px;" | 556 } |
553 " }" | 557 #vertical { |
554 " #container {" | 558 margin-right: 90px; |
555 " margin-top: 10px;" | 559 background-color: red; |
556 // TODO(glebl): Remove the fixed height | 560 height: 70px; |
557 // Fix this once min/max algorithm handles orthogonal children. | 561 width: 30px; |
558 " width: 500px;" | 562 } |
559 " writing-mode: vertical-lr;" | 563 #horizontal { |
560 " }" | 564 background-color: blue; |
561 " #vertical {" | 565 margin-left: 100px; |
562 " margin-right: 90px;" | 566 writing-mode: horizontal-tb; |
563 " background-color: red;" | 567 height: 60px; |
564 " height: 70px;" | 568 width: 30px; |
565 " width: 30px;" | 569 } |
566 " }" | 570 </style> |
567 " #horizontal {" | 571 <div id='container'> |
568 " background-color: blue;" | 572 <div id='vertical'></div> |
569 " margin-left: 100px;" | 573 <div id='horizontal'></div> |
570 " writing-mode: horizontal-tb;" | 574 </div> |
571 " height: 60px;" | 575 )HTML"); |
572 " width: 30px;" | |
573 " }" | |
574 "</style>" | |
575 "<div id='container'>" | |
576 " <div id='vertical'></div>" | |
577 " <div id='horizontal'></div>" | |
578 "</div>"); | |
579 RefPtr<NGPhysicalBoxFragment> fragment; | 576 RefPtr<NGPhysicalBoxFragment> fragment; |
580 std::tie(fragment, std::ignore) = RunBlockLayoutAlgorithmForElement( | 577 std::tie(fragment, std::ignore) = RunBlockLayoutAlgorithmForElement( |
581 document().getElementsByTagName("html")->item(0)); | 578 document().getElementsByTagName("html")->item(0)); |
582 | 579 |
583 // body | 580 // body |
584 auto* body_fragment = toNGPhysicalBoxFragment(fragment->Children()[0].get()); | 581 auto* body_fragment = toNGPhysicalBoxFragment(fragment->Children()[0].get()); |
585 // 10 = std::max(body's margin 8, container's margin top) | 582 // 10 = std::max(body's margin 8, container's margin top) |
586 int body_top_offset = 10; | 583 int body_top_offset = 10; |
587 EXPECT_THAT(body_fragment->TopOffset(), LayoutUnit(body_top_offset)); | 584 EXPECT_THAT(body_fragment->TopOffset(), LayoutUnit(body_top_offset)); |
588 int body_left_offset = 8; | 585 int body_left_offset = 8; |
589 EXPECT_THAT(body_fragment->LeftOffset(), LayoutUnit(body_left_offset)); | 586 EXPECT_THAT(body_fragment->LeftOffset(), LayoutUnit(body_left_offset)); |
590 // height = 70. std::max(vertical height's 70, horizontal's height's 60) | 587 // height = 70. std::max(vertical height's 70, horizontal's height's 60) |
591 // TODO(glebl): Should be 70! Fix this once min/max algorithm handles | 588 // TODO(glebl): Should be 70! Fix this once min/max algorithm handles |
592 // orthogonal children. | 589 // orthogonal children. |
593 int body_fragment_block_size = 500; | 590 int body_fragment_block_size = 130; |
594 ASSERT_EQ( | 591 ASSERT_EQ( |
595 NGPhysicalSize(LayoutUnit(784), LayoutUnit(body_fragment_block_size)), | 592 NGPhysicalSize(LayoutUnit(784), LayoutUnit(body_fragment_block_size)), |
596 body_fragment->Size()); | 593 body_fragment->Size()); |
597 ASSERT_EQ(1UL, body_fragment->Children().size()); | 594 ASSERT_EQ(1UL, body_fragment->Children().size()); |
598 | 595 |
599 // container | 596 // container |
600 auto* container_fragment = | 597 auto* container_fragment = |
601 toNGPhysicalBoxFragment(body_fragment->Children()[0].get()); | 598 toNGPhysicalBoxFragment(body_fragment->Children()[0].get()); |
602 // Container's margins are collapsed with body's fragment. | 599 // Container's margins are collapsed with body's fragment. |
603 EXPECT_THAT(container_fragment->TopOffset(), LayoutUnit()); | 600 EXPECT_THAT(container_fragment->TopOffset(), LayoutUnit()); |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
806 | 803 |
807 const NGPhysicalFragment* child = frag->Children()[0].get(); | 804 const NGPhysicalFragment* child = frag->Children()[0].get(); |
808 EXPECT_EQ(LayoutUnit(kChildWidth), child->Width()); | 805 EXPECT_EQ(LayoutUnit(kChildWidth), child->Width()); |
809 EXPECT_EQ(LayoutUnit(kPaddingLeft + 10), child->LeftOffset()); | 806 EXPECT_EQ(LayoutUnit(kPaddingLeft + 10), child->LeftOffset()); |
810 EXPECT_EQ(LayoutUnit(0), child->TopOffset()); | 807 EXPECT_EQ(LayoutUnit(0), child->TopOffset()); |
811 } | 808 } |
812 | 809 |
813 // Verifies that floats can be correctly positioned if they are inside of nested | 810 // Verifies that floats can be correctly positioned if they are inside of nested |
814 // empty blocks. | 811 // empty blocks. |
815 TEST_F(NGBlockLayoutAlgorithmTest, PositionFloatInsideEmptyBlocks) { | 812 TEST_F(NGBlockLayoutAlgorithmTest, PositionFloatInsideEmptyBlocks) { |
816 setBodyInnerHTML( | 813 setBodyInnerHTML(R"HTML( |
817 "<!DOCTYPE html>" | 814 <style> |
818 "<style>" | 815 #container { |
819 " #container {" | 816 height: 200px; |
820 " height: 200px;" | 817 width: 200px; |
821 " width: 200px;" | 818 } |
822 " }" | 819 #empty1 { |
823 " #empty1 {" | 820 margin: 20px; |
824 " margin: 20px;" | 821 padding: 0 20px; |
825 " padding: 0 20px;" | 822 } |
826 " }" | 823 #empty2 { |
827 " #empty2 {" | 824 margin: 15px; |
828 " margin: 15px;" | 825 padding: 0 15px; |
829 " padding: 0 15px;" | 826 } |
830 " }" | 827 #float { |
831 " #float {" | 828 float: left; |
832 " float: left;" | 829 height: 5px; |
833 " height: 5px;" | 830 width: 5px; |
834 " width: 5px;" | 831 padding: 10px; |
835 " padding: 10px;" | 832 margin: 10px; |
836 " margin: 10px;" | 833 background-color: green; |
837 " background-color: green;" | 834 } |
838 " }" | 835 </style> |
839 "</style>" | 836 <div id='container'> |
840 "<div id='container'>" | 837 <div id='empty1'> |
841 " <div id='empty1'>" | 838 <div id='empty2'> |
842 " <div id='empty2'>" | 839 <div id='float'></div> |
843 " <div id='float'></div>" | 840 </div> |
844 " </div>" | 841 </div> |
845 " </div>" | 842 </div> |
846 "</div>"); | 843 )HTML"); |
847 | 844 |
848 // ** Run LayoutNG algorithm ** | 845 // ** Run LayoutNG algorithm ** |
849 NGConstraintSpace* space; | 846 NGConstraintSpace* space; |
850 RefPtr<NGPhysicalBoxFragment> fragment; | 847 RefPtr<NGPhysicalBoxFragment> fragment; |
851 std::tie(fragment, space) = RunBlockLayoutAlgorithmForElement( | 848 std::tie(fragment, space) = RunBlockLayoutAlgorithmForElement( |
852 document().getElementsByTagName("html")->item(0)); | 849 document().getElementsByTagName("html")->item(0)); |
853 | 850 |
854 auto* body_fragment = toNGPhysicalBoxFragment(fragment->Children()[0].get()); | 851 auto* body_fragment = toNGPhysicalBoxFragment(fragment->Children()[0].get()); |
855 // 20 = std::max(empty1's margin, empty2's margin, body's margin) | 852 // 20 = std::max(empty1's margin, empty2's margin, body's margin) |
856 int body_top_offset = 20; | 853 int body_top_offset = 20; |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
905 ASSERT_TRUE(floating_object->isPlaced()); | 902 ASSERT_TRUE(floating_object->isPlaced()); |
906 // 80 = float_inline_offset(25) + accumulative offset of empty blocks(35 + 20) | 903 // 80 = float_inline_offset(25) + accumulative offset of empty blocks(35 + 20) |
907 EXPECT_THAT(LayoutUnit(80), floating_object->x()); | 904 EXPECT_THAT(LayoutUnit(80), floating_object->x()); |
908 // 10 = float's padding | 905 // 10 = float's padding |
909 EXPECT_THAT(LayoutUnit(10), floating_object->y()); | 906 EXPECT_THAT(LayoutUnit(10), floating_object->y()); |
910 } | 907 } |
911 | 908 |
912 // Verifies that left/right floating and regular blocks can be positioned | 909 // Verifies that left/right floating and regular blocks can be positioned |
913 // correctly by the algorithm. | 910 // correctly by the algorithm. |
914 TEST_F(NGBlockLayoutAlgorithmTest, PositionFloatFragments) { | 911 TEST_F(NGBlockLayoutAlgorithmTest, PositionFloatFragments) { |
915 setBodyInnerHTML( | 912 setBodyInnerHTML(R"HTML( |
916 "<style>" | 913 <style> |
917 " #container {" | 914 #container { |
918 " height: 200px;" | 915 height: 200px; |
919 " width: 200px;" | 916 width: 200px; |
920 " }" | 917 } |
921 " #left-float {" | 918 #left-float { |
922 " background-color: red;" | 919 background-color: red; |
923 " float:left;" | 920 float: left; |
924 " height: 30px;" | 921 height: 30px; |
925 " width: 30px;" | 922 width: 30px; |
926 " }" | 923 } |
927 " #left-wide-float {" | 924 #left-wide-float { |
928 " background-color: greenyellow;" | 925 background-color: greenyellow; |
929 " float:left;" | 926 float: left; |
930 " height: 30px;" | 927 height: 30px; |
931 " width: 180px;" | 928 width: 180px; |
932 " }" | 929 } |
933 " #regular {" | 930 #regular { |
934 " width: 40px;" | 931 width: 40px; |
935 " height: 40px;" | 932 height: 40px; |
936 " background-color: green;" | 933 background-color: green; |
937 " }" | 934 } |
938 " #right-float {" | 935 #right-float { |
939 " background-color: cyan;" | 936 background-color: cyan; |
940 " float:right;" | 937 float: right; |
941 " width: 50px;" | 938 width: 50px; |
942 " height: 50px;" | 939 height: 50px; |
943 " }" | 940 } |
944 " #left-float-with-margin {" | 941 #left-float-with-margin { |
945 " background-color: black;" | 942 background-color: black; |
946 " float:left;" | 943 float: left; |
947 " height: 120px;" | 944 height: 120px; |
948 " margin: 10px;" | 945 margin: 10px; |
949 " width: 120px;" | 946 width: 120px; |
950 " }" | 947 } |
951 "</style>" | 948 </style> |
952 "<div id='container'>" | 949 <div id='container'> |
953 " <div id='left-float'></div>" | 950 <div id='left-float'></div> |
954 " <div id='left-wide-float'></div>" | 951 <div id='left-wide-float'></div> |
955 " <div id='regular'></div>" | 952 <div id='regular'></div> |
956 " <div id='right-float'></div>" | 953 <div id='right-float'></div> |
957 " <div id='left-float-with-margin'></div>" | 954 <div id='left-float-with-margin'></div> |
958 "</div>"); | 955 </div> |
| 956 )HTML"); |
959 | 957 |
960 // ** Run LayoutNG algorithm ** | 958 // ** Run LayoutNG algorithm ** |
961 NGConstraintSpace* space; | 959 NGConstraintSpace* space; |
962 RefPtr<NGPhysicalBoxFragment> fragment; | 960 RefPtr<NGPhysicalBoxFragment> fragment; |
963 std::tie(fragment, space) = RunBlockLayoutAlgorithmForElement( | 961 std::tie(fragment, space) = RunBlockLayoutAlgorithmForElement( |
964 document().getElementsByTagName("html")->item(0)); | 962 document().getElementsByTagName("html")->item(0)); |
965 | 963 |
966 // ** Verify LayoutNG fragments and the list of positioned floats ** | 964 // ** Verify LayoutNG fragments and the list of positioned floats ** |
967 ASSERT_EQ(1UL, fragment->Children().size()); | 965 ASSERT_EQ(1UL, fragment->Children().size()); |
968 auto* body_fragment = toNGPhysicalBoxFragment(fragment->Children()[0].get()); | 966 auto* body_fragment = toNGPhysicalBoxFragment(fragment->Children()[0].get()); |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1077 | 1075 |
1078 EXPECT_THAT( | 1076 EXPECT_THAT( |
1079 space->Exclusions()->storage, | 1077 space->Exclusions()->storage, |
1080 (ElementsAre(Pointee(left_float_exclusion), Pointee(left_wide_exclusion), | 1078 (ElementsAre(Pointee(left_float_exclusion), Pointee(left_wide_exclusion), |
1081 Pointee(right_float_exclusion), | 1079 Pointee(right_float_exclusion), |
1082 Pointee(left_float_with_margin_exclusion)))); | 1080 Pointee(left_float_with_margin_exclusion)))); |
1083 } | 1081 } |
1084 | 1082 |
1085 // Verifies that NG block layout algorithm respects "clear" CSS property. | 1083 // Verifies that NG block layout algorithm respects "clear" CSS property. |
1086 TEST_F(NGBlockLayoutAlgorithmTest, PositionFragmentsWithClear) { | 1084 TEST_F(NGBlockLayoutAlgorithmTest, PositionFragmentsWithClear) { |
1087 setBodyInnerHTML( | 1085 setBodyInnerHTML(R"HTML( |
1088 "<style>" | 1086 <style> |
1089 " #container {" | 1087 #container { |
1090 " height: 200px;" | 1088 height: 200px; |
1091 " width: 200px;" | 1089 width: 200px; |
1092 " }" | 1090 } |
1093 " #float-left {" | 1091 #float-left { |
1094 " background-color: red;" | 1092 background-color: red; |
1095 " float: left;" | 1093 float: left; |
1096 " height: 30px;" | 1094 height: 30px; |
1097 " width: 30px;" | 1095 width: 30px; |
1098 " }" | 1096 } |
1099 " #float-right {" | 1097 #float-right { |
1100 " background-color: blue;" | 1098 background-color: blue; |
1101 " float: right;" | 1099 float: right; |
1102 " height: 170px;" | 1100 height: 170px; |
1103 " width: 40px;" | 1101 width: 40px; |
1104 " }" | 1102 } |
1105 " #clearance {" | 1103 #clearance { |
1106 " background-color: yellow;" | 1104 background-color: yellow; |
1107 " height: 60px;" | 1105 height: 60px; |
1108 " width: 60px;" | 1106 width: 60px; |
1109 " margin: 20px;" | 1107 margin: 20px; |
1110 " }" | 1108 } |
1111 " #block {" | 1109 #block { |
1112 " margin: 40px;" | 1110 margin: 40px; |
1113 " background-color: black;" | 1111 background-color: black; |
1114 " height: 60px;" | 1112 height: 60px; |
1115 " width: 60px;" | 1113 width: 60px; |
1116 " }" | 1114 } |
1117 " #adjoining-clearance {" | 1115 #adjoining-clearance { |
1118 " background-color: green;" | 1116 background-color: green; |
1119 " clear: left;" | 1117 clear: left; |
1120 " height: 20px;" | 1118 height: 20px; |
1121 " width: 20px;" | 1119 width: 20px; |
1122 " margin: 30px;" | 1120 margin: 30px; |
1123 " }" | 1121 } |
1124 "</style>" | 1122 </style> |
1125 "<div id='container'>" | 1123 <div id='container'> |
1126 " <div id='float-left'></div>" | 1124 <div id='float-left'></div> |
1127 " <div id='float-right'></div>" | 1125 <div id='float-right'></div> |
1128 " <div id='clearance'></div>" | 1126 <div id='clearance'></div> |
1129 " <div id='block'></div>" | 1127 <div id='block'></div> |
1130 " <div id='adjoining-clearance'></div>" | 1128 <div id='adjoining-clearance'></div> |
1131 "</div>"); | 1129 </div> |
| 1130 )HTML"); |
1132 | 1131 |
1133 const NGPhysicalBoxFragment* clerance_fragment; | 1132 const NGPhysicalBoxFragment* clerance_fragment; |
1134 const NGPhysicalBoxFragment* body_fragment; | 1133 const NGPhysicalBoxFragment* body_fragment; |
1135 const NGPhysicalBoxFragment* container_fragment; | 1134 const NGPhysicalBoxFragment* container_fragment; |
1136 const NGPhysicalBoxFragment* block_fragment; | 1135 const NGPhysicalBoxFragment* block_fragment; |
1137 const NGPhysicalBoxFragment* adjoining_clearance_fragment; | 1136 const NGPhysicalBoxFragment* adjoining_clearance_fragment; |
1138 auto run_with_clearance = [&](EClear clear_value) { | 1137 auto run_with_clearance = [&](EClear clear_value) { |
1139 RefPtr<NGPhysicalBoxFragment> fragment; | 1138 RefPtr<NGPhysicalBoxFragment> fragment; |
1140 Element* el_with_clear = document().getElementById("clearance"); | 1139 Element* el_with_clear = document().getElementById("clearance"); |
1141 el_with_clear->mutableComputedStyle()->setClear(clear_value); | 1140 el_with_clear->mutableComputedStyle()->setClear(clear_value); |
(...skipping 858 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2000 EXPECT_EQ(LayoutUnit(194), fragment->LeftOffset()); | 1999 EXPECT_EQ(LayoutUnit(194), fragment->LeftOffset()); |
2001 EXPECT_EQ(LayoutUnit(), fragment->TopOffset()); | 2000 EXPECT_EQ(LayoutUnit(), fragment->TopOffset()); |
2002 EXPECT_EQ(LayoutUnit(16), fragment->Width()); | 2001 EXPECT_EQ(LayoutUnit(16), fragment->Width()); |
2003 EXPECT_EQ(LayoutUnit(50), fragment->Height()); | 2002 EXPECT_EQ(LayoutUnit(50), fragment->Height()); |
2004 EXPECT_EQ(0UL, fragment->Children().size()); | 2003 EXPECT_EQ(0UL, fragment->Children().size()); |
2005 EXPECT_FALSE(iterator.NextChild()); | 2004 EXPECT_FALSE(iterator.NextChild()); |
2006 } | 2005 } |
2007 | 2006 |
2008 } // namespace | 2007 } // namespace |
2009 } // namespace blink | 2008 } // namespace blink |
OLD | NEW |