mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-25 09:00:22 +00:00
LibWeb: Implement Blob::bytes()
Implements https://w3c.github.io/FileAPI/#dom-blob-bytes.
This commit is contained in:
parent
1ce9bbdd6d
commit
c5f1e47883
Notes:
github-actions[bot]
2024-07-26 08:22:29 +00:00
Author: https://github.com/kemzeb Commit: https://github.com/LadybirdBrowser/ladybird/commit/c5f1e478838 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/802 Reviewed-by: https://github.com/kennethmyhra ✅ Reviewed-by: https://github.com/shannonbooth
12 changed files with 52 additions and 10 deletions
|
@ -0,0 +1 @@
|
|||
PASS
|
|
@ -0,0 +1,13 @@
|
|||
<script src="../include.js"></script>
|
||||
<script>
|
||||
asyncTest(async (done) => {
|
||||
const blob = new Blob(["This is some data to be read! 🦬"]);
|
||||
const uint8Array = await blob.bytes();
|
||||
const string = new TextDecoder().decode(uint8Array);
|
||||
if (string === "This is some data to be read! 🦬")
|
||||
println("PASS");
|
||||
else
|
||||
println("FAIL");
|
||||
done();
|
||||
});
|
||||
</script>
|
|
@ -111,7 +111,7 @@ static void write_blobs_and_option_to_clipboard(JS::Realm& realm, ReadonlySpan<J
|
|||
|
||||
// 3. Let payload be the result of UTF-8 decoding item’s underlying byte sequence.
|
||||
auto decoder = TextCodec::decoder_for("UTF-8"sv);
|
||||
auto payload = MUST(TextCodec::convert_input_to_utf8_using_given_decoder_unless_there_is_a_byte_order_mark(*decoder, item->bytes()));
|
||||
auto payload = MUST(TextCodec::convert_input_to_utf8_using_given_decoder_unless_there_is_a_byte_order_mark(*decoder, item->raw_bytes()));
|
||||
|
||||
// 4. Insert payload and presentationStyle into the system clipboard using formatString as the native clipboard format.
|
||||
window.page().client().page_did_insert_clipboard_entry(move(payload), move(presentation_style), move(format_string));
|
||||
|
|
|
@ -611,7 +611,7 @@ URL::URL parse(StringView input, Optional<URL::URL> const& base_url)
|
|||
if (blob_url_entry.has_value()) {
|
||||
url.set_blob_url_entry(URL::BlobURLEntry {
|
||||
.type = blob_url_entry->object->type(),
|
||||
.byte_buffer = MUST(ByteBuffer::copy(blob_url_entry->object->bytes())),
|
||||
.byte_buffer = MUST(ByteBuffer::copy(blob_url_entry->object->raw_bytes())),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -841,7 +841,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> scheme_fetch(JS::Realm& r
|
|||
// 8. If request’s header list does not contain `Range`:
|
||||
if (!request->header_list()->contains("Range"sv.bytes())) {
|
||||
// 1. Let bodyWithType be the result of safely extracting blob.
|
||||
auto body_with_type = TRY(safely_extract_body(realm, blob->bytes()));
|
||||
auto body_with_type = TRY(safely_extract_body(realm, blob->raw_bytes()));
|
||||
|
||||
// 2. Set response’s status message to `OK`.
|
||||
response->set_status_message(MUST(ByteBuffer::copy("OK"sv.bytes())));
|
||||
|
@ -2150,7 +2150,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> nonstandard_resource_load
|
|||
return {};
|
||||
},
|
||||
[&](JS::Handle<FileAPI::Blob> const& blob_handle) -> WebIDL::ExceptionOr<void> {
|
||||
load_request.set_body(TRY_OR_THROW_OOM(vm, ByteBuffer::copy(blob_handle->bytes())));
|
||||
load_request.set_body(TRY_OR_THROW_OOM(vm, ByteBuffer::copy(blob_handle->raw_bytes())));
|
||||
return {};
|
||||
},
|
||||
[](Empty) -> WebIDL::ExceptionOr<void> {
|
||||
|
|
|
@ -96,7 +96,7 @@ void Body::fully_read(JS::Realm& realm, Web::Fetch::Infrastructure::Body::Proces
|
|||
error_steps(WebIDL::UnknownError::create(realm, "Out-of-memory"_fly_string));
|
||||
},
|
||||
[&](JS::Handle<FileAPI::Blob> const& blob) {
|
||||
if (auto result = success_steps(blob->bytes()); result.is_error())
|
||||
if (auto result = success_steps(blob->raw_bytes()); result.is_error())
|
||||
error_steps(WebIDL::UnknownError::create(realm, "Out-of-memory"_fly_string));
|
||||
},
|
||||
[&](Empty) {
|
||||
|
|
|
@ -107,7 +107,7 @@ ErrorOr<ByteBuffer> process_blob_parts(Vector<BlobPart> const& blob_parts, Optio
|
|||
},
|
||||
// 3. If element is a Blob, append the bytes it represents to bytes.
|
||||
[&](JS::Handle<Blob> const& blob) -> ErrorOr<void> {
|
||||
return bytes.try_append(blob->bytes());
|
||||
return bytes.try_append(blob->raw_bytes());
|
||||
}));
|
||||
}
|
||||
// 3. Return bytes.
|
||||
|
@ -413,4 +413,30 @@ JS::NonnullGCPtr<JS::Promise> Blob::array_buffer()
|
|||
}));
|
||||
}
|
||||
|
||||
// https://w3c.github.io/FileAPI/#dom-blob-bytes
|
||||
JS::NonnullGCPtr<JS::Promise> Blob::bytes()
|
||||
{
|
||||
auto& realm = this->realm();
|
||||
|
||||
// 1. Let stream be the result of calling get stream on this.
|
||||
auto stream = get_stream();
|
||||
|
||||
// 2. Let reader be the result of getting a reader from stream. If that threw an exception, return a new promise rejected with that exception.
|
||||
auto reader_or_exception = acquire_readable_stream_default_reader(*stream);
|
||||
if (reader_or_exception.is_exception())
|
||||
return WebIDL::create_rejected_promise_from_exception(realm, reader_or_exception.release_error());
|
||||
auto reader = reader_or_exception.release_value();
|
||||
|
||||
// 3. Let promise be the result of reading all bytes from stream with reader.
|
||||
auto promise = reader->read_all_bytes_deprecated();
|
||||
|
||||
// 4. Return the result of transforming promise by a fulfillment handler that returns a new Uint8Array wrapping an ArrayBuffer containing its first argument.
|
||||
return WebIDL::upon_fulfillment(*promise, JS::create_heap_function(heap(), [&realm](JS::Value first_argument) -> WebIDL::ExceptionOr<JS::Value> {
|
||||
auto& object = first_argument.as_object();
|
||||
VERIFY(is<JS::ArrayBuffer>(object));
|
||||
auto& array_buffer = static_cast<JS::ArrayBuffer&>(object);
|
||||
return JS::Uint8Array::create(realm, array_buffer.byte_length(), array_buffer);
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -50,8 +50,9 @@ public:
|
|||
JS::NonnullGCPtr<Streams::ReadableStream> stream();
|
||||
JS::NonnullGCPtr<JS::Promise> text();
|
||||
JS::NonnullGCPtr<JS::Promise> array_buffer();
|
||||
JS::NonnullGCPtr<JS::Promise> bytes();
|
||||
|
||||
ReadonlyBytes bytes() const { return m_byte_buffer.bytes(); }
|
||||
ReadonlyBytes raw_bytes() const { return m_byte_buffer.bytes(); }
|
||||
|
||||
JS::NonnullGCPtr<Streams::ReadableStream> get_stream();
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ interface Blob {
|
|||
[NewObject] ReadableStream stream();
|
||||
[NewObject] Promise<USVString> text();
|
||||
[NewObject] Promise<ArrayBuffer> arrayBuffer();
|
||||
[NewObject] Promise<Uint8Array> bytes();
|
||||
};
|
||||
|
||||
enum EndingType { "transparent", "native" };
|
||||
|
|
|
@ -277,7 +277,7 @@ ErrorOr<SerializedFormData> serialize_to_multipart_form_data(Vector<XHR::FormDat
|
|||
TRY(builder.try_append(TRY(String::formatted("Content-Disposition: form-data; name=\"{}\"; filename=\"{}\"\r\n", escaped_name, escaped_filename))));
|
||||
// The parts of the generated multipart/form-data resource that correspond to file fields must have a `Content-Type` header specified.
|
||||
TRY(builder.try_append(TRY(String::formatted("Content-Type: {}\r\n\r\n", file->type()))));
|
||||
TRY(builder.try_append(file->bytes()));
|
||||
TRY(builder.try_append(file->raw_bytes()));
|
||||
TRY(builder.try_append("\r\n"sv));
|
||||
return {};
|
||||
},
|
||||
|
|
|
@ -210,7 +210,7 @@ JS::NonnullGCPtr<JS::Promise> WindowOrWorkerGlobalScopeMixin::create_image_bitma
|
|||
// 1. Let imageData be the result of reading image's data. If an error occurs during reading of the
|
||||
// object, then reject p with an "InvalidStateError" DOMException and abort these steps.
|
||||
// FIXME: I guess this is always fine for us as the data is already read.
|
||||
auto const image_data = blob->bytes();
|
||||
auto const image_data = blob->raw_bytes();
|
||||
|
||||
// FIXME:
|
||||
// 2. Apply the image sniffing rules to determine the file format of imageData, with MIME type of
|
||||
|
|
|
@ -233,7 +233,7 @@ WebIDL::ExceptionOr<void> WebSocket::send(Variant<JS::Handle<WebIDL::BufferSourc
|
|||
return {};
|
||||
},
|
||||
[this](JS::Handle<FileAPI::Blob> const& blob) -> ErrorOr<void> {
|
||||
auto byte_buffer = TRY(ByteBuffer::copy(blob->bytes()));
|
||||
auto byte_buffer = TRY(ByteBuffer::copy(blob->raw_bytes()));
|
||||
m_websocket->send(byte_buffer, false);
|
||||
return {};
|
||||
}));
|
||||
|
|
Loading…
Reference in a new issue