script: Implement Blob::bytes() (#35151)

* script: Implement Blob.bytes()

Signed-off-by: yoseio <98276492+yoseio@users.noreply.github.com>

* improve read_all_bytes

Signed-off-by: yoseio <98276492+yoseio@users.noreply.github.com>

* fix read_all_bytes

Signed-off-by: yoseio <98276492+yoseio@users.noreply.github.com>

* fix bug

Signed-off-by: yoseio <98276492+yoseio@users.noreply.github.com>

* something went wrong

Signed-off-by: Kousuke Takaki <98276492+yoseio@users.noreply.github.com>

* fix read loop

Signed-off-by: gterzian <2792687+gterzian@users.noreply.github.com>

* add use of can_gc to promise code following rebase

Signed-off-by: gterzian <2792687+gterzian@users.noreply.github.com>

* fix rooting of fulfillment handler

Signed-off-by: gterzian <2792687+gterzian@users.noreply.github.com>

* Update test expectations

Signed-off-by: Taym Haddadi <haddadi.taym@gmail.com>

* use dom for reader in read loop fulfillment handler

Signed-off-by: gterzian <2792687+gterzian@users.noreply.github.com>

* use the global of the reader in read loop fulfillment handler

Signed-off-by: gterzian <2792687+gterzian@users.noreply.github.com>

* remove FAIl expectations for blob methods in detached iframe

Signed-off-by: gterzian <2792687+gterzian@users.noreply.github.com>

---------

Signed-off-by: yoseio <98276492+yoseio@users.noreply.github.com>
Signed-off-by: Kousuke Takaki <98276492+yoseio@users.noreply.github.com>
Signed-off-by: gterzian <2792687+gterzian@users.noreply.github.com>
Signed-off-by: Taym Haddadi <haddadi.taym@gmail.com>
Co-authored-by: gterzian <2792687+gterzian@users.noreply.github.com>
Co-authored-by: Taym Haddadi <haddadi.taym@gmail.com>
This commit is contained in:
Kousuke Takaki 2025-02-28 04:25:27 +09:00 committed by GitHub
parent a1ecce5502
commit 8a3f62933b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 205 additions and 80 deletions

View file

@ -4,17 +4,21 @@
use std::collections::HashMap;
use std::num::NonZeroU32;
use std::ptr;
use std::rc::Rc;
use base::id::{BlobId, BlobIndex, PipelineNamespaceId};
use dom_struct::dom_struct;
use encoding_rs::UTF_8;
use js::jsapi::JSObject;
use js::rust::HandleObject;
use js::typedarray::Uint8;
use net_traits::filemanager_thread::RelativePos;
use script_traits::serializable::BlobImpl;
use uuid::Uuid;
use crate::body::{run_array_buffer_data_algorithm, FetchedData};
use crate::dom::bindings::buffer_source::create_buffer_source;
use crate::dom::bindings::codegen::Bindings::BlobBinding;
use crate::dom::bindings::codegen::Bindings::BlobBinding::BlobMethods;
use crate::dom::bindings::codegen::UnionTypes::ArrayBufferOrArrayBufferViewOrBlobOrString;
@ -297,6 +301,46 @@ impl BlobMethods<crate::DomTypeHolder> for Blob {
);
p
}
/// <https://w3c.github.io/FileAPI/#dom-blob-bytes>
fn Bytes(&self, in_realm: InRealm, can_gc: CanGc) -> Rc<Promise> {
let cx = GlobalScope::get_cx();
let global = GlobalScope::from_safe_context(cx, in_realm);
let p = Promise::new_in_current_realm(in_realm, can_gc);
// 1. Let stream be the result of calling get stream on this.
let stream = self.get_stream(can_gc);
// 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.
let reader = match stream.and_then(|s| s.acquire_default_reader(can_gc)) {
Ok(r) => r,
Err(e) => {
p.reject_error(e, can_gc);
return p;
},
};
// 3. Let promise be the result of reading all bytes from stream with reader.
let p_success = p.clone();
let p_failure = p.clone();
reader.read_all_bytes(
cx,
&global,
Rc::new(move |bytes| {
rooted!(in(*cx) let mut js_object = ptr::null_mut::<JSObject>());
let arr = create_buffer_source::<Uint8>(cx, bytes, js_object.handle_mut(), can_gc)
.expect("Converting input to uint8 array should never fail");
p_success.resolve_native(&arr, can_gc);
}),
Rc::new(move |cx, v| {
p_failure.reject(cx, v, can_gc);
}),
in_realm,
can_gc,
);
p
}
}
/// Get the normalized, MIME-parsable type string