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

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: Set dependent patch. 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/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 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 // computing the sticky constraints. Any such ancestor is the first sticky 332 // computing the sticky constraints. Any such ancestor is the first sticky
333 // element between you and your containing block (exclusive). 333 // element between you and your containing block (exclusive).
334 // 334 //
335 // In most cases, this pointer should be null since your parent is normally your 335 // In most cases, this pointer should be null since your parent is normally your
336 // containing block. However there are cases where this is not true, including 336 // containing block. However there are cases where this is not true, including
337 // inline blocks and tables. The latter is currently irrelevant since only table 337 // inline blocks and tables. The latter is currently irrelevant since only table
338 // cells can be sticky in CSS2.1, but we can test the former. 338 // cells can be sticky in CSS2.1, but we can test the former.
339 TEST_F(LayoutBoxModelObjectTest, 339 TEST_F(LayoutBoxModelObjectTest,
340 StickyPositionFindsCorrectStickyBoxShiftingAncestor) { 340 StickyPositionFindsCorrectStickyBoxShiftingAncestor) {
341 setBodyInnerHTML( 341 setBodyInnerHTML(
342 "<style>#stickyOuterDiv { position: sticky; }" 342 "<style>#stickyOuterDiv { position: sticky; top: 0;}"
343 "#stickyOuterInline { position: sticky; display: inline; }" 343 "#stickyOuterInline { position: sticky; top: 0; display: inline; }"
344 "#stickyInnerInline { position: sticky; display: inline; }</style>" 344 "#unanchoredSticky { position: sticky; display: inline; }"
345 "<div id='stickyOuterDiv'><div id='stickyOuterInline'>" 345 "#stickyInnerInline { position: sticky; top: 0; display: inline; "
346 "<div id='stickyInnerInline'></div></div></div>"); 346 "}</style>"
347 "<div id='stickyOuterDiv'>"
348 " <div id='stickyOuterInline'>"
349 " <div id='unanchoredSticky'>"
350 " <div id='stickyInnerInline'></div>"
351 " </div>"
352 " </div>"
353 "</div>");
347 354
348 LayoutBoxModelObject* stickyOuterDiv = 355 LayoutBoxModelObject* stickyOuterDiv =
349 toLayoutBoxModelObject(getLayoutObjectByElementId("stickyOuterDiv")); 356 toLayoutBoxModelObject(getLayoutObjectByElementId("stickyOuterDiv"));
350 LayoutBoxModelObject* stickyOuterInline = 357 LayoutBoxModelObject* stickyOuterInline =
351 toLayoutBoxModelObject(getLayoutObjectByElementId("stickyOuterInline")); 358 toLayoutBoxModelObject(getLayoutObjectByElementId("stickyOuterInline"));
352 LayoutBoxModelObject* stickyInnerInline = 359 LayoutBoxModelObject* stickyInnerInline =
353 toLayoutBoxModelObject(getLayoutObjectByElementId("stickyInnerInline")); 360 toLayoutBoxModelObject(getLayoutObjectByElementId("stickyInnerInline"));
354 361
355 PaintLayerScrollableArea* scrollableArea = 362 PaintLayerScrollableArea* scrollableArea =
356 stickyOuterDiv->layer()->ancestorOverflowLayer()->getScrollableArea(); 363 stickyOuterDiv->layer()->ancestorOverflowLayer()->getScrollableArea();
357 ASSERT_TRUE(scrollableArea); 364 ASSERT_TRUE(scrollableArea);
358 StickyConstraintsMap constraintsMap = scrollableArea->stickyConstraintsMap(); 365 StickyConstraintsMap constraintsMap = scrollableArea->stickyConstraintsMap();
359 366
360 ASSERT_TRUE(constraintsMap.contains(stickyOuterDiv->layer())); 367 ASSERT_TRUE(constraintsMap.contains(stickyOuterDiv->layer()));
361 ASSERT_TRUE(constraintsMap.contains(stickyOuterInline->layer())); 368 ASSERT_TRUE(constraintsMap.contains(stickyOuterInline->layer()));
362 ASSERT_TRUE(constraintsMap.contains(stickyInnerInline->layer())); 369 ASSERT_TRUE(constraintsMap.contains(stickyInnerInline->layer()));
chrishtr 2017/03/27 16:28:07 ASSERT_FALSE for unanchoredSticky?
flackr 2017/04/07 18:15:45 Done.
363 370
364 // The outer block element trivially has no sticky-box shifting ancestor. 371 // The outer block element trivially has no sticky-box shifting ancestor.
365 EXPECT_FALSE(constraintsMap.at(stickyOuterDiv->layer()) 372 EXPECT_FALSE(constraintsMap.at(stickyOuterDiv->layer())
366 .nearestStickyBoxShiftingStickyBox()); 373 .nearestStickyBoxShiftingStickyBox());
367 374
368 // Neither does the outer inline element, as its parent element is also its 375 // Neither does the outer inline element, as its parent element is also its
369 // containing block. 376 // containing block.
370 EXPECT_FALSE(constraintsMap.at(stickyOuterInline->layer()) 377 EXPECT_FALSE(constraintsMap.at(stickyOuterInline->layer())
371 .nearestStickyBoxShiftingStickyBox()); 378 .nearestStickyBoxShiftingStickyBox());
372 379
373 // However the inner inline element does have a sticky-box shifting ancestor, 380 // However the inner inline element does have a sticky-box shifting ancestor,
374 // as its containing block is the ancestor block element, not its parent. 381 // as its containing block is the ancestor block element, not its parent.
375 EXPECT_EQ(stickyOuterInline, 382 EXPECT_EQ(stickyOuterInline,
376 constraintsMap.at(stickyInnerInline->layer()) 383 constraintsMap.at(stickyInnerInline->layer())
377 .nearestStickyBoxShiftingStickyBox()); 384 .nearestStickyBoxShiftingStickyBox());
378 } 385 }
379 386
380 // Verifies that the correct containing-block shifting ancestor is found when 387 // Verifies that the correct containing-block shifting ancestor is found when
381 // computing the sticky constraints. Any such ancestor is the first sticky 388 // computing the sticky constraints. Any such ancestor is the first sticky
382 // element between your containing block (inclusive) and your ancestor overflow 389 // element between your containing block (inclusive) and your ancestor overflow
383 // layer (exclusive). 390 // layer (exclusive).
384 TEST_F(LayoutBoxModelObjectTest, 391 TEST_F(LayoutBoxModelObjectTest,
385 StickyPositionFindsCorrectContainingBlockShiftingAncestor) { 392 StickyPositionFindsCorrectContainingBlockShiftingAncestor) {
386 // We make the scroller itself sticky in order to check that elements do not 393 // We make the scroller itself sticky in order to check that elements do not
387 // detect it as their containing-block shifting ancestor. 394 // detect it as their containing-block shifting ancestor.
388 setBodyInnerHTML( 395 setBodyInnerHTML(
389 "<style>#scroller { overflow-y: scroll; position: sticky; }" 396 "<style>#scroller { overflow-y: scroll; position: sticky; top: 0;}"
390 "#stickyParent { position: sticky; }" 397 "#stickyParent { position: sticky; top: 0;}"
391 "#stickyChild { position: sticky; }" 398 "#stickyChild { position: sticky; top: 0;}"
392 "#stickyNestedChild { position: sticky; }</style>" 399 "#unanchoredSticky { position: sticky; }"
393 "<div id='scroller'><div id='stickyParent'><div id='stickyChild'></div>" 400 "#stickyNestedChild { position: sticky; top: 0;}</style>"
394 "<div><div id='stickyNestedChild'></div></div></div></div>"); 401 "<div id='scroller'>"
402 " <div id='stickyParent'>"
403 " <div id='unanchoredSticky'>"
404 " <div id='stickyChild'></div>"
405 " <div><div id='stickyNestedChild'></div></div>"
406 " </div>"
407 " </div>"
408 "</div>");
395 409
396 LayoutBoxModelObject* scroller = 410 LayoutBoxModelObject* scroller =
397 toLayoutBoxModelObject(getLayoutObjectByElementId("scroller")); 411 toLayoutBoxModelObject(getLayoutObjectByElementId("scroller"));
398 LayoutBoxModelObject* stickyParent = 412 LayoutBoxModelObject* stickyParent =
399 toLayoutBoxModelObject(getLayoutObjectByElementId("stickyParent")); 413 toLayoutBoxModelObject(getLayoutObjectByElementId("stickyParent"));
400 LayoutBoxModelObject* stickyChild = 414 LayoutBoxModelObject* stickyChild =
401 toLayoutBoxModelObject(getLayoutObjectByElementId("stickyChild")); 415 toLayoutBoxModelObject(getLayoutObjectByElementId("stickyChild"));
402 LayoutBoxModelObject* stickyNestedChild = 416 LayoutBoxModelObject* stickyNestedChild =
403 toLayoutBoxModelObject(getLayoutObjectByElementId("stickyNestedChild")); 417 toLayoutBoxModelObject(getLayoutObjectByElementId("stickyNestedChild"));
404 418
405 PaintLayerScrollableArea* scrollableArea = 419 PaintLayerScrollableArea* scrollableArea =
406 scroller->layer()->getScrollableArea(); 420 scroller->layer()->getScrollableArea();
407 ASSERT_TRUE(scrollableArea); 421 ASSERT_TRUE(scrollableArea);
408 StickyConstraintsMap constraintsMap = scrollableArea->stickyConstraintsMap(); 422 StickyConstraintsMap constraintsMap = scrollableArea->stickyConstraintsMap();
409 423
410 ASSERT_FALSE(constraintsMap.contains(scroller->layer())); 424 ASSERT_FALSE(constraintsMap.contains(scroller->layer()));
411 ASSERT_TRUE(constraintsMap.contains(stickyParent->layer())); 425 ASSERT_TRUE(constraintsMap.contains(stickyParent->layer()));
412 ASSERT_TRUE(constraintsMap.contains(stickyChild->layer())); 426 ASSERT_TRUE(constraintsMap.contains(stickyChild->layer()));
413 ASSERT_TRUE(constraintsMap.contains(stickyNestedChild->layer())); 427 ASSERT_TRUE(constraintsMap.contains(stickyNestedChild->layer()));
414 428
415 // The outer <div> should not detect the scroller as its containing-block 429 // The outer <div> should not detect the scroller as its containing-block
416 // shifting ancestor. 430 // shifting ancestor.
417 EXPECT_FALSE(constraintsMap.at(stickyParent->layer()) 431 EXPECT_FALSE(constraintsMap.at(stickyParent->layer())
418 .nearestStickyBoxShiftingContainingBlock()); 432 .nearestStickyBoxShiftingContainingBlock());
419 433
420 // Both inner children should detect the parent <div> as their 434 // Both inner children should detect the parent <div> as their
421 // containing-block shifting ancestor. 435 // containing-block shifting ancestor. They skip past unanchored sticky
436 // because it will never have a non-zero offset.
422 EXPECT_EQ(stickyParent, 437 EXPECT_EQ(stickyParent,
423 constraintsMap.at(stickyChild->layer()) 438 constraintsMap.at(stickyChild->layer())
424 .nearestStickyBoxShiftingContainingBlock()); 439 .nearestStickyBoxShiftingContainingBlock());
425 EXPECT_EQ(stickyParent, 440 EXPECT_EQ(stickyParent,
426 constraintsMap.at(stickyNestedChild->layer()) 441 constraintsMap.at(stickyNestedChild->layer())
427 .nearestStickyBoxShiftingContainingBlock()); 442 .nearestStickyBoxShiftingContainingBlock());
428 } 443 }
429 444
430 // Verifies that the correct containing-block shifting ancestor is found when 445 // Verifies that the correct containing-block shifting ancestor is found when
431 // computing the sticky constraints, in the case where the overflow ancestor is 446 // computing the sticky constraints, in the case where the overflow ancestor is
432 // the page itself. This is a special-case version of the test above, as we 447 // the page itself. This is a special-case version of the test above, as we
433 // often treat the root page as special when it comes to scroll logic. It should 448 // often treat the root page as special when it comes to scroll logic. It should
434 // not make a difference for containing-block shifting ancestor calculations. 449 // not make a difference for containing-block shifting ancestor calculations.
435 TEST_F(LayoutBoxModelObjectTest, 450 TEST_F(LayoutBoxModelObjectTest,
436 StickyPositionFindsCorrectContainingBlockShiftingAncestorRoot) { 451 StickyPositionFindsCorrectContainingBlockShiftingAncestorRoot) {
437 setBodyInnerHTML( 452 setBodyInnerHTML(
438 "<style>#stickyParent { position: sticky; }" 453 "<style>#stickyParent { position: sticky; top: 0;}"
439 "#stickyGrandchild { position: sticky; }</style>" 454 "#stickyGrandchild { position: sticky; top: 0;}</style>"
440 "<div id='stickyParent'><div><div id='stickyGrandchild'></div></div>" 455 "<div id='stickyParent'><div><div id='stickyGrandchild'></div></div>"
441 "</div>"); 456 "</div>");
442 457
443 LayoutBoxModelObject* stickyParent = 458 LayoutBoxModelObject* stickyParent =
444 toLayoutBoxModelObject(getLayoutObjectByElementId("stickyParent")); 459 toLayoutBoxModelObject(getLayoutObjectByElementId("stickyParent"));
445 LayoutBoxModelObject* stickyGrandchild = 460 LayoutBoxModelObject* stickyGrandchild =
446 toLayoutBoxModelObject(getLayoutObjectByElementId("stickyGrandchild")); 461 toLayoutBoxModelObject(getLayoutObjectByElementId("stickyGrandchild"));
447 462
448 PaintLayerScrollableArea* scrollableArea = 463 PaintLayerScrollableArea* scrollableArea =
449 stickyParent->layer()->ancestorOverflowLayer()->getScrollableArea(); 464 stickyParent->layer()->ancestorOverflowLayer()->getScrollableArea();
(...skipping 11 matching lines...) Expand all
461 } 476 }
462 477
463 // Verifies that the correct containing-block shifting ancestor is found when 478 // Verifies that the correct containing-block shifting ancestor is found when
464 // computing the sticky constraints, in the case of tables. Tables are unusual 479 // computing the sticky constraints, in the case of tables. Tables are unusual
465 // because the containing block for all table elements is the <table> itself, so 480 // because the containing block for all table elements is the <table> itself, so
466 // we have to skip over elements to find the correct ancestor. 481 // we have to skip over elements to find the correct ancestor.
467 TEST_F(LayoutBoxModelObjectTest, 482 TEST_F(LayoutBoxModelObjectTest,
468 StickyPositionFindsCorrectContainingBlockShiftingAncestorTable) { 483 StickyPositionFindsCorrectContainingBlockShiftingAncestorTable) {
469 setBodyInnerHTML( 484 setBodyInnerHTML(
470 "<style>#scroller { overflow-y: scroll; }" 485 "<style>#scroller { overflow-y: scroll; }"
471 "#stickyOuter { position: sticky; }" 486 "#stickyOuter { position: sticky; top: 0;}"
472 "#stickyTh { position: sticky; }</style>" 487 "#stickyTh { position: sticky; top: 0;}</style>"
473 "<div id='scroller'><div id='stickyOuter'><table><thead><tr>" 488 "<div id='scroller'><div id='stickyOuter'><table><thead><tr>"
474 "<th id='stickyTh'></th></tr></thead></table></div></div>"); 489 "<th id='stickyTh'></th></tr></thead></table></div></div>");
475 490
476 LayoutBoxModelObject* scroller = 491 LayoutBoxModelObject* scroller =
477 toLayoutBoxModelObject(getLayoutObjectByElementId("scroller")); 492 toLayoutBoxModelObject(getLayoutObjectByElementId("scroller"));
478 LayoutBoxModelObject* stickyOuter = 493 LayoutBoxModelObject* stickyOuter =
479 toLayoutBoxModelObject(getLayoutObjectByElementId("stickyOuter")); 494 toLayoutBoxModelObject(getLayoutObjectByElementId("stickyOuter"));
480 LayoutBoxModelObject* stickyTh = 495 LayoutBoxModelObject* stickyTh =
481 toLayoutBoxModelObject(getLayoutObjectByElementId("stickyTh")); 496 toLayoutBoxModelObject(getLayoutObjectByElementId("stickyTh"));
482 497
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
836 EXPECT_EQ(LayoutSize(0, 25), innerStickyTh->stickyPositionOffset()); 851 EXPECT_EQ(LayoutSize(0, 25), innerStickyTh->stickyPositionOffset());
837 } 852 }
838 853
839 // Verifies that the calculated position:sticky offsets are correct in the case 854 // Verifies that the calculated position:sticky offsets are correct in the case
840 // of nested inline elements. 855 // of nested inline elements.
841 TEST_F(LayoutBoxModelObjectTest, StickyPositionNestedInlineElements) { 856 TEST_F(LayoutBoxModelObjectTest, StickyPositionNestedInlineElements) {
842 setBodyInnerHTML( 857 setBodyInnerHTML(
843 "<style>#scroller { width: 100px; height: 100px; overflow-y: scroll; }" 858 "<style>#scroller { width: 100px; height: 100px; overflow-y: scroll; }"
844 "#paddingBefore { height: 50px; }" 859 "#paddingBefore { height: 50px; }"
845 "#outerInline { display: inline; position: sticky; top: 0; }" 860 "#outerInline { display: inline; position: sticky; top: 0; }"
861 "#unanchoredSticky { position: sticky; display: inline; }"
846 "#innerInline { display: inline; position: sticky; top: 25px; }" 862 "#innerInline { display: inline; position: sticky; top: 25px; }"
847 "#paddingAfter { height: 200px; }</style>" 863 "#paddingAfter { height: 200px; }</style>"
848 "<div id='scroller'><div id='paddingBefore'></div><div id='outerInline'>" 864 "<div id='scroller'>"
849 "<div id='innerInline'></div></div><div id='paddingAfter'></div></div>"); 865 " <div id='paddingBefore'></div>"
866 " <div id='outerInline'>"
867 " <div id='unanchoredSticky'>"
868 " <div id='innerInline'></div>"
869 " </div>"
870 " </div>"
871 " <div id='paddingAfter'></div>"
872 "</div>");
850 873
851 LayoutBoxModelObject* outerInline = 874 LayoutBoxModelObject* outerInline =
852 toLayoutBoxModelObject(getLayoutObjectByElementId("outerInline")); 875 toLayoutBoxModelObject(getLayoutObjectByElementId("outerInline"));
853 LayoutBoxModelObject* innerInline = 876 LayoutBoxModelObject* innerInline =
854 toLayoutBoxModelObject(getLayoutObjectByElementId("innerInline")); 877 toLayoutBoxModelObject(getLayoutObjectByElementId("innerInline"));
855 878
856 // Scroll the page down. 879 // Scroll the page down.
857 LayoutBoxModelObject* scroller = 880 LayoutBoxModelObject* scroller =
858 toLayoutBoxModelObject(getLayoutObjectByElementId("scroller")); 881 toLayoutBoxModelObject(getLayoutObjectByElementId("scroller"));
859 PaintLayerScrollableArea* scrollableArea = scroller->getScrollableArea(); 882 PaintLayerScrollableArea* scrollableArea = scroller->getScrollableArea();
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
905 928
906 // TODO(smcgruer): Until http://crbug.com/686164 is fixed, we need to update 929 // TODO(smcgruer): Until http://crbug.com/686164 is fixed, we need to update
907 // the constraints here before calculations will be correct. 930 // the constraints here before calculations will be correct.
908 innerSticky->updateStickyPositionConstraints(); 931 innerSticky->updateStickyPositionConstraints();
909 932
910 EXPECT_EQ(LayoutSize(0, 100), outerSticky->stickyPositionOffset()); 933 EXPECT_EQ(LayoutSize(0, 100), outerSticky->stickyPositionOffset());
911 EXPECT_EQ(LayoutSize(0, 25), innerSticky->stickyPositionOffset()); 934 EXPECT_EQ(LayoutSize(0, 25), innerSticky->stickyPositionOffset());
912 } 935 }
913 936
914 } // namespace blink 937 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698