IntersectionObserver.h [plain text]
#pragma once
#if ENABLE(INTERSECTION_OBSERVER)
#include "ActiveDOMObject.h"
#include "GCReachableRef.h"
#include "IntersectionObserverCallback.h"
#include "IntersectionObserverEntry.h"
#include "LengthBox.h"
#include <wtf/RefCounted.h>
#include <wtf/Variant.h>
#include <wtf/WeakPtr.h>
#include <wtf/text/WTFString.h>
namespace WebCore {
class Document;
class Element;
struct IntersectionObserverRegistration {
WeakPtr<IntersectionObserver> observer;
Optional<size_t> previousThresholdIndex;
};
struct IntersectionObserverData {
Vector<WeakPtr<IntersectionObserver>> observers;
Vector<IntersectionObserverRegistration> registrations;
};
class IntersectionObserver : public RefCounted<IntersectionObserver>, public ActiveDOMObject, public CanMakeWeakPtr<IntersectionObserver> {
public:
struct Init {
Element* root { nullptr };
String rootMargin;
Variant<double, Vector<double>> threshold;
};
static ExceptionOr<Ref<IntersectionObserver>> create(Document&, Ref<IntersectionObserverCallback>&&, Init&&);
~IntersectionObserver();
Document* trackingDocument() const { return m_root ? &m_root->document() : m_implicitRootDocument.get(); }
Element* root() const { return m_root; }
String rootMargin() const;
const LengthBox& rootMarginBox() const { return m_rootMargin; }
const Vector<double>& thresholds() const { return m_thresholds; }
const Vector<Element*> observationTargets() const { return m_observationTargets; }
void observe(Element&);
void unobserve(Element&);
void disconnect();
struct TakenRecords {
Vector<Ref<IntersectionObserverEntry>> records;
Vector<GCReachableRef<Element>> pendingTargets;
};
TakenRecords takeRecords();
void targetDestroyed(Element&);
bool hasObservationTargets() const { return m_observationTargets.size(); }
void rootDestroyed();
bool createTimestamp(DOMHighResTimeStamp&) const;
void appendQueuedEntry(Ref<IntersectionObserverEntry>&&);
void notify();
bool hasPendingActivity() const override;
const char* activeDOMObjectName() const override;
bool canSuspendForDocumentSuspension() const override;
void stop() override;
private:
IntersectionObserver(Document&, Ref<IntersectionObserverCallback>&&, Element* root, LengthBox&& parsedRootMargin, Vector<double>&& thresholds);
bool removeTargetRegistration(Element&);
void removeAllTargets();
WeakPtr<Document> m_implicitRootDocument;
Element* m_root;
LengthBox m_rootMargin;
Vector<double> m_thresholds;
RefPtr<IntersectionObserverCallback> m_callback;
Vector<Element*> m_observationTargets;
Vector<GCReachableRef<Element>> m_pendingTargets;
Vector<Ref<IntersectionObserverEntry>> m_queuedEntries;
};
}
#endif // ENABLE(INTERSECTION_OBSERVER)