blob: 2cb2d195cc7bd9a1a61293a9dc15fe151647ec92 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ScrollAnchor_h
#define ScrollAnchor_h
#include "core/CoreExport.h"
#include "platform/geometry/LayoutPoint.h"
#include "platform/heap/Handle.h"
namespace blink {
class LayoutObject;
class ScrollableArea;
// Scrolls to compensate for layout movements (bit.ly/scroll-anchoring).
class CORE_EXPORT ScrollAnchor final {
DISALLOW_NEW();
public:
ScrollAnchor(ScrollableArea*);
~ScrollAnchor();
// The LayoutObject we are currently anchored to. Lazily computed during
// save() and cached until the next call to clear().
LayoutObject* anchorObject() const { return m_anchorObject; }
// Invalidates the anchor.
void clear();
// Records the anchor's location in relation to the scroller. Should be
// called when the scroller is about to be laid out.
void save();
// Scrolls to compensate for any change in the anchor's relative location
// since the most recent call to save(). Should be called immediately after
// the scroller has been laid out.
void restore();
enum class Corner {
TopLeft = 0,
TopRight,
BottomLeft,
BottomRight
};
// Which corner of the anchor object we are currently anchored to.
// Only meaningful if anchorObject() is non-null.
Corner corner() const { return m_corner; }
DEFINE_INLINE_TRACE() { visitor->trace(m_scroller); }
private:
void findAnchor();
enum WalkStatus {
Skip = 0,
Constrain,
Continue,
Return
};
struct ExamineResult {
ExamineResult(WalkStatus s)
: status(s)
, viable(false)
, corner(Corner::TopLeft) {}
ExamineResult(WalkStatus s, Corner c)
: status(s)
, viable(true)
, corner(c) {}
WalkStatus status;
bool viable;
Corner corner;
};
ExamineResult examine(const LayoutObject*) const;
// The scroller that owns and is adjusted by this ScrollAnchor.
RawPtrWillBeMember<ScrollableArea> m_scroller;
// The LayoutObject we should anchor to. Lazily computed.
LayoutObject* m_anchorObject;
// Which corner of m_anchorObject's bounding box to anchor to.
Corner m_corner;
// Location of m_layoutObject relative to scroller at time of save().
LayoutPoint m_savedRelativeOffset;
};
} // namespace blink
#endif // ScrollAnchor_h
|