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

Unified Diff: third_party/WebKit/Source/core/page/scrolling/StickyPositionScrollingConstraints.cpp

Issue 2961613002: Slightly refactor StickyPositionScrollingConstraints API and add documentation (Closed)
Patch Set: More documentation, split out ancestor offset calculation Created 3 years, 6 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/page/scrolling/StickyPositionScrollingConstraints.cpp
diff --git a/third_party/WebKit/Source/core/page/scrolling/StickyPositionScrollingConstraints.cpp b/third_party/WebKit/Source/core/page/scrolling/StickyPositionScrollingConstraints.cpp
index 61150ecbbc4485b164011349d4eae3a78b547eee..8297c0982bf5e69a4109395e0bd9a63669140330 100644
--- a/third_party/WebKit/Source/core/page/scrolling/StickyPositionScrollingConstraints.cpp
+++ b/third_party/WebKit/Source/core/page/scrolling/StickyPositionScrollingConstraints.cpp
@@ -9,28 +9,38 @@ namespace blink {
FloatSize StickyPositionScrollingConstraints::ComputeStickyOffset(
const FloatRect& viewport_rect,
- const StickyPositionScrollingConstraints* ancestor_sticky_box_constraints,
- const StickyPositionScrollingConstraints*
- ancestor_containing_block_constraints) {
- // Adjust the constraint rect locations based on our ancestor sticky elements
- // These adjustments are necessary to avoid double offsetting in the case of
- // nested sticky elements.
- FloatSize ancestor_sticky_box_offset =
- ancestor_sticky_box_constraints
- ? ancestor_sticky_box_constraints->GetTotalStickyBoxStickyOffset()
- : FloatSize();
- FloatSize ancestor_containing_block_offset =
- ancestor_containing_block_constraints
- ? ancestor_containing_block_constraints
- ->GetTotalContainingBlockStickyOffset()
- : FloatSize();
+ const StickyConstraintsMap& constraints_map) {
FloatRect sticky_box_rect = scroll_container_relative_sticky_box_rect_;
FloatRect containing_block_rect =
scroll_container_relative_containing_block_rect_;
+ FloatSize ancestor_sticky_box_offset =
+ AncestorStickyBoxOffset(constraints_map);
+ FloatSize ancestor_containing_block_offset =
+ AncestorContainingBlockOffset(constraints_map);
+
+ // Adjust the cached rect locations for any sticky ancestor elements. The
+ // sticky offset applied to those ancestors affects us as follows:
+ //
+ // 1. |nearest_sticky_layer_shifting_sticky_box_| is a sticky layer between
+ // ourselves and our containing block, e.g. an inline parent. As such,
smcgruer 2017/06/26 19:18:56 I think this is inaccurate, an inline parent is in
flackr 2017/06/29 15:24:10 Yeah so it needs to be a sticky layer that is not
smcgruer 2017/06/29 18:51:46 Nested inline appears to work, so will likely use
flackr 2017/06/30 02:48:35 Yes, I was thinking it might be related if the rea
smcgruer 2017/07/07 13:51:57 Fixed the comment.
+ // it shifts only the sticky_box_rect, and not the containing_block_rect.
+ // 2. |nearest_sticky_layer_shifting_containing_block_| is a sticky layer
+ // between our containing block (inclusive) and our scroll ancestor
+ // (exclusive). As such, it shifts both the sticky_box_rect and the
+ // containing_block_rect.
+ //
+ // Note that this calculation assumes that |ComputeStickyOffset| is being
+ // called top down, e.g. it has been called on any ancestors we have before
+ // being called on us.
sticky_box_rect.Move(ancestor_sticky_box_offset +
ancestor_containing_block_offset);
containing_block_rect.Move(ancestor_containing_block_offset);
+ // We now attempt to shift sticky_box_rect to obey the specified sticky
+ // constraints, whilst always staying within our containing block. This
+ // shifting produces the final sticky offset below.
+ //
+ // As per the spec, 'left' overrides 'right' and 'top' overrides 'bottom'.
FloatRect box_rect = sticky_box_rect;
if (HasAnchorEdge(kAnchorEdgeRight)) {
@@ -81,6 +91,13 @@ FloatSize StickyPositionScrollingConstraints::ComputeStickyOffset(
FloatSize sticky_offset = box_rect.Location() - sticky_box_rect.Location();
+ // For performance, we cache our accumulated sticky offsets for any descendant
+ // sticky to use in it's own |ComputeStickyOffset| call. If these were not
+ // cached, one would instead need to call |ComputeStickyOffset| on every
+ // sticky ancestor in turn, accumulating the results.
+
+ // TODO(smcgruer): Document why these are calculated like this and why the two
smcgruer 2017/06/26 19:18:56 As per our IM discussion, I am still trying to exp
+ // different members are necessary.
total_sticky_box_sticky_offset_ = ancestor_sticky_box_offset + sticky_offset;
total_containing_block_sticky_offset_ = ancestor_sticky_box_offset +
ancestor_containing_block_offset +
@@ -91,14 +108,33 @@ FloatSize StickyPositionScrollingConstraints::ComputeStickyOffset(
FloatSize StickyPositionScrollingConstraints::GetOffsetForStickyPosition(
const StickyConstraintsMap& constraints_map) const {
- FloatSize nearest_sticky_box_shifting_sticky_box_constraints_offset;
- if (nearest_sticky_box_shifting_sticky_box_) {
- nearest_sticky_box_shifting_sticky_box_constraints_offset =
- constraints_map.at(nearest_sticky_box_shifting_sticky_box_->Layer())
- .GetTotalStickyBoxStickyOffset();
+ FloatSize nearest_sticky_layer_shifting_sticky_box_constraints_offset;
+ if (nearest_sticky_layer_shifting_sticky_box_) {
+ nearest_sticky_layer_shifting_sticky_box_constraints_offset =
+ constraints_map.at(nearest_sticky_layer_shifting_sticky_box_)
+ .total_sticky_box_sticky_offset_;
}
return total_sticky_box_sticky_offset_ -
- nearest_sticky_box_shifting_sticky_box_constraints_offset;
+ nearest_sticky_layer_shifting_sticky_box_constraints_offset;
+}
+
+FloatSize StickyPositionScrollingConstraints::AncestorStickyBoxOffset(
+ const StickyConstraintsMap& constraints_map) {
+ if (!nearest_sticky_layer_shifting_sticky_box_)
+ return FloatSize();
+ DCHECK(constraints_map.Contains(nearest_sticky_layer_shifting_sticky_box_));
flackr 2017/06/29 15:24:10 Is this check necessary when we use the constraint
smcgruer 2017/06/29 18:51:46 It's necessary. at() just calls EmptyValue() if it
+ return constraints_map.at(nearest_sticky_layer_shifting_sticky_box_)
+ .total_sticky_box_sticky_offset_;
+}
+
+FloatSize StickyPositionScrollingConstraints::AncestorContainingBlockOffset(
+ const StickyConstraintsMap& constraints_map) {
+ if (!nearest_sticky_layer_shifting_containing_block_)
+ return FloatSize();
+ DCHECK(constraints_map.Contains(
+ nearest_sticky_layer_shifting_containing_block_));
+ return constraints_map.at(nearest_sticky_layer_shifting_containing_block_)
+ .total_containing_block_sticky_offset_;
}
} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698