blob: a7751158742e8523c8da00c908a91cd614365975 (
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_ResizeObserverController_h
#define mozilla_dom_ResizeObserverController_h
#include "mozilla/dom/ResizeObserver.h"
#include "mozilla/TimeStamp.h"
#include "nsRefreshDriver.h"
namespace mozilla {
namespace dom {
class ResizeObserverController;
/*
* ResizeObserverNotificationHelper will trigger ResizeObserver notifications
* by registering with the Refresh Driver.
*/
class ResizeObserverNotificationHelper final : public nsARefreshObserver
{
public:
NS_INLINE_DECL_REFCOUNTING(ResizeObserverNotificationHelper, override)
explicit ResizeObserverNotificationHelper(ResizeObserverController* aOwner)
: mOwner(aOwner)
, mRegistered(false)
{
MOZ_ASSERT(mOwner, "Need a non-null owner");
}
void WillRefresh(TimeStamp aTime) override;
nsRefreshDriver* GetRefreshDriver() const;
void Register();
void Unregister();
void Disconnect();
protected:
virtual ~ResizeObserverNotificationHelper();
ResizeObserverController* mOwner;
bool mRegistered;
};
/*
* ResizeObserverController contains the list of ResizeObservers and controls
* the flow of notification.
*/
class ResizeObserverController final
{
public:
explicit ResizeObserverController(nsIDocument* aDocument)
: mDocument(aDocument)
, mIsNotificationActive(false)
{
MOZ_ASSERT(mDocument, "Need a non-null document");
mResizeObserverNotificationHelper =
new ResizeObserverNotificationHelper(this);
}
// Methods for supporting cycle-collection
void Traverse(nsCycleCollectionTraversalCallback& aCb);
void Unlink();
void AddResizeObserver(ResizeObserver* aObserver);
/*
* Schedule the notification via ResizeObserverNotificationHelper refresh
* observer.
*/
void ScheduleNotification();
/*
* Notify all ResizeObservers by gathering and broadcasting all active
* observations.
*/
void Notify();
nsIPresShell* GetShell() const;
~ResizeObserverController();
private:
/*
* Calls GatherActiveObservations(aDepth) for all ResizeObservers in this
* controller. All observations in each ResizeObserver with element's depth
* more than aDepth will be gathered.
*/
void GatherAllActiveObservations(uint32_t aDepth);
/*
* Calls BroadcastActiveObservations() for all ResizeObservers in this
* controller. It also returns the shallowest depth of observed target
* elements from all ResizeObserver or UINT32_MAX if there is no any
* active obsevations at all.
*/
uint32_t BroadcastAllActiveObservations();
/*
* Returns whether there is any ResizeObserver that has active observations.
*/
bool HasAnyActiveObservations() const;
/*
* Returns whether there is any ResizeObserver that has skipped observations.
*/
bool HasAnySkippedObservations() const;
protected:
// Raw pointer is OK because mDocument strongly owns us & hence must outlive
// us.
nsIDocument* const mDocument;
RefPtr<ResizeObserverNotificationHelper> mResizeObserverNotificationHelper;
nsTArray<RefPtr<ResizeObserver>> mResizeObservers;
bool mIsNotificationActive;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_ResizeObserverController_h
|