OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/compositing/CompositedLayerMapping.h" | 5 #include "core/layout/compositing/CompositedLayerMapping.h" |
6 | 6 |
7 #include "core/frame/FrameView.h" | 7 #include "core/frame/FrameView.h" |
8 #include "core/layout/LayoutBoxModelObject.h" | 8 #include "core/layout/LayoutBoxModelObject.h" |
9 #include "core/layout/LayoutTestHelper.h" | 9 #include "core/layout/LayoutTestHelper.h" |
10 #include "core/layout/api/LayoutViewItem.h" | 10 #include "core/layout/api/LayoutViewItem.h" |
(...skipping 1478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1489 ->compositedLayerMapping(); | 1489 ->compositedLayerMapping(); |
1490 | 1490 |
1491 // Box offsets the content by the combination of the shadow offset and blur | 1491 // Box offsets the content by the combination of the shadow offset and blur |
1492 // radius plus an additional pixel of anti-aliasing. | 1492 // radius plus an additional pixel of anti-aliasing. |
1493 ASSERT_TRUE(sticky1); | 1493 ASSERT_TRUE(sticky1); |
1494 WebLayerStickyPositionConstraint constraint1 = | 1494 WebLayerStickyPositionConstraint constraint1 = |
1495 sticky1->mainGraphicsLayer() | 1495 sticky1->mainGraphicsLayer() |
1496 ->contentLayer() | 1496 ->contentLayer() |
1497 ->layer() | 1497 ->layer() |
1498 ->stickyPositionConstraint(); | 1498 ->stickyPositionConstraint(); |
1499 EXPECT_EQ(IntPoint(-11, -11), | 1499 EXPECT_EQ(FloatPoint(-11, -11), |
1500 IntPoint(constraint1.parentRelativeStickyBoxOffset)); | 1500 FloatPoint(constraint1.parentRelativeStickyBoxOffset)); |
1501 | 1501 |
1502 // Since the nested div will be squashed into the same composited layer the | 1502 // Since the nested div will be squashed into the same composited layer the |
1503 // sticky element is offset by the nested element's offset. | 1503 // sticky element is offset by the nested element's offset. |
1504 ASSERT_TRUE(sticky2); | 1504 ASSERT_TRUE(sticky2); |
1505 WebLayerStickyPositionConstraint constraint2 = | 1505 WebLayerStickyPositionConstraint constraint2 = |
1506 sticky2->mainGraphicsLayer() | 1506 sticky2->mainGraphicsLayer() |
1507 ->contentLayer() | 1507 ->contentLayer() |
1508 ->layer() | 1508 ->layer() |
1509 ->stickyPositionConstraint(); | 1509 ->stickyPositionConstraint(); |
1510 EXPECT_EQ(IntPoint(-50, -50), | 1510 EXPECT_EQ(FloatPoint(-50, -50), |
1511 IntPoint(constraint2.parentRelativeStickyBoxOffset)); | 1511 FloatPoint(constraint2.parentRelativeStickyBoxOffset)); |
1512 } | 1512 } |
1513 | 1513 |
1514 TEST_P(CompositedLayerMappingTest, StickyPositionTableCellContentOffset) { | 1514 TEST_P(CompositedLayerMappingTest, StickyPositionTableCellContentOffset) { |
1515 setBodyInnerHTML( | 1515 setBodyInnerHTML( |
1516 "<style>body {height: 2000px; width: 2000px;} " | 1516 "<style>body {height: 2000px; width: 2000px;} " |
1517 "td, th { height: 50px; width: 50px; } " | 1517 "td, th { height: 50px; width: 50px; } " |
1518 "table {border: none; }" | 1518 "table {border: none; }" |
1519 "#scroller { overflow: auto; will-change: transform; height: 50px; }" | 1519 "#scroller { overflow: auto; will-change: transform; height: 50px; }" |
1520 "#sticky { position: sticky; left: 0; will-change: transform; }" | 1520 "#sticky { position: sticky; left: 0; will-change: transform; }" |
1521 "</style>" | 1521 "</style>" |
1522 "<div id='scroller'><table cellspacing='0' cellpadding='0'>" | 1522 "<div id='scroller'><table cellspacing='0' cellpadding='0'>" |
1523 " <thead><tr><td></td></tr></thead>" | 1523 " <thead><tr><td></td></tr></thead>" |
1524 " <tr><td id='sticky'></td></tr>" | 1524 " <tr><td id='sticky'></td></tr>" |
1525 "</table></div>"); | 1525 "</table></div>"); |
1526 document().view()->updateLifecycleToCompositingCleanPlusScrolling(); | 1526 document().view()->updateLifecycleToCompositingCleanPlusScrolling(); |
1527 | 1527 |
1528 CompositedLayerMapping* sticky = | 1528 CompositedLayerMapping* sticky = |
1529 toLayoutBlock(getLayoutObjectByElementId("sticky")) | 1529 toLayoutBlock(getLayoutObjectByElementId("sticky")) |
1530 ->layer() | 1530 ->layer() |
1531 ->compositedLayerMapping(); | 1531 ->compositedLayerMapping(); |
1532 | 1532 |
1533 ASSERT_TRUE(sticky); | 1533 ASSERT_TRUE(sticky); |
1534 WebLayerStickyPositionConstraint constraint = | 1534 WebLayerStickyPositionConstraint constraint = |
1535 sticky->mainGraphicsLayer() | 1535 sticky->mainGraphicsLayer() |
1536 ->contentLayer() | 1536 ->contentLayer() |
1537 ->layer() | 1537 ->layer() |
1538 ->stickyPositionConstraint(); | 1538 ->stickyPositionConstraint(); |
1539 EXPECT_EQ(IntPoint(0, 50), | 1539 EXPECT_EQ(FloatPoint(0, 50), |
1540 IntPoint(constraint.parentRelativeStickyBoxOffset)); | 1540 FloatPoint(constraint.parentRelativeStickyBoxOffset)); |
1541 } | 1541 } |
1542 | 1542 |
1543 TEST_P(CompositedLayerMappingTest, StickyPositionEnclosingLayersContentOffset) { | 1543 TEST_P(CompositedLayerMappingTest, StickyPositionEnclosingLayersContentOffset) { |
1544 setBodyInnerHTML( | 1544 setBodyInnerHTML( |
1545 "<style>.composited { will-change: transform; }" | 1545 "<style>.composited { will-change: transform; }" |
1546 "#scroller { overflow: auto; height: 200px; width: 200px; }" | 1546 "#scroller { overflow: auto; height: 200px; width: 200px; }" |
1547 ".container { height: 500px; }" | 1547 ".container { height: 500px; }" |
1548 ".innerPadding { height: 10px; }" | 1548 ".innerPadding { height: 10px; }" |
1549 "#sticky { position: sticky; top: 25px; height: 50px; }</style>" | 1549 "#sticky { position: sticky; top: 25px; height: 50px; }</style>" |
1550 "<div id='scroller' class='composited'>" | 1550 "<div id='scroller' class='composited'>" |
1551 "<div class='composited container'>" | 1551 "<div class='composited container'>" |
1552 " <div class='composited container'>" | 1552 " <div class='composited container'>" |
1553 " <div class='innerPadding'></div>" | 1553 " <div class='innerPadding'></div>" |
1554 " <div id='sticky' class='composited'></div>" | 1554 " <div id='sticky' class='composited'></div>" |
1555 " </div></div></div>"); | 1555 " </div></div></div>"); |
1556 | 1556 |
1557 PaintLayer* stickyLayer = | 1557 PaintLayer* stickyLayer = |
1558 toLayoutBox(getLayoutObjectByElementId("sticky"))->layer(); | 1558 toLayoutBox(getLayoutObjectByElementId("sticky"))->layer(); |
1559 CompositedLayerMapping* stickyMapping = stickyLayer->compositedLayerMapping(); | 1559 CompositedLayerMapping* stickyMapping = stickyLayer->compositedLayerMapping(); |
1560 ASSERT_TRUE(stickyMapping); | 1560 ASSERT_TRUE(stickyMapping); |
1561 | 1561 |
1562 WebLayerStickyPositionConstraint constraint = | 1562 WebLayerStickyPositionConstraint constraint = |
1563 stickyMapping->mainGraphicsLayer() | 1563 stickyMapping->mainGraphicsLayer() |
1564 ->contentLayer() | 1564 ->contentLayer() |
1565 ->layer() | 1565 ->layer() |
1566 ->stickyPositionConstraint(); | 1566 ->stickyPositionConstraint(); |
1567 EXPECT_EQ(IntPoint(0, 10), | 1567 EXPECT_EQ(FloatPoint(0, 10), |
1568 IntPoint(constraint.parentRelativeStickyBoxOffset)); | 1568 FloatPoint(constraint.parentRelativeStickyBoxOffset)); |
1569 | 1569 |
1570 // Now scroll the page - this should not affect the parent-relative offset. | 1570 // Now scroll the page - this should not affect the parent-relative offset. |
1571 LayoutBoxModelObject* scroller = | 1571 LayoutBoxModelObject* scroller = |
1572 toLayoutBoxModelObject(getLayoutObjectByElementId("scroller")); | 1572 toLayoutBoxModelObject(getLayoutObjectByElementId("scroller")); |
1573 PaintLayerScrollableArea* scrollableArea = scroller->getScrollableArea(); | 1573 PaintLayerScrollableArea* scrollableArea = scroller->getScrollableArea(); |
1574 scrollableArea->scrollToAbsolutePosition( | 1574 scrollableArea->scrollToAbsolutePosition( |
1575 FloatPoint(scrollableArea->scrollPosition().x(), 100)); | 1575 FloatPoint(scrollableArea->scrollPosition().x(), 100)); |
1576 ASSERT_EQ(100.0, scrollableArea->scrollPosition().y()); | 1576 ASSERT_EQ(100.0, scrollableArea->scrollPosition().y()); |
1577 | 1577 |
1578 stickyLayer->setNeedsCompositingInputsUpdate(); | 1578 stickyLayer->setNeedsCompositingInputsUpdate(); |
1579 EXPECT_TRUE(stickyLayer->needsCompositingInputsUpdate()); | 1579 EXPECT_TRUE(stickyLayer->needsCompositingInputsUpdate()); |
1580 document().view()->updateLifecycleToCompositingCleanPlusScrolling(); | 1580 document().view()->updateLifecycleToCompositingCleanPlusScrolling(); |
1581 EXPECT_FALSE(stickyLayer->needsCompositingInputsUpdate()); | 1581 EXPECT_FALSE(stickyLayer->needsCompositingInputsUpdate()); |
1582 | 1582 |
1583 constraint = stickyMapping->mainGraphicsLayer() | 1583 constraint = stickyMapping->mainGraphicsLayer() |
1584 ->contentLayer() | 1584 ->contentLayer() |
1585 ->layer() | 1585 ->layer() |
1586 ->stickyPositionConstraint(); | 1586 ->stickyPositionConstraint(); |
1587 EXPECT_EQ(IntPoint(0, 10), | 1587 EXPECT_EQ(FloatPoint(0, 10), |
1588 IntPoint(constraint.parentRelativeStickyBoxOffset)); | 1588 FloatPoint(constraint.parentRelativeStickyBoxOffset)); |
| 1589 } |
| 1590 |
| 1591 TEST_P(CompositedLayerMappingTest, StickyPositionNestedStickyContentOffset) { |
| 1592 setBodyInnerHTML( |
| 1593 "<style>.composited { will-change: transform; }" |
| 1594 "#scroller { overflow: auto; height: 200px; width: 200px; }" |
| 1595 ".container { height: 500px; }" |
| 1596 "#outerSticky { position: sticky; top: 0; height: 100px; }" |
| 1597 "#middleSticky { position: sticky; top: 10px; height: 50px; }" |
| 1598 "#innerSticky { position: sticky; top: 25px; height: 25px; }</style>" |
| 1599 "<div id='scroller' class='composited'>" |
| 1600 " <div style='height: 50px'></div>" |
| 1601 " <div class='composited container'>" |
| 1602 " <div style='height: 10px;'></div>" |
| 1603 " <div id='outerSticky' class='composited'>" |
| 1604 " <div id='middleSticky' class='composited'>" |
| 1605 " <div style='height: 5px;'></div>" |
| 1606 " <div id='innerSticky' class='composited'></div>" |
| 1607 " </div>" |
| 1608 " </div>" |
| 1609 " </div>" |
| 1610 "</div>"); |
| 1611 |
| 1612 PaintLayer* outerSticky = |
| 1613 toLayoutBox(getLayoutObjectByElementId("outerSticky"))->layer(); |
| 1614 PaintLayer* middleSticky = |
| 1615 toLayoutBox(getLayoutObjectByElementId("middleSticky"))->layer(); |
| 1616 PaintLayer* innerSticky = |
| 1617 toLayoutBox(getLayoutObjectByElementId("innerSticky"))->layer(); |
| 1618 |
| 1619 WebLayerStickyPositionConstraint outerStickyConstraint = |
| 1620 outerSticky->compositedLayerMapping() |
| 1621 ->mainGraphicsLayer() |
| 1622 ->contentLayer() |
| 1623 ->layer() |
| 1624 ->stickyPositionConstraint(); |
| 1625 WebLayerStickyPositionConstraint middleStickyConstraint = |
| 1626 middleSticky->compositedLayerMapping() |
| 1627 ->mainGraphicsLayer() |
| 1628 ->contentLayer() |
| 1629 ->layer() |
| 1630 ->stickyPositionConstraint(); |
| 1631 WebLayerStickyPositionConstraint innerStickyConstraint = |
| 1632 innerSticky->compositedLayerMapping() |
| 1633 ->mainGraphicsLayer() |
| 1634 ->contentLayer() |
| 1635 ->layer() |
| 1636 ->stickyPositionConstraint(); |
| 1637 |
| 1638 EXPECT_EQ(FloatPoint(0, 10), |
| 1639 FloatPoint(outerStickyConstraint.parentRelativeStickyBoxOffset)); |
| 1640 EXPECT_EQ(FloatPoint(0, 0), |
| 1641 FloatPoint(middleStickyConstraint.parentRelativeStickyBoxOffset)); |
| 1642 EXPECT_EQ(FloatPoint(0, 5), |
| 1643 FloatPoint(innerStickyConstraint.parentRelativeStickyBoxOffset)); |
| 1644 |
| 1645 // Scroll the content to engage the sticky elements. |
| 1646 LayoutBoxModelObject* scroller = |
| 1647 toLayoutBoxModelObject(getLayoutObjectByElementId("scroller")); |
| 1648 PaintLayerScrollableArea* scrollableArea = scroller->getScrollableArea(); |
| 1649 scrollableArea->scrollToAbsolutePosition( |
| 1650 FloatPoint(scrollableArea->scrollPosition().x(), 110)); |
| 1651 ASSERT_EQ(110.0, scrollableArea->scrollPosition().y()); |
| 1652 |
| 1653 outerSticky->setNeedsCompositingInputsUpdate(); |
| 1654 middleSticky->setNeedsCompositingInputsUpdate(); |
| 1655 innerSticky->setNeedsCompositingInputsUpdate(); |
| 1656 |
| 1657 document().view()->updateLifecycleToCompositingCleanPlusScrolling(); |
| 1658 |
| 1659 outerStickyConstraint = outerSticky->compositedLayerMapping() |
| 1660 ->mainGraphicsLayer() |
| 1661 ->contentLayer() |
| 1662 ->layer() |
| 1663 ->stickyPositionConstraint(); |
| 1664 middleStickyConstraint = middleSticky->compositedLayerMapping() |
| 1665 ->mainGraphicsLayer() |
| 1666 ->contentLayer() |
| 1667 ->layer() |
| 1668 ->stickyPositionConstraint(); |
| 1669 innerStickyConstraint = innerSticky->compositedLayerMapping() |
| 1670 ->mainGraphicsLayer() |
| 1671 ->contentLayer() |
| 1672 ->layer() |
| 1673 ->stickyPositionConstraint(); |
| 1674 |
| 1675 // After scrolling and despite ancestor sticky changes, the offset relative to |
| 1676 // the parent layer should remain constant. |
| 1677 EXPECT_EQ(FloatPoint(0, 10), |
| 1678 FloatPoint(outerStickyConstraint.parentRelativeStickyBoxOffset)); |
| 1679 EXPECT_EQ(FloatPoint(0, 0), |
| 1680 FloatPoint(middleStickyConstraint.parentRelativeStickyBoxOffset)); |
| 1681 EXPECT_EQ(FloatPoint(0, 5), |
| 1682 FloatPoint(innerStickyConstraint.parentRelativeStickyBoxOffset)); |
1589 } | 1683 } |
1590 | 1684 |
1591 } // namespace blink | 1685 } // namespace blink |
OLD | NEW |