mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-04-26 01:35:08 +02:00
Previously, the LibWeb bindings generator would output multiple per interface files like Prototype/Constructor/Namespace/GlobalMixin depending on the contents of that IDL file. This complicates the build system as it means that it does not know what files will be generated without knowledge of the contents of that IDL file. Instead, for each IDL file only generate a single Bindings/<IDLFile>.h and Bindings/<IDLFile>.cpp.
150 lines
5.0 KiB
C++
150 lines
5.0 KiB
C++
/*
|
||
* Copyright (c) 2022, Andreas Kling <andreas@ladybird.org>
|
||
* Copyright (c) 2024, Jamie Mansfield <jmansfield@cadixdev.org>
|
||
* Copyright (c) 2026, Sam Atkins <sam@ladybird.org>
|
||
*
|
||
* SPDX-License-Identifier: BSD-2-Clause
|
||
*/
|
||
|
||
#include <LibJS/Runtime/Array.h>
|
||
#include <LibWeb/Bindings/Intrinsics.h>
|
||
#include <LibWeb/Bindings/MessageEvent.h>
|
||
#include <LibWeb/HTML/MessageEvent.h>
|
||
#include <LibWeb/HTML/MessagePort.h>
|
||
#include <LibWeb/HTML/WindowProxy.h>
|
||
|
||
namespace Web::HTML {
|
||
|
||
GC_DEFINE_ALLOCATOR(MessageEvent);
|
||
|
||
GC::Ref<MessageEvent> MessageEvent::create(JS::Realm& realm, FlyString const& event_name, MessageEventInit const& event_init)
|
||
{
|
||
return realm.create<MessageEvent>(realm, event_name, event_init);
|
||
}
|
||
|
||
WebIDL::ExceptionOr<GC::Ref<MessageEvent>> MessageEvent::construct_impl(JS::Realm& realm, FlyString const& event_name, MessageEventInit const& event_init)
|
||
{
|
||
return create(realm, event_name, event_init);
|
||
}
|
||
|
||
MessageEvent::MessageEventSourceInternal MessageEvent::to_message_event_source_internal(NullableMessageEventSource const& source)
|
||
{
|
||
return source.visit(
|
||
[](Empty) -> MessageEventSourceInternal { return Empty {}; },
|
||
[](auto const& root) -> MessageEventSourceInternal { return GC::Ref { *root }; });
|
||
}
|
||
|
||
MessageEvent::MessageEvent(JS::Realm& realm, FlyString const& event_name, MessageEventInit const& event_init)
|
||
: DOM::Event(realm, event_name, event_init)
|
||
, m_data(event_init.data)
|
||
, m_origin(event_init.origin)
|
||
, m_last_event_id(event_init.last_event_id)
|
||
, m_source(to_message_event_source_internal(event_init.source))
|
||
{
|
||
m_ports.ensure_capacity(event_init.ports.size());
|
||
for (auto const& port : event_init.ports) {
|
||
VERIFY(port);
|
||
m_ports.unchecked_append(static_cast<JS::Object&>(*port));
|
||
}
|
||
}
|
||
|
||
MessageEvent::~MessageEvent() = default;
|
||
|
||
void MessageEvent::initialize(JS::Realm& realm)
|
||
{
|
||
WEB_SET_PROTOTYPE_FOR_INTERFACE(MessageEvent);
|
||
Base::initialize(realm);
|
||
}
|
||
|
||
void MessageEvent::visit_edges(Cell::Visitor& visitor)
|
||
{
|
||
Base::visit_edges(visitor);
|
||
visitor.visit(m_data);
|
||
visitor.visit(m_ports_array);
|
||
visitor.visit(m_ports);
|
||
m_source.visit(
|
||
[](Empty) {},
|
||
[&](auto const& ref) { visitor.visit(ref); });
|
||
}
|
||
|
||
// https://html.spec.whatwg.org/multipage/comms.html#dom-messageevent-origin
|
||
String MessageEvent::origin() const
|
||
{
|
||
return m_origin.visit(
|
||
// 1. If this's origin is an origin, then return the serialization of this's origin.
|
||
[](URL::Origin const& origin) {
|
||
return origin.serialize();
|
||
},
|
||
// 2. If this's origin is null, then return the empty string.
|
||
[](Empty) {
|
||
return String {};
|
||
},
|
||
// 3. Return this's origin.
|
||
[](String const& origin) {
|
||
return origin;
|
||
});
|
||
}
|
||
|
||
NullableMessageEventSource MessageEvent::source() const
|
||
{
|
||
return m_source.visit(
|
||
[](Empty) -> NullableMessageEventSource { return Empty {}; },
|
||
[](auto const& ref) -> NullableMessageEventSource { return GC::Root { *ref }; });
|
||
}
|
||
|
||
GC::Ref<JS::Object> MessageEvent::ports() const
|
||
{
|
||
if (!m_ports_array) {
|
||
GC::RootVector<JS::Value> port_vector(heap());
|
||
for (auto const& port : m_ports)
|
||
port_vector.append(port);
|
||
|
||
m_ports_array = JS::Array::create_from(realm(), port_vector);
|
||
MUST(m_ports_array->set_integrity_level(IntegrityLevel::Frozen));
|
||
}
|
||
return *m_ports_array;
|
||
}
|
||
|
||
// https://html.spec.whatwg.org/multipage/comms.html#dom-messageevent-initmessageevent
|
||
void MessageEvent::init_message_event(String const& type, bool bubbles, bool cancelable, JS::Value data, String const& origin, String const& last_event_id, NullableMessageEventSource source, Vector<GC::Root<MessagePort>> const& ports)
|
||
{
|
||
// The initMessageEvent(type, bubbles, cancelable, data, origin, lastEventId, source, ports) method must initialize the event in a
|
||
// manner analogous to the similarly-named initEvent() method.
|
||
|
||
// 1. If this’s dispatch flag is set, then return.
|
||
if (dispatched())
|
||
return;
|
||
|
||
// 2. Initialize this with type, bubbles, and cancelable.
|
||
initialize_event(type, bubbles, cancelable);
|
||
|
||
// Implementation Defined: Initialise other values.
|
||
m_data = data;
|
||
m_origin = origin;
|
||
m_last_event_id = last_event_id;
|
||
m_source = to_message_event_source_internal(source);
|
||
|
||
m_ports_array = nullptr;
|
||
m_ports.clear();
|
||
m_ports.ensure_capacity(ports.size());
|
||
for (auto const& port : ports) {
|
||
VERIFY(port);
|
||
m_ports.unchecked_append(static_cast<JS::Object&>(*port));
|
||
}
|
||
}
|
||
|
||
// https://html.spec.whatwg.org/multipage/comms.html#the-messageevent-interface:extract-an-origin
|
||
Optional<URL::Origin> MessageEvent::extract_an_origin() const
|
||
{
|
||
// Objects implementing the MessageEvent interface's extract an origin steps are to return this's origin if it is an origin; otherwise null.
|
||
return m_origin.visit(
|
||
[](URL::Origin const& origin) -> Optional<URL::Origin> {
|
||
return origin;
|
||
},
|
||
[](auto const&) -> Optional<URL::Origin> {
|
||
return {};
|
||
});
|
||
}
|
||
|
||
}
|