MessagePort.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. /*
  2. * Copyright (c) 2021, Andreas Kling <andreas@ladybird.org>
  3. * Copyright (c) 2023, Andrew Kaster <akaster@serenityos.org>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #pragma once
  8. #include <AK/RefCounted.h>
  9. #include <AK/Weakable.h>
  10. #include <LibCore/Socket.h>
  11. #include <LibIPC/File.h>
  12. #include <LibIPC/Transport.h>
  13. #include <LibWeb/Bindings/Transferable.h>
  14. #include <LibWeb/DOM/EventTarget.h>
  15. #include <LibWeb/Forward.h>
  16. namespace Web::HTML {
  17. #define ENUMERATE_MESSAGE_PORT_EVENT_HANDLERS(E) \
  18. E(onmessage, HTML::EventNames::message) \
  19. E(onmessageerror, HTML::EventNames::messageerror)
  20. // https://html.spec.whatwg.org/multipage/web-messaging.html#message-ports
  21. class MessagePort final : public DOM::EventTarget
  22. , public Bindings::Transferable {
  23. WEB_PLATFORM_OBJECT(MessagePort, DOM::EventTarget);
  24. GC_DECLARE_ALLOCATOR(MessagePort);
  25. public:
  26. [[nodiscard]] static GC::Ref<MessagePort> create(JS::Realm&);
  27. static void for_each_message_port(Function<void(MessagePort&)>);
  28. virtual ~MessagePort() override;
  29. // https://html.spec.whatwg.org/multipage/web-messaging.html#entangle
  30. void entangle_with(MessagePort&);
  31. void disentangle();
  32. // https://html.spec.whatwg.org/multipage/web-messaging.html#dom-messageport-postmessage
  33. WebIDL::ExceptionOr<void> post_message(JS::Value message, Vector<GC::Root<JS::Object>> const& transfer);
  34. // https://html.spec.whatwg.org/multipage/web-messaging.html#dom-messageport-postmessage-options
  35. WebIDL::ExceptionOr<void> post_message(JS::Value message, StructuredSerializeOptions const& options);
  36. void start();
  37. void close();
  38. #undef __ENUMERATE
  39. #define __ENUMERATE(attribute_name, event_name) \
  40. void set_##attribute_name(WebIDL::CallbackType*); \
  41. WebIDL::CallbackType* attribute_name();
  42. ENUMERATE_MESSAGE_PORT_EVENT_HANDLERS(__ENUMERATE)
  43. #undef __ENUMERATE
  44. // ^Transferable
  45. virtual WebIDL::ExceptionOr<void> transfer_steps(HTML::TransferDataHolder&) override;
  46. virtual WebIDL::ExceptionOr<void> transfer_receiving_steps(HTML::TransferDataHolder&) override;
  47. virtual HTML::TransferType primary_interface() const override { return HTML::TransferType::MessagePort; }
  48. void set_worker_event_target(GC::Ref<DOM::EventTarget>);
  49. private:
  50. explicit MessagePort(JS::Realm&);
  51. virtual void initialize(JS::Realm&) override;
  52. virtual void visit_edges(Cell::Visitor&) override;
  53. bool is_entangled() const;
  54. WebIDL::ExceptionOr<void> message_port_post_message_steps(GC::Ptr<MessagePort> target_port, JS::Value message, StructuredSerializeOptions const& options);
  55. void post_message_task_steps(SerializedTransferRecord&);
  56. void post_port_message(SerializedTransferRecord);
  57. ErrorOr<void> send_message_on_transport(SerializedTransferRecord const&);
  58. void read_from_transport();
  59. enum class ParseDecision {
  60. NotEnoughData,
  61. ParseNextMessage,
  62. };
  63. ErrorOr<ParseDecision> parse_message();
  64. // The HTML spec implies(!) that this is MessagePort.[[RemotePort]]
  65. GC::Ptr<MessagePort> m_remote_port;
  66. // https://html.spec.whatwg.org/multipage/web-messaging.html#has-been-shipped
  67. bool m_has_been_shipped { false };
  68. Optional<IPC::Transport> m_transport;
  69. enum class SocketState : u8 {
  70. Header,
  71. Data,
  72. Error,
  73. } m_socket_state { SocketState::Header };
  74. size_t m_socket_incoming_message_size { 0 };
  75. Queue<IPC::File> m_unprocessed_fds;
  76. Vector<u8> m_buffered_data;
  77. GC::Ptr<DOM::EventTarget> m_worker_event_target;
  78. };
  79. }