ladybird/Libraries/LibWeb/WebSockets/WebSocket.h
Shannon Booth 97abc707c7 LibWeb/Bindings: Generate buffer typedefs as variants
Represent BufferSource and ArrayBufferView as ordinary IDL typedefs over
their underlying union types, instead of special casing in the IDL
generator. This allows the union conversion/return machinery handle
these types consistently with other typedefs, which removes buffer
specific paths from the IDL generator.

This necessitates changing the WebIDL::BufferSource and
WebIDL::ArrayBufferView classes as views over these variants. This
replaces the old GC backed BufferableObject wrapper structure and
provide convenience helpers to determine things such as the byte length,
byte offset, backing buffer, and typed-array APIs.
2026-05-30 11:22:08 +02:00

89 lines
2.8 KiB
C++

/*
* Copyright (c) 2021-2022, Dex♪ <dexes.ttp@gmail.com>
* Copyright (c) 2023, Kenneth Myhra <kennethmyhra@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/ByteBuffer.h>
#include <LibCore/EventReceiver.h>
#include <LibRequests/Forward.h>
#include <LibRequests/WebSocket.h>
#include <LibURL/URL.h>
#include <LibWeb/Bindings/PlatformObject.h>
#include <LibWeb/DOM/EventTarget.h>
#include <LibWeb/Forward.h>
#include <LibWeb/WebIDL/Buffers.h>
#include <LibWeb/WebIDL/ExceptionOr.h>
#define ENUMERATE_WEBSOCKET_EVENT_HANDLERS(E) \
E(onerror, HTML::EventNames::error) \
E(onclose, HTML::EventNames::close) \
E(onopen, HTML::EventNames::open) \
E(onmessage, HTML::EventNames::message)
namespace Web::WebSockets {
using WebSocketSendData = FlattenVariant<WebIDL::BufferSourceVariant, Variant<GC::Ref<FileAPI::Blob>, String>>;
class WebSocket final : public DOM::EventTarget {
WEB_PLATFORM_OBJECT(WebSocket, DOM::EventTarget);
GC_DECLARE_ALLOCATOR(WebSocket);
public:
static constexpr bool OVERRIDES_FINALIZE = true;
static constexpr bool OVERRIDES_MUST_SURVIVE_GARBAGE_COLLECTION = true;
static WebIDL::ExceptionOr<GC::Ref<WebSocket>> construct_impl(JS::Realm&, String const& url, Optional<Variant<String, Vector<String>>> const& protocols);
virtual ~WebSocket() override;
String url() const { return m_url.to_string(); }
void set_url(URL::URL url) { m_url = move(url); }
#undef __ENUMERATE
#define __ENUMERATE(attribute_name, event_name) \
void set_##attribute_name(WebIDL::CallbackType*); \
WebIDL::CallbackType* attribute_name();
ENUMERATE_WEBSOCKET_EVENT_HANDLERS(__ENUMERATE)
#undef __ENUMERATE
Requests::WebSocket::ReadyState ready_state() const;
String extensions() const;
WebIDL::ExceptionOr<String> protocol() const;
String const& binary_type() { return m_binary_type; }
void set_binary_type(String const& type) { m_binary_type = type; }
WebIDL::ExceptionOr<void> close(Optional<u16> code, Optional<String> reason);
WebIDL::ExceptionOr<void> send(WebSocketSendData const& data);
void make_disappear();
private:
void on_open();
void on_message(ByteBuffer message, bool is_text);
void on_error();
void on_close(u16 code, String reason, bool was_clean);
WebSocket(JS::Realm&);
virtual void initialize(JS::Realm&) override;
virtual void finalize() override;
virtual bool must_survive_garbage_collection() const override;
ErrorOr<void> establish_web_socket_connection(URL::URL const& url_record, Vector<String> const& protocols, HTML::EnvironmentSettingsObject& client);
URL::URL m_url;
String m_binary_type { "blob"_string };
RefPtr<Requests::WebSocket> m_websocket;
IntrusiveListNode<WebSocket> m_list_node;
public:
using List = IntrusiveList<&WebSocket::m_list_node>;
};
}