LibWeb+Meta: Add wrapper for the BufferSource/ArrayBufferView IDL types
These wrappers will make it much easier to do various operations on the different ArrayBuffer-related classes in LibWeb compared to the current solution, which is to just accept a Handle<Object> everywhere (and use "any" in the *.idl files). Co-Authored-By: Matthew Olsson <mattco@serenityos.org>
This commit is contained in:
parent
54d0aafff0
commit
04c094343f
Notes:
sideshowbarker
2024-07-17 04:34:25 +09:00
Author: https://github.com/shannonbooth Commit: https://github.com/SerenityOS/serenity/commit/04c094343f Pull-request: https://github.com/SerenityOS/serenity/pull/22027
27 changed files with 286 additions and 71 deletions
|
@ -180,7 +180,10 @@ CppType idl_type_name_to_cpp_type(Type const& type, Interface const& interface)
|
|||
return { .name = "JS::Handle<JS::Object>", .sequence_storage_type = SequenceStorageType::Vector };
|
||||
|
||||
if (type.name() == "BufferSource")
|
||||
return { .name = "JS::Handle<JS::Object>", .sequence_storage_type = SequenceStorageType::MarkedVector };
|
||||
return { .name = "JS::Handle<WebIDL::BufferSource>", .sequence_storage_type = SequenceStorageType::MarkedVector };
|
||||
|
||||
if (type.name() == "ArrayBufferView")
|
||||
return { .name = "JS::Handle<WebIDL::ArrayBufferView>", .sequence_storage_type = SequenceStorageType::MarkedVector };
|
||||
|
||||
if (type.name() == "File")
|
||||
return { .name = "JS::Handle<FileAPI::File>", .sequence_storage_type = SequenceStorageType::MarkedVector };
|
||||
|
@ -611,20 +614,33 @@ static void generate_to_cpp(SourceGenerator& generator, ParameterType& parameter
|
|||
} else if (parameter.type->name() == "BufferSource" || parameter.type->name() == "Float32Array" || parameter.type->name() == "Float64Array" || parameter.type->name() == "Uint8Array") {
|
||||
if (optional) {
|
||||
scoped_generator.append(R"~~~(
|
||||
Optional<JS::Handle<JS::Object>> @cpp_name@;
|
||||
Optional<JS::Handle<WebIDL::BufferSource>> @cpp_name@;
|
||||
if (!@js_name@@js_suffix@.is_undefined()) {
|
||||
)~~~");
|
||||
} else {
|
||||
scoped_generator.append(R"~~~(
|
||||
JS::Handle<JS::Object> @cpp_name@;
|
||||
JS::Handle<WebIDL::BufferSource> @cpp_name@;
|
||||
)~~~");
|
||||
}
|
||||
scoped_generator.append(R"~~~(
|
||||
if (!@js_name@@js_suffix@.is_object() || !(is<JS::TypedArrayBase>(@js_name@@js_suffix@.as_object()) || is<JS::ArrayBuffer>(@js_name@@js_suffix@.as_object()) || is<JS::DataView>(@js_name@@js_suffix@.as_object())))
|
||||
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "@parameter.type.name@");
|
||||
|
||||
// TODO: Should we make this a Variant?
|
||||
@cpp_name@ = JS::make_handle(&@js_name@@js_suffix@.as_object());
|
||||
@cpp_name@ = JS::make_handle(vm.heap().allocate<WebIDL::BufferSource>(realm, @js_name@@js_suffix@.as_object()));
|
||||
)~~~");
|
||||
|
||||
if (optional) {
|
||||
scoped_generator.append(R"~~~(
|
||||
}
|
||||
)~~~");
|
||||
}
|
||||
|
||||
} else if (parameter.type->name() == "ArrayBufferView") {
|
||||
scoped_generator.append(R"~~~(
|
||||
if (!@js_name@@js_suffix@.is_object() || !(is<JS::TypedArrayBase>(@js_name@@js_suffix@.as_object()) || is<JS::DataView>(@js_name@@js_suffix@.as_object())))
|
||||
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "@parameter.type.name@");
|
||||
|
||||
auto @cpp_name@ = JS::make_handle(vm.heap().allocate<WebIDL::ArrayBufferView>(realm, @js_name@@js_suffix@.as_object()));
|
||||
)~~~");
|
||||
if (optional) {
|
||||
scoped_generator.append(R"~~~(
|
||||
|
@ -1124,28 +1140,40 @@ static void generate_to_cpp(SourceGenerator& generator, ParameterType& parameter
|
|||
|
||||
// 6. If Type(V) is Object and V has an [[ArrayBufferData]] internal slot, then
|
||||
// 1. If types includes ArrayBuffer, then return the result of converting V to ArrayBuffer.
|
||||
for (auto& type : types) {
|
||||
if (type->name() == "BufferSource") {
|
||||
union_generator.append(R"~~~(
|
||||
if (is<JS::TypedArrayBase>(@js_name@@js_suffix@_object) || is<JS::ArrayBuffer>(@js_name@@js_suffix@_object) || is<JS::DataView>(@js_name@@js_suffix@_object))
|
||||
return JS::make_handle(@js_name@@js_suffix@_object);
|
||||
)~~~");
|
||||
}
|
||||
}
|
||||
// 2. If types includes object, then return the IDL value that is a reference to the object V.
|
||||
if (includes_object) {
|
||||
if (any_of(types, [](auto const& type) { return type->name() == "ArrayBuffer"; }) || includes_object) {
|
||||
union_generator.append(R"~~~(
|
||||
return @js_name@@js_suffix@_object;
|
||||
if (is<JS::ArrayBuffer>(@js_name@@js_suffix@_object))
|
||||
return JS::make_handle(@js_name@@js_suffix@_object);
|
||||
}
|
||||
)~~~");
|
||||
}
|
||||
|
||||
// FIXME: 7. If Type(V) is Object and V has a [[DataView]] internal slot, then:
|
||||
// 1. If types includes DataView, then return the result of converting V to DataView.
|
||||
// 2. If types includes object, then return the IDL value that is a reference to the object V.
|
||||
// 7. If Type(V) is Object and V has a [[DataView]] internal slot, then:
|
||||
// 1. If types includes DataView, then return the result of converting V to DataView.
|
||||
// 2. If types includes object, then return the IDL value that is a reference to the object V.
|
||||
if (any_of(types, [](auto const& type) { return type->name() == "DataView"; }) || includes_object) {
|
||||
union_generator.append(R"~~~(
|
||||
if (is<JS::DataView>(@js_name@@js_suffix@_object))
|
||||
return JS::make_handle(@js_name@@js_suffix@_object);
|
||||
}
|
||||
)~~~");
|
||||
}
|
||||
|
||||
// FIXME: 8. If Type(V) is Object and V has a [[TypedArrayName]] internal slot, then:
|
||||
// 1. If types includes a typed array type whose name is the value of V’s [[TypedArrayName]] internal slot, then return the result of converting V to that type.
|
||||
// 2. If types includes object, then return the IDL value that is a reference to the object V.
|
||||
// 8. If Type(V) is Object and V has a [[TypedArrayName]] internal slot, then:
|
||||
// 1. If types includes a typed array type whose name is the value of V’s [[TypedArrayName]] internal slot, then return the result of converting V to that type.
|
||||
// 2. If types includes object, then return the IDL value that is a reference to the object V.
|
||||
auto has_typed_array_name = any_of(types, [](auto const& type) {
|
||||
return type->name().is_one_of("Int8Array"sv, "Int16Array"sv, "Int32Array"sv, "Uint8Array"sv, "Uint16Array"sv, "Uint32Array"sv, "Uint8ClampedArray"sv, "BigInt64Array"sv, "BigUint64Array", "Float32Array"sv, "Float64Array"sv);
|
||||
});
|
||||
|
||||
if (has_typed_array_name || includes_object) {
|
||||
union_generator.append(R"~~~(
|
||||
if (is<JS::TypedArrayBase>(@js_name@@js_suffix@_object))
|
||||
return JS::make_handle(@js_name@@js_suffix@_object);
|
||||
}
|
||||
)~~~");
|
||||
}
|
||||
|
||||
// 9. If IsCallable(V) is true, then:
|
||||
// 1. If types includes a callback function type, then return the result of converting V to that callback function type.
|
||||
|
@ -1679,6 +1707,10 @@ static void generate_wrap_statement(SourceGenerator& generator, DeprecatedString
|
|||
} else if (type.name() == "Location" || type.name() == "Promise" || type.name() == "Uint8Array" || type.name() == "Uint8ClampedArray" || type.name() == "any") {
|
||||
scoped_generator.append(R"~~~(
|
||||
@result_expression@ @value@;
|
||||
)~~~");
|
||||
} else if (type.name() == "ArrayBufferView" || type.name() == "BufferSource") {
|
||||
scoped_generator.append(R"~~~(
|
||||
@result_expression@ JS::Value(const_cast<JS::Object*>(@value@->raw_object().ptr()));
|
||||
)~~~");
|
||||
} else if (is<IDL::UnionType>(type)) {
|
||||
auto& union_type = verify_cast<IDL::UnionType>(type);
|
||||
|
@ -3359,6 +3391,7 @@ void generate_namespace_implementation(IDL::Interface const& interface, StringBu
|
|||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/HTML/Window.h>
|
||||
#include <LibWeb/HTML/WindowProxy.h>
|
||||
#include <LibWeb/WebIDL/Buffers.h>
|
||||
#include <LibWeb/WebIDL/OverloadResolution.h>
|
||||
|
||||
)~~~");
|
||||
|
@ -3570,6 +3603,7 @@ void generate_constructor_implementation(IDL::Interface const& interface, String
|
|||
# include <LibWeb/URL/@name@.h>
|
||||
#endif
|
||||
#include <LibWeb/HTML/WindowProxy.h>
|
||||
#include <LibWeb/WebIDL/Buffers.h>
|
||||
#include <LibWeb/WebIDL/CallbackType.h>
|
||||
|
||||
)~~~");
|
||||
|
@ -4023,6 +4057,7 @@ void generate_prototype_implementation(IDL::Interface const& interface, StringBu
|
|||
#include <LibWeb/HTML/Scripting/Environments.h>
|
||||
#include <LibWeb/HTML/Window.h>
|
||||
#include <LibWeb/HTML/WindowProxy.h>
|
||||
#include <LibWeb/WebIDL/Buffers.h>
|
||||
#include <LibWeb/WebIDL/OverloadResolution.h>
|
||||
|
||||
#if __has_include(<LibWeb/Bindings/@prototype_base_class@.h>)
|
||||
|
|
|
@ -235,6 +235,7 @@ class AsyncGeneratorPrototype;
|
|||
class GeneratorPrototype;
|
||||
class WrapForValidIteratorPrototype;
|
||||
|
||||
class TypedArrayBase;
|
||||
class TypedArrayConstructor;
|
||||
class TypedArrayPrototype;
|
||||
|
||||
|
|
|
@ -622,6 +622,7 @@ set(SOURCES
|
|||
WebGL/WebGLRenderingContext.cpp
|
||||
WebGL/WebGLRenderingContextBase.cpp
|
||||
WebIDL/AbstractOperations.cpp
|
||||
WebIDL/Buffers.cpp
|
||||
WebIDL/CallbackType.cpp
|
||||
WebIDL/DOMException.cpp
|
||||
WebIDL/OverloadResolution.cpp
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/Crypto/SubtleCrypto.h>
|
||||
#include <LibWeb/WebIDL/AbstractOperations.h>
|
||||
#include <LibWeb/WebIDL/Buffers.h>
|
||||
#include <LibWeb/WebIDL/ExceptionOr.h>
|
||||
|
||||
namespace Web::Crypto {
|
||||
|
@ -35,14 +36,14 @@ void SubtleCrypto::initialize(JS::Realm& realm)
|
|||
}
|
||||
|
||||
// https://w3c.github.io/webcrypto/#dfn-SubtleCrypto-method-digest
|
||||
JS::NonnullGCPtr<JS::Promise> SubtleCrypto::digest(String const& algorithm, JS::Handle<JS::Object> const& data)
|
||||
JS::NonnullGCPtr<JS::Promise> SubtleCrypto::digest(String const& algorithm, JS::Handle<WebIDL::BufferSource> const& data)
|
||||
{
|
||||
auto& realm = this->realm();
|
||||
|
||||
// 1. Let algorithm be the algorithm parameter passed to the digest() method.
|
||||
|
||||
// 2. Let data be the result of getting a copy of the bytes held by the data parameter passed to the digest() method.
|
||||
auto data_buffer_or_error = WebIDL::get_buffer_source_copy(*data.cell());
|
||||
auto data_buffer_or_error = WebIDL::get_buffer_source_copy(*data->raw_object());
|
||||
if (data_buffer_or_error.is_error()) {
|
||||
auto error = WebIDL::OperationError::create(realm, "Failed to copy bytes from ArrayBuffer"_fly_string);
|
||||
auto promise = JS::Promise::create(realm);
|
||||
|
|
|
@ -20,7 +20,7 @@ public:
|
|||
|
||||
virtual ~SubtleCrypto() override;
|
||||
|
||||
JS::NonnullGCPtr<JS::Promise> digest(String const& algorithm, JS::Handle<JS::Object> const& data);
|
||||
JS::NonnullGCPtr<JS::Promise> digest(String const& algorithm, JS::Handle<WebIDL::BufferSource> const& data);
|
||||
|
||||
private:
|
||||
explicit SubtleCrypto(JS::Realm&);
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/Encoding/TextDecoder.h>
|
||||
#include <LibWeb/WebIDL/AbstractOperations.h>
|
||||
#include <LibWeb/WebIDL/Buffers.h>
|
||||
|
||||
namespace Web::Encoding {
|
||||
|
||||
|
@ -44,14 +45,13 @@ void TextDecoder::initialize(JS::Realm& realm)
|
|||
}
|
||||
|
||||
// https://encoding.spec.whatwg.org/#dom-textdecoder-decode
|
||||
WebIDL::ExceptionOr<String> TextDecoder::decode(Optional<JS::Handle<JS::Object>> const& input, Optional<TextDecodeOptions> const&) const
|
||||
WebIDL::ExceptionOr<String> TextDecoder::decode(Optional<JS::Handle<WebIDL::BufferSource>> const& input, Optional<TextDecodeOptions> const&) const
|
||||
{
|
||||
if (!input.has_value())
|
||||
return TRY_OR_THROW_OOM(vm(), m_decoder.to_utf8({}));
|
||||
|
||||
// FIXME: Implement the streaming stuff.
|
||||
|
||||
auto data_buffer_or_error = WebIDL::get_buffer_source_copy(*input->cell());
|
||||
auto data_buffer_or_error = WebIDL::get_buffer_source_copy(*input.value()->raw_object());
|
||||
if (data_buffer_or_error.is_error())
|
||||
return WebIDL::OperationError::create(realm(), "Failed to copy bytes from ArrayBuffer"_fly_string);
|
||||
auto& data_buffer = data_buffer_or_error.value();
|
||||
|
|
|
@ -37,7 +37,7 @@ public:
|
|||
|
||||
virtual ~TextDecoder() override;
|
||||
|
||||
WebIDL::ExceptionOr<String> decode(Optional<JS::Handle<JS::Object>> const&, Optional<TextDecodeOptions> const& options = {}) const;
|
||||
WebIDL::ExceptionOr<String> decode(Optional<JS::Handle<WebIDL::BufferSource>> const&, Optional<TextDecodeOptions> const& options = {}) const;
|
||||
|
||||
FlyString const& encoding() const { return m_encoding; }
|
||||
bool fatal() const { return m_fatal; }
|
||||
|
|
|
@ -50,10 +50,9 @@ JS::NonnullGCPtr<JS::Uint8Array> TextEncoder::encode(String const& input) const
|
|||
}
|
||||
|
||||
// https://encoding.spec.whatwg.org/#dom-textencoder-encodeinto
|
||||
TextEncoderEncodeIntoResult TextEncoder::encode_into(String const& source, JS::Handle<JS::Object> const& destination) const
|
||||
TextEncoderEncodeIntoResult TextEncoder::encode_into(String const& source, JS::Handle<WebIDL::BufferSource> const& destination) const
|
||||
{
|
||||
auto& destination_array = static_cast<JS::Uint8Array&>(*destination);
|
||||
auto data = destination_array.data();
|
||||
auto& data = destination->viewed_array_buffer()->buffer();
|
||||
|
||||
// 1. Let read be 0.
|
||||
unsigned long long read = 0;
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <LibJS/Forward.h>
|
||||
#include <LibWeb/Bindings/PlatformObject.h>
|
||||
#include <LibWeb/Forward.h>
|
||||
#include <LibWeb/WebIDL/Buffers.h>
|
||||
|
||||
namespace Web::Encoding {
|
||||
|
||||
|
@ -32,7 +33,7 @@ public:
|
|||
virtual ~TextEncoder() override;
|
||||
|
||||
JS::NonnullGCPtr<JS::Uint8Array> encode(String const& input) const;
|
||||
TextEncoderEncodeIntoResult encode_into(String const& source, JS::Handle<JS::Object> const& destination) const;
|
||||
TextEncoderEncodeIntoResult encode_into(String const& source, JS::Handle<WebIDL::BufferSource> const& destination) const;
|
||||
|
||||
static FlyString const& encoding();
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <LibWeb/HTML/FormControlInfrastructure.h>
|
||||
#include <LibWeb/URL/URLSearchParams.h>
|
||||
#include <LibWeb/WebIDL/AbstractOperations.h>
|
||||
#include <LibWeb/WebIDL/Buffers.h>
|
||||
#include <LibWeb/WebIDL/ExceptionOr.h>
|
||||
#include <LibWeb/XHR/FormData.h>
|
||||
|
||||
|
@ -68,7 +69,6 @@ WebIDL::ExceptionOr<Infrastructure::BodyWithType> extract_body(JS::Realm& realm,
|
|||
Optional<ByteBuffer> type {};
|
||||
|
||||
// 10. Switch on object.
|
||||
// FIXME: Still need to support BufferSource
|
||||
TRY(object.visit(
|
||||
[&](JS::Handle<FileAPI::Blob> const& blob) -> WebIDL::ExceptionOr<void> {
|
||||
// Set source to object.
|
||||
|
@ -85,9 +85,9 @@ WebIDL::ExceptionOr<Infrastructure::BodyWithType> extract_body(JS::Realm& realm,
|
|||
source = TRY_OR_THROW_OOM(vm, ByteBuffer::copy(bytes));
|
||||
return {};
|
||||
},
|
||||
[&](JS::Handle<JS::Object> const& buffer_source) -> WebIDL::ExceptionOr<void> {
|
||||
[&](JS::Handle<WebIDL::BufferSource> const& buffer_source) -> WebIDL::ExceptionOr<void> {
|
||||
// Set source to a copy of the bytes held by object.
|
||||
source = TRY_OR_THROW_OOM(vm, WebIDL::get_buffer_source_copy(*buffer_source.cell()));
|
||||
source = TRY_OR_THROW_OOM(vm, WebIDL::get_buffer_source_copy(*buffer_source->raw_object()));
|
||||
return {};
|
||||
},
|
||||
[&](JS::Handle<XHR::FormData> const& form_data) -> WebIDL::ExceptionOr<void> {
|
||||
|
|
|
@ -14,9 +14,9 @@
|
|||
namespace Web::Fetch {
|
||||
|
||||
// https://fetch.spec.whatwg.org/#bodyinit
|
||||
using BodyInit = Variant<JS::Handle<Streams::ReadableStream>, JS::Handle<FileAPI::Blob>, JS::Handle<JS::Object>, JS::Handle<XHR::FormData>, JS::Handle<URL::URLSearchParams>, String>;
|
||||
using BodyInit = Variant<JS::Handle<Streams::ReadableStream>, JS::Handle<FileAPI::Blob>, JS::Handle<WebIDL::BufferSource>, JS::Handle<XHR::FormData>, JS::Handle<URL::URLSearchParams>, String>;
|
||||
|
||||
using BodyInitOrReadableBytes = Variant<JS::Handle<Streams::ReadableStream>, JS::Handle<FileAPI::Blob>, JS::Handle<JS::Object>, JS::Handle<XHR::FormData>, JS::Handle<URL::URLSearchParams>, String, ReadonlyBytes>;
|
||||
using BodyInitOrReadableBytes = Variant<JS::Handle<Streams::ReadableStream>, JS::Handle<FileAPI::Blob>, JS::Handle<WebIDL::BufferSource>, JS::Handle<XHR::FormData>, JS::Handle<URL::URLSearchParams>, String, ReadonlyBytes>;
|
||||
WebIDL::ExceptionOr<Infrastructure::BodyWithType> safely_extract_body(JS::Realm&, BodyInitOrReadableBytes const&);
|
||||
WebIDL::ExceptionOr<Infrastructure::BodyWithType> extract_body(JS::Realm&, BodyInitOrReadableBytes const&, bool keepalive = false);
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <LibWeb/Streams/AbstractOperations.h>
|
||||
#include <LibWeb/Streams/ReadableStreamDefaultReader.h>
|
||||
#include <LibWeb/WebIDL/AbstractOperations.h>
|
||||
#include <LibWeb/WebIDL/Buffers.h>
|
||||
|
||||
namespace Web::FileAPI {
|
||||
|
||||
|
@ -99,8 +100,8 @@ ErrorOr<ByteBuffer> process_blob_parts(Vector<BlobPart> const& blob_parts, Optio
|
|||
return bytes.try_append(s.bytes());
|
||||
},
|
||||
// 2. If element is a BufferSource, get a copy of the bytes held by the buffer source, and append those bytes to bytes.
|
||||
[&](JS::Handle<JS::Object> const& buffer_source) -> ErrorOr<void> {
|
||||
auto data_buffer = TRY(WebIDL::get_buffer_source_copy(*buffer_source.cell()));
|
||||
[&](JS::Handle<WebIDL::BufferSource> const& buffer_source) -> ErrorOr<void> {
|
||||
auto data_buffer = TRY(WebIDL::get_buffer_source_copy(*buffer_source->raw_object()));
|
||||
return bytes.try_append(data_buffer.bytes());
|
||||
},
|
||||
// 3. If element is a Blob, append the bytes it represents to bytes.
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
namespace Web::FileAPI {
|
||||
|
||||
using BlobPart = Variant<JS::Handle<JS::Object>, JS::Handle<Blob>, String>;
|
||||
using BlobPart = Variant<JS::Handle<WebIDL::BufferSource>, JS::Handle<Blob>, String>;
|
||||
|
||||
struct BlobPropertyBag {
|
||||
String type = String {};
|
||||
|
|
|
@ -678,6 +678,8 @@ class WebGLRenderingContextBase;
|
|||
}
|
||||
|
||||
namespace Web::WebIDL {
|
||||
class ArrayBufferView;
|
||||
class BufferSource;
|
||||
class CallbackType;
|
||||
class DOMException;
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <LibJS/Runtime/TypedArray.h>
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/Geometry/DOMMatrix.h>
|
||||
#include <LibWeb/WebIDL/Buffers.h>
|
||||
#include <LibWeb/WebIDL/ExceptionOr.h>
|
||||
|
||||
namespace Web::Geometry {
|
||||
|
@ -108,13 +109,13 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrix>> DOMMatrix::from_matrix(JS::VM&
|
|||
}
|
||||
|
||||
// https://drafts.fxtf.org/geometry/#dom-dommatrix-fromfloat32array
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrix>> DOMMatrix::from_float32_array(JS::VM& vm, JS::Handle<JS::Object> const& array32)
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrix>> DOMMatrix::from_float32_array(JS::VM& vm, JS::Handle<WebIDL::BufferSource> const& array32)
|
||||
{
|
||||
if (!is<JS::Float32Array>(*array32))
|
||||
if (!is<JS::Float32Array>(*array32->raw_object()))
|
||||
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "Float32Array");
|
||||
|
||||
auto& realm = *vm.current_realm();
|
||||
auto& float32_array = static_cast<JS::Float32Array&>(*array32);
|
||||
auto& float32_array = static_cast<JS::Float32Array&>(*array32->raw_object());
|
||||
ReadonlySpan<float> elements = float32_array.data();
|
||||
|
||||
// If array32 has 6 elements, return the result of invoking create a 2d matrix of type DOMMatrixReadOnly or DOMMatrix as appropriate, with a sequence of numbers taking the values from array32 in the provided order.
|
||||
|
@ -133,13 +134,13 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrix>> DOMMatrix::from_float32_array(J
|
|||
}
|
||||
|
||||
// https://drafts.fxtf.org/geometry/#dom-dommatrix-fromfloat64array
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrix>> DOMMatrix::from_float64_array(JS::VM& vm, JS::Handle<JS::Object> const& array64)
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrix>> DOMMatrix::from_float64_array(JS::VM& vm, JS::Handle<WebIDL::BufferSource> const& array64)
|
||||
{
|
||||
if (!is<JS::Float64Array>(*array64))
|
||||
if (!is<JS::Float64Array>(*array64->raw_object()))
|
||||
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "Float64Array");
|
||||
|
||||
auto& realm = *vm.current_realm();
|
||||
auto& float64_array = static_cast<JS::Float64Array&>(*array64);
|
||||
auto& float64_array = static_cast<JS::Float64Array&>(*array64->raw_object());
|
||||
ReadonlySpan<double> elements = float64_array.data();
|
||||
|
||||
// If array64 has 6 elements, return the result of invoking create a 2d matrix of type DOMMatrixReadOnly or DOMMatrix as appropriate, with a sequence of numbers taking the values from array64 in the provided order.
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <LibWeb/Geometry/DOMMatrixReadOnly.h>
|
||||
#include <LibWeb/WebIDL/Buffers.h>
|
||||
|
||||
namespace Web::Geometry {
|
||||
|
||||
|
@ -25,8 +26,8 @@ public:
|
|||
virtual ~DOMMatrix() override;
|
||||
|
||||
static WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrix>> from_matrix(JS::VM&, DOMMatrixInit other = {});
|
||||
static WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrix>> from_float32_array(JS::VM&, JS::Handle<JS::Object> const& array32);
|
||||
static WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrix>> from_float64_array(JS::VM&, JS::Handle<JS::Object> const& array64);
|
||||
static WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrix>> from_float32_array(JS::VM&, JS::Handle<WebIDL::BufferSource> const& array32);
|
||||
static WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrix>> from_float64_array(JS::VM&, JS::Handle<WebIDL::BufferSource> const& array64);
|
||||
|
||||
void set_m11(double value);
|
||||
void set_m12(double value);
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <LibWeb/Geometry/DOMMatrix.h>
|
||||
#include <LibWeb/Geometry/DOMMatrixReadOnly.h>
|
||||
#include <LibWeb/Geometry/DOMPoint.h>
|
||||
#include <LibWeb/WebIDL/Buffers.h>
|
||||
#include <LibWeb/WebIDL/ExceptionOr.h>
|
||||
|
||||
namespace Web::Geometry {
|
||||
|
@ -208,13 +209,13 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrixReadOnly>> DOMMatrixReadOnly::from
|
|||
}
|
||||
|
||||
// https://drafts.fxtf.org/geometry/#dom-dommatrixreadonly-fromfloat32array
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrixReadOnly>> DOMMatrixReadOnly::from_float32_array(JS::VM& vm, JS::Handle<JS::Object> const& array32)
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrixReadOnly>> DOMMatrixReadOnly::from_float32_array(JS::VM& vm, JS::Handle<WebIDL::BufferSource> const& array32)
|
||||
{
|
||||
if (!is<JS::Float32Array>(*array32))
|
||||
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "Float32Array");
|
||||
|
||||
auto& realm = *vm.current_realm();
|
||||
auto& float32_array = static_cast<JS::Float32Array&>(*array32);
|
||||
auto& float32_array = static_cast<JS::Float32Array&>(*array32->raw_object());
|
||||
ReadonlySpan<float> elements = float32_array.data();
|
||||
|
||||
// If array32 has 6 elements, return the result of invoking create a 2d matrix of type DOMMatrixReadOnly or DOMMatrix as appropriate, with a sequence of numbers taking the values from array32 in the provided order.
|
||||
|
@ -233,13 +234,13 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrixReadOnly>> DOMMatrixReadOnly::from
|
|||
}
|
||||
|
||||
// https://drafts.fxtf.org/geometry/#dom-dommatrixreadonly-fromfloat64array
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrixReadOnly>> DOMMatrixReadOnly::from_float64_array(JS::VM& vm, JS::Handle<JS::Object> const& array64)
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrixReadOnly>> DOMMatrixReadOnly::from_float64_array(JS::VM& vm, JS::Handle<WebIDL::BufferSource> const& array64)
|
||||
{
|
||||
if (!is<JS::Float64Array>(*array64))
|
||||
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "Float64Array");
|
||||
|
||||
auto& realm = *vm.current_realm();
|
||||
auto& float64_array = static_cast<JS::Float64Array&>(*array64);
|
||||
auto& float64_array = static_cast<JS::Float64Array&>(*array64->raw_object());
|
||||
ReadonlySpan<double> elements = float64_array.data();
|
||||
|
||||
// If array64 has 6 elements, return the result of invoking create a 2d matrix of type DOMMatrixReadOnly or DOMMatrix as appropriate, with a sequence of numbers taking the values from array64 in the provided order.
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <LibGfx/Matrix4x4.h>
|
||||
#include <LibWeb/Bindings/PlatformObject.h>
|
||||
#include <LibWeb/Forward.h>
|
||||
#include <LibWeb/WebIDL/Buffers.h>
|
||||
|
||||
namespace Web::Geometry {
|
||||
|
||||
|
@ -56,8 +57,8 @@ public:
|
|||
virtual ~DOMMatrixReadOnly() override;
|
||||
|
||||
static WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrixReadOnly>> from_matrix(JS::VM&, DOMMatrixInit& other);
|
||||
static WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrixReadOnly>> from_float32_array(JS::VM&, JS::Handle<JS::Object> const& array32);
|
||||
static WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrixReadOnly>> from_float64_array(JS::VM&, JS::Handle<JS::Object> const& array64);
|
||||
static WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrixReadOnly>> from_float32_array(JS::VM&, JS::Handle<WebIDL::BufferSource> const& array32);
|
||||
static WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrixReadOnly>> from_float64_array(JS::VM&, JS::Handle<WebIDL::BufferSource> const& array64);
|
||||
|
||||
// https://drafts.fxtf.org/geometry/#dommatrix-attributes
|
||||
double m11() const { return m_matrix.elements()[0][0]; }
|
||||
|
|
|
@ -11,16 +11,17 @@
|
|||
#include <LibWeb/Bindings/ModulePrototype.h>
|
||||
#include <LibWeb/WebAssembly/Module.h>
|
||||
#include <LibWeb/WebAssembly/WebAssembly.h>
|
||||
#include <LibWeb/WebIDL/Buffers.h>
|
||||
|
||||
namespace Web::WebAssembly {
|
||||
|
||||
JS_DEFINE_ALLOCATOR(Module);
|
||||
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<Module>> Module::construct_impl(JS::Realm& realm, JS::Handle<JS::Object>& bytes)
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<Module>> Module::construct_impl(JS::Realm& realm, JS::Handle<WebIDL::BufferSource>& bytes)
|
||||
{
|
||||
auto& vm = realm.vm();
|
||||
|
||||
auto index = TRY(Detail::parse_module(vm, bytes.cell()));
|
||||
auto index = TRY(Detail::parse_module(vm, bytes->raw_object()));
|
||||
return vm.heap().allocate<Module>(realm, realm, index);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ class Module : public Bindings::PlatformObject {
|
|||
JS_DECLARE_ALLOCATOR(Module);
|
||||
|
||||
public:
|
||||
static WebIDL::ExceptionOr<JS::NonnullGCPtr<Module>> construct_impl(JS::Realm&, JS::Handle<JS::Object>& bytes);
|
||||
static WebIDL::ExceptionOr<JS::NonnullGCPtr<Module>> construct_impl(JS::Realm&, JS::Handle<WebIDL::BufferSource>& bytes);
|
||||
|
||||
size_t index() const { return m_index; }
|
||||
Wasm::Module const& module() const;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <LibWeb/WebAssembly/Module.h>
|
||||
#include <LibWeb/WebAssembly/Table.h>
|
||||
#include <LibWeb/WebAssembly/WebAssembly.h>
|
||||
#include <LibWeb/WebIDL/Buffers.h>
|
||||
|
||||
namespace Web::WebAssembly {
|
||||
|
||||
|
@ -53,13 +54,13 @@ void visit_edges(JS::Cell::Visitor& visitor)
|
|||
}
|
||||
|
||||
// https://webassembly.github.io/spec/js-api/#dom-webassembly-validate
|
||||
bool validate(JS::VM& vm, JS::Handle<JS::Object>& bytes)
|
||||
bool validate(JS::VM& vm, JS::Handle<WebIDL::BufferSource>& bytes)
|
||||
{
|
||||
// 1. Let stableBytes be a copy of the bytes held by the buffer bytes.
|
||||
// Note: There's no need to copy the bytes here as the buffer data cannot change while we're compiling the module.
|
||||
|
||||
// 2. Compile stableBytes as a WebAssembly module and store the results as module.
|
||||
auto maybe_module = Detail::parse_module(vm, bytes.cell());
|
||||
auto maybe_module = Detail::parse_module(vm, bytes->raw_object());
|
||||
|
||||
// 3. If module is error, return false.
|
||||
if (maybe_module.is_error())
|
||||
|
@ -77,12 +78,12 @@ bool validate(JS::VM& vm, JS::Handle<JS::Object>& bytes)
|
|||
}
|
||||
|
||||
// https://webassembly.github.io/spec/js-api/#dom-webassembly-compile
|
||||
WebIDL::ExceptionOr<JS::Value> compile(JS::VM& vm, JS::Handle<JS::Object>& bytes)
|
||||
WebIDL::ExceptionOr<JS::Value> compile(JS::VM& vm, JS::Handle<WebIDL::BufferSource>& bytes)
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
|
||||
// FIXME: This shouldn't block!
|
||||
auto module = Detail::parse_module(vm, bytes.cell());
|
||||
auto module = Detail::parse_module(vm, bytes->raw_object());
|
||||
auto promise = JS::Promise::create(realm);
|
||||
|
||||
if (module.is_error()) {
|
||||
|
@ -96,7 +97,7 @@ WebIDL::ExceptionOr<JS::Value> compile(JS::VM& vm, JS::Handle<JS::Object>& bytes
|
|||
}
|
||||
|
||||
// https://webassembly.github.io/spec/js-api/#dom-webassembly-instantiate
|
||||
WebIDL::ExceptionOr<JS::Value> instantiate(JS::VM& vm, JS::Handle<JS::Object>& bytes, Optional<JS::Handle<JS::Object>>& import_object)
|
||||
WebIDL::ExceptionOr<JS::Value> instantiate(JS::VM& vm, JS::Handle<WebIDL::BufferSource>& bytes, Optional<JS::Handle<JS::Object>>& import_object)
|
||||
{
|
||||
// FIXME: Implement the importObject parameter.
|
||||
(void)import_object;
|
||||
|
@ -104,7 +105,7 @@ WebIDL::ExceptionOr<JS::Value> instantiate(JS::VM& vm, JS::Handle<JS::Object>& b
|
|||
auto& realm = *vm.current_realm();
|
||||
|
||||
// FIXME: This shouldn't block!
|
||||
auto module = Detail::parse_module(vm, bytes.cell());
|
||||
auto module = Detail::parse_module(vm, bytes->raw_object());
|
||||
auto promise = JS::Promise::create(realm);
|
||||
|
||||
if (module.is_error()) {
|
||||
|
|
|
@ -20,10 +20,10 @@ namespace Web::WebAssembly {
|
|||
|
||||
void visit_edges(JS::Cell::Visitor&);
|
||||
|
||||
bool validate(JS::VM&, JS::Handle<JS::Object>& bytes);
|
||||
WebIDL::ExceptionOr<JS::Value> compile(JS::VM&, JS::Handle<JS::Object>& bytes);
|
||||
bool validate(JS::VM&, JS::Handle<WebIDL::BufferSource>& bytes);
|
||||
WebIDL::ExceptionOr<JS::Value> compile(JS::VM&, JS::Handle<WebIDL::BufferSource>& bytes);
|
||||
|
||||
WebIDL::ExceptionOr<JS::Value> instantiate(JS::VM&, JS::Handle<JS::Object>& bytes, Optional<JS::Handle<JS::Object>>& import_object);
|
||||
WebIDL::ExceptionOr<JS::Value> instantiate(JS::VM&, JS::Handle<WebIDL::BufferSource>& bytes, Optional<JS::Handle<JS::Object>>& import_object);
|
||||
WebIDL::ExceptionOr<JS::Value> instantiate(JS::VM&, Module const& module_object, Optional<JS::Handle<JS::Object>>& import_object);
|
||||
|
||||
namespace Detail {
|
||||
|
|
82
Userland/Libraries/LibWeb/WebIDL/Buffers.cpp
Normal file
82
Userland/Libraries/LibWeb/WebIDL/Buffers.cpp
Normal file
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Shannon Booth <shannon@serenityos.org>
|
||||
* Copyright (c) 2023, Matthew Olsson <mattco@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibJS/Runtime/DataView.h>
|
||||
#include <LibJS/Runtime/TypedArray.h>
|
||||
#include <LibWeb/WebIDL/Buffers.h>
|
||||
|
||||
namespace Web::WebIDL {
|
||||
|
||||
u32 BufferableObjectBase::byte_length() const
|
||||
{
|
||||
return m_bufferable_object.visit([](auto& obj) { return static_cast<u32>(obj->byte_length()); });
|
||||
}
|
||||
|
||||
JS::NonnullGCPtr<JS::Object> BufferableObjectBase::raw_object()
|
||||
{
|
||||
return m_bufferable_object.visit([](auto const& obj) -> JS::NonnullGCPtr<JS::Object> { return obj; });
|
||||
}
|
||||
|
||||
JS::GCPtr<JS::ArrayBuffer> BufferableObjectBase::viewed_array_buffer()
|
||||
{
|
||||
return m_bufferable_object.visit(
|
||||
[](JS::NonnullGCPtr<JS::ArrayBuffer> array_buffer) -> JS::GCPtr<JS::ArrayBuffer> { return array_buffer; },
|
||||
[](auto const& view) -> JS::GCPtr<JS::ArrayBuffer> { return view->viewed_array_buffer(); });
|
||||
}
|
||||
|
||||
BufferableObject BufferableObjectBase::bufferable_object_from_raw_object(JS::NonnullGCPtr<JS::Object> object)
|
||||
{
|
||||
if (is<JS::TypedArrayBase>(*object))
|
||||
return JS::NonnullGCPtr { static_cast<JS::TypedArrayBase&>(*object) };
|
||||
|
||||
if (is<JS::DataView>(*object))
|
||||
return JS::NonnullGCPtr { static_cast<JS::DataView&>(*object) };
|
||||
|
||||
if (is<JS::ArrayBuffer>(*object))
|
||||
return JS::NonnullGCPtr { static_cast<JS::ArrayBuffer&>(*object) };
|
||||
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
BufferableObjectBase::BufferableObjectBase(JS::NonnullGCPtr<JS::Object> object)
|
||||
: m_bufferable_object(bufferable_object_from_raw_object(object))
|
||||
{
|
||||
}
|
||||
|
||||
bool BufferableObjectBase::is_typed_array_base() const
|
||||
{
|
||||
return m_bufferable_object.has<JS::NonnullGCPtr<JS::TypedArrayBase>>();
|
||||
}
|
||||
|
||||
bool BufferableObjectBase::is_data_view() const
|
||||
{
|
||||
return m_bufferable_object.has<JS::NonnullGCPtr<JS::DataView>>();
|
||||
}
|
||||
|
||||
bool BufferableObjectBase::is_array_buffer() const
|
||||
{
|
||||
return m_bufferable_object.has<JS::NonnullGCPtr<JS::ArrayBuffer>>();
|
||||
}
|
||||
|
||||
void BufferableObjectBase::visit_edges(Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
m_bufferable_object.visit([&](auto& obj) { visitor.visit(obj); });
|
||||
}
|
||||
|
||||
ArrayBufferView::~ArrayBufferView() = default;
|
||||
|
||||
u32 ArrayBufferView::byte_offset() const
|
||||
{
|
||||
return m_bufferable_object.visit(
|
||||
[](JS::NonnullGCPtr<JS::ArrayBuffer>) -> u32 { VERIFY_NOT_REACHED(); },
|
||||
[](auto& view) -> u32 { return static_cast<u32>(view->byte_offset()); });
|
||||
}
|
||||
|
||||
BufferSource::~BufferSource() = default;
|
||||
|
||||
}
|
85
Userland/Libraries/LibWeb/WebIDL/Buffers.h
Normal file
85
Userland/Libraries/LibWeb/WebIDL/Buffers.h
Normal file
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Shannon Booth <shannon@serenityos.org>
|
||||
* Copyright (c) 2023, Matthew Olsson <mattco@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Variant.h>
|
||||
#include <LibJS/Forward.h>
|
||||
#include <LibJS/Heap/Cell.h>
|
||||
|
||||
namespace Web::WebIDL {
|
||||
|
||||
using BufferableObject = Variant<
|
||||
JS::NonnullGCPtr<JS::TypedArrayBase>,
|
||||
JS::NonnullGCPtr<JS::DataView>,
|
||||
JS::NonnullGCPtr<JS::ArrayBuffer>>;
|
||||
|
||||
class BufferableObjectBase : public JS::Cell {
|
||||
JS_CELL(BufferableObjectBase, JS::Cell);
|
||||
|
||||
public:
|
||||
virtual ~BufferableObjectBase() override = default;
|
||||
|
||||
u32 byte_length() const;
|
||||
|
||||
JS::NonnullGCPtr<JS::Object> raw_object();
|
||||
JS::GCPtr<JS::ArrayBuffer> viewed_array_buffer();
|
||||
|
||||
BufferableObject const& bufferable_object() const { return m_bufferable_object; }
|
||||
BufferableObject& bufferable_object() { return m_bufferable_object; }
|
||||
|
||||
protected:
|
||||
BufferableObjectBase(JS::NonnullGCPtr<JS::Object>);
|
||||
|
||||
virtual void visit_edges(Visitor&) override;
|
||||
|
||||
bool is_data_view() const;
|
||||
bool is_typed_array_base() const;
|
||||
bool is_array_buffer() const;
|
||||
|
||||
static BufferableObject bufferable_object_from_raw_object(JS::NonnullGCPtr<JS::Object>);
|
||||
|
||||
BufferableObject m_bufferable_object;
|
||||
};
|
||||
|
||||
// https://webidl.spec.whatwg.org/#ArrayBufferView
|
||||
//
|
||||
// typedef (Int8Array or Int16Array or Int32Array or
|
||||
// Uint8Array or Uint16Array or Uint32Array or Uint8ClampedArray or
|
||||
// BigInt64Array or BigUint64Array or
|
||||
// Float32Array or Float64Array or DataView) ArrayBufferView;
|
||||
class ArrayBufferView : public BufferableObjectBase {
|
||||
JS_CELL(ArrayBufferView, BufferableObjectBase);
|
||||
|
||||
public:
|
||||
using BufferableObjectBase::BufferableObjectBase;
|
||||
|
||||
virtual ~ArrayBufferView() override;
|
||||
|
||||
using BufferableObjectBase::is_data_view;
|
||||
using BufferableObjectBase::is_typed_array_base;
|
||||
|
||||
u32 byte_offset() const;
|
||||
};
|
||||
|
||||
// https://webidl.spec.whatwg.org/#BufferSource
|
||||
//
|
||||
// typedef (ArrayBufferView or ArrayBuffer) BufferSource;
|
||||
class BufferSource : public BufferableObjectBase {
|
||||
JS_CELL(BufferSource, BufferableObjectBase);
|
||||
|
||||
public:
|
||||
using BufferableObjectBase::BufferableObjectBase;
|
||||
|
||||
virtual ~BufferSource() override;
|
||||
|
||||
using BufferableObjectBase::is_array_buffer;
|
||||
using BufferableObjectBase::is_data_view;
|
||||
using BufferableObjectBase::is_typed_array_base;
|
||||
};
|
||||
|
||||
}
|
|
@ -20,6 +20,7 @@
|
|||
#include <LibWeb/HTML/Origin.h>
|
||||
#include <LibWeb/HTML/Window.h>
|
||||
#include <LibWeb/WebIDL/AbstractOperations.h>
|
||||
#include <LibWeb/WebIDL/Buffers.h>
|
||||
#include <LibWeb/WebIDL/DOMException.h>
|
||||
#include <LibWeb/WebIDL/ExceptionOr.h>
|
||||
#include <LibWeb/WebSockets/WebSocket.h>
|
||||
|
@ -230,7 +231,7 @@ WebIDL::ExceptionOr<void> WebSocket::close(Optional<u16> code, Optional<String>
|
|||
}
|
||||
|
||||
// https://websockets.spec.whatwg.org/#dom-websocket-send
|
||||
WebIDL::ExceptionOr<void> WebSocket::send(Variant<JS::Handle<JS::Object>, JS::Handle<FileAPI::Blob>, String> const& data)
|
||||
WebIDL::ExceptionOr<void> WebSocket::send(Variant<JS::Handle<WebIDL::BufferSource>, JS::Handle<FileAPI::Blob>, String> const& data)
|
||||
{
|
||||
auto state = ready_state();
|
||||
if (state == WebSocket::ReadyState::Connecting)
|
||||
|
@ -242,10 +243,10 @@ WebIDL::ExceptionOr<void> WebSocket::send(Variant<JS::Handle<JS::Object>, JS::Ha
|
|||
m_websocket->send(string);
|
||||
return {};
|
||||
},
|
||||
[this](JS::Handle<JS::Object> const& buffer_source) -> ErrorOr<void> {
|
||||
[this](JS::Handle<WebIDL::BufferSource> const& buffer_source) -> ErrorOr<void> {
|
||||
// FIXME: While the spec doesn't say to do this, it's not observable except from potentially throwing OOM.
|
||||
// Can we avoid this copy?
|
||||
auto data_buffer = TRY(WebIDL::get_buffer_source_copy(*buffer_source.cell()));
|
||||
auto data_buffer = TRY(WebIDL::get_buffer_source_copy(*buffer_source->raw_object()));
|
||||
m_websocket->send(data_buffer, false);
|
||||
return {};
|
||||
},
|
||||
|
|
|
@ -61,7 +61,7 @@ public:
|
|||
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(Variant<JS::Handle<JS::Object>, JS::Handle<FileAPI::Blob>, String> const& data);
|
||||
WebIDL::ExceptionOr<void> send(Variant<JS::Handle<WebIDL::BufferSource>, JS::Handle<FileAPI::Blob>, String> const& data);
|
||||
|
||||
private:
|
||||
void on_open();
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
namespace Web::XHR {
|
||||
|
||||
// https://fetch.spec.whatwg.org/#typedefdef-xmlhttprequestbodyinit
|
||||
using DocumentOrXMLHttpRequestBodyInit = Variant<JS::Handle<Web::DOM::Document>, JS::Handle<Web::FileAPI::Blob>, JS::Handle<JS::Object>, JS::Handle<XHR::FormData>, JS::Handle<Web::URL::URLSearchParams>, AK::String>;
|
||||
using DocumentOrXMLHttpRequestBodyInit = Variant<JS::Handle<Web::DOM::Document>, JS::Handle<Web::FileAPI::Blob>, JS::Handle<WebIDL::BufferSource>, JS::Handle<XHR::FormData>, JS::Handle<Web::URL::URLSearchParams>, AK::String>;
|
||||
|
||||
class XMLHttpRequest final : public XMLHttpRequestEventTarget {
|
||||
WEB_PLATFORM_OBJECT(XMLHttpRequest, XMLHttpRequestEventTarget);
|
||||
|
|
Loading…
Add table
Reference in a new issue