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

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

Issue 2961613002: Slightly refactor StickyPositionScrollingConstraints API and add documentation (Closed)
Patch Set: remove accidental file 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 unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/page/scrolling/StickyPositionScrollingConstraints.h" 5 #include "core/page/scrolling/StickyPositionScrollingConstraints.h"
6 #include "core/paint/PaintLayer.h" 6 #include "core/paint/PaintLayer.h"
7 7
8 namespace blink { 8 namespace blink {
9 9
10 FloatSize StickyPositionScrollingConstraints::ComputeStickyOffset( 10 FloatSize StickyPositionScrollingConstraints::ComputeStickyOffset(
11 const FloatRect& viewport_rect, 11 const FloatRect& overflow_clip_rect,
12 const StickyPositionScrollingConstraints* ancestor_sticky_box_constraints, 12 const StickyConstraintsMap& constraints_map) {
13 const StickyPositionScrollingConstraints*
14 ancestor_containing_block_constraints) {
15 // Adjust the constraint rect locations based on our ancestor sticky elements
16 // These adjustments are necessary to avoid double offsetting in the case of
17 // nested sticky elements.
18 FloatSize ancestor_sticky_box_offset =
19 ancestor_sticky_box_constraints
20 ? ancestor_sticky_box_constraints->GetTotalStickyBoxStickyOffset()
21 : FloatSize();
22 FloatSize ancestor_containing_block_offset =
23 ancestor_containing_block_constraints
24 ? ancestor_containing_block_constraints
25 ->GetTotalContainingBlockStickyOffset()
26 : FloatSize();
27 FloatRect sticky_box_rect = scroll_container_relative_sticky_box_rect_; 13 FloatRect sticky_box_rect = scroll_container_relative_sticky_box_rect_;
28 FloatRect containing_block_rect = 14 FloatRect containing_block_rect =
29 scroll_container_relative_containing_block_rect_; 15 scroll_container_relative_containing_block_rect_;
16 FloatSize ancestor_sticky_box_offset =
17 AncestorStickyBoxOffset(constraints_map);
18 FloatSize ancestor_containing_block_offset =
19 AncestorContainingBlockOffset(constraints_map);
20
21 // Adjust the cached rect locations for any sticky ancestor elements. The
22 // sticky offset applied to those ancestors affects us as follows:
23 //
24 // 1. |nearest_sticky_layer_shifting_sticky_box_| is a sticky layer between
25 // ourselves and our containing block, e.g. an inline parent. As such,
26 // it shifts only the sticky_box_rect, and not the containing_block_rect.
27 // 2. |nearest_sticky_layer_shifting_containing_block_| is a sticky layer
28 // between our containing block (inclusive) and our scroll ancestor
29 // (exclusive). As such, it shifts both the sticky_box_rect and the
30 // containing_block_rect.
31 //
32 // Note that this calculation assumes that |ComputeStickyOffset| is being
33 // called top down, e.g. it has been called on any ancestors we have before
34 // being called on us.
30 sticky_box_rect.Move(ancestor_sticky_box_offset + 35 sticky_box_rect.Move(ancestor_sticky_box_offset +
31 ancestor_containing_block_offset); 36 ancestor_containing_block_offset);
32 containing_block_rect.Move(ancestor_containing_block_offset); 37 containing_block_rect.Move(ancestor_containing_block_offset);
33 38
39 // We now attempt to shift sticky_box_rect to obey the specified sticky
40 // constraints, whilst always staying within our containing block. This
41 // shifting produces the final sticky offset below.
42 //
43 // As per the spec, 'left' overrides 'right' and 'top' overrides 'bottom'.
34 FloatRect box_rect = sticky_box_rect; 44 FloatRect box_rect = sticky_box_rect;
35 45
36 if (HasAnchorEdge(kAnchorEdgeRight)) { 46 if (HasAnchorEdge(kAnchorEdgeRight)) {
37 float right_limit = viewport_rect.MaxX() - right_offset_; 47 float right_limit = overflow_clip_rect.MaxX() - right_offset_;
38 float right_delta = 48 float right_delta =
39 std::min<float>(0, right_limit - sticky_box_rect.MaxX()); 49 std::min<float>(0, right_limit - sticky_box_rect.MaxX());
40 float available_space = 50 float available_space =
41 std::min<float>(0, containing_block_rect.X() - sticky_box_rect.X()); 51 std::min<float>(0, containing_block_rect.X() - sticky_box_rect.X());
42 if (right_delta < available_space) 52 if (right_delta < available_space)
43 right_delta = available_space; 53 right_delta = available_space;
44 54
45 box_rect.Move(right_delta, 0); 55 box_rect.Move(right_delta, 0);
46 } 56 }
47 57
48 if (HasAnchorEdge(kAnchorEdgeLeft)) { 58 if (HasAnchorEdge(kAnchorEdgeLeft)) {
49 float left_limit = viewport_rect.X() + left_offset_; 59 float left_limit = overflow_clip_rect.X() + left_offset_;
50 float left_delta = std::max<float>(0, left_limit - sticky_box_rect.X()); 60 float left_delta = std::max<float>(0, left_limit - sticky_box_rect.X());
51 float available_space = std::max<float>( 61 float available_space = std::max<float>(
52 0, containing_block_rect.MaxX() - sticky_box_rect.MaxX()); 62 0, containing_block_rect.MaxX() - sticky_box_rect.MaxX());
53 if (left_delta > available_space) 63 if (left_delta > available_space)
54 left_delta = available_space; 64 left_delta = available_space;
55 65
56 box_rect.Move(left_delta, 0); 66 box_rect.Move(left_delta, 0);
57 } 67 }
58 68
59 if (HasAnchorEdge(kAnchorEdgeBottom)) { 69 if (HasAnchorEdge(kAnchorEdgeBottom)) {
60 float bottom_limit = viewport_rect.MaxY() - bottom_offset_; 70 float bottom_limit = overflow_clip_rect.MaxY() - bottom_offset_;
61 float bottom_delta = 71 float bottom_delta =
62 std::min<float>(0, bottom_limit - sticky_box_rect.MaxY()); 72 std::min<float>(0, bottom_limit - sticky_box_rect.MaxY());
63 float available_space = 73 float available_space =
64 std::min<float>(0, containing_block_rect.Y() - sticky_box_rect.Y()); 74 std::min<float>(0, containing_block_rect.Y() - sticky_box_rect.Y());
65 if (bottom_delta < available_space) 75 if (bottom_delta < available_space)
66 bottom_delta = available_space; 76 bottom_delta = available_space;
67 77
68 box_rect.Move(0, bottom_delta); 78 box_rect.Move(0, bottom_delta);
69 } 79 }
70 80
71 if (HasAnchorEdge(kAnchorEdgeTop)) { 81 if (HasAnchorEdge(kAnchorEdgeTop)) {
72 float top_limit = viewport_rect.Y() + top_offset_; 82 float top_limit = overflow_clip_rect.Y() + top_offset_;
73 float top_delta = std::max<float>(0, top_limit - sticky_box_rect.Y()); 83 float top_delta = std::max<float>(0, top_limit - sticky_box_rect.Y());
74 float available_space = std::max<float>( 84 float available_space = std::max<float>(
75 0, containing_block_rect.MaxY() - sticky_box_rect.MaxY()); 85 0, containing_block_rect.MaxY() - sticky_box_rect.MaxY());
76 if (top_delta > available_space) 86 if (top_delta > available_space)
77 top_delta = available_space; 87 top_delta = available_space;
78 88
79 box_rect.Move(0, top_delta); 89 box_rect.Move(0, top_delta);
80 } 90 }
81 91
82 FloatSize sticky_offset = box_rect.Location() - sticky_box_rect.Location(); 92 FloatSize sticky_offset = box_rect.Location() - sticky_box_rect.Location();
83 93
94 // For performance, we cache our accumulated sticky offsets for any descendant
95 // sticky to use in it's own |ComputeStickyOffset| call. If these were not
96 // cached, one would instead need to call |ComputeStickyOffset| on every
97 // sticky ancestor in turn, accumulating the results.
98
99 // TODO(smcgruer): Document why these are calculated like this and why the two
100 // different members are necessary.
flackr 2017/06/30 02:48:35 There's some comments in the header file for these
smcgruer 2017/07/07 13:51:58 Done.
flackr 2017/07/19 17:13:34 Sorry, to be specific I meant augment the document
smcgruer 2017/07/20 19:25:08 Done.
84 total_sticky_box_sticky_offset_ = ancestor_sticky_box_offset + sticky_offset; 101 total_sticky_box_sticky_offset_ = ancestor_sticky_box_offset + sticky_offset;
85 total_containing_block_sticky_offset_ = ancestor_sticky_box_offset + 102 total_containing_block_sticky_offset_ = ancestor_sticky_box_offset +
86 ancestor_containing_block_offset + 103 ancestor_containing_block_offset +
87 sticky_offset; 104 sticky_offset;
88 105
89 return sticky_offset; 106 return sticky_offset;
90 } 107 }
91 108
92 FloatSize StickyPositionScrollingConstraints::GetOffsetForStickyPosition( 109 FloatSize StickyPositionScrollingConstraints::GetOffsetForStickyPosition(
93 const StickyConstraintsMap& constraints_map) const { 110 const StickyConstraintsMap& constraints_map) const {
94 FloatSize nearest_sticky_box_shifting_sticky_box_constraints_offset; 111 FloatSize nearest_sticky_layer_shifting_sticky_box_constraints_offset;
95 if (nearest_sticky_box_shifting_sticky_box_) { 112 if (nearest_sticky_layer_shifting_sticky_box_) {
96 nearest_sticky_box_shifting_sticky_box_constraints_offset = 113 nearest_sticky_layer_shifting_sticky_box_constraints_offset =
97 constraints_map.at(nearest_sticky_box_shifting_sticky_box_->Layer()) 114 constraints_map.at(nearest_sticky_layer_shifting_sticky_box_)
98 .GetTotalStickyBoxStickyOffset(); 115 .total_sticky_box_sticky_offset_;
99 } 116 }
100 return total_sticky_box_sticky_offset_ - 117 return total_sticky_box_sticky_offset_ -
101 nearest_sticky_box_shifting_sticky_box_constraints_offset; 118 nearest_sticky_layer_shifting_sticky_box_constraints_offset;
119 }
120
121 FloatSize StickyPositionScrollingConstraints::AncestorStickyBoxOffset(
122 const StickyConstraintsMap& constraints_map) {
123 if (!nearest_sticky_layer_shifting_sticky_box_)
124 return FloatSize();
125 DCHECK(constraints_map.Contains(nearest_sticky_layer_shifting_sticky_box_));
126 return constraints_map.at(nearest_sticky_layer_shifting_sticky_box_)
127 .total_sticky_box_sticky_offset_;
128 }
129
130 FloatSize StickyPositionScrollingConstraints::AncestorContainingBlockOffset(
131 const StickyConstraintsMap& constraints_map) {
132 if (!nearest_sticky_layer_shifting_containing_block_) {
133 return FloatSize();
134 }
135 DCHECK(constraints_map.Contains(
136 nearest_sticky_layer_shifting_containing_block_));
137 return constraints_map.at(nearest_sticky_layer_shifting_containing_block_)
138 .total_containing_block_sticky_offset_;
102 } 139 }
103 140
104 } // namespace blink 141 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698