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

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

Issue 2961613002: Slightly refactor StickyPositionScrollingConstraints API and add documentation (Closed)
Patch Set: Add diagram + example Created 3 years, 5 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
« no previous file with comments | « third_party/WebKit/Source/core/page/scrolling/StickyPositionScrollingConstraints.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..10e8efd6d8af6b5a69391c36e7f4a21d55a93945 100644
--- a/third_party/WebKit/Source/core/page/scrolling/StickyPositionScrollingConstraints.cpp
+++ b/third_party/WebKit/Source/core/page/scrolling/StickyPositionScrollingConstraints.cpp
@@ -8,33 +8,43 @@
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 FloatRect& overflow_clip_rect,
+ 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. a nested inline parent.
+ // 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)) {
- float right_limit = viewport_rect.MaxX() - right_offset_;
+ float right_limit = overflow_clip_rect.MaxX() - right_offset_;
float right_delta =
std::min<float>(0, right_limit - sticky_box_rect.MaxX());
float available_space =
@@ -46,7 +56,7 @@ FloatSize StickyPositionScrollingConstraints::ComputeStickyOffset(
}
if (HasAnchorEdge(kAnchorEdgeLeft)) {
- float left_limit = viewport_rect.X() + left_offset_;
+ float left_limit = overflow_clip_rect.X() + left_offset_;
float left_delta = std::max<float>(0, left_limit - sticky_box_rect.X());
float available_space = std::max<float>(
0, containing_block_rect.MaxX() - sticky_box_rect.MaxX());
@@ -57,7 +67,7 @@ FloatSize StickyPositionScrollingConstraints::ComputeStickyOffset(
}
if (HasAnchorEdge(kAnchorEdgeBottom)) {
- float bottom_limit = viewport_rect.MaxY() - bottom_offset_;
+ float bottom_limit = overflow_clip_rect.MaxY() - bottom_offset_;
float bottom_delta =
std::min<float>(0, bottom_limit - sticky_box_rect.MaxY());
float available_space =
@@ -69,7 +79,7 @@ FloatSize StickyPositionScrollingConstraints::ComputeStickyOffset(
}
if (HasAnchorEdge(kAnchorEdgeTop)) {
- float top_limit = viewport_rect.Y() + top_offset_;
+ float top_limit = overflow_clip_rect.Y() + top_offset_;
float top_delta = std::max<float>(0, top_limit - sticky_box_rect.Y());
float available_space = std::max<float>(
0, containing_block_rect.MaxY() - sticky_box_rect.MaxY());
@@ -81,6 +91,8 @@ FloatSize StickyPositionScrollingConstraints::ComputeStickyOffset(
FloatSize sticky_offset = box_rect.Location() - sticky_box_rect.Location();
+ // Now that we have computed our current sticky offset, update the cached
+ // accumulated sticky offsets.
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 +103,34 @@ 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_));
+ 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
« no previous file with comments | « third_party/WebKit/Source/core/page/scrolling/StickyPositionScrollingConstraints.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698