/src/mozilla-central/layout/generic/StickyScrollContainer.h
Line | Count | Source (jump to first uncovered line) |
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/. */ |
6 | | |
7 | | /** |
8 | | * compute sticky positioning, both during reflow and when the scrolling |
9 | | * container scrolls |
10 | | */ |
11 | | |
12 | | #ifndef StickyScrollContainer_h |
13 | | #define StickyScrollContainer_h |
14 | | |
15 | | #include "nsPoint.h" |
16 | | #include "nsRectAbsolute.h" |
17 | | #include "nsTArray.h" |
18 | | #include "nsIScrollPositionListener.h" |
19 | | |
20 | | struct nsRect; |
21 | | class nsIFrame; |
22 | | class nsIScrollableFrame; |
23 | | |
24 | | namespace mozilla { |
25 | | |
26 | | class StickyScrollContainer final : public nsIScrollPositionListener |
27 | | { |
28 | | public: |
29 | | /** |
30 | | * Find (and create if necessary) the StickyScrollContainer associated with |
31 | | * the scroll container of the given frame, if a scroll container exists. |
32 | | */ |
33 | | static StickyScrollContainer* GetStickyScrollContainerForFrame(nsIFrame* aFrame); |
34 | | |
35 | | /** |
36 | | * Find the StickyScrollContainer associated with the given scroll frame, |
37 | | * if it exists. |
38 | | */ |
39 | | static StickyScrollContainer* GetStickyScrollContainerForScrollFrame(nsIFrame* aScrollFrame); |
40 | | |
41 | | /** |
42 | | * aFrame may have moved into or out of a scroll frame's frame subtree. |
43 | | */ |
44 | | static void NotifyReparentedFrameAcrossScrollFrameBoundary(nsIFrame* aFrame, |
45 | | nsIFrame* aOldParent); |
46 | | |
47 | 0 | void AddFrame(nsIFrame* aFrame) { |
48 | 0 | mFrames.AppendElement(aFrame); |
49 | 0 | } |
50 | 0 | void RemoveFrame(nsIFrame* aFrame) { |
51 | 0 | mFrames.RemoveElement(aFrame); |
52 | 0 | } |
53 | | |
54 | 0 | nsIScrollableFrame* ScrollFrame() const { |
55 | 0 | return mScrollFrame; |
56 | 0 | } |
57 | | |
58 | | // Compute the offsets for a sticky position element |
59 | | static void ComputeStickyOffsets(nsIFrame* aFrame); |
60 | | |
61 | | /** |
62 | | * Compute the position of a sticky positioned frame, based on information |
63 | | * stored in its properties along with our scroll frame and scroll position. |
64 | | */ |
65 | | nsPoint ComputePosition(nsIFrame* aFrame) const; |
66 | | |
67 | | /** |
68 | | * Compute where a frame should not scroll with the page, represented by the |
69 | | * difference of two rectangles. |
70 | | */ |
71 | | void GetScrollRanges(nsIFrame* aFrame, nsRectAbsolute* aOuter, nsRectAbsolute* aInner) const; |
72 | | |
73 | | /** |
74 | | * Compute and set the position of a frame and its following continuations. |
75 | | */ |
76 | | void PositionContinuations(nsIFrame* aFrame); |
77 | | |
78 | | /** |
79 | | * Compute and set the position of all sticky frames, given the current |
80 | | * scroll position of the scroll frame. If not in reflow, aSubtreeRoot should |
81 | | * be null; otherwise, overflow-area updates will be limited to not affect |
82 | | * aSubtreeRoot or its ancestors. |
83 | | */ |
84 | | void UpdatePositions(nsPoint aScrollPosition, nsIFrame* aSubtreeRoot); |
85 | | |
86 | | // nsIScrollPositionListener |
87 | | virtual void ScrollPositionWillChange(nscoord aX, nscoord aY) override; |
88 | | virtual void ScrollPositionDidChange(nscoord aX, nscoord aY) override; |
89 | | |
90 | | ~StickyScrollContainer(); |
91 | | |
92 | | private: |
93 | | explicit StickyScrollContainer(nsIScrollableFrame* aScrollFrame); |
94 | | |
95 | | /** |
96 | | * Compute two rectangles that determine sticky positioning: |aStick|, based |
97 | | * on the scroll container, and |aContain|, based on the containing block. |
98 | | * Sticky positioning keeps the frame position (its upper-left corner) always |
99 | | * within |aContain| and secondarily within |aStick|. |
100 | | */ |
101 | | void ComputeStickyLimits(nsIFrame* aFrame, nsRect* aStick, |
102 | | nsRect* aContain) const; |
103 | | |
104 | | nsIScrollableFrame* const mScrollFrame; |
105 | | nsTArray<nsIFrame*> mFrames; |
106 | | nsPoint mScrollPosition; |
107 | | }; |
108 | | |
109 | | } // namespace mozilla |
110 | | |
111 | | #endif /* StickyScrollContainer_h */ |