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

Side by Side Diff: third_party/WebKit/Source/core/layout/LayoutBoxModelObjectTest.cpp

Issue 2769353002: Only create sticky position constraints for constrained sticky position. (Closed)
Patch Set: Merge with master. Created 3 years, 8 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/LayoutBoxModelObject.h" 5 #include "core/layout/LayoutBoxModelObject.h"
6 6
7 #include "core/dom/DOMTokenList.h" 7 #include "core/dom/DOMTokenList.h"
8 #include "core/dom/DocumentLifecycle.h" 8 #include "core/dom/DocumentLifecycle.h"
9 #include "core/html/HTMLElement.h" 9 #include "core/html/HTMLElement.h"
10 #include "core/layout/ImageQualityController.h" 10 #include "core/layout/ImageQualityController.h"
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 // computing the sticky constraints. Any such ancestor is the first sticky 335 // computing the sticky constraints. Any such ancestor is the first sticky
336 // element between you and your containing block (exclusive). 336 // element between you and your containing block (exclusive).
337 // 337 //
338 // In most cases, this pointer should be null since your parent is normally your 338 // In most cases, this pointer should be null since your parent is normally your
339 // containing block. However there are cases where this is not true, including 339 // containing block. However there are cases where this is not true, including
340 // inline blocks and tables. The latter is currently irrelevant since only table 340 // inline blocks and tables. The latter is currently irrelevant since only table
341 // cells can be sticky in CSS2.1, but we can test the former. 341 // cells can be sticky in CSS2.1, but we can test the former.
342 TEST_F(LayoutBoxModelObjectTest, 342 TEST_F(LayoutBoxModelObjectTest,
343 StickyPositionFindsCorrectStickyBoxShiftingAncestor) { 343 StickyPositionFindsCorrectStickyBoxShiftingAncestor) {
344 SetBodyInnerHTML( 344 SetBodyInnerHTML(
345 "<style>#stickyOuterDiv { position: sticky; }" 345 "<style>#stickyOuterDiv { position: sticky; top: 0;}"
346 "#stickyOuterInline { position: sticky; display: inline; }" 346 "#stickyOuterInline { position: sticky; top: 0; display: inline; }"
347 "#stickyInnerInline { position: sticky; display: inline; }" 347 "#unanchoredSticky { position: sticky; display: inline; }"
348 ".inline { display: inline; }</style>" 348 ".inline { display: inline; }"
349 "#stickyInnerInline { position: sticky; top: 0; display: inline; "
350 "}</style>"
349 "<div id='stickyOuterDiv'>" 351 "<div id='stickyOuterDiv'>"
350 " <div id='stickyOuterInline'>" 352 " <div id='stickyOuterInline'>"
351 " <div class='inline'>" 353 " <div id='unanchoredSticky'>"
352 " <div id='stickyInnerInline'></div>" 354 " <div class='inline'>"
355 " <div id='stickyInnerInline'></div>"
356 " </div>"
353 " </div>" 357 " </div>"
354 " </div>" 358 " </div>"
355 "</div>"); 359 "</div>");
356 360
357 LayoutBoxModelObject* sticky_outer_div = 361 LayoutBoxModelObject* sticky_outer_div =
358 ToLayoutBoxModelObject(GetLayoutObjectByElementId("stickyOuterDiv")); 362 ToLayoutBoxModelObject(GetLayoutObjectByElementId("stickyOuterDiv"));
359 LayoutBoxModelObject* sticky_outer_inline = 363 LayoutBoxModelObject* sticky_outer_inline =
360 ToLayoutBoxModelObject(GetLayoutObjectByElementId("stickyOuterInline")); 364 ToLayoutBoxModelObject(GetLayoutObjectByElementId("stickyOuterInline"));
365 LayoutBoxModelObject* unanchored_sticky =
366 ToLayoutBoxModelObject(GetLayoutObjectByElementId("unanchoredSticky"));
361 LayoutBoxModelObject* sticky_inner_inline = 367 LayoutBoxModelObject* sticky_inner_inline =
362 ToLayoutBoxModelObject(GetLayoutObjectByElementId("stickyInnerInline")); 368 ToLayoutBoxModelObject(GetLayoutObjectByElementId("stickyInnerInline"));
363 369
364 PaintLayerScrollableArea* scrollable_area = 370 PaintLayerScrollableArea* scrollable_area =
365 sticky_outer_div->Layer()->AncestorOverflowLayer()->GetScrollableArea(); 371 sticky_outer_div->Layer()->AncestorOverflowLayer()->GetScrollableArea();
366 ASSERT_TRUE(scrollable_area); 372 ASSERT_TRUE(scrollable_area);
367 StickyConstraintsMap constraints_map = 373 StickyConstraintsMap constraints_map =
368 scrollable_area->GetStickyConstraintsMap(); 374 scrollable_area->GetStickyConstraintsMap();
369 375
370 ASSERT_TRUE(constraints_map.Contains(sticky_outer_div->Layer())); 376 ASSERT_TRUE(constraints_map.Contains(sticky_outer_div->Layer()));
371 ASSERT_TRUE(constraints_map.Contains(sticky_outer_inline->Layer())); 377 ASSERT_TRUE(constraints_map.Contains(sticky_outer_inline->Layer()));
378 ASSERT_FALSE(constraints_map.Contains(unanchored_sticky->Layer()));
372 ASSERT_TRUE(constraints_map.Contains(sticky_inner_inline->Layer())); 379 ASSERT_TRUE(constraints_map.Contains(sticky_inner_inline->Layer()));
373 380
374 // The outer block element trivially has no sticky-box shifting ancestor. 381 // The outer block element trivially has no sticky-box shifting ancestor.
375 EXPECT_FALSE(constraints_map.at(sticky_outer_div->Layer()) 382 EXPECT_FALSE(constraints_map.at(sticky_outer_div->Layer())
376 .NearestStickyBoxShiftingStickyBox()); 383 .NearestStickyBoxShiftingStickyBox());
377 384
378 // Neither does the outer inline element, as its parent element is also its 385 // Neither does the outer inline element, as its parent element is also its
379 // containing block. 386 // containing block.
380 EXPECT_FALSE(constraints_map.at(sticky_outer_inline->Layer()) 387 EXPECT_FALSE(constraints_map.at(sticky_outer_inline->Layer())
381 .NearestStickyBoxShiftingStickyBox()); 388 .NearestStickyBoxShiftingStickyBox());
382 389
383 // However the inner inline element does have a sticky-box shifting ancestor, 390 // However the inner inline element does have a sticky-box shifting ancestor,
384 // as its containing block is the ancestor block element, above its ancestor 391 // as its containing block is the ancestor block element, above its ancestor
385 // sticky element. 392 // sticky element.
386 EXPECT_EQ(sticky_outer_inline, 393 EXPECT_EQ(sticky_outer_inline,
387 constraints_map.at(sticky_inner_inline->Layer()) 394 constraints_map.at(sticky_inner_inline->Layer())
388 .NearestStickyBoxShiftingStickyBox()); 395 .NearestStickyBoxShiftingStickyBox());
389 } 396 }
390 397
391 // Verifies that the correct containing-block shifting ancestor is found when 398 // Verifies that the correct containing-block shifting ancestor is found when
392 // computing the sticky constraints. Any such ancestor is the first sticky 399 // computing the sticky constraints. Any such ancestor is the first sticky
393 // element between your containing block (inclusive) and your ancestor overflow 400 // element between your containing block (inclusive) and your ancestor overflow
394 // layer (exclusive). 401 // layer (exclusive).
395 TEST_F(LayoutBoxModelObjectTest, 402 TEST_F(LayoutBoxModelObjectTest,
396 StickyPositionFindsCorrectContainingBlockShiftingAncestor) { 403 StickyPositionFindsCorrectContainingBlockShiftingAncestor) {
397 // We make the scroller itself sticky in order to check that elements do not 404 // We make the scroller itself sticky in order to check that elements do not
398 // detect it as their containing-block shifting ancestor. 405 // detect it as their containing-block shifting ancestor.
399 SetBodyInnerHTML( 406 SetBodyInnerHTML(
400 "<style>#scroller { overflow-y: scroll; position: sticky; }" 407 "<style>#scroller { overflow-y: scroll; position: sticky; top: 0;}"
401 "#stickyParent { position: sticky; }" 408 "#stickyParent { position: sticky; top: 0;}"
402 "#stickyChild { position: sticky; }" 409 "#stickyChild { position: sticky; top: 0;}"
403 "#stickyNestedChild { position: sticky; }</style>" 410 "#unanchoredSticky { position: sticky; }"
404 "<div id='scroller'><div id='stickyParent'><div id='stickyChild'></div>" 411 "#stickyNestedChild { position: sticky; top: 0;}</style>"
405 "<div><div id='stickyNestedChild'></div></div></div></div>"); 412 "<div id='scroller'>"
413 " <div id='stickyParent'>"
414 " <div id='unanchoredSticky'>"
415 " <div id='stickyChild'></div>"
416 " <div><div id='stickyNestedChild'></div></div>"
417 " </div>"
418 " </div>"
419 "</div>");
406 420
407 LayoutBoxModelObject* scroller = 421 LayoutBoxModelObject* scroller =
408 ToLayoutBoxModelObject(GetLayoutObjectByElementId("scroller")); 422 ToLayoutBoxModelObject(GetLayoutObjectByElementId("scroller"));
409 LayoutBoxModelObject* sticky_parent = 423 LayoutBoxModelObject* sticky_parent =
410 ToLayoutBoxModelObject(GetLayoutObjectByElementId("stickyParent")); 424 ToLayoutBoxModelObject(GetLayoutObjectByElementId("stickyParent"));
411 LayoutBoxModelObject* sticky_child = 425 LayoutBoxModelObject* sticky_child =
412 ToLayoutBoxModelObject(GetLayoutObjectByElementId("stickyChild")); 426 ToLayoutBoxModelObject(GetLayoutObjectByElementId("stickyChild"));
413 LayoutBoxModelObject* sticky_nested_child = 427 LayoutBoxModelObject* sticky_nested_child =
414 ToLayoutBoxModelObject(GetLayoutObjectByElementId("stickyNestedChild")); 428 ToLayoutBoxModelObject(GetLayoutObjectByElementId("stickyNestedChild"));
415 429
416 PaintLayerScrollableArea* scrollable_area = 430 PaintLayerScrollableArea* scrollable_area =
417 scroller->Layer()->GetScrollableArea(); 431 scroller->Layer()->GetScrollableArea();
418 ASSERT_TRUE(scrollable_area); 432 ASSERT_TRUE(scrollable_area);
419 StickyConstraintsMap constraints_map = 433 StickyConstraintsMap constraints_map =
420 scrollable_area->GetStickyConstraintsMap(); 434 scrollable_area->GetStickyConstraintsMap();
421 435
422 ASSERT_FALSE(constraints_map.Contains(scroller->Layer())); 436 ASSERT_FALSE(constraints_map.Contains(scroller->Layer()));
423 ASSERT_TRUE(constraints_map.Contains(sticky_parent->Layer())); 437 ASSERT_TRUE(constraints_map.Contains(sticky_parent->Layer()));
424 ASSERT_TRUE(constraints_map.Contains(sticky_child->Layer())); 438 ASSERT_TRUE(constraints_map.Contains(sticky_child->Layer()));
425 ASSERT_TRUE(constraints_map.Contains(sticky_nested_child->Layer())); 439 ASSERT_TRUE(constraints_map.Contains(sticky_nested_child->Layer()));
426 440
427 // The outer <div> should not detect the scroller as its containing-block 441 // The outer <div> should not detect the scroller as its containing-block
428 // shifting ancestor. 442 // shifting ancestor.
429 EXPECT_FALSE(constraints_map.at(sticky_parent->Layer()) 443 EXPECT_FALSE(constraints_map.at(sticky_parent->Layer())
430 .NearestStickyBoxShiftingContainingBlock()); 444 .NearestStickyBoxShiftingContainingBlock());
431 445
432 // Both inner children should detect the parent <div> as their 446 // Both inner children should detect the parent <div> as their
433 // containing-block shifting ancestor. 447 // containing-block shifting ancestor. They skip past unanchored sticky
448 // because it will never have a non-zero offset.
434 EXPECT_EQ(sticky_parent, constraints_map.at(sticky_child->Layer()) 449 EXPECT_EQ(sticky_parent, constraints_map.at(sticky_child->Layer())
435 .NearestStickyBoxShiftingContainingBlock()); 450 .NearestStickyBoxShiftingContainingBlock());
436 EXPECT_EQ(sticky_parent, constraints_map.at(sticky_nested_child->Layer()) 451 EXPECT_EQ(sticky_parent, constraints_map.at(sticky_nested_child->Layer())
437 .NearestStickyBoxShiftingContainingBlock()); 452 .NearestStickyBoxShiftingContainingBlock());
438 } 453 }
439 454
440 // Verifies that the correct containing-block shifting ancestor is found when 455 // Verifies that the correct containing-block shifting ancestor is found when
441 // computing the sticky constraints, in the case where the overflow ancestor is 456 // computing the sticky constraints, in the case where the overflow ancestor is
442 // the page itself. This is a special-case version of the test above, as we 457 // the page itself. This is a special-case version of the test above, as we
443 // often treat the root page as special when it comes to scroll logic. It should 458 // often treat the root page as special when it comes to scroll logic. It should
444 // not make a difference for containing-block shifting ancestor calculations. 459 // not make a difference for containing-block shifting ancestor calculations.
445 TEST_F(LayoutBoxModelObjectTest, 460 TEST_F(LayoutBoxModelObjectTest,
446 StickyPositionFindsCorrectContainingBlockShiftingAncestorRoot) { 461 StickyPositionFindsCorrectContainingBlockShiftingAncestorRoot) {
447 SetBodyInnerHTML( 462 SetBodyInnerHTML(
448 "<style>#stickyParent { position: sticky; }" 463 "<style>#stickyParent { position: sticky; top: 0;}"
449 "#stickyGrandchild { position: sticky; }</style>" 464 "#stickyGrandchild { position: sticky; top: 0;}</style>"
450 "<div id='stickyParent'><div><div id='stickyGrandchild'></div></div>" 465 "<div id='stickyParent'><div><div id='stickyGrandchild'></div></div>"
451 "</div>"); 466 "</div>");
452 467
453 LayoutBoxModelObject* sticky_parent = 468 LayoutBoxModelObject* sticky_parent =
454 ToLayoutBoxModelObject(GetLayoutObjectByElementId("stickyParent")); 469 ToLayoutBoxModelObject(GetLayoutObjectByElementId("stickyParent"));
455 LayoutBoxModelObject* sticky_grandchild = 470 LayoutBoxModelObject* sticky_grandchild =
456 ToLayoutBoxModelObject(GetLayoutObjectByElementId("stickyGrandchild")); 471 ToLayoutBoxModelObject(GetLayoutObjectByElementId("stickyGrandchild"));
457 472
458 PaintLayerScrollableArea* scrollable_area = 473 PaintLayerScrollableArea* scrollable_area =
459 sticky_parent->Layer()->AncestorOverflowLayer()->GetScrollableArea(); 474 sticky_parent->Layer()->AncestorOverflowLayer()->GetScrollableArea();
(...skipping 11 matching lines...) Expand all
471 } 486 }
472 487
473 // Verifies that the correct containing-block shifting ancestor is found when 488 // Verifies that the correct containing-block shifting ancestor is found when
474 // computing the sticky constraints, in the case of tables. Tables are unusual 489 // computing the sticky constraints, in the case of tables. Tables are unusual
475 // because the containing block for all table elements is the <table> itself, so 490 // because the containing block for all table elements is the <table> itself, so
476 // we have to skip over elements to find the correct ancestor. 491 // we have to skip over elements to find the correct ancestor.
477 TEST_F(LayoutBoxModelObjectTest, 492 TEST_F(LayoutBoxModelObjectTest,
478 StickyPositionFindsCorrectContainingBlockShiftingAncestorTable) { 493 StickyPositionFindsCorrectContainingBlockShiftingAncestorTable) {
479 SetBodyInnerHTML( 494 SetBodyInnerHTML(
480 "<style>#scroller { overflow-y: scroll; }" 495 "<style>#scroller { overflow-y: scroll; }"
481 "#stickyOuter { position: sticky; }" 496 "#stickyOuter { position: sticky; top: 0;}"
482 "#stickyTh { position: sticky; }</style>" 497 "#stickyTh { position: sticky; top: 0;}</style>"
483 "<div id='scroller'><div id='stickyOuter'><table><thead><tr>" 498 "<div id='scroller'><div id='stickyOuter'><table><thead><tr>"
484 "<th id='stickyTh'></th></tr></thead></table></div></div>"); 499 "<th id='stickyTh'></th></tr></thead></table></div></div>");
485 500
486 LayoutBoxModelObject* scroller = 501 LayoutBoxModelObject* scroller =
487 ToLayoutBoxModelObject(GetLayoutObjectByElementId("scroller")); 502 ToLayoutBoxModelObject(GetLayoutObjectByElementId("scroller"));
488 LayoutBoxModelObject* sticky_outer = 503 LayoutBoxModelObject* sticky_outer =
489 ToLayoutBoxModelObject(GetLayoutObjectByElementId("stickyOuter")); 504 ToLayoutBoxModelObject(GetLayoutObjectByElementId("stickyOuter"));
490 LayoutBoxModelObject* sticky_th = 505 LayoutBoxModelObject* sticky_th =
491 ToLayoutBoxModelObject(GetLayoutObjectByElementId("stickyTh")); 506 ToLayoutBoxModelObject(GetLayoutObjectByElementId("stickyTh"));
492 507
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
846 EXPECT_EQ(LayoutSize(0, 25), inner_sticky_th->StickyPositionOffset()); 861 EXPECT_EQ(LayoutSize(0, 25), inner_sticky_th->StickyPositionOffset());
847 } 862 }
848 863
849 // Verifies that the calculated position:sticky offsets are correct in the case 864 // Verifies that the calculated position:sticky offsets are correct in the case
850 // of nested inline elements. 865 // of nested inline elements.
851 TEST_F(LayoutBoxModelObjectTest, StickyPositionNestedInlineElements) { 866 TEST_F(LayoutBoxModelObjectTest, StickyPositionNestedInlineElements) {
852 SetBodyInnerHTML( 867 SetBodyInnerHTML(
853 "<style>#scroller { width: 100px; height: 100px; overflow-y: scroll; }" 868 "<style>#scroller { width: 100px; height: 100px; overflow-y: scroll; }"
854 "#paddingBefore { height: 50px; }" 869 "#paddingBefore { height: 50px; }"
855 "#outerInline { display: inline; position: sticky; top: 0; }" 870 "#outerInline { display: inline; position: sticky; top: 0; }"
871 "#unanchoredSticky { position: sticky; display: inline; }"
856 ".inline {display: inline;}" 872 ".inline {display: inline;}"
857 "#innerInline { display: inline; position: sticky; top: 25px; }" 873 "#innerInline { display: inline; position: sticky; top: 25px; }"
858 "#paddingAfter { height: 200px; }</style>" 874 "#paddingAfter { height: 200px; }</style>"
859 "<div id='scroller'>" 875 "<div id='scroller'>"
860 " <div id='paddingBefore'></div>" 876 " <div id='paddingBefore'></div>"
861 " <div id='outerInline'>" 877 " <div id='outerInline'>"
862 " <div class='inline'>" 878 " <div id='unanchoredSticky'>"
863 " <div id='innerInline'></div>" 879 " <div class='inline'>"
880 " <div id='innerInline'></div>"
881 " </div>"
864 " </div>" 882 " </div>"
865 " </div>" 883 " </div>"
866 " <div id='paddingAfter'></div>" 884 " <div id='paddingAfter'></div>"
867 "</div>"); 885 "</div>");
868 886
869 LayoutBoxModelObject* outer_inline = 887 LayoutBoxModelObject* outer_inline =
870 ToLayoutBoxModelObject(GetLayoutObjectByElementId("outerInline")); 888 ToLayoutBoxModelObject(GetLayoutObjectByElementId("outerInline"));
871 LayoutBoxModelObject* inner_inline = 889 LayoutBoxModelObject* inner_inline =
872 ToLayoutBoxModelObject(GetLayoutObjectByElementId("innerInline")); 890 ToLayoutBoxModelObject(GetLayoutObjectByElementId("innerInline"));
873 891
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
924 942
925 // TODO(smcgruer): Until http://crbug.com/686164 is fixed, we need to update 943 // TODO(smcgruer): Until http://crbug.com/686164 is fixed, we need to update
926 // the constraints here before calculations will be correct. 944 // the constraints here before calculations will be correct.
927 inner_sticky->UpdateStickyPositionConstraints(); 945 inner_sticky->UpdateStickyPositionConstraints();
928 946
929 EXPECT_EQ(LayoutSize(0, 100), outer_sticky->StickyPositionOffset()); 947 EXPECT_EQ(LayoutSize(0, 100), outer_sticky->StickyPositionOffset());
930 EXPECT_EQ(LayoutSize(0, 25), inner_sticky->StickyPositionOffset()); 948 EXPECT_EQ(LayoutSize(0, 25), inner_sticky->StickyPositionOffset());
931 } 949 }
932 950
933 } // namespace blink 951 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698