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 file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_dom_ResizeObserverController_h
8 #define mozilla_dom_ResizeObserverController_h
10 #include "mozilla/dom/Document.h"
11 #include "mozilla/dom/ResizeObserver.h"
12 #include "mozilla/TimeStamp.h"
13 #include "nsRefreshObservers.h"
14 #include "nsTObserverArray.h"
16 class nsRefreshDriver
;
24 class ResizeObserverController
;
27 * ResizeObserverNotificationHelper will trigger ResizeObserver notifications
28 * by registering with the Refresh Driver.
30 class ResizeObserverNotificationHelper final
: public nsARefreshObserver
{
32 NS_INLINE_DECL_REFCOUNTING(ResizeObserverNotificationHelper
, override
)
34 explicit ResizeObserverNotificationHelper(ResizeObserverController
* aOwner
)
35 : mOwner(aOwner
), mRegistered(false) {
36 MOZ_ASSERT(mOwner
, "Need a non-null owner");
39 MOZ_CAN_RUN_SCRIPT
void WillRefresh(TimeStamp aTime
) override
;
41 nsRefreshDriver
* GetRefreshDriver() const;
47 bool IsRegistered() const { return mRegistered
; }
49 void DetachFromOwner() { mOwner
= nullptr; }
52 virtual ~ResizeObserverNotificationHelper();
54 ResizeObserverController
* mOwner
;
59 * ResizeObserverController contains the list of ResizeObservers and controls
60 * the flow of notification.
62 class ResizeObserverController final
{
64 explicit ResizeObserverController(Document
* aDocument
)
65 : mDocument(aDocument
),
66 mResizeObserverNotificationHelper(
67 new ResizeObserverNotificationHelper(this)) {
68 MOZ_ASSERT(mDocument
, "Need a non-null document");
71 void AddSizeOfIncludingThis(nsWindowSizes
&) const;
73 void ShellDetachedFromDocument();
74 void AddResizeObserver(ResizeObserver
& aObserver
) {
75 MOZ_ASSERT(!mResizeObservers
.Contains(&aObserver
));
76 // Insert internal ResizeObservers before scripted ones, since they may have
77 // observable side-effects and we don't want to expose the insertion time.
78 if (aObserver
.HasNativeCallback()) {
79 mResizeObservers
.InsertElementAt(0, &aObserver
);
81 mResizeObservers
.AppendElement(&aObserver
);
85 void RemoveResizeObserver(ResizeObserver
& aObserver
) {
86 MOZ_ASSERT(mResizeObservers
.Contains(&aObserver
));
87 mResizeObservers
.RemoveElement(&aObserver
);
91 * Schedule the notification via ResizeObserverNotificationHelper refresh
94 void ScheduleNotification();
97 * Notify all ResizeObservers by gathering and broadcasting all active
100 MOZ_CAN_RUN_SCRIPT
void Notify();
102 PresShell
* GetPresShell() const { return mDocument
->GetPresShell(); }
104 ~ResizeObserverController();
108 * Calls GatherActiveObservations(aDepth) for all ResizeObservers in this
109 * controller. All observations in each ResizeObserver with element's depth
110 * more than aDepth will be gathered.
112 void GatherAllActiveObservations(uint32_t aDepth
);
115 * Calls BroadcastActiveObservations() for all ResizeObservers in this
116 * controller. It also returns the shallowest depth of observed target
117 * elements with active observations from all ResizeObservers or
118 * numeric_limits<uint32_t>::max() if there aren't any active observations
121 MOZ_CAN_RUN_SCRIPT
uint32_t BroadcastAllActiveObservations();
124 * Returns whether there is any ResizeObserver that has active observations.
126 bool HasAnyActiveObservations() const;
129 * Returns whether there is any ResizeObserver that has skipped observations.
131 bool HasAnySkippedObservations() const;
133 // Raw pointer is OK because mDocument strongly owns us & hence must outlive
135 Document
* const mDocument
;
137 RefPtr
<ResizeObserverNotificationHelper
> mResizeObserverNotificationHelper
;
138 nsTArray
<ResizeObserver
*> mResizeObservers
;
142 } // namespace mozilla
144 #endif // mozilla_dom_ResizeObserverController_h