mirror of
https://github.com/servo/servo.git
synced 2025-07-22 23:03:42 +01:00
Various CanGc fixes in components/script/dom (#33706)
* Propagate 'can_gc' in IFrame DOM code Signed-off-by: webbeef <me@webbeef.org> * Propagate 'can_gc' in HTML video and image elements Signed-off-by: webbeef <me@webbeef.org> * Propagate 'can_gc' in Blob and dependencies Signed-off-by: webbeef <me@webbeef.org> * Leftover can_gc fixes for HTMLMediaElement Signed-off-by: webbeef <me@webbeef.org> * Address comment Signed-off-by: webbeef <me@webbeef.org> --------- Signed-off-by: webbeef <me@webbeef.org>
This commit is contained in:
parent
7d931e673a
commit
d3c0785d64
14 changed files with 67 additions and 42 deletions
|
@ -39,7 +39,7 @@ use crate::dom::promisenativehandler::{Callback, PromiseNativeHandler};
|
||||||
use crate::dom::readablestream::{get_read_promise_bytes, get_read_promise_done, ReadableStream};
|
use crate::dom::readablestream::{get_read_promise_bytes, get_read_promise_done, ReadableStream};
|
||||||
use crate::dom::urlsearchparams::URLSearchParams;
|
use crate::dom::urlsearchparams::URLSearchParams;
|
||||||
use crate::realms::{enter_realm, AlreadyInRealm, InRealm};
|
use crate::realms::{enter_realm, AlreadyInRealm, InRealm};
|
||||||
use crate::script_runtime::JSContext;
|
use crate::script_runtime::{CanGc, JSContext};
|
||||||
use crate::task::TaskCanceller;
|
use crate::task::TaskCanceller;
|
||||||
use crate::task_source::networking::NetworkingTaskSource;
|
use crate::task_source::networking::NetworkingTaskSource;
|
||||||
use crate::task_source::{TaskSource, TaskSourceName};
|
use crate::task_source::{TaskSource, TaskSourceName};
|
||||||
|
@ -286,7 +286,7 @@ struct TransmitBodyPromiseHandler {
|
||||||
|
|
||||||
impl Callback for TransmitBodyPromiseHandler {
|
impl Callback for TransmitBodyPromiseHandler {
|
||||||
/// Step 5 of <https://fetch.spec.whatwg.org/#concept-request-transmit-body>
|
/// Step 5 of <https://fetch.spec.whatwg.org/#concept-request-transmit-body>
|
||||||
fn callback(&self, cx: JSContext, v: HandleValue, _realm: InRealm) {
|
fn callback(&self, cx: JSContext, v: HandleValue, _realm: InRealm, _can_gc: CanGc) {
|
||||||
let is_done = match get_read_promise_done(cx, &v) {
|
let is_done = match get_read_promise_done(cx, &v) {
|
||||||
Ok(is_done) => is_done,
|
Ok(is_done) => is_done,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
|
@ -335,7 +335,7 @@ struct TransmitBodyPromiseRejectionHandler {
|
||||||
|
|
||||||
impl Callback for TransmitBodyPromiseRejectionHandler {
|
impl Callback for TransmitBodyPromiseRejectionHandler {
|
||||||
/// <https://fetch.spec.whatwg.org/#concept-request-transmit-body>
|
/// <https://fetch.spec.whatwg.org/#concept-request-transmit-body>
|
||||||
fn callback(&self, _cx: JSContext, _v: HandleValue, _realm: InRealm) {
|
fn callback(&self, _cx: JSContext, _v: HandleValue, _realm: InRealm, _can_gc: CanGc) {
|
||||||
// Step 5.4, the "rejection" steps.
|
// Step 5.4, the "rejection" steps.
|
||||||
let _ = self.control_sender.send(BodyChunkRequest::Error);
|
let _ = self.control_sender.send(BodyChunkRequest::Error);
|
||||||
self.stream.stop_reading();
|
self.stream.stop_reading();
|
||||||
|
@ -605,7 +605,7 @@ impl Callback for ConsumeBodyPromiseRejectionHandler {
|
||||||
/// Continuing Step 4 of <https://fetch.spec.whatwg.org/#concept-body-consume-body>
|
/// Continuing Step 4 of <https://fetch.spec.whatwg.org/#concept-body-consume-body>
|
||||||
/// Step 3 of <https://fetch.spec.whatwg.org/#concept-read-all-bytes-from-readablestream>,
|
/// Step 3 of <https://fetch.spec.whatwg.org/#concept-read-all-bytes-from-readablestream>,
|
||||||
// the rejection steps.
|
// the rejection steps.
|
||||||
fn callback(&self, cx: JSContext, v: HandleValue, _realm: InRealm) {
|
fn callback(&self, cx: JSContext, v: HandleValue, _realm: InRealm, _can_gc: CanGc) {
|
||||||
self.result_promise.reject(cx, v);
|
self.result_promise.reject(cx, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -624,12 +624,12 @@ struct ConsumeBodyPromiseHandler {
|
||||||
|
|
||||||
impl ConsumeBodyPromiseHandler {
|
impl ConsumeBodyPromiseHandler {
|
||||||
/// Step 5 of <https://fetch.spec.whatwg.org/#concept-body-consume-body>
|
/// Step 5 of <https://fetch.spec.whatwg.org/#concept-body-consume-body>
|
||||||
fn resolve_result_promise(&self, cx: JSContext) {
|
fn resolve_result_promise(&self, cx: JSContext, can_gc: CanGc) {
|
||||||
let body_type = self.body_type.borrow_mut().take().unwrap();
|
let body_type = self.body_type.borrow_mut().take().unwrap();
|
||||||
let mime_type = self.mime_type.borrow_mut().take().unwrap();
|
let mime_type = self.mime_type.borrow_mut().take().unwrap();
|
||||||
let body = self.bytes.borrow_mut().take().unwrap();
|
let body = self.bytes.borrow_mut().take().unwrap();
|
||||||
|
|
||||||
let pkg_data_results = run_package_data_algorithm(cx, body, body_type, mime_type);
|
let pkg_data_results = run_package_data_algorithm(cx, body, body_type, mime_type, can_gc);
|
||||||
|
|
||||||
match pkg_data_results {
|
match pkg_data_results {
|
||||||
Ok(results) => {
|
Ok(results) => {
|
||||||
|
@ -650,7 +650,7 @@ impl ConsumeBodyPromiseHandler {
|
||||||
impl Callback for ConsumeBodyPromiseHandler {
|
impl Callback for ConsumeBodyPromiseHandler {
|
||||||
/// Continuing Step 4 of <https://fetch.spec.whatwg.org/#concept-body-consume-body>
|
/// Continuing Step 4 of <https://fetch.spec.whatwg.org/#concept-body-consume-body>
|
||||||
/// Step 3 of <https://fetch.spec.whatwg.org/#concept-read-all-bytes-from-readablestream>.
|
/// Step 3 of <https://fetch.spec.whatwg.org/#concept-read-all-bytes-from-readablestream>.
|
||||||
fn callback(&self, cx: JSContext, v: HandleValue, _realm: InRealm) {
|
fn callback(&self, cx: JSContext, v: HandleValue, _realm: InRealm, can_gc: CanGc) {
|
||||||
let stream = self
|
let stream = self
|
||||||
.stream
|
.stream
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
@ -667,7 +667,7 @@ impl Callback for ConsumeBodyPromiseHandler {
|
||||||
|
|
||||||
if is_done {
|
if is_done {
|
||||||
// When read is fulfilled with an object whose done property is true.
|
// When read is fulfilled with an object whose done property is true.
|
||||||
self.resolve_result_promise(cx);
|
self.resolve_result_promise(cx, can_gc);
|
||||||
} else {
|
} else {
|
||||||
let chunk = match get_read_promise_bytes(cx, &v) {
|
let chunk = match get_read_promise_bytes(cx, &v) {
|
||||||
Ok(chunk) => chunk,
|
Ok(chunk) => chunk,
|
||||||
|
@ -796,6 +796,7 @@ fn run_package_data_algorithm(
|
||||||
bytes: Vec<u8>,
|
bytes: Vec<u8>,
|
||||||
body_type: BodyType,
|
body_type: BodyType,
|
||||||
mime_type: Vec<u8>,
|
mime_type: Vec<u8>,
|
||||||
|
can_gc: CanGc,
|
||||||
) -> Fallible<FetchedData> {
|
) -> Fallible<FetchedData> {
|
||||||
let mime = &*mime_type;
|
let mime = &*mime_type;
|
||||||
let in_realm_proof = AlreadyInRealm::assert_for_cx(cx);
|
let in_realm_proof = AlreadyInRealm::assert_for_cx(cx);
|
||||||
|
@ -803,7 +804,7 @@ fn run_package_data_algorithm(
|
||||||
match body_type {
|
match body_type {
|
||||||
BodyType::Text => run_text_data_algorithm(bytes),
|
BodyType::Text => run_text_data_algorithm(bytes),
|
||||||
BodyType::Json => run_json_data_algorithm(cx, bytes),
|
BodyType::Json => run_json_data_algorithm(cx, bytes),
|
||||||
BodyType::Blob => run_blob_data_algorithm(&global, bytes, mime),
|
BodyType::Blob => run_blob_data_algorithm(&global, bytes, mime, can_gc),
|
||||||
BodyType::FormData => run_form_data_algorithm(&global, bytes, mime),
|
BodyType::FormData => run_form_data_algorithm(&global, bytes, mime),
|
||||||
BodyType::ArrayBuffer => run_array_buffer_data_algorithm(cx, bytes),
|
BodyType::ArrayBuffer => run_array_buffer_data_algorithm(cx, bytes),
|
||||||
}
|
}
|
||||||
|
@ -843,6 +844,7 @@ fn run_blob_data_algorithm(
|
||||||
root: &GlobalScope,
|
root: &GlobalScope,
|
||||||
bytes: Vec<u8>,
|
bytes: Vec<u8>,
|
||||||
mime: &[u8],
|
mime: &[u8],
|
||||||
|
can_gc: CanGc,
|
||||||
) -> Fallible<FetchedData> {
|
) -> Fallible<FetchedData> {
|
||||||
let mime_string = if let Ok(s) = String::from_utf8(mime.to_vec()) {
|
let mime_string = if let Ok(s) = String::from_utf8(mime.to_vec()) {
|
||||||
s
|
s
|
||||||
|
@ -852,6 +854,7 @@ fn run_blob_data_algorithm(
|
||||||
let blob = Blob::new(
|
let blob = Blob::new(
|
||||||
root,
|
root,
|
||||||
BlobImpl::new_from_bytes(bytes, normalize_type_string(&mime_string)),
|
BlobImpl::new_from_bytes(bytes, normalize_type_string(&mime_string)),
|
||||||
|
can_gc,
|
||||||
);
|
);
|
||||||
Ok(FetchedData::BlobData(blob))
|
Ok(FetchedData::BlobData(blob))
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,8 +41,8 @@ pub struct Blob {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Blob {
|
impl Blob {
|
||||||
pub fn new(global: &GlobalScope, blob_impl: BlobImpl) -> DomRoot<Blob> {
|
pub fn new(global: &GlobalScope, blob_impl: BlobImpl, can_gc: CanGc) -> DomRoot<Blob> {
|
||||||
Self::new_with_proto(global, None, blob_impl, CanGc::note())
|
Self::new_with_proto(global, None, blob_impl, can_gc)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_with_proto(
|
fn new_with_proto(
|
||||||
|
@ -162,7 +162,7 @@ impl Serializable for Blob {
|
||||||
*blob_impls = None;
|
*blob_impls = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let deserialized_blob = Blob::new(owner, blob_impl);
|
let deserialized_blob = Blob::new(owner, blob_impl, CanGc::note());
|
||||||
|
|
||||||
let blobs = blobs.get_or_insert_with(HashMap::new);
|
let blobs = blobs.get_or_insert_with(HashMap::new);
|
||||||
blobs.insert(storage_key, deserialized_blob);
|
blobs.insert(storage_key, deserialized_blob);
|
||||||
|
@ -251,7 +251,7 @@ impl BlobMethods for Blob {
|
||||||
normalize_type_string(content_type.unwrap_or(DOMString::from("")).as_ref());
|
normalize_type_string(content_type.unwrap_or(DOMString::from("")).as_ref());
|
||||||
let rel_pos = RelativePos::from_opts(start, end);
|
let rel_pos = RelativePos::from_opts(start, end);
|
||||||
let blob_impl = BlobImpl::new_sliced(rel_pos, self.blob_id, type_string);
|
let blob_impl = BlobImpl::new_sliced(rel_pos, self.blob_id, type_string);
|
||||||
Blob::new(&self.global(), blob_impl)
|
Blob::new(&self.global(), blob_impl, CanGc::note())
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://w3c.github.io/FileAPI/#text-method-algo
|
// https://w3c.github.io/FileAPI/#text-method-algo
|
||||||
|
|
|
@ -351,7 +351,7 @@ impl HTMLIFrameElement {
|
||||||
} else {
|
} else {
|
||||||
HistoryEntryReplacement::Disabled
|
HistoryEntryReplacement::Disabled
|
||||||
};
|
};
|
||||||
self.navigate_or_reload_child_browsing_context(load_data, replace, CanGc::note());
|
self.navigate_or_reload_child_browsing_context(load_data, replace, can_gc);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_nested_browsing_context(&self, can_gc: CanGc) {
|
fn create_nested_browsing_context(&self, can_gc: CanGc) {
|
||||||
|
|
|
@ -1894,8 +1894,8 @@ impl ImageCacheListener for HTMLImageElement {
|
||||||
self.generation.get()
|
self.generation.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_image_response(&self, response: ImageResponse) {
|
fn process_image_response(&self, response: ImageResponse, can_gc: CanGc) {
|
||||||
self.process_image_response(response, CanGc::note());
|
self.process_image_response(response, can_gc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -923,9 +923,9 @@ impl HTMLMediaElement {
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#concept-media-load-resource
|
// https://html.spec.whatwg.org/multipage/#concept-media-load-resource
|
||||||
fn resource_fetch_algorithm(&self, resource: Resource, can_gc: CanGc) {
|
fn resource_fetch_algorithm(&self, resource: Resource, can_gc: CanGc) {
|
||||||
if let Err(e) = self.setup_media_player(&resource, CanGc::note()) {
|
if let Err(e) = self.setup_media_player(&resource, can_gc) {
|
||||||
eprintln!("Setup media player error {:?}", e);
|
eprintln!("Setup media player error {:?}", e);
|
||||||
self.queue_dedicated_media_source_failure_steps(CanGc::note());
|
self.queue_dedicated_media_source_failure_steps(can_gc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1001,7 +1001,7 @@ impl HTMLMediaElement {
|
||||||
.set_stream(&track.id(), pos == tracks.len() - 1)
|
.set_stream(&track.id(), pos == tracks.len() - 1)
|
||||||
.is_err()
|
.is_err()
|
||||||
{
|
{
|
||||||
self.queue_dedicated_media_source_failure_steps(CanGc::note());
|
self.queue_dedicated_media_source_failure_steps(can_gc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1188,7 +1188,7 @@ impl HTMLMediaElement {
|
||||||
self.autoplaying.set(true);
|
self.autoplaying.set(true);
|
||||||
|
|
||||||
// Step 9.
|
// Step 9.
|
||||||
self.invoke_resource_selection_algorithm(CanGc::note());
|
self.invoke_resource_selection_algorithm(can_gc);
|
||||||
|
|
||||||
// Step 10.
|
// Step 10.
|
||||||
// FIXME(nox): Stop playback of any previously running media resource.
|
// FIXME(nox): Stop playback of any previously running media resource.
|
||||||
|
|
|
@ -174,7 +174,7 @@ impl HTMLVideoElement {
|
||||||
url,
|
url,
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
self.process_image_response(ImageResponse::Loaded(image, url));
|
self.process_image_response(ImageResponse::Loaded(image, url), can_gc);
|
||||||
},
|
},
|
||||||
ImageCacheResult::ReadyForRequest(id) => {
|
ImageCacheResult::ReadyForRequest(id) => {
|
||||||
self.do_fetch_poster_frame(poster_url, id, cancel_receiver, can_gc)
|
self.do_fetch_poster_frame(poster_url, id, cancel_receiver, can_gc)
|
||||||
|
@ -293,18 +293,18 @@ impl ImageCacheListener for HTMLVideoElement {
|
||||||
self.generation_id.get()
|
self.generation_id.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_image_response(&self, response: ImageResponse) {
|
fn process_image_response(&self, response: ImageResponse, can_gc: CanGc) {
|
||||||
match response {
|
match response {
|
||||||
ImageResponse::Loaded(image, url) => {
|
ImageResponse::Loaded(image, url) => {
|
||||||
debug!("Loaded poster image for video element: {:?}", url);
|
debug!("Loaded poster image for video element: {:?}", url);
|
||||||
self.htmlmediaelement.process_poster_image_loaded(image);
|
self.htmlmediaelement.process_poster_image_loaded(image);
|
||||||
LoadBlocker::terminate(&mut self.load_blocker.borrow_mut(), CanGc::note());
|
LoadBlocker::terminate(&mut self.load_blocker.borrow_mut(), can_gc);
|
||||||
},
|
},
|
||||||
ImageResponse::MetadataLoaded(..) => {},
|
ImageResponse::MetadataLoaded(..) => {},
|
||||||
// The image cache may have loaded a placeholder for an invalid poster url
|
// The image cache may have loaded a placeholder for an invalid poster url
|
||||||
ImageResponse::PlaceholderLoaded(..) | ImageResponse::None => {
|
ImageResponse::PlaceholderLoaded(..) | ImageResponse::None => {
|
||||||
// A failed load should unblock the document load.
|
// A failed load should unblock the document load.
|
||||||
LoadBlocker::terminate(&mut self.load_blocker.borrow_mut(), CanGc::note());
|
LoadBlocker::terminate(&mut self.load_blocker.borrow_mut(), can_gc);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,10 +12,10 @@ use crate::dom::bindings::root::DomRoot;
|
||||||
use crate::dom::bindings::trace::JSTraceable;
|
use crate::dom::bindings::trace::JSTraceable;
|
||||||
use crate::dom::globalscope::GlobalScope;
|
use crate::dom::globalscope::GlobalScope;
|
||||||
use crate::realms::InRealm;
|
use crate::realms::InRealm;
|
||||||
use crate::script_runtime::JSContext as SafeJSContext;
|
use crate::script_runtime::{CanGc, JSContext as SafeJSContext};
|
||||||
|
|
||||||
pub trait Callback: JSTraceable + MallocSizeOf {
|
pub trait Callback: JSTraceable + MallocSizeOf {
|
||||||
fn callback(&self, cx: SafeJSContext, v: HandleValue, realm: InRealm);
|
fn callback(&self, cx: SafeJSContext, v: HandleValue, realm: InRealm, can_gc: CanGc);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
|
@ -50,7 +50,7 @@ impl PromiseNativeHandler {
|
||||||
) {
|
) {
|
||||||
let cx = unsafe { SafeJSContext::from_ptr(cx) };
|
let cx = unsafe { SafeJSContext::from_ptr(cx) };
|
||||||
if let Some(ref callback) = *callback {
|
if let Some(ref callback) = *callback {
|
||||||
callback.callback(cx, v, realm)
|
callback.callback(cx, v, realm, CanGc::note())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ use crate::dom::messageevent::MessageEvent;
|
||||||
use crate::dom::rtcerror::RTCError;
|
use crate::dom::rtcerror::RTCError;
|
||||||
use crate::dom::rtcerrorevent::RTCErrorEvent;
|
use crate::dom::rtcerrorevent::RTCErrorEvent;
|
||||||
use crate::dom::rtcpeerconnection::RTCPeerConnection;
|
use crate::dom::rtcpeerconnection::RTCPeerConnection;
|
||||||
|
use crate::script_runtime::CanGc;
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
pub struct RTCDataChannel {
|
pub struct RTCDataChannel {
|
||||||
|
@ -154,7 +155,7 @@ impl RTCDataChannel {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
pub fn on_message(&self, channel_message: DataChannelMessage) {
|
pub fn on_message(&self, channel_message: DataChannelMessage, can_gc: CanGc) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let global = self.global();
|
let global = self.global();
|
||||||
let cx = GlobalScope::get_cx();
|
let cx = GlobalScope::get_cx();
|
||||||
|
@ -167,8 +168,11 @@ impl RTCDataChannel {
|
||||||
},
|
},
|
||||||
DataChannelMessage::Binary(data) => match &**self.binary_type.borrow() {
|
DataChannelMessage::Binary(data) => match &**self.binary_type.borrow() {
|
||||||
"blob" => {
|
"blob" => {
|
||||||
let blob =
|
let blob = Blob::new(
|
||||||
Blob::new(&global, BlobImpl::new_from_bytes(data, "".to_owned()));
|
&global,
|
||||||
|
BlobImpl::new_from_bytes(data, "".to_owned()),
|
||||||
|
can_gc,
|
||||||
|
);
|
||||||
blob.to_jsval(*cx, message.handle_mut());
|
blob.to_jsval(*cx, message.handle_mut());
|
||||||
},
|
},
|
||||||
"arraybuffer" => {
|
"arraybuffer" => {
|
||||||
|
|
|
@ -165,7 +165,7 @@ impl WebRtcSignaller for RTCSignaller {
|
||||||
let this = this.root();
|
let this = this.root();
|
||||||
let global = this.global();
|
let global = this.global();
|
||||||
let _ac = enter_realm(&*global);
|
let _ac = enter_realm(&*global);
|
||||||
this.on_data_channel_event(channel, event);
|
this.on_data_channel_event(channel, event, CanGc::note());
|
||||||
}),
|
}),
|
||||||
&self.canceller,
|
&self.canceller,
|
||||||
);
|
);
|
||||||
|
@ -292,7 +292,12 @@ impl RTCPeerConnection {
|
||||||
event.upcast::<Event>().fire(self.upcast());
|
event.upcast::<Event>().fire(self.upcast());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_data_channel_event(&self, channel_id: DataChannelId, event: DataChannelEvent) {
|
fn on_data_channel_event(
|
||||||
|
&self,
|
||||||
|
channel_id: DataChannelId,
|
||||||
|
event: DataChannelEvent,
|
||||||
|
can_gc: CanGc,
|
||||||
|
) {
|
||||||
if self.closed.get() {
|
if self.closed.get() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -331,7 +336,7 @@ impl RTCPeerConnection {
|
||||||
DataChannelEvent::Open => channel.on_open(),
|
DataChannelEvent::Open => channel.on_open(),
|
||||||
DataChannelEvent::Close => channel.on_close(),
|
DataChannelEvent::Close => channel.on_close(),
|
||||||
DataChannelEvent::Error(error) => channel.on_error(error),
|
DataChannelEvent::Error(error) => channel.on_error(error),
|
||||||
DataChannelEvent::OnMessage(message) => channel.on_message(message),
|
DataChannelEvent::OnMessage(message) => channel.on_message(message, can_gc),
|
||||||
DataChannelEvent::StateChange(state) => channel.on_state_change(state),
|
DataChannelEvent::StateChange(state) => channel.on_state_change(state),
|
||||||
DataChannelEvent::NewChannel => unreachable!(),
|
DataChannelEvent::NewChannel => unreachable!(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -182,6 +182,7 @@ impl TestBindingMethods for TestBinding {
|
||||||
Blob::new(
|
Blob::new(
|
||||||
&self.global(),
|
&self.global(),
|
||||||
BlobImpl::new_from_bytes(vec![], "".to_owned()),
|
BlobImpl::new_from_bytes(vec![], "".to_owned()),
|
||||||
|
CanGc::note(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
fn SetInterfaceAttribute(&self, _: &Blob) {}
|
fn SetInterfaceAttribute(&self, _: &Blob) {}
|
||||||
|
@ -327,6 +328,7 @@ impl TestBindingMethods for TestBinding {
|
||||||
Some(Blob::new(
|
Some(Blob::new(
|
||||||
&self.global(),
|
&self.global(),
|
||||||
BlobImpl::new_from_bytes(vec![], "".to_owned()),
|
BlobImpl::new_from_bytes(vec![], "".to_owned()),
|
||||||
|
CanGc::note(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
fn SetInterfaceAttributeNullable(&self, _: Option<&Blob>) {}
|
fn SetInterfaceAttributeNullable(&self, _: Option<&Blob>) {}
|
||||||
|
@ -421,6 +423,7 @@ impl TestBindingMethods for TestBinding {
|
||||||
Blob::new(
|
Blob::new(
|
||||||
&self.global(),
|
&self.global(),
|
||||||
BlobImpl::new_from_bytes(vec![], "".to_owned()),
|
BlobImpl::new_from_bytes(vec![], "".to_owned()),
|
||||||
|
CanGc::note(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
fn ReceiveAny(&self, _: SafeJSContext) -> JSVal {
|
fn ReceiveAny(&self, _: SafeJSContext) -> JSVal {
|
||||||
|
@ -469,6 +472,7 @@ impl TestBindingMethods for TestBinding {
|
||||||
vec![Blob::new(
|
vec![Blob::new(
|
||||||
&self.global(),
|
&self.global(),
|
||||||
BlobImpl::new_from_bytes(vec![], "".to_owned()),
|
BlobImpl::new_from_bytes(vec![], "".to_owned()),
|
||||||
|
CanGc::note(),
|
||||||
)]
|
)]
|
||||||
}
|
}
|
||||||
fn ReceiveUnionIdentity(
|
fn ReceiveUnionIdentity(
|
||||||
|
@ -534,6 +538,7 @@ impl TestBindingMethods for TestBinding {
|
||||||
Some(Blob::new(
|
Some(Blob::new(
|
||||||
&self.global(),
|
&self.global(),
|
||||||
BlobImpl::new_from_bytes(vec![], "".to_owned()),
|
BlobImpl::new_from_bytes(vec![], "".to_owned()),
|
||||||
|
CanGc::note(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
fn ReceiveNullableObject(&self, cx: SafeJSContext) -> Option<NonNull<JSObject>> {
|
fn ReceiveNullableObject(&self, cx: SafeJSContext) -> Option<NonNull<JSObject>> {
|
||||||
|
@ -1030,7 +1035,7 @@ impl TestBindingMethods for TestBinding {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Callback for SimpleHandler {
|
impl Callback for SimpleHandler {
|
||||||
fn callback(&self, cx: SafeJSContext, v: HandleValue, realm: InRealm) {
|
fn callback(&self, cx: SafeJSContext, v: HandleValue, realm: InRealm, _can_gc: CanGc) {
|
||||||
let global = GlobalScope::from_safe_context(cx, realm);
|
let global = GlobalScope::from_safe_context(cx, realm);
|
||||||
let _ = self.handler.Call_(&*global, v, ExceptionHandling::Report);
|
let _ = self.handler.Call_(&*global, v, ExceptionHandling::Report);
|
||||||
}
|
}
|
||||||
|
|
|
@ -575,8 +575,11 @@ impl TaskOnce for MessageReceivedTask {
|
||||||
MessageData::Text(text) => text.to_jsval(*cx, message.handle_mut()),
|
MessageData::Text(text) => text.to_jsval(*cx, message.handle_mut()),
|
||||||
MessageData::Binary(data) => match ws.binary_type.get() {
|
MessageData::Binary(data) => match ws.binary_type.get() {
|
||||||
BinaryType::Blob => {
|
BinaryType::Blob => {
|
||||||
let blob =
|
let blob = Blob::new(
|
||||||
Blob::new(&global, BlobImpl::new_from_bytes(data, "".to_owned()));
|
&global,
|
||||||
|
BlobImpl::new_from_bytes(data, "".to_owned()),
|
||||||
|
CanGc::note(),
|
||||||
|
);
|
||||||
blob.to_jsval(*cx, message.handle_mut());
|
blob.to_jsval(*cx, message.handle_mut());
|
||||||
},
|
},
|
||||||
BinaryType::Arraybuffer => {
|
BinaryType::Arraybuffer => {
|
||||||
|
|
|
@ -972,7 +972,7 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
|
||||||
self.json_response(cx).to_jsval(*cx, rval.handle_mut());
|
self.json_response(cx).to_jsval(*cx, rval.handle_mut());
|
||||||
},
|
},
|
||||||
XMLHttpRequestResponseType::Blob => unsafe {
|
XMLHttpRequestResponseType::Blob => unsafe {
|
||||||
self.blob_response().to_jsval(*cx, rval.handle_mut());
|
self.blob_response(can_gc).to_jsval(*cx, rval.handle_mut());
|
||||||
},
|
},
|
||||||
XMLHttpRequestResponseType::Arraybuffer => match self.arraybuffer_response(cx) {
|
XMLHttpRequestResponseType::Arraybuffer => match self.arraybuffer_response(cx) {
|
||||||
Some(array_buffer) => unsafe { array_buffer.to_jsval(*cx, rval.handle_mut()) },
|
Some(array_buffer) => unsafe { array_buffer.to_jsval(*cx, rval.handle_mut()) },
|
||||||
|
@ -1326,7 +1326,7 @@ impl XMLHttpRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://xhr.spec.whatwg.org/#blob-response>
|
/// <https://xhr.spec.whatwg.org/#blob-response>
|
||||||
fn blob_response(&self) -> DomRoot<Blob> {
|
fn blob_response(&self, can_gc: CanGc) -> DomRoot<Blob> {
|
||||||
// Step 1
|
// Step 1
|
||||||
if let Some(response) = self.response_blob.get() {
|
if let Some(response) = self.response_blob.get() {
|
||||||
return response;
|
return response;
|
||||||
|
@ -1340,7 +1340,11 @@ impl XMLHttpRequest {
|
||||||
|
|
||||||
// Step 3, 4
|
// Step 3, 4
|
||||||
let bytes = self.response.borrow().to_vec();
|
let bytes = self.response.borrow().to_vec();
|
||||||
let blob = Blob::new(&self.global(), BlobImpl::new_from_bytes(bytes, mime));
|
let blob = Blob::new(
|
||||||
|
&self.global(),
|
||||||
|
BlobImpl::new_from_bytes(bytes, mime),
|
||||||
|
can_gc,
|
||||||
|
);
|
||||||
self.response_blob.set(Some(&blob));
|
self.response_blob.set(Some(&blob));
|
||||||
blob
|
blob
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,11 +11,12 @@ use crate::dom::bindings::conversions::DerivedFrom;
|
||||||
use crate::dom::bindings::refcounted::Trusted;
|
use crate::dom::bindings::refcounted::Trusted;
|
||||||
use crate::dom::bindings::reflector::DomObject;
|
use crate::dom::bindings::reflector::DomObject;
|
||||||
use crate::dom::node::{window_from_node, Node};
|
use crate::dom::node::{window_from_node, Node};
|
||||||
|
use crate::script_runtime::CanGc;
|
||||||
use crate::task_source::TaskSource;
|
use crate::task_source::TaskSource;
|
||||||
|
|
||||||
pub trait ImageCacheListener {
|
pub trait ImageCacheListener {
|
||||||
fn generation_id(&self) -> u32;
|
fn generation_id(&self) -> u32;
|
||||||
fn process_image_response(&self, response: ImageResponse);
|
fn process_image_response(&self, response: ImageResponse, can_gc: CanGc);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_cache_listener_for_element<
|
pub fn generate_cache_listener_for_element<
|
||||||
|
@ -42,7 +43,7 @@ pub fn generate_cache_listener_for_element<
|
||||||
let element = element.root();
|
let element = element.root();
|
||||||
// Ignore any image response for a previous request that has been discarded.
|
// Ignore any image response for a previous request that has been discarded.
|
||||||
if generation == element.generation_id() {
|
if generation == element.generation_id() {
|
||||||
element.process_image_response(image);
|
element.process_image_response(image, CanGc::note());
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
&canceller,
|
&canceller,
|
||||||
|
|
|
@ -866,7 +866,7 @@ impl ModuleHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Callback for ModuleHandler {
|
impl Callback for ModuleHandler {
|
||||||
fn callback(&self, _cx: SafeJSContext, _v: HandleValue, _realm: InRealm) {
|
fn callback(&self, _cx: SafeJSContext, _v: HandleValue, _realm: InRealm, _can_gc: CanGc) {
|
||||||
let task = self.task.borrow_mut().take().unwrap();
|
let task = self.task.borrow_mut().take().unwrap();
|
||||||
task.run_box();
|
task.run_box();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue