/* * Copyright (c) 2021, Andreas Kling * Copyright (c) 2023, Andrew Kaster * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include #include #include namespace Web::HTML { #define ENUMERATE_MESSAGE_PORT_EVENT_HANDLERS(E) \ E(onmessage, HTML::EventNames::message) \ E(onmessageerror, HTML::EventNames::messageerror) // https://html.spec.whatwg.org/multipage/web-messaging.html#message-ports class MessagePort final : public DOM::EventTarget , public Bindings::Transferable { WEB_PLATFORM_OBJECT(MessagePort, DOM::EventTarget); GC_DECLARE_ALLOCATOR(MessagePort); public: [[nodiscard]] static GC::Ref create(JS::Realm&); static void for_each_message_port(Function); virtual ~MessagePort() override; // https://html.spec.whatwg.org/multipage/web-messaging.html#entangle void entangle_with(MessagePort&); void disentangle(); // https://html.spec.whatwg.org/multipage/web-messaging.html#dom-messageport-postmessage WebIDL::ExceptionOr post_message(JS::Value message, Vector> const& transfer); // https://html.spec.whatwg.org/multipage/web-messaging.html#dom-messageport-postmessage-options WebIDL::ExceptionOr post_message(JS::Value message, StructuredSerializeOptions const& options); void start(); void close(); #undef __ENUMERATE #define __ENUMERATE(attribute_name, event_name) \ void set_##attribute_name(WebIDL::CallbackType*); \ WebIDL::CallbackType* attribute_name(); ENUMERATE_MESSAGE_PORT_EVENT_HANDLERS(__ENUMERATE) #undef __ENUMERATE // ^Transferable virtual WebIDL::ExceptionOr transfer_steps(HTML::TransferDataHolder&) override; virtual WebIDL::ExceptionOr transfer_receiving_steps(HTML::TransferDataHolder&) override; virtual HTML::TransferType primary_interface() const override { return HTML::TransferType::MessagePort; } void set_worker_event_target(GC::Ref); private: explicit MessagePort(JS::Realm&); virtual void initialize(JS::Realm&) override; virtual void visit_edges(Cell::Visitor&) override; bool is_entangled() const; WebIDL::ExceptionOr message_port_post_message_steps(GC::Ptr target_port, JS::Value message, StructuredSerializeOptions const& options); void post_message_task_steps(SerializedTransferRecord&); void post_port_message(SerializedTransferRecord); ErrorOr send_message_on_transport(SerializedTransferRecord const&); void read_from_transport(); enum class ParseDecision { NotEnoughData, ParseNextMessage, }; ErrorOr parse_message(); // The HTML spec implies(!) that this is MessagePort.[[RemotePort]] GC::Ptr m_remote_port; // https://html.spec.whatwg.org/multipage/web-messaging.html#has-been-shipped bool m_has_been_shipped { false }; Optional m_transport; enum class SocketState : u8 { Header, Data, Error, } m_socket_state { SocketState::Header }; size_t m_socket_incoming_message_size { 0 }; Queue m_unprocessed_fds; Vector m_buffered_data; GC::Ptr m_worker_event_target; }; }