Bug 1839315: part 4) Link from `SheetLoadData::mWasAlternate` to spec. r=emilio DONTBUILD
[gecko.git] / layout / generic / StickyScrollContainer.h
blob64f2aea5086da0c5637627775c1899fa5d96ac25
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/. */
7 /**
8 * compute sticky positioning, both during reflow and when the scrolling
9 * container scrolls
12 #ifndef StickyScrollContainer_h
13 #define StickyScrollContainer_h
15 #include "nsPoint.h"
16 #include "nsRectAbsolute.h"
17 #include "nsTArray.h"
18 #include "nsIScrollPositionListener.h"
20 struct nsRect;
21 class nsIFrame;
22 class nsIScrollableFrame;
24 namespace mozilla {
26 class StickyScrollContainer final : public nsIScrollPositionListener {
27 public:
28 /**
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(
33 nsIFrame* aFrame);
35 /**
36 * Find the StickyScrollContainer associated with the given scroll frame,
37 * if it exists.
39 static StickyScrollContainer* GetStickyScrollContainerForScrollFrame(
40 nsIFrame* aScrollFrame);
42 /**
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);
56 /**
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;
62 /**
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;
69 /**
70 * Compute and set the position of a frame and its following continuations.
72 void PositionContinuations(nsIFrame* aFrame);
74 /**
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();
88 const nsTArray<nsIFrame*>& GetFrames() const { return mFrames; }
90 /**
91 * Returns true if the frame is "stuck" in the y direction, ie it's acting
92 * like fixed position. aFrame should be in GetFrames().
94 bool IsStuckInYDirection(nsIFrame* aFrame) const;
96 private:
97 explicit StickyScrollContainer(nsIScrollableFrame* aScrollFrame);
99 /**
100 * Compute two rectangles that determine sticky positioning: |aStick|, based
101 * on the scroll container, and |aContain|, based on the containing block.
102 * Sticky positioning keeps the frame position (its upper-left corner) always
103 * within |aContain| and secondarily within |aStick|.
105 void ComputeStickyLimits(nsIFrame* aFrame, nsRect* aStick,
106 nsRect* aContain) const;
108 nsIScrollableFrame* const mScrollFrame;
109 nsTArray<nsIFrame*> mFrames;
110 nsPoint mScrollPosition;
113 } // namespace mozilla
115 #endif /* StickyScrollContainer_h */