Source code

Revision control

Copy as Markdown

Other Tools

/* -*- 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 */
#ifndef mozilla_dom_ResizeObserverController_h
#define mozilla_dom_ResizeObserverController_h
#include "mozilla/dom/Document.h"
#include "mozilla/dom/ResizeObserver.h"
#include "mozilla/TimeStamp.h"
#include "nsRefreshObservers.h"
#include "nsTObserverArray.h"
class nsRefreshDriver;
namespace mozilla {
class PresShell;
namespace dom {
class ResizeObserverController;
* ResizeObserverNotificationHelper will trigger ResizeObserver notifications
* by registering with the Refresh Driver.
class ResizeObserverNotificationHelper final : public nsARefreshObserver {
NS_INLINE_DECL_REFCOUNTING(ResizeObserverNotificationHelper, override)
explicit ResizeObserverNotificationHelper(ResizeObserverController* aOwner)
: mOwner(aOwner), mRegistered(false) {
MOZ_ASSERT(mOwner, "Need a non-null owner");
MOZ_CAN_RUN_SCRIPT void WillRefresh(TimeStamp aTime) override;
nsRefreshDriver* GetRefreshDriver() const;
void Register();
void Unregister();
bool IsRegistered() const { return mRegistered; }
void DetachFromOwner() { mOwner = nullptr; }
virtual ~ResizeObserverNotificationHelper();
ResizeObserverController* mOwner;
bool mRegistered;
* ResizeObserverController contains the list of ResizeObservers and controls
* the flow of notification.
class ResizeObserverController final {
explicit ResizeObserverController(Document* aDocument)
: mDocument(aDocument),
new ResizeObserverNotificationHelper(this)) {
MOZ_ASSERT(mDocument, "Need a non-null document");
void AddSizeOfIncludingThis(nsWindowSizes&) const;
void ShellDetachedFromDocument();
void AddResizeObserver(ResizeObserver& aObserver) {
// Insert internal ResizeObservers before scripted ones, since they may have
// observable side-effects and we don't want to expose the insertion time.
if (aObserver.HasNativeCallback()) {
mResizeObservers.InsertElementAt(0, &aObserver);
} else {
void RemoveResizeObserver(ResizeObserver& aObserver) {
* Schedule the notification via ResizeObserverNotificationHelper refresh
* observer.
void ScheduleNotification();
* Notify all ResizeObservers by gathering and broadcasting all active
* observations.
MOZ_CAN_RUN_SCRIPT void Notify();
PresShell* GetPresShell() const { return mDocument->GetPresShell(); }
* 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 with active observations from all ResizeObservers or
* numeric_limits<uint32_t>::max() if there aren't any active observations
* at all.
MOZ_CAN_RUN_SCRIPT 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;
// Raw pointer is OK because mDocument strongly owns us & hence must outlive
// us.
Document* const mDocument;
RefPtr<ResizeObserverNotificationHelper> mResizeObserverNotificationHelper;
nsTArray<ResizeObserver*> mResizeObservers;
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_ResizeObserverController_h