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 769 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 780 FloatSize skippedContainersOffset; | 780 FloatSize skippedContainersOffset; |
| 781 LayoutBlock* containingBlock = this->containingBlock(); | 781 LayoutBlock* containingBlock = this->containingBlock(); |
| 782 // The location container for boxes is not always the containing block. | 782 // The location container for boxes is not always the containing block. |
| 783 LayoutBox* locationContainer = isLayoutInline() | 783 LayoutBox* locationContainer = isLayoutInline() |
| 784 ? containingBlock | 784 ? containingBlock |
| 785 : toLayoutBox(this)->locationContainer(); | 785 : toLayoutBox(this)->locationContainer(); |
| 786 // Skip anonymous containing blocks. | 786 // Skip anonymous containing blocks. |
| 787 while (containingBlock->isAnonymous()) { | 787 while (containingBlock->isAnonymous()) { |
| 788 containingBlock = containingBlock->containingBlock(); | 788 containingBlock = containingBlock->containingBlock(); |
| 789 } | 789 } |
| 790 MapCoordinatesFlags flags = 0; | 790 MapCoordinatesFlags flags = IgnoreSticky; |
| 791 skippedContainersOffset = | 791 skippedContainersOffset = |
| 792 toFloatSize(locationContainer | 792 toFloatSize(locationContainer |
| 793 ->localToAncestorQuadWithoutTransforms( | 793 ->localToAncestorQuadWithoutTransforms( |
| 794 FloatQuad(), containingBlock, flags) | 794 FloatQuad(), containingBlock, flags) |
| 795 .boundingBox() | 795 .boundingBox() |
| 796 .location()); | 796 .location()); |
| 797 LayoutBox* scrollAncestor = | 797 LayoutBox* scrollAncestor = |
| 798 layer()->ancestorOverflowLayer()->isRootLayer() | 798 layer()->ancestorOverflowLayer()->isRootLayer() |
| 799 ? nullptr | 799 ? nullptr |
| 800 : toLayoutBox(layer()->ancestorOverflowLayer()->layoutObject()); | 800 : toLayoutBox(layer()->ancestorOverflowLayer()->layoutObject()); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 878 // the container is our scroll ancestor, we also need to remove the border | 878 // the container is our scroll ancestor, we also need to remove the border |
| 879 // box because we want the position from within the scroller border. | 879 // box because we want the position from within the scroller border. |
| 880 FloatSize containerBorderOffset(containingBlock->borderLeft(), | 880 FloatSize containerBorderOffset(containingBlock->borderLeft(), |
| 881 containingBlock->borderTop()); | 881 containingBlock->borderTop()); |
| 882 stickyLocation -= containerBorderOffset; | 882 stickyLocation -= containerBorderOffset; |
| 883 constraints.setScrollContainerRelativeStickyBoxRect( | 883 constraints.setScrollContainerRelativeStickyBoxRect( |
| 884 FloatRect(scrollContainerRelativePaddingBoxRect.location() + | 884 FloatRect(scrollContainerRelativePaddingBoxRect.location() + |
| 885 toFloatSize(stickyLocation), | 885 toFloatSize(stickyLocation), |
| 886 flippedStickyBoxRect.size())); | 886 flippedStickyBoxRect.size())); |
| 887 | 887 |
| 888 // To correctly compute the offsets, the constraints need to know about any | |
| 889 // nested position:sticky between themselves and their containingBlock, and | |
| 890 // between the containingBlock and their scrollAncestor. | |
| 891 // | |
| 892 // The respective search ranges are [container, containingBlock) and | |
| 893 // [containingBlock, scrollAncestor). | |
| 894 | |
| 895 // TODO(smcgruer): Fold these into the walks to find the containingBlock and | |
| 896 // scrollAncestor. | |
| 897 LayoutObject* maybeStickyAncestor = locationContainer; | |
| 898 while (maybeStickyAncestor && maybeStickyAncestor != containingBlock) { | |
| 899 if (maybeStickyAncestor->isStickyPositioned()) { | |
| 900 constraints.setNearestStickyElementShiftingStickyBox( | |
| 901 toLayoutBoxModelObject(maybeStickyAncestor)); | |
| 902 break; | |
| 903 } | |
| 904 maybeStickyAncestor = | |
| 905 maybeStickyAncestor->isLayoutInline() | |
| 906 ? maybeStickyAncestor->containingBlock() | |
| 907 : toLayoutBox(maybeStickyAncestor)->locationContainer(); | |
| 908 } | |
|
flackr
2017/01/31 18:33:00
Create a function for this common loop code, maybe
smcgruer
2017/01/31 20:42:16
I was intended to look at folding these into the w
flackr
2017/02/02 18:18:11
Yes, we should just clean it up with a helper func
| |
| 909 | |
| 910 // NOTE(smcgruer): We cannot use |scrollAncestor| here as it disregards the | |
| 911 // root ancestorOverflowLayer(), which we should include for the purposes of | |
| 912 // finding the nearest sticky element that shifts the containing block rect. | |
| 913 LayoutObject* ancestorOverflowLayer = | |
| 914 layer()->ancestorOverflowLayer()->layoutObject(); | |
| 915 maybeStickyAncestor = containingBlock; | |
| 916 while (maybeStickyAncestor && maybeStickyAncestor != ancestorOverflowLayer) { | |
| 917 if (maybeStickyAncestor->isStickyPositioned()) { | |
| 918 constraints.setNearestStickyElementShiftingContainingBlock( | |
| 919 toLayoutBoxModelObject(maybeStickyAncestor)); | |
| 920 break; | |
| 921 } | |
| 922 maybeStickyAncestor = | |
| 923 maybeStickyAncestor->isLayoutInline() | |
| 924 ? maybeStickyAncestor->containingBlock() | |
| 925 : toLayoutBox(maybeStickyAncestor)->locationContainer(); | |
| 926 } | |
| 927 | |
| 888 // We skip the right or top sticky offset if there is not enough space to | 928 // We skip the right or top sticky offset if there is not enough space to |
| 889 // honor both the left/right or top/bottom offsets. | 929 // honor both the left/right or top/bottom offsets. |
| 890 LayoutUnit horizontalOffsets = | 930 LayoutUnit horizontalOffsets = |
| 891 minimumValueForLength(style()->right(), | 931 minimumValueForLength(style()->right(), |
| 892 LayoutUnit(constrainingSize.width())) + | 932 LayoutUnit(constrainingSize.width())) + |
| 893 minimumValueForLength(style()->left(), | 933 minimumValueForLength(style()->left(), |
| 894 LayoutUnit(constrainingSize.width())); | 934 LayoutUnit(constrainingSize.width())); |
| 895 bool skipRight = false; | 935 bool skipRight = false; |
| 896 bool skipLeft = false; | 936 bool skipLeft = false; |
| 897 if (!style()->left().isAuto() && !style()->right().isAuto()) { | 937 if (!style()->left().isAuto() && !style()->right().isAuto()) { |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 975 LayoutSize LayoutBoxModelObject::stickyPositionOffset() const { | 1015 LayoutSize LayoutBoxModelObject::stickyPositionOffset() const { |
| 976 const PaintLayer* ancestorOverflowLayer = layer()->ancestorOverflowLayer(); | 1016 const PaintLayer* ancestorOverflowLayer = layer()->ancestorOverflowLayer(); |
| 977 // TODO: Force compositing input update if we ask for offset before | 1017 // TODO: Force compositing input update if we ask for offset before |
| 978 // compositing inputs have been computed? | 1018 // compositing inputs have been computed? |
| 979 if (!ancestorOverflowLayer) | 1019 if (!ancestorOverflowLayer) |
| 980 return LayoutSize(); | 1020 return LayoutSize(); |
| 981 FloatRect constrainingRect = computeStickyConstrainingRect(); | 1021 FloatRect constrainingRect = computeStickyConstrainingRect(); |
| 982 PaintLayerScrollableArea* scrollableArea = | 1022 PaintLayerScrollableArea* scrollableArea = |
| 983 ancestorOverflowLayer->getScrollableArea(); | 1023 ancestorOverflowLayer->getScrollableArea(); |
| 984 | 1024 |
| 1025 auto it = scrollableArea->stickyConstraintsMap().find(layer()); | |
| 1026 | |
| 985 // The sticky offset is physical, so we can just return the delta computed in | 1027 // The sticky offset is physical, so we can just return the delta computed in |
| 986 // absolute coords (though it may be wrong with transforms). | 1028 // absolute coords (though it may be wrong with transforms). |
| 987 // TODO: Force compositing input update if we ask for offset with stale | 1029 // TODO: Force compositing input update if we ask for offset with stale |
| 988 // compositing inputs. | 1030 // compositing inputs. |
| 989 if (!scrollableArea->stickyConstraintsMap().contains(layer())) | 1031 if (it == scrollableArea->stickyConstraintsMap().end()) |
| 990 return LayoutSize(); | 1032 return LayoutSize(); |
| 1033 | |
| 1034 StickyPositionScrollingConstraints& constraints = it->value; | |
| 1035 | |
| 1036 FloatSize ancestorStickyBoxOffset; | |
| 1037 FloatSize ancestorContainingBlockOffset; | |
| 1038 | |
| 1039 const LayoutBoxModelObject* toContainingBlock = | |
| 1040 constraints.nearestStickyElementShiftingStickyBox(); | |
| 1041 if (toContainingBlock) { | |
| 1042 ancestorStickyBoxOffset = scrollableArea->stickyConstraintsMap() | |
| 1043 .get(toContainingBlock->layer()) | |
|
flackr
2017/01/31 18:33:00
nit: Helper function to get sticky constraints for
smcgruer
2017/01/31 20:42:16
Done.
| |
| 1044 .getTotalStickyBoxStickyOffset(); | |
|
flackr
2017/01/31 18:33:00
It'd probably be cleaner to get these as part of c
smcgruer
2017/01/31 20:42:16
Done.
| |
| 1045 } | |
| 1046 | |
| 1047 const LayoutBoxModelObject* toViewport = | |
| 1048 constraints.nearestStickyElementShiftingContainingBlock(); | |
| 1049 if (toViewport) { | |
| 1050 ancestorContainingBlockOffset = scrollableArea->stickyConstraintsMap() | |
| 1051 .get(toViewport->layer()) | |
| 1052 .getTotalContainingBlockStickyOffset(); | |
| 1053 } | |
| 1054 | |
| 991 return LayoutSize( | 1055 return LayoutSize( |
| 992 scrollableArea->stickyConstraintsMap().get(layer()).computeStickyOffset( | 1056 constraints.computeStickyOffset(constrainingRect, ancestorStickyBoxOffset, |
| 993 constrainingRect)); | 1057 ancestorContainingBlockOffset)); |
| 994 } | 1058 } |
| 995 | 1059 |
| 996 LayoutPoint LayoutBoxModelObject::adjustedPositionRelativeTo( | 1060 LayoutPoint LayoutBoxModelObject::adjustedPositionRelativeTo( |
| 997 const LayoutPoint& startPoint, | 1061 const LayoutPoint& startPoint, |
| 998 const Element* offsetParent) const { | 1062 const Element* offsetParent) const { |
| 999 // If the element is the HTML body element or doesn't have a parent | 1063 // If the element is the HTML body element or doesn't have a parent |
| 1000 // return 0 and stop this algorithm. | 1064 // return 0 and stop this algorithm. |
| 1001 if (isBody() || !parent()) | 1065 if (isBody() || !parent()) |
| 1002 return LayoutPoint(); | 1066 return LayoutPoint(); |
| 1003 | 1067 |
| (...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1352 if (rootElementStyle->hasBackground()) | 1416 if (rootElementStyle->hasBackground()) |
| 1353 return false; | 1417 return false; |
| 1354 | 1418 |
| 1355 if (node() != document().firstBodyElement()) | 1419 if (node() != document().firstBodyElement()) |
| 1356 return false; | 1420 return false; |
| 1357 | 1421 |
| 1358 return true; | 1422 return true; |
| 1359 } | 1423 } |
| 1360 | 1424 |
| 1361 } // namespace blink | 1425 } // namespace blink |
| OLD | NEW |