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

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

Issue 2636253002: Handle nested position:sticky elements (Closed)
Patch Set: Offset rects correctly and accumulate correctly Created 3 years, 11 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.h
diff --git a/third_party/WebKit/Source/core/page/scrolling/StickyPositionScrollingConstraints.h b/third_party/WebKit/Source/core/page/scrolling/StickyPositionScrollingConstraints.h
index e37687262edcd4a096f127a3a5054eeb78330e66..8809b13572177cb2dac53d96a149b349059ac2a7 100644
--- a/third_party/WebKit/Source/core/page/scrolling/StickyPositionScrollingConstraints.h
+++ b/third_party/WebKit/Source/core/page/scrolling/StickyPositionScrollingConstraints.h
@@ -6,9 +6,12 @@
#define StickyPositionScrollingConstraints_h
#include "platform/geometry/FloatRect.h"
+#include "platform/geometry/FloatSize.h"
namespace blink {
+class LayoutBoxModelObject;
+
class StickyPositionScrollingConstraints final {
public:
enum AnchorEdgeFlags {
@@ -24,7 +27,9 @@ class StickyPositionScrollingConstraints final {
m_leftOffset(0),
m_rightOffset(0),
m_topOffset(0),
- m_bottomOffset(0) {}
+ m_bottomOffset(0),
+ m_nearestStickyElementToContainingBlock(nullptr),
+ m_nearestStickyElementFromContainingBlockToScrollContainer(nullptr) {}
StickyPositionScrollingConstraints(
const StickyPositionScrollingConstraints& other)
@@ -36,9 +41,26 @@ class StickyPositionScrollingConstraints final {
m_scrollContainerRelativeContainingBlockRect(
other.m_scrollContainerRelativeContainingBlockRect),
m_scrollContainerRelativeStickyBoxRect(
- other.m_scrollContainerRelativeStickyBoxRect) {}
+ other.m_scrollContainerRelativeStickyBoxRect),
+ m_nearestStickyElementToContainingBlock(
+ other.m_nearestStickyElementToContainingBlock),
+ m_nearestStickyElementFromContainingBlockToScrollContainer(
+ other.m_nearestStickyElementFromContainingBlockToScrollContainer),
+ m_accumulatedStickyOffsetToContainingBlock(
+ other.m_accumulatedStickyOffsetToContainingBlock),
+ m_accumulatedStickyOffsetFromContainingBlockToScrollContainer(
+ other
+ .m_accumulatedStickyOffsetFromContainingBlockToScrollContainer) {
+ }
- FloatSize computeStickyOffset(const FloatRect& viewportRect) const;
+ FloatSize computeStickyOffset(const FloatRect& viewportRect,
+ const FloatSize& accumulatedToCB,
+ const FloatSize& accumulatedToVP);
+
+ bool hasAncestorStickyElement() {
+ return m_nearestStickyElementToContainingBlock ||
+ m_nearestStickyElementFromContainingBlockToScrollContainer;
+ }
AnchorEdges anchorEdges() const { return m_anchorEdges; }
bool hasAnchorEdge(AnchorEdgeFlags flag) const {
@@ -71,6 +93,30 @@ class StickyPositionScrollingConstraints final {
return m_scrollContainerRelativeStickyBoxRect;
}
+ void setNearestStickyElementToContainingBlock(LayoutBoxModelObject* layer) {
+ m_nearestStickyElementToContainingBlock = layer;
+ }
+ const LayoutBoxModelObject* nearestStickyElementToContainingBlock() {
+ return m_nearestStickyElementToContainingBlock;
+ }
+
+ void setNearestStickyElementFromContainingBlockToScrollContainer(
+ LayoutBoxModelObject* layer) {
+ m_nearestStickyElementFromContainingBlockToScrollContainer = layer;
+ }
+ const LayoutBoxModelObject*
+ nearestStickyElementFromContainingBlockToScrollContainer() {
+ return m_nearestStickyElementFromContainingBlockToScrollContainer;
+ }
+
+ const FloatSize& getAccumulatedStickyOffsetToContainingBlock() {
+ return m_accumulatedStickyOffsetToContainingBlock;
+ }
+ const FloatSize&
+ getAccumulatedStickyOffsetFromContainingBlockToScrollContainer() {
+ return m_accumulatedStickyOffsetFromContainingBlockToScrollContainer;
+ }
+
bool operator==(const StickyPositionScrollingConstraints& other) const {
return m_leftOffset == other.m_leftOffset &&
m_rightOffset == other.m_rightOffset &&
@@ -79,7 +125,17 @@ class StickyPositionScrollingConstraints final {
m_scrollContainerRelativeContainingBlockRect ==
other.m_scrollContainerRelativeContainingBlockRect &&
m_scrollContainerRelativeStickyBoxRect ==
- other.m_scrollContainerRelativeStickyBoxRect;
+ other.m_scrollContainerRelativeStickyBoxRect &&
+ m_nearestStickyElementToContainingBlock ==
+ other.m_nearestStickyElementToContainingBlock &&
+ m_nearestStickyElementFromContainingBlockToScrollContainer ==
+ other
+ .m_nearestStickyElementFromContainingBlockToScrollContainer &&
+ m_accumulatedStickyOffsetToContainingBlock ==
+ other.m_accumulatedStickyOffsetToContainingBlock &&
+ m_accumulatedStickyOffsetFromContainingBlockToScrollContainer ==
+ other
+ .m_accumulatedStickyOffsetFromContainingBlockToScrollContainer;
}
bool operator!=(const StickyPositionScrollingConstraints& other) const {
@@ -94,6 +150,27 @@ class StickyPositionScrollingConstraints final {
float m_bottomOffset;
FloatRect m_scrollContainerRelativeContainingBlockRect;
FloatRect m_scrollContainerRelativeStickyBoxRect;
+
+ // In order to properly compute the stickyOffset, we need to know if we have
+ // any sticky ancestors both between ourselves and our containingBlock and
+ // between our containingBlock and the viewport.
+ //
+ // Any such ancestors are computed at layout time, and then the accumulated
+ // offset from them is recomputed after each scroll update.
+ LayoutBoxModelObject* m_nearestStickyElementToContainingBlock;
+ LayoutBoxModelObject*
+ m_nearestStickyElementFromContainingBlockToScrollContainer;
flackr 2017/01/20 02:42:44 Maybe m_nearestStickyElementShifting(ContainingBlo
smcgruer 2017/01/24 15:45:22 Done.
+
+ // For performance, we cache our accumulated sticky offset for descendant
+ // sticky elements to use. Because we can either be the "to containing block"
flackr 2017/01/20 02:42:44 nit: explain that we offset the constraint rects o
smcgruer 2017/01/24 15:45:22 Done.
+ // or the "to scroll container" ancestor for a given sticky element, we need
+ // to accumulate both.
+ //
+ // NOTE(smcgruer): The case where we can be both a "to containing block"
+ // and a "to scroll container" ancestor for different sticky descendants is
+ // quite complex. See the NAME_ME test in LayoutBoxModelObjectTest.cpp.
+ FloatSize m_accumulatedStickyOffsetToContainingBlock;
+ FloatSize m_accumulatedStickyOffsetFromContainingBlockToScrollContainer;
flackr 2017/01/20 02:42:44 How about m_totalStickyBoxStickyOffset and m_total
smcgruer 2017/01/24 15:45:22 Done.
};
} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698