Files
ladybird/Libraries/LibWeb/DOM/MutationObserver.h
Shannon Booth 5adfd1c43a LibWeb/Bindings: Generate struct definitions from IDL dictionaries
Previously we were inconsistent by generating code for enum definitions
but not generating code for dictionaries. With future changes to the
IDL generator to expose helpers to convert to and from IDL values
this produced circular depdendencies. To solve this problem, also
generate the dictionary definitions in bindings headers.
2026-05-09 10:49:49 +02:00

112 lines
3.7 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* Copyright (c) 2022, Luke Wilde <lukew@serenityos.org>
* Copyright (c) 2022, Andreas Kling <andreas@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <LibGC/Root.h>
#include <LibWeb/Bindings/MutationObserver.h>
#include <LibWeb/DOM/MutationRecord.h>
#include <LibWeb/WebIDL/CallbackType.h>
#include <LibWeb/WebIDL/ExceptionOr.h>
namespace Web::DOM {
// https://dom.spec.whatwg.org/#mutationobserver
class MutationObserver final : public Bindings::PlatformObject {
WEB_PLATFORM_OBJECT(MutationObserver, Bindings::PlatformObject);
GC_DECLARE_ALLOCATOR(MutationObserver);
public:
static WebIDL::ExceptionOr<GC::Ref<MutationObserver>> construct_impl(JS::Realm&, GC::Ptr<WebIDL::CallbackType>);
virtual ~MutationObserver() override;
WebIDL::ExceptionOr<void> observe(Node& target, Bindings::MutationObserverInit = {});
void disconnect();
Vector<GC::Root<MutationRecord>> take_records();
Vector<GC::Weak<Node>>& node_list() { return m_node_list; }
Vector<GC::Weak<Node>> const& node_list() const { return m_node_list; }
WebIDL::CallbackType& callback() { return *m_callback; }
void enqueue_record(Badge<Node>, GC::Ref<MutationRecord> mutation_record)
{
m_record_queue.append(*mutation_record);
}
private:
MutationObserver(JS::Realm&, GC::Ptr<WebIDL::CallbackType>);
virtual void initialize(JS::Realm&) override;
virtual void visit_edges(Cell::Visitor&) override;
// https://dom.spec.whatwg.org/#concept-mo-callback
GC::Ptr<WebIDL::CallbackType> m_callback;
// https://dom.spec.whatwg.org/#mutationobserver-node-list
// Registered observers in a nodes registered observer list have a weak reference to the node.
Vector<GC::Weak<Node>> m_node_list;
// https://dom.spec.whatwg.org/#concept-mo-queue
Vector<GC::Ref<MutationRecord>> m_record_queue;
};
// https://dom.spec.whatwg.org/#registered-observer
class RegisteredObserver : public JS::Cell {
GC_CELL(RegisteredObserver, JS::Cell);
GC_DECLARE_ALLOCATOR(RegisteredObserver);
public:
static GC::Ref<RegisteredObserver> create(MutationObserver&, Bindings::MutationObserverInit const&);
virtual ~RegisteredObserver() override;
virtual bool is_transient() const { return false; }
GC::Ref<MutationObserver> observer() const { return m_observer; }
Bindings::MutationObserverInit const& options() const { return m_options; }
void set_options(Bindings::MutationObserverInit options) { m_options = move(options); }
template<typename T>
bool fast_is() const = delete;
protected:
RegisteredObserver(MutationObserver& observer, Bindings::MutationObserverInit const& options);
virtual void visit_edges(Cell::Visitor&) override;
private:
GC::Ref<MutationObserver> m_observer;
Bindings::MutationObserverInit m_options;
};
// https://dom.spec.whatwg.org/#transient-registered-observer
class TransientRegisteredObserver final : public RegisteredObserver {
GC_CELL(TransientRegisteredObserver, RegisteredObserver);
GC_DECLARE_ALLOCATOR(TransientRegisteredObserver);
public:
static GC::Ref<TransientRegisteredObserver> create(MutationObserver&, Bindings::MutationObserverInit const&, RegisteredObserver& source);
virtual ~TransientRegisteredObserver() override;
GC::Ref<RegisteredObserver> source() const { return m_source; }
virtual bool is_transient() const override { return true; }
private:
TransientRegisteredObserver(MutationObserver& observer, Bindings::MutationObserverInit const& options, RegisteredObserver& source);
virtual void visit_edges(Cell::Visitor&) override;
GC::Ref<RegisteredObserver> m_source;
};
template<>
inline bool RegisteredObserver::fast_is<TransientRegisteredObserver>() const { return is_transient(); }
}