Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
| 4 * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) | 4 * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) |
| 5 * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com) | 5 * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com) |
| 6 * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. | 6 * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. |
| 7 * Copyright (C) 2010 Google Inc. All rights reserved. | 7 * Copyright (C) 2010 Google Inc. All rights reserved. |
| 8 * | 8 * |
| 9 * This library is free software; you can redistribute it and/or | 9 * This library is free software; you can redistribute it and/or |
| 10 * modify it under the terms of the GNU Library General Public | 10 * modify it under the terms of the GNU Library General Public |
| (...skipping 855 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 866 // the container is our scroll ancestor, we also need to remove the border | 866 // the container is our scroll ancestor, we also need to remove the border |
| 867 // box because we want the position from within the scroller border. | 867 // box because we want the position from within the scroller border. |
| 868 FloatSize containerBorderOffset(containingBlock->borderLeft(), | 868 FloatSize containerBorderOffset(containingBlock->borderLeft(), |
| 869 containingBlock->borderTop()); | 869 containingBlock->borderTop()); |
| 870 stickyLocation -= containerBorderOffset; | 870 stickyLocation -= containerBorderOffset; |
| 871 constraints.setScrollContainerRelativeStickyBoxRect( | 871 constraints.setScrollContainerRelativeStickyBoxRect( |
| 872 FloatRect(scrollContainerRelativePaddingBoxRect.location() + | 872 FloatRect(scrollContainerRelativePaddingBoxRect.location() + |
| 873 toFloatSize(stickyLocation), | 873 toFloatSize(stickyLocation), |
| 874 flippedStickyBoxRect.size())); | 874 flippedStickyBoxRect.size())); |
| 875 | 875 |
| 876 // To correctly compute the offsets, the constraints need to know about any | |
| 877 // nested position:sticky between themselves and their containingBlock, and | |
| 878 // between the containingBlock and the viewport. | |
| 879 | |
| 880 LayoutObject* maybeStickyAncestor = parent(); | |
| 881 while (maybeStickyAncestor && | |
| 882 maybeStickyAncestor != containingBlock->parent()) { | |
|
flackr
2017/01/18 16:09:47
We should stop before the containing block, the co
smcgruer
2017/01/18 19:10:50
Not sure I follow: no element should have itself a
flackr
2017/01/19 01:44:41
Not true. For the purposes of sticky position, the
smcgruer
2017/01/19 19:28:01
Done.
| |
| 883 if (maybeStickyAncestor->isStickyPositioned()) { | |
| 884 constraints.setNearestStickyElementToContainingBlock( | |
| 885 toLayoutBoxModelObject(maybeStickyAncestor)); | |
| 886 break; | |
| 887 } | |
| 888 maybeStickyAncestor = maybeStickyAncestor->parent(); | |
| 889 } | |
|
flackr
2017/01/18 14:42:56
We should try combining this with the walk to find
| |
| 890 | |
| 891 maybeStickyAncestor = containingBlock->parent(); | |
| 892 while (maybeStickyAncestor && | |
| 893 maybeStickyAncestor != scrollAncestor->parent()) { | |
|
flackr
2017/01/18 14:42:56
I don't think we need to track if the ancestor scr
smcgruer
2017/01/18 19:10:51
Good spot! Fixed and added a test. Also had to wra
| |
| 894 if (maybeStickyAncestor->isStickyPositioned()) { | |
| 895 constraints.setNearestStickyElementFromContainingBlockToViewport( | |
|
flackr
2017/01/18 14:42:56
for consistency s/ToViewport/ToScrollContainer (I
smcgruer
2017/01/18 19:10:50
Done.
| |
| 896 toLayoutBoxModelObject(maybeStickyAncestor)); | |
| 897 break; | |
| 898 } | |
| 899 maybeStickyAncestor = maybeStickyAncestor->parent(); | |
| 900 } | |
| 901 | |
| 876 // We skip the right or top sticky offset if there is not enough space to | 902 // We skip the right or top sticky offset if there is not enough space to |
| 877 // honor both the left/right or top/bottom offsets. | 903 // honor both the left/right or top/bottom offsets. |
| 878 LayoutUnit horizontalOffsets = | 904 LayoutUnit horizontalOffsets = |
| 879 minimumValueForLength(style()->right(), | 905 minimumValueForLength(style()->right(), |
| 880 LayoutUnit(constrainingSize.width())) + | 906 LayoutUnit(constrainingSize.width())) + |
| 881 minimumValueForLength(style()->left(), | 907 minimumValueForLength(style()->left(), |
| 882 LayoutUnit(constrainingSize.width())); | 908 LayoutUnit(constrainingSize.width())); |
| 883 bool skipRight = false; | 909 bool skipRight = false; |
| 884 bool skipLeft = false; | 910 bool skipLeft = false; |
| 885 if (!style()->left().isAuto() && !style()->right().isAuto()) { | 911 if (!style()->left().isAuto() && !style()->right().isAuto()) { |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 969 FloatRect constrainingRect = computeStickyConstrainingRect(); | 995 FloatRect constrainingRect = computeStickyConstrainingRect(); |
| 970 PaintLayerScrollableArea* scrollableArea = | 996 PaintLayerScrollableArea* scrollableArea = |
| 971 ancestorOverflowLayer->getScrollableArea(); | 997 ancestorOverflowLayer->getScrollableArea(); |
| 972 | 998 |
| 973 // The sticky offset is physical, so we can just return the delta computed in | 999 // The sticky offset is physical, so we can just return the delta computed in |
| 974 // absolute coords (though it may be wrong with transforms). | 1000 // absolute coords (though it may be wrong with transforms). |
| 975 // TODO: Force compositing input update if we ask for offset with stale | 1001 // TODO: Force compositing input update if we ask for offset with stale |
| 976 // compositing inputs. | 1002 // compositing inputs. |
| 977 if (!scrollableArea->stickyConstraintsMap().contains(layer())) | 1003 if (!scrollableArea->stickyConstraintsMap().contains(layer())) |
| 978 return LayoutSize(); | 1004 return LayoutSize(); |
| 979 return LayoutSize( | 1005 |
| 980 scrollableArea->stickyConstraintsMap().get(layer()).computeStickyOffset( | 1006 auto it = scrollableArea->stickyConstraintsMap().find(layer()); |
|
flackr
2017/01/18 14:42:56
Out of curiosity, why not stickyConstraintsMap().g
smcgruer
2017/01/18 19:10:51
As far as I can tell, WTF::HashMap::get() returns
flackr
2017/01/19 01:44:41
Okay no problem.
| |
| 981 constrainingRect)); | 1007 DCHECK(it != scrollableArea->stickyConstraintsMap().end()); |
| 1008 | |
| 1009 StickyPositionScrollingConstraints& constraints = it->value; | |
| 1010 | |
| 1011 FloatSize accumulatedOffsetToContainingBlock; | |
| 1012 FloatSize accumulatedOffsetToViewport; | |
| 1013 | |
| 1014 const LayoutBoxModelObject* toContainingBlock = | |
| 1015 constraints.nearestStickyElementToContainingBlock(); | |
| 1016 if (toContainingBlock) { | |
| 1017 accumulatedOffsetToContainingBlock = | |
| 1018 scrollableArea->stickyConstraintsMap() | |
| 1019 .get(toContainingBlock->layer()) | |
| 1020 .getCachedAccumulatedStickyOffset(); | |
| 1021 } | |
| 1022 | |
| 1023 const LayoutBoxModelObject* toViewport = | |
| 1024 constraints.nearestStickyElementFromContainingBlockToViewport(); | |
| 1025 if (toViewport) { | |
| 1026 accumulatedOffsetToViewport = scrollableArea->stickyConstraintsMap() | |
| 1027 .get(toViewport->layer()) | |
| 1028 .getCachedAccumulatedStickyOffset(); | |
| 1029 } | |
| 1030 | |
| 1031 return LayoutSize(constraints.computeStickyOffset( | |
| 1032 constrainingRect, accumulatedOffsetToContainingBlock, | |
| 1033 accumulatedOffsetToViewport)); | |
| 982 } | 1034 } |
| 983 | 1035 |
| 984 LayoutPoint LayoutBoxModelObject::adjustedPositionRelativeTo( | 1036 LayoutPoint LayoutBoxModelObject::adjustedPositionRelativeTo( |
| 985 const LayoutPoint& startPoint, | 1037 const LayoutPoint& startPoint, |
| 986 const Element* offsetParent) const { | 1038 const Element* offsetParent) const { |
| 987 // If the element is the HTML body element or doesn't have a parent | 1039 // If the element is the HTML body element or doesn't have a parent |
| 988 // return 0 and stop this algorithm. | 1040 // return 0 and stop this algorithm. |
| 989 if (isBody() || !parent()) | 1041 if (isBody() || !parent()) |
| 990 return LayoutPoint(); | 1042 return LayoutPoint(); |
| 991 | 1043 |
| (...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1340 if (rootElementStyle->hasBackground()) | 1392 if (rootElementStyle->hasBackground()) |
| 1341 return false; | 1393 return false; |
| 1342 | 1394 |
| 1343 if (node() != document().firstBodyElement()) | 1395 if (node() != document().firstBodyElement()) |
| 1344 return false; | 1396 return false; |
| 1345 | 1397 |
| 1346 return true; | 1398 return true; |
| 1347 } | 1399 } |
| 1348 | 1400 |
| 1349 } // namespace blink | 1401 } // namespace blink |
| OLD | NEW |