CanGc fixes in several files (#33958)

* few cangc fixes

Signed-off-by: L Ashwin B <lashwinib@gmail.com>

* few cangc fixes

Signed-off-by: L Ashwin B <lashwinib@gmail.com>

---------

Signed-off-by: L Ashwin B <lashwinib@gmail.com>
This commit is contained in:
chickenleaf 2024-10-22 03:02:22 +05:30 committed by GitHub
parent 1bf68567b8
commit ebfea9b352
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 170 additions and 129 deletions

View file

@ -121,6 +121,10 @@ DOMInterfaces = {
'weakReferenceable': True,
},
'FileReader': {
'canGc': ['Abort'],
},
'GPU': {
'inRealms': ['RequestAdapter'],
},
@ -164,11 +168,11 @@ DOMInterfaces = {
},
'HTMLFormElement': {
'canGc': ['RequestSubmit', 'ReportValidity'],
'canGc': ['RequestSubmit', 'ReportValidity', 'Submit'],
},
'HTMLInputElement': {
'canGc': ['ReportValidity'],
'canGc': ['ReportValidity', 'SelectFiles'],
},
'HTMLMediaElement': {
@ -276,7 +280,7 @@ DOMInterfaces = {
},
'Response': {
'canGc': ['Error', 'Redirect', 'Clone', 'Text', 'Blob', 'FormData', 'Json', 'ArrayBuffer'],
'canGc': ['Error', 'Redirect', 'Clone', 'Text', 'Blob', 'FormData', 'Json', 'ArrayBuffer', 'Headers'],
},
'Request': {
@ -342,7 +346,7 @@ DOMInterfaces = {
},
'XMLHttpRequest': {
'canGc': ['Abort', 'GetResponseXML', 'Response'],
'canGc': ['Abort', 'GetResponseXML', 'Response', 'Send'],
},
'XRBoundedReferenceSpace': {

View file

@ -46,8 +46,9 @@ impl File {
blob_impl: BlobImpl,
name: DOMString,
modified: Option<SystemTime>,
can_gc: CanGc,
) -> DomRoot<File> {
Self::new_with_proto(global, None, blob_impl, name, modified, CanGc::note())
Self::new_with_proto(global, None, blob_impl, name, modified, can_gc)
}
#[allow(crown::unrooted_must_root)]
@ -70,7 +71,11 @@ impl File {
}
// Construct from selected file message from file manager thread
pub fn new_from_selected(window: &Window, selected: SelectedFile) -> DomRoot<File> {
pub fn new_from_selected(
window: &Window,
selected: SelectedFile,
can_gc: CanGc,
) -> DomRoot<File> {
let name = DOMString::from(
selected
.filename
@ -88,6 +93,7 @@ impl File {
),
name,
Some(selected.modified),
can_gc,
)
}

View file

@ -166,6 +166,7 @@ impl FileReader {
filereader: TrustedFileReader,
gen_id: GenerationId,
error: DOMErrorName,
can_gc: CanGc,
) {
let fr = filereader.root();
@ -185,17 +186,17 @@ impl FileReader {
let exception = DOMException::new(&fr.global(), error);
fr.error.set(Some(&exception));
fr.dispatch_progress_event(atom!("error"), 0, None);
fr.dispatch_progress_event(atom!("error"), 0, None, can_gc);
return_on_abort!();
// Step 3
fr.dispatch_progress_event(atom!("loadend"), 0, None);
fr.dispatch_progress_event(atom!("loadend"), 0, None, can_gc);
return_on_abort!();
// Step 4
fr.terminate_ongoing_reading();
}
// https://w3c.github.io/FileAPI/#dfn-readAsText
pub fn process_read_data(filereader: TrustedFileReader, gen_id: GenerationId) {
pub fn process_read_data(filereader: TrustedFileReader, gen_id: GenerationId, can_gc: CanGc) {
let fr = filereader.root();
macro_rules! return_on_abort(
@ -207,11 +208,11 @@ impl FileReader {
);
return_on_abort!();
//FIXME Step 7 send current progress
fr.dispatch_progress_event(atom!("progress"), 0, None);
fr.dispatch_progress_event(atom!("progress"), 0, None, can_gc);
}
// https://w3c.github.io/FileAPI/#dfn-readAsText
pub fn process_read(filereader: TrustedFileReader, gen_id: GenerationId) {
pub fn process_read(filereader: TrustedFileReader, gen_id: GenerationId, can_gc: CanGc) {
let fr = filereader.root();
macro_rules! return_on_abort(
@ -223,7 +224,7 @@ impl FileReader {
);
return_on_abort!();
// Step 6
fr.dispatch_progress_event(atom!("loadstart"), 0, None);
fr.dispatch_progress_event(atom!("loadstart"), 0, None, can_gc);
}
// https://w3c.github.io/FileAPI/#dfn-readAsText
@ -232,6 +233,7 @@ impl FileReader {
gen_id: GenerationId,
data: ReadMetaData,
blob_contents: Vec<u8>,
can_gc: CanGc,
) {
let fr = filereader.root();
@ -267,11 +269,11 @@ impl FileReader {
};
// Step 8.3
fr.dispatch_progress_event(atom!("load"), 0, None);
fr.dispatch_progress_event(atom!("load"), 0, None, can_gc);
return_on_abort!();
// Step 8.4
if fr.ready_state.get() != FileReaderReadyState::Loading {
fr.dispatch_progress_event(atom!("loadend"), 0, None);
fr.dispatch_progress_event(atom!("loadend"), 0, None, can_gc);
}
return_on_abort!();
}
@ -368,7 +370,7 @@ impl FileReaderMethods for FileReader {
}
// https://w3c.github.io/FileAPI/#dfn-abort
fn Abort(&self) {
fn Abort(&self, can_gc: CanGc) {
// Step 2
if self.ready_state.get() == FileReaderReadyState::Loading {
self.change_ready_state(FileReaderReadyState::Done);
@ -381,8 +383,8 @@ impl FileReaderMethods for FileReader {
self.terminate_ongoing_reading();
// Steps 5 & 6
self.dispatch_progress_event(atom!("abort"), 0, None);
self.dispatch_progress_event(atom!("loadend"), 0, None);
self.dispatch_progress_event(atom!("abort"), 0, None, can_gc);
self.dispatch_progress_event(atom!("loadend"), 0, None, can_gc);
}
// https://w3c.github.io/FileAPI/#dfn-error
@ -412,7 +414,7 @@ impl FileReaderMethods for FileReader {
}
impl FileReader {
fn dispatch_progress_event(&self, type_: Atom, loaded: u64, total: Option<u64>) {
fn dispatch_progress_event(&self, type_: Atom, loaded: u64, total: Option<u64>, can_gc: CanGc) {
let progressevent = ProgressEvent::new(
&self.global(),
type_,
@ -421,6 +423,7 @@ impl FileReader {
total.is_some(),
loaded,
total.unwrap_or(0),
can_gc,
);
progressevent.upcast::<Event>().fire(self.upcast());
}

View file

@ -110,7 +110,11 @@ impl FormDataMethods for FormData {
let datum = FormDatum {
ty: DOMString::from("file"),
name: DOMString::from(name.0.clone()),
value: FormDatumValue::File(DomRoot::from_ref(&*self.create_an_entry(blob, filename))),
value: FormDatumValue::File(DomRoot::from_ref(&*self.create_an_entry(
blob,
filename,
CanGc::note(),
))),
};
self.data
@ -187,7 +191,7 @@ impl FormDataMethods for FormData {
#[allow(crown::unrooted_must_root)]
// https://xhr.spec.whatwg.org/#dom-formdata-set
fn Set_(&self, name: USVString, blob: &Blob, filename: Option<USVString>) {
let file = self.create_an_entry(blob, filename);
let file = self.create_an_entry(blob, filename, CanGc::note());
let mut data = self.data.borrow_mut();
let local_name = LocalName::from(name.0.clone());
@ -207,7 +211,12 @@ impl FormDataMethods for FormData {
impl FormData {
// https://xhr.spec.whatwg.org/#create-an-entry
fn create_an_entry(&self, blob: &Blob, opt_filename: Option<USVString>) -> DomRoot<File> {
fn create_an_entry(
&self,
blob: &Blob,
opt_filename: Option<USVString>,
can_gc: CanGc,
) -> DomRoot<File> {
// Steps 3-4
let name = match opt_filename {
Some(filename) => DOMString::from(filename.0),
@ -229,6 +238,7 @@ impl FormData {
BlobImpl::new_from_bytes(bytes, blob.type_string()),
name,
None,
can_gc,
)
}

View file

@ -216,7 +216,7 @@ impl Gamepad {
self.gamepad_id
}
pub fn update_connected(&self, connected: bool, has_gesture: bool) {
pub fn update_connected(&self, connected: bool, has_gesture: bool, can_gc: CanGc) {
if self.connected.get() == connected {
return;
}
@ -229,7 +229,7 @@ impl Gamepad {
};
if has_gesture {
self.notify_event(event_type);
self.notify_event(event_type, can_gc);
}
}
@ -245,8 +245,8 @@ impl Gamepad {
self.timestamp.set(timestamp);
}
pub fn notify_event(&self, event_type: GamepadEventType) {
let event = GamepadEvent::new_with_type(&self.global(), event_type, self, CanGc::note());
pub fn notify_event(&self, event_type: GamepadEventType, can_gc: CanGc) {
let event = GamepadEvent::new_with_type(&self.global(), event_type, self, can_gc);
event
.upcast::<Event>()
.fire(self.global().as_window().upcast::<EventTarget>());

View file

@ -3239,7 +3239,7 @@ impl GlobalScope {
false,
CanGc::note(),
);
navigator.set_gamepad(selected_index as usize, &gamepad);
navigator.set_gamepad(selected_index as usize, &gamepad, CanGc::note());
}
}),
&self.task_canceller(TaskSourceName::Gamepad),
@ -3258,7 +3258,7 @@ impl GlobalScope {
let navigator = window.Navigator();
if let Some(gamepad) = navigator.get_gamepad(index) {
if window.Document().is_fully_active() {
gamepad.update_connected(false, gamepad.exposed());
gamepad.update_connected(false, gamepad.exposed(), CanGc::note());
navigator.remove_gamepad(index);
}
}
@ -3304,7 +3304,7 @@ impl GlobalScope {
window.task_manager().gamepad_task_source().queue_with_canceller(
task!(update_gamepad_connect: move || {
let gamepad = new_gamepad.root();
gamepad.notify_event(GamepadEventType::Connected);
gamepad.notify_event(GamepadEventType::Connected, CanGc::note());
}),
&window.upcast::<GlobalScope>()
.task_canceller(TaskSourceName::Gamepad),

View file

@ -269,11 +269,11 @@ impl HTMLFormElementMethods for HTMLFormElement {
make_getter!(Rel, "rel");
// https://html.spec.whatwg.org/multipage/#the-form-element:concept-form-submit
fn Submit(&self) {
fn Submit(&self, can_gc: CanGc) {
self.submit(
SubmittedFrom::FromForm,
FormSubmitterElement::Form(self),
CanGc::note(),
can_gc,
);
}

View file

@ -1559,9 +1559,9 @@ impl HTMLInputElementMethods for HTMLInputElement {
// enabled by dom.htmlinputelement.select_files.enabled,
// used for test purpose.
// check-tidy: no specs after this line
fn SelectFiles(&self, paths: Vec<DOMString>) {
fn SelectFiles(&self, paths: Vec<DOMString>, can_gc: CanGc) {
if self.input_type() == InputType::File {
self.select_files(Some(paths));
self.select_files(Some(paths), can_gc);
}
}
@ -1826,7 +1826,7 @@ impl HTMLInputElement {
// https://html.spec.whatwg.org/multipage/#file-upload-state-(type=file)
// Select files by invoking UI or by passed in argument
fn select_files(&self, opt_test_paths: Option<Vec<DOMString>>) {
fn select_files(&self, opt_test_paths: Option<Vec<DOMString>>, can_gc: CanGc) {
let window = window_from_node(self);
let origin = get_blob_origin(&window.get_url());
let resource_threads = window.upcast::<GlobalScope>().resource_threads();
@ -1851,7 +1851,7 @@ impl HTMLInputElement {
match recv.recv().expect("IpcSender side error") {
Ok(selected_files) => {
for selected in selected_files {
files.push(File::new_from_selected(&window, selected));
files.push(File::new_from_selected(&window, selected, can_gc));
}
},
Err(err) => error = Some(err),
@ -1877,7 +1877,7 @@ impl HTMLInputElement {
match recv.recv().expect("IpcSender side error") {
Ok(selected) => {
files.push(File::new_from_selected(&window, selected));
files.push(File::new_from_selected(&window, selected, can_gc));
},
Err(err) => error = Some(err),
};
@ -2839,7 +2839,7 @@ impl Activatable for HTMLInputElement {
target.fire_bubbling_event(atom!("input"));
target.fire_bubbling_event(atom!("change"));
},
InputType::File => self.select_files(None),
InputType::File => self.select_files(None, CanGc::note()),
_ => (),
}
}

View file

@ -1632,6 +1632,7 @@ impl HTMLMediaElement {
false,
false,
&Some(VideoTrackOrAudioTrackOrTextTrack::AudioTrack(audio_track)),
can_gc,
);
event.upcast::<Event>().fire(self.upcast::<EventTarget>());
@ -1686,6 +1687,7 @@ impl HTMLMediaElement {
false,
false,
&Some(VideoTrackOrAudioTrackOrTextTrack::VideoTrack(video_track)),
can_gc,
);
event.upcast::<Event>().fire(self.upcast::<EventTarget>());

View file

@ -29,7 +29,7 @@ use crate::dom::pluginarray::PluginArray;
use crate::dom::serviceworkercontainer::ServiceWorkerContainer;
use crate::dom::window::Window;
use crate::dom::xrsystem::XRSystem;
use crate::script_runtime::JSContext;
use crate::script_runtime::{CanGc, JSContext};
pub(super) fn hardware_concurrency() -> u64 {
static CPUS: LazyLock<u64> = LazyLock::new(|| num_cpus::get().try_into().unwrap_or(1));
@ -85,14 +85,14 @@ impl Navigator {
self.gamepads.borrow().get(index).and_then(|g| g.get())
}
pub fn set_gamepad(&self, index: usize, gamepad: &Gamepad) {
pub fn set_gamepad(&self, index: usize, gamepad: &Gamepad, can_gc: CanGc) {
if let Some(gamepad_to_set) = self.gamepads.borrow().get(index) {
gamepad_to_set.set(Some(gamepad));
}
if self.has_gamepad_gesture.get() {
gamepad.set_exposed(true);
if self.global().as_window().Document().is_fully_active() {
gamepad.notify_event(GamepadEventType::Connected);
gamepad.notify_event(GamepadEventType::Connected, can_gc);
}
}
}

View file

@ -36,6 +36,7 @@ impl ProgressEvent {
}
}
#[allow(clippy::too_many_arguments)]
pub fn new(
global: &GlobalScope,
type_: Atom,
@ -44,6 +45,7 @@ impl ProgressEvent {
length_computable: bool,
loaded: u64,
total: u64,
can_gc: CanGc,
) -> DomRoot<ProgressEvent> {
Self::new_with_proto(
global,
@ -54,7 +56,7 @@ impl ProgressEvent {
length_computable,
loaded,
total,
CanGc::note(),
can_gc,
)
}

View file

@ -113,8 +113,8 @@ impl BodyMixin for Response {
self.body_stream.get()
}
fn get_mime_type(&self, _can_gc: CanGc) -> Vec<u8> {
let headers = self.Headers();
fn get_mime_type(&self, can_gc: CanGc) -> Vec<u8> {
let headers = self.Headers(can_gc);
headers.extract_mime_type()
}
}
@ -172,7 +172,7 @@ impl ResponseMethods for Response {
// Step 5
if let Some(ref headers_member) = init.headers {
r.Headers().fill(Some(headers_member.clone()))?;
r.Headers(can_gc).fill(Some(headers_member.clone()))?;
}
// Step 6
@ -197,11 +197,11 @@ impl ResponseMethods for Response {
// Step 6.3
if let Some(content_type_contents) = content_type {
if !r
.Headers()
.Headers(can_gc)
.Has(ByteString::new(b"Content-Type".to_vec()))
.unwrap()
{
r.Headers().Append(
r.Headers(can_gc).Append(
ByteString::new(b"Content-Type".to_vec()),
ByteString::new(content_type_contents.as_bytes().to_vec()),
)?;
@ -221,7 +221,7 @@ impl ResponseMethods for Response {
fn Error(global: &GlobalScope, can_gc: CanGc) -> DomRoot<Response> {
let r = Response::new(global, can_gc);
*r.response_type.borrow_mut() = DOMResponseType::Error;
r.Headers().set_guard(Guard::Immutable);
r.Headers(can_gc).set_guard(Guard::Immutable);
*r.status.borrow_mut() = HttpStatus::new_error();
r
}
@ -258,12 +258,12 @@ impl ResponseMethods for Response {
// Step 6
let url_bytestring =
ByteString::from_str(url.as_str()).unwrap_or(ByteString::new(b"".to_vec()));
r.Headers()
r.Headers(can_gc)
.Set(ByteString::new(b"Location".to_vec()), url_bytestring)?;
// Step 4 continued
// Headers Guard is set to Immutable here to prevent error in Step 6
r.Headers().set_guard(Guard::Immutable);
r.Headers(can_gc).set_guard(Guard::Immutable);
// Step 7
Ok(r)
@ -305,9 +305,9 @@ impl ResponseMethods for Response {
}
// https://fetch.spec.whatwg.org/#dom-response-headers
fn Headers(&self) -> DomRoot<Headers> {
fn Headers(&self, can_gc: CanGc) -> DomRoot<Headers> {
self.headers_reflector
.or_init(|| Headers::for_response(&self.global(), CanGc::note()))
.or_init(|| Headers::for_response(&self.global(), can_gc))
}
// https://fetch.spec.whatwg.org/#dom-response-clone
@ -319,8 +319,12 @@ impl ResponseMethods for Response {
// Step 2
let new_response = Response::new(&self.global(), can_gc);
new_response.Headers().copy_from_headers(self.Headers())?;
new_response.Headers().set_guard(self.Headers().get_guard());
new_response
.Headers(can_gc)
.copy_from_headers(self.Headers(can_gc))?;
new_response
.Headers(can_gc)
.set_guard(self.Headers(can_gc).get_guard());
// https://fetch.spec.whatwg.org/#concept-response-clone
// Instead of storing a net_traits::Response internally, we
@ -388,16 +392,17 @@ fn serialize_without_fragment(url: &ServoUrl) -> &str {
}
impl Response {
pub fn set_type(&self, new_response_type: DOMResponseType) {
pub fn set_type(&self, new_response_type: DOMResponseType, can_gc: CanGc) {
*self.response_type.borrow_mut() = new_response_type;
self.set_response_members_by_type(new_response_type);
self.set_response_members_by_type(new_response_type, can_gc);
}
pub fn set_headers(&self, option_hyper_headers: Option<Serde<HyperHeaders>>) {
self.Headers().set_headers(match option_hyper_headers {
Some(hyper_headers) => hyper_headers.into_inner(),
None => HyperHeaders::new(),
});
pub fn set_headers(&self, option_hyper_headers: Option<Serde<HyperHeaders>>, can_gc: CanGc) {
self.Headers(can_gc)
.set_headers(match option_hyper_headers {
Some(hyper_headers) => hyper_headers.into_inner(),
None => HyperHeaders::new(),
});
}
pub fn set_status(&self, status: &HttpStatus) {
@ -412,21 +417,21 @@ impl Response {
*self.redirected.borrow_mut() = is_redirected;
}
fn set_response_members_by_type(&self, response_type: DOMResponseType) {
fn set_response_members_by_type(&self, response_type: DOMResponseType, can_gc: CanGc) {
match response_type {
DOMResponseType::Error => {
*self.status.borrow_mut() = HttpStatus::new_error();
self.set_headers(None);
self.set_headers(None, can_gc);
},
DOMResponseType::Opaque => {
*self.url_list.borrow_mut() = vec![];
*self.status.borrow_mut() = HttpStatus::new_error();
self.set_headers(None);
self.set_headers(None, can_gc);
self.body_stream.set(None);
},
DOMResponseType::Opaqueredirect => {
*self.status.borrow_mut() = HttpStatus::new_error();
self.set_headers(None);
self.set_headers(None, can_gc);
self.body_stream.set(None);
},
DOMResponseType::Default => {},

View file

@ -93,16 +93,9 @@ impl SecurityPolicyViolationEvent {
bubbles: EventBubbles,
cancelable: EventCancelable,
init: &SecurityPolicyViolationEventInit,
can_gc: CanGc,
) -> DomRoot<Self> {
Self::new_with_proto(
global,
None,
type_,
bubbles,
cancelable,
init,
CanGc::note(),
)
Self::new_with_proto(global, None, type_, bubbles, cancelable, init, can_gc)
}
}

View file

@ -158,22 +158,22 @@ struct SerializationIterator {
stack: Vec<SerializationCommand>,
}
fn rev_children_iter(n: &Node) -> impl Iterator<Item = DomRoot<Node>> {
fn rev_children_iter(n: &Node, can_gc: CanGc) -> impl Iterator<Item = DomRoot<Node>> {
if n.downcast::<Element>().is_some_and(|e| e.is_void()) {
return Node::new_document_node().rev_children();
}
match n.downcast::<HTMLTemplateElement>() {
Some(t) => t.Content(CanGc::note()).upcast::<Node>().rev_children(),
Some(t) => t.Content(can_gc).upcast::<Node>().rev_children(),
None => n.rev_children(),
}
}
impl SerializationIterator {
fn new(node: &Node, skip_first: bool) -> SerializationIterator {
fn new(node: &Node, skip_first: bool, can_gc: CanGc) -> SerializationIterator {
let mut ret = SerializationIterator { stack: vec![] };
if skip_first || node.is::<DocumentFragment>() || node.is::<Document>() {
for c in rev_children_iter(node) {
for c in rev_children_iter(node, can_gc) {
ret.push_node(&c);
}
} else {
@ -203,7 +203,7 @@ impl Iterator for SerializationIterator {
if let Some(SerializationCommand::OpenElement(ref e)) = res {
self.stack
.push(SerializationCommand::CloseElement(e.clone()));
for c in rev_children_iter(e.upcast::<Node>()) {
for c in rev_children_iter(e.upcast::<Node>(), CanGc::note()) {
self.push_node(&c);
}
}
@ -220,7 +220,7 @@ impl<'a> Serialize for &'a Node {
) -> io::Result<()> {
let node = *self;
let iter = SerializationIterator::new(node, traversal_scope != IncludeNode);
let iter = SerializationIterator::new(node, traversal_scope != IncludeNode, CanGc::note());
for cmd in iter {
match cmd {

View file

@ -17,6 +17,7 @@ use crate::dom::eventtarget::EventTarget;
use crate::dom::texttrack::TextTrack;
use crate::dom::trackevent::TrackEvent;
use crate::dom::window::Window;
use crate::script_runtime::CanGc;
use crate::task_source::TaskSource;
#[dom_struct]
@ -83,6 +84,7 @@ impl TextTrackList {
&Some(VideoTrackOrAudioTrackOrTextTrack::TextTrack(
DomRoot::from_ref(&track)
)),
CanGc::note()
);
event.upcast::<Event>().fire(this.upcast::<EventTarget>());

View file

@ -65,16 +65,9 @@ impl TrackEvent {
bubbles: bool,
cancelable: bool,
track: &Option<VideoTrackOrAudioTrackOrTextTrack>,
can_gc: CanGc,
) -> DomRoot<TrackEvent> {
Self::new_with_proto(
global,
None,
type_,
bubbles,
cancelable,
track,
CanGc::note(),
)
Self::new_with_proto(global, None, type_, bubbles, cancelable, track, can_gc)
}
fn new_with_proto(

View file

@ -554,7 +554,7 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
}
/// <https://xhr.spec.whatwg.org/#the-send()-method>
fn Send(&self, data: Option<DocumentOrXMLHttpRequestBodyInit>) -> ErrorResult {
fn Send(&self, data: Option<DocumentOrXMLHttpRequestBodyInit>, can_gc: CanGc) -> ErrorResult {
// Step 1, 2
if self.ready_state.get() != XMLHttpRequestState::Opened || self.send_flag.get() {
return Err(Error::InvalidState);
@ -661,13 +661,13 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
// abort or open we will need the current generation id to detect it.
// Substep 1
let gen_id = self.generation_id.get();
self.dispatch_response_progress_event(atom!("loadstart"));
self.dispatch_response_progress_event(atom!("loadstart"), can_gc);
if self.generation_id.get() != gen_id {
return Ok(());
}
// Substep 2
if !self.upload_complete.get() && self.upload_listener.get() {
self.dispatch_upload_progress_event(atom!("loadstart"), Ok(Some(0)));
self.dispatch_upload_progress_event(atom!("loadstart"), Ok(Some(0)), can_gc);
if self.generation_id.get() != gen_id {
return Ok(());
}
@ -1114,11 +1114,11 @@ impl XMLHttpRequest {
self.upload_complete.set(true);
// Substeps 2-4
if !self.sync.get() && self.upload_listener.get() {
self.dispatch_upload_progress_event(atom!("progress"), Ok(None));
self.dispatch_upload_progress_event(atom!("progress"), Ok(None), can_gc);
return_if_fetch_was_terminated!();
self.dispatch_upload_progress_event(atom!("load"), Ok(None));
self.dispatch_upload_progress_event(atom!("load"), Ok(None), can_gc);
return_if_fetch_was_terminated!();
self.dispatch_upload_progress_event(atom!("loadend"), Ok(None));
self.dispatch_upload_progress_event(atom!("loadend"), Ok(None), can_gc);
return_if_fetch_was_terminated!();
}
// Part of step 13, send() (processing response)
@ -1171,7 +1171,7 @@ impl XMLHttpRequest {
);
event.fire(self.upcast());
return_if_fetch_was_terminated!();
self.dispatch_response_progress_event(atom!("progress"));
self.dispatch_response_progress_event(atom!("progress"), can_gc);
}
},
XHRProgress::Done(_) => {
@ -1193,9 +1193,9 @@ impl XMLHttpRequest {
self.change_ready_state(XMLHttpRequestState::Done, can_gc);
return_if_fetch_was_terminated!();
// Subsubsteps 11-12
self.dispatch_response_progress_event(atom!("load"));
self.dispatch_response_progress_event(atom!("load"), can_gc);
return_if_fetch_was_terminated!();
self.dispatch_response_progress_event(atom!("loadend"));
self.dispatch_response_progress_event(atom!("loadend"), can_gc);
},
XHRProgress::Errored(_, e) => {
self.cancel_timeout();
@ -1217,15 +1217,15 @@ impl XMLHttpRequest {
if !upload_complete.get() {
upload_complete.set(true);
if self.upload_listener.get() {
self.dispatch_upload_progress_event(Atom::from(errormsg), Err(()));
self.dispatch_upload_progress_event(Atom::from(errormsg), Err(()), can_gc);
return_if_fetch_was_terminated!();
self.dispatch_upload_progress_event(atom!("loadend"), Err(()));
self.dispatch_upload_progress_event(atom!("loadend"), Err(()), can_gc);
return_if_fetch_was_terminated!();
}
}
self.dispatch_response_progress_event(Atom::from(errormsg));
self.dispatch_response_progress_event(Atom::from(errormsg), can_gc);
return_if_fetch_was_terminated!();
self.dispatch_response_progress_event(atom!("loadend"));
self.dispatch_response_progress_event(atom!("loadend"), can_gc);
},
}
}
@ -1237,7 +1237,14 @@ impl XMLHttpRequest {
self.response_status.set(Ok(()));
}
fn dispatch_progress_event(&self, upload: bool, type_: Atom, loaded: u64, total: Option<u64>) {
fn dispatch_progress_event(
&self,
upload: bool,
type_: Atom,
loaded: u64,
total: Option<u64>,
can_gc: CanGc,
) {
let (total_length, length_computable) = if self
.response_headers
.borrow()
@ -1255,6 +1262,7 @@ impl XMLHttpRequest {
length_computable,
loaded,
total_length,
can_gc,
);
let target = if upload {
self.upload.upcast()
@ -1264,7 +1272,12 @@ impl XMLHttpRequest {
progressevent.upcast::<Event>().fire(target);
}
fn dispatch_upload_progress_event(&self, type_: Atom, partial_load: Result<Option<u64>, ()>) {
fn dispatch_upload_progress_event(
&self,
type_: Atom,
partial_load: Result<Option<u64>, ()>,
can_gc: CanGc,
) {
// If partial_load is Ok(None), loading has completed and we can just use the value from the request body
// If an error occured, we pass 0 for both loaded and total
@ -1276,17 +1289,17 @@ impl XMLHttpRequest {
},
Err(()) => (0, None),
};
self.dispatch_progress_event(true, type_, loaded, total);
self.dispatch_progress_event(true, type_, loaded, total, can_gc);
}
fn dispatch_response_progress_event(&self, type_: Atom) {
fn dispatch_response_progress_event(&self, type_: Atom, can_gc: CanGc) {
let len = self.response.borrow().len() as u64;
let total = self
.response_headers
.borrow()
.typed_get::<ContentLength>()
.map(|v| v.0);
self.dispatch_progress_event(false, type_, len, total);
self.dispatch_progress_event(false, type_, len, total, can_gc);
}
fn set_timeout(&self, duration: Duration) {

View file

@ -71,7 +71,7 @@ impl XRInputSourceArray {
pub fn remove_input_source(&self, session: &XRSession, id: InputId, can_gc: CanGc) {
let global = self.global();
let removed = if let Some(i) = self.input_sources.borrow().iter().find(|i| i.id() == id) {
i.gamepad().update_connected(false, false);
i.gamepad().update_connected(false, false, can_gc);
[DomRoot::from_ref(&**i)]
} else {
return;
@ -101,7 +101,7 @@ impl XRInputSourceArray {
let global = self.global();
let root;
let removed = if let Some(i) = self.input_sources.borrow().iter().find(|i| i.id() == id) {
i.gamepad().update_connected(false, false);
i.gamepad().update_connected(false, false, can_gc);
root = [DomRoot::from_ref(&**i)];
&root as &[_]
} else {

View file

@ -149,7 +149,7 @@ pub fn Fetch(
// Step 7. Let responseObject be null.
// NOTE: We do initialize the object earlier earlier so we can use it to track errors
let response = Response::new(global, can_gc);
response.Headers().set_guard(Guard::Immutable);
response.Headers(can_gc).set_guard(Guard::Immutable);
// Step 2. Let requestObject be the result of invoking the initial value of Request as constructor
// with input and init as arguments. If this throws an exception, reject p with it and return p.
@ -231,35 +231,39 @@ impl FetchResponseListener for FetchContext {
promise.reject_error(Error::Type("Network error occurred".to_string()));
self.fetch_promise = Some(TrustedPromise::new(promise));
let response = self.response_object.root();
response.set_type(DOMResponseType::Error);
response.set_type(DOMResponseType::Error, CanGc::note());
response.error_stream(Error::Type("Network error occurred".to_string()));
return;
},
// Step 4.2
Ok(metadata) => match metadata {
FetchMetadata::Unfiltered(m) => {
fill_headers_with_metadata(self.response_object.root(), m);
fill_headers_with_metadata(self.response_object.root(), m, CanGc::note());
self.response_object
.root()
.set_type(DOMResponseType::Default);
.set_type(DOMResponseType::Default, CanGc::note());
},
FetchMetadata::Filtered { filtered, .. } => match filtered {
FilteredMetadata::Basic(m) => {
fill_headers_with_metadata(self.response_object.root(), m);
self.response_object.root().set_type(DOMResponseType::Basic);
fill_headers_with_metadata(self.response_object.root(), m, CanGc::note());
self.response_object
.root()
.set_type(DOMResponseType::Basic, CanGc::note());
},
FilteredMetadata::Cors(m) => {
fill_headers_with_metadata(self.response_object.root(), m);
self.response_object.root().set_type(DOMResponseType::Cors);
fill_headers_with_metadata(self.response_object.root(), m, CanGc::note());
self.response_object
.root()
.set_type(DOMResponseType::Cors, CanGc::note());
},
FilteredMetadata::Opaque => {
self.response_object
.root()
.set_type(DOMResponseType::Opaque);
.set_type(DOMResponseType::Opaque, CanGc::note());
},
FilteredMetadata::OpaqueRedirect(url) => {
let r = self.response_object.root();
r.set_type(DOMResponseType::Opaqueredirect);
r.set_type(DOMResponseType::Opaqueredirect, CanGc::note());
r.set_final_url(url);
},
},
@ -317,8 +321,8 @@ impl ResourceTimingListener for FetchContext {
}
}
fn fill_headers_with_metadata(r: DomRoot<Response>, m: Metadata) {
r.set_headers(m.headers);
fn fill_headers_with_metadata(r: DomRoot<Response>, m: Metadata, can_gc: CanGc) {
r.set_headers(m.headers, can_gc);
r.set_status(&m.status);
r.set_final_url(m.final_url);
r.set_redirected(m.redirected);

View file

@ -1025,7 +1025,7 @@ unsafe extern "C" fn consume_stream(
root_from_handleobject::<Response>(RustHandleObject::from_raw(obj), *cx)
{
//Step 2.2 Let mimeType be the result of extracting a MIME type from responses header list.
let mimetype = unwrapped_source.Headers().extract_mime_type();
let mimetype = unwrapped_source.Headers(CanGc::note()).extract_mime_type();
//Step 2.3 If mimeType is not `application/wasm`, return with a TypeError and abort these substeps.
if !&mimetype[..].eq_ignore_ascii_case(b"application/wasm") {

View file

@ -19,6 +19,7 @@ use crate::dom::event::{Event, EventBubbles, EventCancelable};
use crate::dom::eventtarget::EventTarget;
use crate::dom::securitypolicyviolationevent::SecurityPolicyViolationEvent;
use crate::dom::types::GlobalScope;
use crate::script_runtime::CanGc;
use crate::task::TaskOnce;
pub struct CSPViolationReporter {
@ -100,7 +101,7 @@ impl CSPViolationReporter {
}
}
fn fire_violation_event(&self) {
fn fire_violation_event(&self, can_gc: CanGc) {
let target = self.target.root();
let global = &target.global();
let report = self.get_report(global);
@ -111,6 +112,7 @@ impl CSPViolationReporter {
EventBubbles::Bubbles,
EventCancelable::Cancelable,
&report.into(),
can_gc,
);
event.upcast::<Event>().fire(&target);
@ -142,7 +144,7 @@ impl TaskOnce for CSPViolationReporter {
// > If target implements EventTarget, fire an event named securitypolicyviolation
// > that uses the SecurityPolicyViolationEvent interface
// > at target with its attributes initialized as follows:
self.fire_violation_event();
self.fire_violation_event(CanGc::note());
// TODO: Support `report-to` directive that corresponds to 5.5.3.5.
}
}

View file

@ -6,7 +6,7 @@ use base::id::PipelineId;
use crate::dom::domexception::DOMErrorName;
use crate::dom::filereader::{FileReader, GenerationId, ReadMetaData, TrustedFileReader};
use crate::script_runtime::{CommonScriptMsg, ScriptChan, ScriptThreadEventCategory};
use crate::script_runtime::{CanGc, CommonScriptMsg, ScriptChan, ScriptThreadEventCategory};
use crate::task::{TaskCanceller, TaskOnce};
use crate::task_source::{TaskSource, TaskSourceName};
@ -40,7 +40,7 @@ impl TaskSource for FileReadingTaskSource {
impl TaskOnce for FileReadingTask {
fn run_once(self) {
self.handle_task();
self.handle_task(CanGc::note());
}
}
@ -53,17 +53,19 @@ pub enum FileReadingTask {
}
impl FileReadingTask {
pub fn handle_task(self) {
pub fn handle_task(self, can_gc: CanGc) {
use self::FileReadingTask::*;
match self {
ProcessRead(reader, gen_id) => FileReader::process_read(reader, gen_id),
ProcessReadData(reader, gen_id) => FileReader::process_read_data(reader, gen_id),
ProcessRead(reader, gen_id) => FileReader::process_read(reader, gen_id, can_gc),
ProcessReadData(reader, gen_id) => {
FileReader::process_read_data(reader, gen_id, can_gc)
},
ProcessReadError(reader, gen_id, error) => {
FileReader::process_read_error(reader, gen_id, error)
FileReader::process_read_error(reader, gen_id, error, can_gc)
},
ProcessReadEOF(reader, gen_id, metadata, blob_contents) => {
FileReader::process_read_eof(reader, gen_id, metadata, blob_contents)
FileReader::process_read_eof(reader, gen_id, metadata, blob_contents, can_gc)
},
}
}