/* * Copyright (c) 2021, Tim Flynn * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include namespace Web::IntersectionObserver { struct IntersectionObserverInit { Optional, JS::Handle>> root; String root_margin { "0px"_string }; Variant> threshold { 0 }; }; // https://www.w3.org/TR/intersection-observer/#intersectionobserverregistration struct IntersectionObserverRegistration { // https://www.w3.org/TR/intersection-observer/#dom-intersectionobserverregistration-observer // [A]n observer property holding an IntersectionObserver. JS::Handle observer; // https://www.w3.org/TR/intersection-observer/#dom-intersectionobserverregistration-observer // NOTE: Optional is used in place of the spec using -1 to indicate no previous index. // [A] previousThresholdIndex property holding a number between -1 and the length of the observer’s thresholds property (inclusive). Optional previous_threshold_index; // https://www.w3.org/TR/intersection-observer/#dom-intersectionobserverregistration-previousisintersecting // [A] previousIsIntersecting property holding a boolean. bool previous_is_intersecting { false }; }; // https://w3c.github.io/IntersectionObserver/#intersection-observer-interface class IntersectionObserver final : public Bindings::PlatformObject { WEB_PLATFORM_OBJECT(IntersectionObserver, Bindings::PlatformObject); public: static WebIDL::ExceptionOr> construct_impl(JS::Realm&, JS::GCPtr callback, IntersectionObserverInit const& options = {}); virtual ~IntersectionObserver() override; void observe(DOM::Element& target); void unobserve(DOM::Element& target); void disconnect(); Vector> take_records(); Vector> const& observation_targets() const { return m_observation_targets; } Variant, JS::Handle, Empty> root() const; Vector const& thresholds() const { return m_thresholds; } Variant, JS::Handle> intersection_root() const; CSSPixelRect root_intersection_rectangle() const; void queue_entry(Badge, JS::NonnullGCPtr); WebIDL::CallbackType& callback() { return *m_callback; } private: explicit IntersectionObserver(JS::Realm&, JS::GCPtr callback, Optional, JS::Handle>> const& root, Vector&& thresholds); virtual void initialize(JS::Realm&) override; virtual void visit_edges(JS::Cell::Visitor&) override; virtual void finalize() override; // https://www.w3.org/TR/intersection-observer/#dom-intersectionobserver-callback-slot JS::GCPtr m_callback; // https://www.w3.org/TR/intersection-observer/#dom-intersectionobserver-root Optional, JS::Handle>> m_root; // https://www.w3.org/TR/intersection-observer/#dom-intersectionobserver-thresholds Vector m_thresholds; // https://www.w3.org/TR/intersection-observer/#dom-intersectionobserver-queuedentries-slot Vector> m_queued_entries; // https://www.w3.org/TR/intersection-observer/#dom-intersectionobserver-observationtargets-slot Vector> m_observation_targets; }; }