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 their scrollAncestor. | |
| 879 // | |
| 880 // The respective search ranges are [parent(), containingBlock) and | |
| 881 // [containingBlock, scrollAncestor). | |
| 882 | |
| 883 // TODO(smcgruer): Fold these into the walks to find the containingBlock and | |
| 884 // scrollAncestor. | |
| 885 | |
| 886 LayoutObject* maybeStickyAncestor = parent(); | |
| 887 while (maybeStickyAncestor && maybeStickyAncestor != containingBlock) { | |
| 888 if (maybeStickyAncestor->isStickyPositioned()) { | |
| 889 constraints.setNearestStickyElementShiftingStickyBox( | |
| 890 toLayoutBoxModelObject(maybeStickyAncestor)); | |
| 891 break; | |
| 892 } | |
| 893 maybeStickyAncestor = maybeStickyAncestor->parent(); | |
| 894 } | |
| 895 | |
| 896 // NOTE(smcgruer): We cannot use |scrollAncestor| here as it disregards the | |
| 897 // root ancestorOverflowLayer(), which we should include for the purposes of | |
| 898 // finding the nearest sticky element that shifts the containing block rect. | |
| 899 LayoutObject* ancestorOverflowLayer = | |
| 900 layer()->ancestorOverflowLayer()->layoutObject(); | |
| 901 maybeStickyAncestor = containingBlock; | |
| 902 while (maybeStickyAncestor && maybeStickyAncestor != ancestorOverflowLayer) { | |
| 903 if (maybeStickyAncestor->isStickyPositioned()) { | |
| 904 constraints.setNearestStickyElementShiftingContainingBlock( | |
| 905 toLayoutBoxModelObject(maybeStickyAncestor)); | |
| 906 break; | |
| 907 } | |
| 908 maybeStickyAncestor = maybeStickyAncestor->parent(); | |
|
flackr
2017/01/24 20:28:48
Technically we should be following the locationCon
smcgruer
2017/01/28 00:55:31
Done.
| |
| 909 } | |
| 910 | |
| 876 // We skip the right or top sticky offset if there is not enough space to | 911 // 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. | 912 // honor both the left/right or top/bottom offsets. |
| 878 LayoutUnit horizontalOffsets = | 913 LayoutUnit horizontalOffsets = |
| 879 minimumValueForLength(style()->right(), | 914 minimumValueForLength(style()->right(), |
| 880 LayoutUnit(constrainingSize.width())) + | 915 LayoutUnit(constrainingSize.width())) + |
| 881 minimumValueForLength(style()->left(), | 916 minimumValueForLength(style()->left(), |
| 882 LayoutUnit(constrainingSize.width())); | 917 LayoutUnit(constrainingSize.width())); |
| 883 bool skipRight = false; | 918 bool skipRight = false; |
| 884 bool skipLeft = false; | 919 bool skipLeft = false; |
| 885 if (!style()->left().isAuto() && !style()->right().isAuto()) { | 920 if (!style()->left().isAuto() && !style()->right().isAuto()) { |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 963 LayoutSize LayoutBoxModelObject::stickyPositionOffset() const { | 998 LayoutSize LayoutBoxModelObject::stickyPositionOffset() const { |
| 964 const PaintLayer* ancestorOverflowLayer = layer()->ancestorOverflowLayer(); | 999 const PaintLayer* ancestorOverflowLayer = layer()->ancestorOverflowLayer(); |
| 965 // TODO: Force compositing input update if we ask for offset before | 1000 // TODO: Force compositing input update if we ask for offset before |
| 966 // compositing inputs have been computed? | 1001 // compositing inputs have been computed? |
| 967 if (!ancestorOverflowLayer) | 1002 if (!ancestorOverflowLayer) |
| 968 return LayoutSize(); | 1003 return LayoutSize(); |
| 969 FloatRect constrainingRect = computeStickyConstrainingRect(); | 1004 FloatRect constrainingRect = computeStickyConstrainingRect(); |
| 970 PaintLayerScrollableArea* scrollableArea = | 1005 PaintLayerScrollableArea* scrollableArea = |
| 971 ancestorOverflowLayer->getScrollableArea(); | 1006 ancestorOverflowLayer->getScrollableArea(); |
| 972 | 1007 |
| 1008 auto it = scrollableArea->stickyConstraintsMap().find(layer()); | |
| 1009 | |
| 973 // The sticky offset is physical, so we can just return the delta computed in | 1010 // The sticky offset is physical, so we can just return the delta computed in |
| 974 // absolute coords (though it may be wrong with transforms). | 1011 // absolute coords (though it may be wrong with transforms). |
| 975 // TODO: Force compositing input update if we ask for offset with stale | 1012 // TODO: Force compositing input update if we ask for offset with stale |
| 976 // compositing inputs. | 1013 // compositing inputs. |
| 977 if (!scrollableArea->stickyConstraintsMap().contains(layer())) | 1014 if (it == scrollableArea->stickyConstraintsMap().end()) |
| 978 return LayoutSize(); | 1015 return LayoutSize(); |
| 1016 | |
| 1017 StickyPositionScrollingConstraints& constraints = it->value; | |
| 1018 | |
| 1019 FloatSize ancestorStickyBoxOffset; | |
| 1020 FloatSize ancestorContainingBlockOffset; | |
| 1021 | |
| 1022 const LayoutBoxModelObject* toContainingBlock = | |
| 1023 constraints.nearestStickyElementShiftingStickyBox(); | |
| 1024 if (toContainingBlock) { | |
| 1025 ancestorStickyBoxOffset = scrollableArea->stickyConstraintsMap() | |
| 1026 .get(toContainingBlock->layer()) | |
| 1027 .getTotalStickyBoxStickyOffset(); | |
| 1028 } | |
| 1029 | |
| 1030 const LayoutBoxModelObject* toViewport = | |
| 1031 constraints.nearestStickyElementShiftingContainingBlock(); | |
| 1032 if (toViewport) { | |
| 1033 ancestorContainingBlockOffset = scrollableArea->stickyConstraintsMap() | |
| 1034 .get(toViewport->layer()) | |
| 1035 .getTotalContainingBlockStickyOffset(); | |
| 1036 } | |
| 1037 | |
| 979 return LayoutSize( | 1038 return LayoutSize( |
| 980 scrollableArea->stickyConstraintsMap().get(layer()).computeStickyOffset( | 1039 constraints.computeStickyOffset(constrainingRect, ancestorStickyBoxOffset, |
| 981 constrainingRect)); | 1040 ancestorContainingBlockOffset)); |
| 982 } | 1041 } |
| 983 | 1042 |
| 984 LayoutPoint LayoutBoxModelObject::adjustedPositionRelativeTo( | 1043 LayoutPoint LayoutBoxModelObject::adjustedPositionRelativeTo( |
| 985 const LayoutPoint& startPoint, | 1044 const LayoutPoint& startPoint, |
| 986 const Element* offsetParent) const { | 1045 const Element* offsetParent) const { |
| 987 // If the element is the HTML body element or doesn't have a parent | 1046 // If the element is the HTML body element or doesn't have a parent |
| 988 // return 0 and stop this algorithm. | 1047 // return 0 and stop this algorithm. |
| 989 if (isBody() || !parent()) | 1048 if (isBody() || !parent()) |
| 990 return LayoutPoint(); | 1049 return LayoutPoint(); |
| 991 | 1050 |
| (...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1340 if (rootElementStyle->hasBackground()) | 1399 if (rootElementStyle->hasBackground()) |
| 1341 return false; | 1400 return false; |
| 1342 | 1401 |
| 1343 if (node() != document().firstBodyElement()) | 1402 if (node() != document().firstBodyElement()) |
| 1344 return false; | 1403 return false; |
| 1345 | 1404 |
| 1346 return true; | 1405 return true; |
| 1347 } | 1406 } |
| 1348 | 1407 |
| 1349 } // namespace blink | 1408 } // namespace blink |
| OLD | NEW |