Coverage Report

Created: 2018-09-25 14:53

/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 */