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

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

Issue 2708883005: Handle nested position:sticky elements correctly (main thread) (Closed)
Patch Set: Rebase Created 3 years, 10 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..84dab3cc2f76ad7170d18bed9235375e5dc16c62 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_nearestStickyBoxShiftingStickyBox(nullptr),
+ m_nearestStickyBoxShiftingContainingBlock(nullptr) {}
StickyPositionScrollingConstraints(
const StickyPositionScrollingConstraints& other)
@@ -36,9 +41,25 @@ class StickyPositionScrollingConstraints final {
m_scrollContainerRelativeContainingBlockRect(
other.m_scrollContainerRelativeContainingBlockRect),
m_scrollContainerRelativeStickyBoxRect(
- other.m_scrollContainerRelativeStickyBoxRect) {}
-
- FloatSize computeStickyOffset(const FloatRect& viewportRect) const;
+ other.m_scrollContainerRelativeStickyBoxRect),
+ m_nearestStickyBoxShiftingStickyBox(
+ other.m_nearestStickyBoxShiftingStickyBox),
+ m_nearestStickyBoxShiftingContainingBlock(
+ other.m_nearestStickyBoxShiftingContainingBlock),
+ m_totalStickyBoxStickyOffset(other.m_totalStickyBoxStickyOffset),
+ m_totalContainingBlockStickyOffset(
+ other.m_totalContainingBlockStickyOffset) {}
+
+ FloatSize computeStickyOffset(
+ const FloatRect& viewportRect,
+ const StickyPositionScrollingConstraints* ancestorStickyBoxConstraints,
+ const StickyPositionScrollingConstraints*
+ ancestorContainingBlockConstraints);
+
+ bool hasAncestorStickyElement() const {
+ return m_nearestStickyBoxShiftingStickyBox ||
+ m_nearestStickyBoxShiftingContainingBlock;
+ }
AnchorEdges anchorEdges() const { return m_anchorEdges; }
bool hasAnchorEdge(AnchorEdgeFlags flag) const {
@@ -71,6 +92,27 @@ class StickyPositionScrollingConstraints final {
return m_scrollContainerRelativeStickyBoxRect;
}
+ void setNearestStickyBoxShiftingStickyBox(LayoutBoxModelObject* layer) {
+ m_nearestStickyBoxShiftingStickyBox = layer;
+ }
+ LayoutBoxModelObject* nearestStickyBoxShiftingStickyBox() const {
+ return m_nearestStickyBoxShiftingStickyBox;
+ }
+
+ void setNearestStickyBoxShiftingContainingBlock(LayoutBoxModelObject* layer) {
+ m_nearestStickyBoxShiftingContainingBlock = layer;
+ }
+ LayoutBoxModelObject* nearestStickyBoxShiftingContainingBlock() const {
+ return m_nearestStickyBoxShiftingContainingBlock;
+ }
+
+ const FloatSize& getTotalStickyBoxStickyOffset() const {
+ return m_totalStickyBoxStickyOffset;
+ }
+ const FloatSize& getTotalContainingBlockStickyOffset() const {
+ return m_totalContainingBlockStickyOffset;
+ }
+
bool operator==(const StickyPositionScrollingConstraints& other) const {
return m_leftOffset == other.m_leftOffset &&
m_rightOffset == other.m_rightOffset &&
@@ -79,7 +121,14 @@ class StickyPositionScrollingConstraints final {
m_scrollContainerRelativeContainingBlockRect ==
other.m_scrollContainerRelativeContainingBlockRect &&
m_scrollContainerRelativeStickyBoxRect ==
- other.m_scrollContainerRelativeStickyBoxRect;
+ other.m_scrollContainerRelativeStickyBoxRect &&
+ m_nearestStickyBoxShiftingStickyBox ==
+ other.m_nearestStickyBoxShiftingStickyBox &&
+ m_nearestStickyBoxShiftingContainingBlock ==
+ other.m_nearestStickyBoxShiftingContainingBlock &&
+ m_totalStickyBoxStickyOffset == other.m_totalStickyBoxStickyOffset &&
+ m_totalContainingBlockStickyOffset ==
+ other.m_totalContainingBlockStickyOffset;
}
bool operator!=(const StickyPositionScrollingConstraints& other) const {
@@ -94,6 +143,26 @@ 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 containing block and
+ // between our containing block and the viewport. These ancestors are needed
+ // to properly shift our constraining rects with regards to the containing
+ // block and viewport.
+ LayoutBoxModelObject* m_nearestStickyBoxShiftingStickyBox;
+ LayoutBoxModelObject* m_nearestStickyBoxShiftingContainingBlock;
+
+ // For performance we cache our accumulated sticky offset to allow descendant
+ // sticky elements to offset their constraint rects. Because we can either
+ // affect the sticky box constraint rect or the containing block constraint
+ // rect, we need to accumulate both.
+ //
+ // The case where we can affect both the sticky box constraint rect and the
+ // constraining block constriant rect for different sticky descendants is
+ // quite complex. See the StickyPositionComplexTableNesting test in
+ // LayoutBoxModelObjectTest.cpp.
+ FloatSize m_totalStickyBoxStickyOffset;
+ FloatSize m_totalContainingBlockStickyOffset;
};
} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698