1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 * compute sticky positioning, both during reflow and when the scrolling
12 #ifndef StickyScrollContainer_h
13 #define StickyScrollContainer_h
16 #include "nsRectAbsolute.h"
18 #include "nsIScrollPositionListener.h"
22 class nsIScrollableFrame
;
26 class StickyScrollContainer final
: public nsIScrollPositionListener
{
29 * Find (and create if necessary) the StickyScrollContainer associated with
30 * the scroll container of the given frame, if a scroll container exists.
32 static StickyScrollContainer
* GetStickyScrollContainerForFrame(
36 * Find the StickyScrollContainer associated with the given scroll frame,
39 static StickyScrollContainer
* GetStickyScrollContainerForScrollFrame(
40 nsIFrame
* aScrollFrame
);
43 * aFrame may have moved into or out of a scroll frame's frame subtree.
45 static void NotifyReparentedFrameAcrossScrollFrameBoundary(
46 nsIFrame
* aFrame
, nsIFrame
* aOldParent
);
48 void AddFrame(nsIFrame
* aFrame
) { mFrames
.AppendElement(aFrame
); }
49 void RemoveFrame(nsIFrame
* aFrame
) { mFrames
.RemoveElement(aFrame
); }
51 nsIScrollableFrame
* ScrollFrame() const { return mScrollFrame
; }
53 // Compute the offsets for a sticky position element
54 static void ComputeStickyOffsets(nsIFrame
* aFrame
);
57 * Compute the position of a sticky positioned frame, based on information
58 * stored in its properties along with our scroll frame and scroll position.
60 nsPoint
ComputePosition(nsIFrame
* aFrame
) const;
63 * Compute where a frame should not scroll with the page, represented by the
64 * difference of two rectangles.
66 void GetScrollRanges(nsIFrame
* aFrame
, nsRectAbsolute
* aOuter
,
67 nsRectAbsolute
* aInner
) const;
70 * Compute and set the position of a frame and its following continuations.
72 void PositionContinuations(nsIFrame
* aFrame
);
75 * Compute and set the position of all sticky frames, given the current
76 * scroll position of the scroll frame. If not in reflow, aSubtreeRoot should
77 * be null; otherwise, overflow-area updates will be limited to not affect
78 * aSubtreeRoot or its ancestors.
80 void UpdatePositions(nsPoint aScrollPosition
, nsIFrame
* aSubtreeRoot
);
82 // nsIScrollPositionListener
83 virtual void ScrollPositionWillChange(nscoord aX
, nscoord aY
) override
;
84 virtual void ScrollPositionDidChange(nscoord aX
, nscoord aY
) override
;
86 ~StickyScrollContainer();
89 explicit StickyScrollContainer(nsIScrollableFrame
* aScrollFrame
);
92 * Compute two rectangles that determine sticky positioning: |aStick|, based
93 * on the scroll container, and |aContain|, based on the containing block.
94 * Sticky positioning keeps the frame position (its upper-left corner) always
95 * within |aContain| and secondarily within |aStick|.
97 void ComputeStickyLimits(nsIFrame
* aFrame
, nsRect
* aStick
,
98 nsRect
* aContain
) const;
100 nsIScrollableFrame
* const mScrollFrame
;
101 nsTArray
<nsIFrame
*> mFrames
;
102 nsPoint mScrollPosition
;
105 } // namespace mozilla
107 #endif /* StickyScrollContainer_h */