CanGc fixes from EventTarget::fire_event (#33985)

Signed-off-by: taniishkaaa <tanishkasingh2004@gmail.com>
This commit is contained in:
tanishka 2024-10-24 04:18:19 +05:30 committed by GitHub
parent bb4932026c
commit ea875f0a51
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
35 changed files with 155 additions and 115 deletions

View file

@ -15,6 +15,7 @@ use crate::dom::bindings::str::DOMString;
use crate::dom::eventtarget::EventTarget;
use crate::dom::htmlmediaelement::HTMLMediaElement;
use crate::dom::window::Window;
use crate::script_runtime::CanGc;
use crate::task_source::TaskSource;
#[dom_struct]
@ -96,7 +97,7 @@ impl AudioTrackList {
let _ = source.queue_with_canceller(
task!(media_track_change: move || {
let this = this.root();
this.upcast::<EventTarget>().fire_event(atom!("change"));
this.upcast::<EventTarget>().fire_event(atom!("change"), CanGc::note());
}),
&canceller,
);

View file

@ -375,6 +375,10 @@ DOMInterfaces = {
'canGc': ['GetTransform', 'SetStrokeStyle', 'SetFillStyle', 'SetShadowColor'],
},
'Performance': {
'canGc': ['Mark', 'Measure'],
},
'Permissions': {
'canGc': ['Query', 'Request', 'Revoke'],
},
@ -476,7 +480,7 @@ DOMInterfaces = {
'WorkerGlobalScope': {
'inRealms': ['Fetch'],
'canGc': ['Fetch', 'CreateImageBitmap'],
'canGc': ['Fetch', 'CreateImageBitmap', 'ImportScripts'],
},
'Worklet': {

View file

@ -430,6 +430,7 @@ impl DedicatedWorkerGlobalScope {
request,
&global_scope.resource_threads().sender(),
global_scope,
CanGc::note(),
) {
Err(_) => {
println!("error loading script {}", serialized_worker_url);

View file

@ -1076,7 +1076,7 @@ impl Document {
}
// https://html.spec.whatwg.org/multipage/#current-document-readiness
pub fn set_ready_state(&self, state: DocumentReadyState) {
pub fn set_ready_state(&self, state: DocumentReadyState, can_gc: CanGc) {
match state {
DocumentReadyState::Loading => {
if self.window().is_top_level() {
@ -1096,7 +1096,7 @@ impl Document {
self.ready_state.set(state);
self.upcast::<EventTarget>()
.fire_event(atom!("readystatechange"));
.fire_event(atom!("readystatechange"), can_gc);
}
/// Return whether scripting is enabled or not
@ -2456,7 +2456,7 @@ impl Document {
}
// Step 7.1.
document.set_ready_state(DocumentReadyState::Complete);
document.set_ready_state(DocumentReadyState::Complete, CanGc::note());
// Step 7.2.
if document.browsing_context().is_none() {
@ -4232,7 +4232,7 @@ impl Document {
VisibilityStateEntry::new(&self.global(), visibility_state, CrossProcessInstant::now());
self.window
.Performance()
.queue_entry(entry.upcast::<PerformanceEntry>());
.queue_entry(entry.upcast::<PerformanceEntry>(), can_gc);
// Step 4 Run the screen orientation change steps with document.
// TODO ScreenOrientation hasn't implemented yet

View file

@ -91,7 +91,7 @@ impl DOMParserMethods for DOMParser {
can_gc,
);
ServoParser::parse_html_document(&document, Some(s), url, can_gc);
document.set_ready_state(DocumentReadyState::Complete);
document.set_ready_state(DocumentReadyState::Complete, can_gc);
Ok(document)
},
Text_xml | Application_xml | Application_xhtml_xml | Image_svg_xml => {
@ -113,7 +113,7 @@ impl DOMParserMethods for DOMParser {
can_gc,
);
ServoParser::parse_xml_document(&document, Some(s), url, can_gc);
document.set_ready_state(DocumentReadyState::Complete);
document.set_ready_state(DocumentReadyState::Complete, can_gc);
Ok(document)
},
}

View file

@ -4400,7 +4400,7 @@ impl TaskOnce for ElementPerformFullscreenEnter {
if self.error || !element.fullscreen_element_ready_check() {
document
.upcast::<EventTarget>()
.fire_event(atom!("fullscreenerror"));
.fire_event(atom!("fullscreenerror"), CanGc::note());
promise.reject_error(Error::Type(String::from("fullscreen is not connected")));
return;
}
@ -4418,7 +4418,7 @@ impl TaskOnce for ElementPerformFullscreenEnter {
// Step 7.6
document
.upcast::<EventTarget>()
.fire_event(atom!("fullscreenchange"));
.fire_event(atom!("fullscreenchange"), CanGc::note());
// Step 7.7
promise.resolve_native(&());
@ -4459,7 +4459,7 @@ impl TaskOnce for ElementPerformFullscreenExit {
// Step 9.8
document
.upcast::<EventTarget>()
.fire_event(atom!("fullscreenchange"));
.fire_event(atom!("fullscreenchange"), CanGc::note());
// Step 9.10
self.promise.root().resolve_native(&());

View file

@ -631,7 +631,7 @@ pub struct SimpleEventTask {
impl TaskOnce for SimpleEventTask {
fn run_once(self) {
let target = self.target.root();
target.fire_event(self.name);
target.fire_event(self.name, CanGc::note());
}
}

View file

@ -118,7 +118,7 @@ impl EventSourceContext {
let event_source = event_source.root();
if event_source.ready_state.get() != ReadyState::Closed {
event_source.ready_state.set(ReadyState::Open);
event_source.upcast::<EventTarget>().fire_event(atom!("open"));
event_source.upcast::<EventTarget>().fire_event(atom!("open"), CanGc::note());
}
}),
&global,
@ -159,7 +159,7 @@ impl EventSourceContext {
event_source.ready_state.set(ReadyState::Connecting);
// Step 1.3.
event_source.upcast::<EventTarget>().fire_event(atom!("error"));
event_source.upcast::<EventTarget>().fire_event(atom!("error"), CanGc::note());
// Step 2.
let duration = event_source.reconnection_time.get();
@ -438,7 +438,7 @@ impl FetchResponseListener for EventSourceContext {
}
fn submit_resource_timing(&mut self) {
network_listener::submit_timing(self)
network_listener::submit_timing(self, CanGc::note())
}
}
@ -505,7 +505,7 @@ impl EventSource {
let event_source = event_source.root();
if event_source.ready_state.get() != ReadyState::Closed {
event_source.ready_state.set(ReadyState::Closed);
event_source.upcast::<EventTarget>().fire_event(atom!("error"));
event_source.upcast::<EventTarget>().fire_event(atom!("error"), CanGc::note());
}
}),
&global,

View file

@ -660,12 +660,12 @@ impl EventTarget {
}
// https://dom.spec.whatwg.org/#concept-event-fire
pub fn fire_event(&self, name: Atom) -> DomRoot<Event> {
pub fn fire_event(&self, name: Atom, can_gc: CanGc) -> DomRoot<Event> {
self.fire_event_with_params(
name,
EventBubbles::DoesNotBubble,
EventCancelable::NotCancelable,
CanGc::note(),
can_gc,
)
}

View file

@ -90,7 +90,7 @@ impl VirtualMethods for HTMLDetailsElement {
task!(details_notification_task_steps: move || {
let this = this.root();
if counter == this.toggle_counter.get() {
this.upcast::<EventTarget>().fire_event(atom!("toggle"));
this.upcast::<EventTarget>().fire_event(atom!("toggle"), CanGc::note());
}
}),
window.upcast(),

View file

@ -504,7 +504,8 @@ impl HTMLIFrameElement {
// TODO Step 3 - set child document `mut iframe load` flag
// Step 4
self.upcast::<EventTarget>().fire_event(atom!("load"));
self.upcast::<EventTarget>()
.fire_event(atom!("load"), can_gc);
let mut blocker = self.load_blocker.borrow_mut();
LoadBlocker::terminate(&mut blocker, can_gc);

View file

@ -299,7 +299,7 @@ impl FetchResponseListener for ImageContext {
}
fn submit_resource_timing(&mut self) {
network_listener::submit_timing(self)
network_listener::submit_timing(self, CanGc::note())
}
}
@ -485,14 +485,18 @@ impl HTMLImageElement {
// Fire image.onload and loadend
if trigger_image_load {
// TODO: https://html.spec.whatwg.org/multipage/#fire-a-progress-event-or-event
self.upcast::<EventTarget>().fire_event(atom!("load"));
self.upcast::<EventTarget>().fire_event(atom!("loadend"));
self.upcast::<EventTarget>()
.fire_event(atom!("load"), can_gc);
self.upcast::<EventTarget>()
.fire_event(atom!("loadend"), can_gc);
}
// Fire image.onerror
if trigger_image_error {
self.upcast::<EventTarget>().fire_event(atom!("error"));
self.upcast::<EventTarget>().fire_event(atom!("loadend"));
self.upcast::<EventTarget>()
.fire_event(atom!("error"), can_gc);
self.upcast::<EventTarget>()
.fire_event(atom!("loadend"), can_gc);
}
// Trigger reflow
@ -901,7 +905,7 @@ impl HTMLImageElement {
let src_present = elem.has_attribute(&local_name!("src"));
if src_present || Self::uses_srcset_or_picture(elem) {
this.upcast::<EventTarget>().fire_event(atom!("error"));
this.upcast::<EventTarget>().fire_event(atom!("error"), CanGc::note());
}
}),
window.upcast(),
@ -932,7 +936,7 @@ impl HTMLImageElement {
this.current_request.borrow_mut();
current_request.source_url = Some(USVString(src))
}
this.upcast::<EventTarget>().fire_event(atom!("error"));
this.upcast::<EventTarget>().fire_event(atom!("error"), CanGc::note());
}),
window.upcast(),
@ -1027,7 +1031,7 @@ impl HTMLImageElement {
current_request.source_url = Some(USVString(src));
}
// TODO: restart animation, if set.
this.upcast::<EventTarget>().fire_event(atom!("load"));
this.upcast::<EventTarget>().fire_event(atom!("load"), CanGc::note());
}),
window.upcast(),
);
@ -1278,7 +1282,7 @@ impl HTMLImageElement {
this.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage);
// Step 15.7
this.upcast::<EventTarget>().fire_event(atom!("load"));
this.upcast::<EventTarget>().fire_event(atom!("load"), CanGc::note());
}),
window.upcast(),
);

View file

@ -714,13 +714,13 @@ impl FetchResponseListener for PrefetchContext {
self.link
.root()
.upcast::<EventTarget>()
.fire_event(atom!("error"));
.fire_event(atom!("error"), CanGc::note());
} else {
// Step 2. Otherwise, fire an event named load at el.
self.link
.root()
.upcast::<EventTarget>()
.fire_event(atom!("load"));
.fire_event(atom!("load"), CanGc::note());
}
}
@ -733,7 +733,7 @@ impl FetchResponseListener for PrefetchContext {
}
fn submit_resource_timing(&mut self) {
submit_timing(self)
submit_timing(self, CanGc::note())
}
}

View file

@ -549,10 +549,10 @@ impl HTMLMediaElement {
this.fulfill_in_flight_play_promises(|| {
// Step 2.3.1.
this.upcast::<EventTarget>().fire_event(atom!("timeupdate"));
this.upcast::<EventTarget>().fire_event(atom!("timeupdate"), CanGc::note());
// Step 2.3.2.
this.upcast::<EventTarget>().fire_event(atom!("pause"));
this.upcast::<EventTarget>().fire_event(atom!("pause"), CanGc::note());
if let Some(ref player) = *this.player.borrow() {
if let Err(e) = player.lock().unwrap().pause() {
@ -597,7 +597,7 @@ impl HTMLMediaElement {
this.fulfill_in_flight_play_promises(|| {
// Step 2.1.
this.upcast::<EventTarget>().fire_event(atom!("playing"));
this.upcast::<EventTarget>().fire_event(atom!("playing"), CanGc::note());
this.play_media();
// Step 2.2.
@ -641,7 +641,7 @@ impl HTMLMediaElement {
let _ = task_source.queue(
task!(media_reached_current_data: move || {
let this = this.root();
this.upcast::<EventTarget>().fire_event(atom!("loadeddata"));
this.upcast::<EventTarget>().fire_event(atom!("loadeddata"), CanGc::note());
this.delay_load_event(false, CanGc::note());
}),
window.upcast(),
@ -829,7 +829,9 @@ impl HTMLMediaElement {
let src = source.Src();
// Step 9.attr.2.
if src.is_empty() {
source.upcast::<EventTarget>().fire_event(atom!("error"));
source
.upcast::<EventTarget>()
.fire_event(atom!("error"), can_gc);
self.queue_dedicated_media_source_failure_steps();
return;
}
@ -837,7 +839,9 @@ impl HTMLMediaElement {
let url_record = match base_url.join(&src) {
Ok(url) => url,
Err(_) => {
source.upcast::<EventTarget>().fire_event(atom!("error"));
source
.upcast::<EventTarget>()
.fire_event(atom!("error"), can_gc);
self.queue_dedicated_media_source_failure_steps();
return;
},
@ -1022,7 +1026,7 @@ impl HTMLMediaElement {
this.set_show_poster(true);
// Step 5.
this.upcast::<EventTarget>().fire_event(atom!("error"));
this.upcast::<EventTarget>().fire_event(atom!("error"), CanGc::note());
if let Some(ref player) = *this.player.borrow() {
if let Err(e) = player.lock().unwrap().stop() {
@ -1504,7 +1508,7 @@ impl HTMLMediaElement {
task!(reaches_the_end_steps: move || {
let this = this.root();
// Step 3.1.
this.upcast::<EventTarget>().fire_event(atom!("timeupdate"));
this.upcast::<EventTarget>().fire_event(atom!("timeupdate"), CanGc::note());
// Step 3.2.
if this.Ended() && !this.Paused() {
@ -1512,7 +1516,7 @@ impl HTMLMediaElement {
this.paused.set(true);
// Step 3.2.2.
this.upcast::<EventTarget>().fire_event(atom!("pause"));
this.upcast::<EventTarget>().fire_event(atom!("pause"), CanGc::note());
// Step 3.2.3.
this.take_pending_play_promises(Err(Error::Abort));
@ -1520,7 +1524,7 @@ impl HTMLMediaElement {
}
// Step 3.3.
this.upcast::<EventTarget>().fire_event(atom!("ended"));
this.upcast::<EventTarget>().fire_event(atom!("ended"), CanGc::note());
}),
window.upcast(),
);
@ -1573,7 +1577,8 @@ impl HTMLMediaElement {
self.delay_load_event(false, can_gc);
// 5. Fire an event named error at the media element.
self.upcast::<EventTarget>().fire_event(atom!("error"));
self.upcast::<EventTarget>()
.fire_event(atom!("error"), can_gc);
// TODO: 6. Abort the overall resource selection algorithm.
},
@ -2836,11 +2841,13 @@ impl FetchResponseListener for HTMLMediaElementFetchListener {
}
if status.is_ok() && self.latest_fetched_content != 0 {
elem.upcast::<EventTarget>().fire_event(atom!("progress"));
elem.upcast::<EventTarget>()
.fire_event(atom!("progress"), CanGc::note());
elem.network_state.set(NetworkState::Idle);
elem.upcast::<EventTarget>().fire_event(atom!("suspend"));
elem.upcast::<EventTarget>()
.fire_event(atom!("suspend"), CanGc::note());
}
// => "If the connection is interrupted after some media data has been received..."
else if elem.ready_state.get() != ReadyState::HaveNothing {
@ -2868,7 +2875,8 @@ impl FetchResponseListener for HTMLMediaElementFetchListener {
elem.delay_load_event(false, CanGc::note());
// Step 5
elem.upcast::<EventTarget>().fire_event(atom!("error"));
elem.upcast::<EventTarget>()
.fire_event(atom!("error"), CanGc::note());
} else {
// => "If the media data cannot be fetched at all..."
elem.queue_dedicated_media_source_failure_steps();
@ -2884,7 +2892,7 @@ impl FetchResponseListener for HTMLMediaElementFetchListener {
}
fn submit_resource_timing(&mut self) {
network_listener::submit_timing(self)
network_listener::submit_timing(self, CanGc::note())
}
}

View file

@ -488,7 +488,7 @@ impl FetchResponseListener for ClassicContext {
}
fn submit_resource_timing(&mut self) {
network_listener::submit_timing(self)
network_listener::submit_timing(self, CanGc::note())
}
}

View file

@ -368,7 +368,7 @@ impl FetchResponseListener for PosterFrameFetchContext {
}
fn submit_resource_timing(&mut self) {
network_listener::submit_timing(self)
network_listener::submit_timing(self, CanGc::note())
}
}

View file

@ -29,6 +29,7 @@ use crate::dom::performancenavigation::PerformanceNavigation;
use crate::dom::performancenavigationtiming::PerformanceNavigationTiming;
use crate::dom::performanceobserver::PerformanceObserver as DOMPerformanceObserver;
use crate::dom::window::Window;
use crate::script_runtime::CanGc;
const INVALID_ENTRY_NAMES: &[&str] = &[
"navigationStart",
@ -276,9 +277,9 @@ impl Performance {
/// <https://w3c.github.io/performance-timeline/#queue-a-performanceentry>
/// Also this algorithm has been extented according to :
/// <https://w3c.github.io/resource-timing/#sec-extensions-performance-interface>
pub fn queue_entry(&self, entry: &PerformanceEntry) -> Option<usize> {
pub fn queue_entry(&self, entry: &PerformanceEntry, can_gc: CanGc) -> Option<usize> {
// https://w3c.github.io/performance-timeline/#dfn-determine-eligibility-for-adding-a-performance-entry
if entry.entry_type() == "resource" && !self.should_queue_resource_entry(entry) {
if entry.entry_type() == "resource" && !self.should_queue_resource_entry(entry, can_gc) {
return None;
}
@ -349,14 +350,14 @@ impl Performance {
self.resource_timing_buffer_current_size.get() <=
self.resource_timing_buffer_size_limit.get()
}
fn copy_secondary_resource_timing_buffer(&self) {
fn copy_secondary_resource_timing_buffer(&self, can_gc: CanGc) {
while self.can_add_resource_timing_entry() {
let entry = self
.resource_timing_secondary_entries
.borrow_mut()
.pop_front();
if let Some(ref entry) = entry {
self.queue_entry(entry);
self.queue_entry(entry, can_gc);
} else {
break;
}
@ -364,15 +365,15 @@ impl Performance {
}
// `fire a buffer full event` paragraph of
// https://w3c.github.io/resource-timing/#sec-extensions-performance-interface
fn fire_buffer_full_event(&self) {
fn fire_buffer_full_event(&self, can_gc: CanGc) {
while !self.resource_timing_secondary_entries.borrow().is_empty() {
let no_of_excess_entries_before = self.resource_timing_secondary_entries.borrow().len();
if !self.can_add_resource_timing_entry() {
self.upcast::<EventTarget>()
.fire_event(atom!("resourcetimingbufferfull"));
.fire_event(atom!("resourcetimingbufferfull"), can_gc);
}
self.copy_secondary_resource_timing_buffer();
self.copy_secondary_resource_timing_buffer(can_gc);
let no_of_excess_entries_after = self.resource_timing_secondary_entries.borrow().len();
if no_of_excess_entries_before <= no_of_excess_entries_after {
self.resource_timing_secondary_entries.borrow_mut().clear();
@ -383,7 +384,7 @@ impl Performance {
}
/// `add a PerformanceResourceTiming entry` paragraph of
/// <https://w3c.github.io/resource-timing/#sec-extensions-performance-interface>
fn should_queue_resource_entry(&self, entry: &PerformanceEntry) -> bool {
fn should_queue_resource_entry(&self, entry: &PerformanceEntry, can_gc: CanGc) -> bool {
// Step 1 is done in the args list.
if !self.resource_timing_buffer_pending_full_event.get() {
// Step 2.
@ -397,7 +398,7 @@ impl Performance {
}
// Step 3.
self.resource_timing_buffer_pending_full_event.set(true);
self.fire_buffer_full_event();
self.fire_buffer_full_event(can_gc);
}
// Steps 4 and 5.
self.resource_timing_secondary_entries
@ -469,7 +470,7 @@ impl PerformanceMethods for Performance {
}
// https://w3c.github.io/user-timing/#dom-performance-mark
fn Mark(&self, mark_name: DOMString) -> Fallible<()> {
fn Mark(&self, mark_name: DOMString, can_gc: CanGc) -> Fallible<()> {
let global = self.global();
// Step 1.
if global.is::<Window>() && INVALID_ENTRY_NAMES.contains(&mark_name.as_ref()) {
@ -484,7 +485,7 @@ impl PerformanceMethods for Performance {
Duration::ZERO,
);
// Steps 7 and 8.
self.queue_entry(entry.upcast::<PerformanceEntry>());
self.queue_entry(entry.upcast::<PerformanceEntry>(), can_gc);
// Step 9.
Ok(())
@ -503,6 +504,7 @@ impl PerformanceMethods for Performance {
measure_name: DOMString,
start_mark: Option<DOMString>,
end_mark: Option<DOMString>,
can_gc: CanGc,
) -> Fallible<()> {
// Steps 1 and 2.
let end_time = end_mark
@ -532,7 +534,7 @@ impl PerformanceMethods for Performance {
);
// Step 9 and 10.
self.queue_entry(entry.upcast::<PerformanceEntry>());
self.queue_entry(entry.upcast::<PerformanceEntry>(), can_gc);
// Step 11.
Ok(())

View file

@ -96,7 +96,7 @@ impl Selection {
task!(selectionchange_task_steps: move || {
let this = this.root();
this.task_queued.set(false);
this.document.upcast::<EventTarget>().fire_event(atom!("selectionchange"));
this.document.upcast::<EventTarget>().fire_event(atom!("selectionchange"), CanGc::note());
}),
window.upcast(),
)

View file

@ -27,7 +27,7 @@ use crate::dom::bindings::structuredclone;
use crate::dom::bindings::trace::RootedTraceableBox;
use crate::dom::eventtarget::EventTarget;
use crate::dom::globalscope::GlobalScope;
use crate::script_runtime::JSContext;
use crate::script_runtime::{CanGc, JSContext};
use crate::task::TaskOnce;
pub type TrustedServiceWorkerAddress = Trusted<ServiceWorker>;
@ -74,15 +74,15 @@ impl ServiceWorker {
)
}
pub fn dispatch_simple_error(address: TrustedServiceWorkerAddress) {
pub fn dispatch_simple_error(address: TrustedServiceWorkerAddress, can_gc: CanGc) {
let service_worker = address.root();
service_worker.upcast().fire_event(atom!("error"));
service_worker.upcast().fire_event(atom!("error"), can_gc);
}
pub fn set_transition_state(&self, state: ServiceWorkerState) {
pub fn set_transition_state(&self, state: ServiceWorkerState, can_gc: CanGc) {
self.state.set(state);
self.upcast::<EventTarget>()
.fire_event(atom!("statechange"));
.fire_event(atom!("statechange"), can_gc);
}
pub fn get_script_url(&self) -> ServoUrl {
@ -167,6 +167,6 @@ impl ServiceWorkerMethods for ServiceWorker {
impl TaskOnce for SimpleWorkerErrorHandler<ServiceWorker> {
#[allow(crown::unrooted_must_root)]
fn run_once(self) {
ServiceWorker::dispatch_simple_error(self.addr);
ServiceWorker::dispatch_simple_error(self.addr, CanGc::note());
}
}

View file

@ -360,17 +360,21 @@ impl ServiceWorkerGlobalScope {
.referrer_policy(referrer_policy)
.origin(origin);
let (_url, source) =
match load_whole_resource(request, &resource_threads_sender, global.upcast()) {
Err(_) => {
println!("error loading script {}", serialized_worker_url);
scope.clear_js_runtime();
return;
},
Ok((metadata, bytes)) => {
(metadata.final_url, String::from_utf8(bytes).unwrap())
},
};
let (_url, source) = match load_whole_resource(
request,
&resource_threads_sender,
global.upcast(),
CanGc::note(),
) {
Err(_) => {
println!("error loading script {}", serialized_worker_url);
scope.clear_js_runtime();
return;
},
Ok((metadata, bytes)) => {
(metadata.final_url, String::from_utf8(bytes).unwrap())
},
};
unsafe {
// Handle interrupt requests
@ -465,7 +469,8 @@ impl ServiceWorkerGlobalScope {
// TODO XXXcreativcoder This will eventually use a FetchEvent interface to fire event
// when we have the Request and Response dom api's implemented
// https://w3c.github.io/ServiceWorker/#fetchevent-interface
self.upcast::<EventTarget>().fire_event(atom!("fetch"));
self.upcast::<EventTarget>()
.fire_event(atom!("fetch"), can_gc);
let _ = mediator.response_chan.send(None);
},
WakeUp => {},

View file

@ -404,14 +404,15 @@ impl ServoParser {
// Step 2.
self.document
.set_ready_state(DocumentReadyState::Interactive);
.set_ready_state(DocumentReadyState::Interactive, can_gc);
// Step 3.
self.tokenizer.end(can_gc);
self.document.set_current_parser(None);
// Step 4.
self.document.set_ready_state(DocumentReadyState::Complete);
self.document
.set_ready_state(DocumentReadyState::Complete, can_gc);
}
// https://html.spec.whatwg.org/multipage/#active-parser
@ -633,7 +634,7 @@ impl ServoParser {
// Step 1.
self.document
.set_ready_state(DocumentReadyState::Interactive);
.set_ready_state(DocumentReadyState::Interactive, can_gc);
// Step 2.
self.tokenizer.end(can_gc);
@ -1006,10 +1007,10 @@ impl FetchResponseListener for ParserContext {
CrossProcessInstant::now(),
document,
);
self.pushed_entry_index = document
.global()
.performance()
.queue_entry(performance_entry.upcast::<PerformanceEntry>());
self.pushed_entry_index = document.global().performance().queue_entry(
performance_entry.upcast::<PerformanceEntry>(),
CanGc::note(),
);
}
}

View file

@ -99,13 +99,13 @@ impl TextTrackList {
// FIXME(#22314, dlrobertson) allow TextTracks to be
// removed from the TextTrackList.
#[allow(dead_code)]
pub fn remove(&self, idx: usize) {
pub fn remove(&self, idx: usize, can_gc: CanGc) {
if let Some(track) = self.dom_tracks.borrow().get(idx) {
track.remove_track_list();
}
self.dom_tracks.borrow_mut().remove(idx);
self.upcast::<EventTarget>()
.fire_event(atom!("removetrack"));
.fire_event(atom!("removetrack"), can_gc);
}
}

View file

@ -15,6 +15,7 @@ use crate::dom::eventtarget::EventTarget;
use crate::dom::htmlmediaelement::HTMLMediaElement;
use crate::dom::videotrack::VideoTrack;
use crate::dom::window::Window;
use crate::script_runtime::CanGc;
use crate::task_source::TaskSource;
#[dom_struct]
@ -99,7 +100,7 @@ impl VideoTrackList {
let _ = source.queue_with_canceller(
task!(media_track_change: move || {
let this = this.root();
this.upcast::<EventTarget>().fire_event(atom!("change"));
this.upcast::<EventTarget>().fire_event(atom!("change"), CanGc::note());
}),
&canceller,
);

View file

@ -478,7 +478,7 @@ impl TaskOnce for ConnectionEstablishedTask {
};
// Step 4.
ws.upcast().fire_event(atom!("open"));
ws.upcast().fire_event(atom!("open"), CanGc::note());
}
}
@ -524,7 +524,7 @@ impl TaskOnce for CloseTask {
// Step 2.
if self.failed {
ws.upcast().fire_event(atom!("error"));
ws.upcast().fire_event(atom!("error"), CanGc::note());
}
// Step 3.

View file

@ -128,9 +128,9 @@ impl Worker {
}
}
pub fn dispatch_simple_error(address: TrustedWorkerAddress) {
pub fn dispatch_simple_error(address: TrustedWorkerAddress, can_gc: CanGc) {
let worker = address.root();
worker.upcast().fire_event(atom!("error"));
worker.upcast().fire_event(atom!("error"), can_gc);
}
/// <https://html.spec.whatwg.org/multipage/#dom-dedicatedworkerglobalscope-postmessage>
@ -301,6 +301,6 @@ impl WorkerMethods for Worker {
impl TaskOnce for SimpleWorkerErrorHandler<Worker> {
#[allow(crown::unrooted_must_root)]
fn run_once(self) {
Worker::dispatch_simple_error(self.addr);
Worker::dispatch_simple_error(self.addr, CanGc::note());
}
}

View file

@ -248,7 +248,7 @@ impl WorkerGlobalScopeMethods for WorkerGlobalScope {
error_event_handler!(error, GetOnerror, SetOnerror);
// https://html.spec.whatwg.org/multipage/#dom-workerglobalscope-importscripts
fn ImportScripts(&self, url_strings: Vec<DOMString>) -> ErrorResult {
fn ImportScripts(&self, url_strings: Vec<DOMString>, can_gc: CanGc) -> ErrorResult {
let mut urls = Vec::with_capacity(url_strings.len());
for url in url_strings {
let url = self.worker_url.borrow().join(&url);
@ -274,6 +274,7 @@ impl WorkerGlobalScopeMethods for WorkerGlobalScope {
request,
&global_scope.resource_threads().sender(),
global_scope,
can_gc,
) {
Err(_) => return Err(Error::Network),
Ok((metadata, bytes)) => (metadata.final_url, String::from_utf8(bytes).unwrap()),

View file

@ -662,6 +662,7 @@ impl WorkletThread {
request,
&resource_fetcher,
global_scope.upcast::<GlobalScope>(),
can_gc,
)
.ok()
.and_then(|(_, bytes)| String::from_utf8(bytes).ok());

View file

@ -291,7 +291,7 @@ impl XMLHttpRequest {
}
fn submit_resource_timing(&mut self) {
network_listener::submit_timing(self)
network_listener::submit_timing(self, CanGc::note())
}
}

View file

@ -303,7 +303,7 @@ impl FetchResponseListener for FetchContext {
fn submit_resource_timing(&mut self) {
// navigation submission is handled in servoparser/mod.rs
if self.resource_timing.timing_type == ResourceTimingType::Resource {
network_listener::submit_timing(self)
network_listener::submit_timing(self, CanGc::note())
}
}
}
@ -333,6 +333,7 @@ pub fn load_whole_resource(
request: RequestBuilder,
core_resource_thread: &CoreResourceThread,
global: &GlobalScope,
can_gc: CanGc,
) -> Result<(Metadata, Vec<u8>), NetworkError> {
let request = request.https_state(global.get_https_state());
let (action_sender, action_receiver) = ipc::channel().unwrap();
@ -360,7 +361,7 @@ pub fn load_whole_resource(
FetchResponseMsg::ProcessResponseEOF(_, Ok(_)) => {
let metadata = metadata.unwrap();
if let Some(timing) = &metadata.timing {
submit_timing_data(global, url, InitiatorType::Other, timing);
submit_timing_data(global, url, InitiatorType::Other, timing, can_gc);
}
return Ok((metadata, buf));
},

View file

@ -24,6 +24,7 @@ use crate::dom::globalscope::GlobalScope;
use crate::dom::node::{document_from_node, Node};
use crate::dom::performanceresourcetiming::InitiatorType;
use crate::network_listener::{self, PreInvoke, ResourceTimingListener};
use crate::script_runtime::CanGc;
struct LayoutImageContext {
id: PendingImageId,
@ -74,7 +75,7 @@ impl FetchResponseListener for LayoutImageContext {
}
fn submit_resource_timing(&mut self) {
network_listener::submit_timing(self)
network_listener::submit_timing(self, CanGc::note())
}
}

View file

@ -15,6 +15,7 @@ use crate::dom::bindings::root::DomRoot;
use crate::dom::globalscope::GlobalScope;
use crate::dom::performanceentry::PerformanceEntry;
use crate::dom::performanceresourcetiming::{InitiatorType, PerformanceResourceTiming};
use crate::script_runtime::CanGc;
use crate::task::{TaskCanceller, TaskOnce};
use crate::task_source::networking::NetworkingTaskSource;
use crate::task_source::TaskSource;
@ -32,7 +33,10 @@ pub trait ResourceTimingListener {
fn resource_timing_global(&self) -> DomRoot<GlobalScope>;
}
pub fn submit_timing<T: ResourceTimingListener + FetchResponseListener>(listener: &T) {
pub fn submit_timing<T: ResourceTimingListener + FetchResponseListener>(
listener: &T,
can_gc: CanGc,
) {
if listener.resource_timing().timing_type != ResourceTimingType::Resource {
warn!(
"Submitting non-resource ({:?}) timing as resource",
@ -52,6 +56,7 @@ pub fn submit_timing<T: ResourceTimingListener + FetchResponseListener>(listener
url,
initiator_type,
listener.resource_timing(),
can_gc,
);
}
@ -60,12 +65,13 @@ pub fn submit_timing_data(
url: ServoUrl,
initiator_type: InitiatorType,
resource_timing: &ResourceFetchTiming,
can_gc: CanGc,
) {
let performance_entry =
PerformanceResourceTiming::new(global, url, initiator_type, None, resource_timing);
global
.performance()
.queue_entry(performance_entry.upcast::<PerformanceEntry>());
.queue_entry(performance_entry.upcast::<PerformanceEntry>(), can_gc);
}
impl<Listener: PreInvoke + Send + 'static> NetworkListener<Listener> {

View file

@ -1210,7 +1210,7 @@ impl FetchResponseListener for ModuleContext {
}
fn submit_resource_timing(&mut self) {
network_listener::submit_timing(self)
network_listener::submit_timing(self, CanGc::note())
}
}

View file

@ -2418,7 +2418,7 @@ impl ScriptThread {
self.handle_exit_pipeline_msg(pipeline_id, discard_browsing_context, can_gc)
},
ConstellationControlMsg::PaintMetric(pipeline_id, metric_type, metric_value) => {
self.handle_paint_metric(pipeline_id, metric_type, metric_value)
self.handle_paint_metric(pipeline_id, metric_type, metric_value, can_gc)
},
ConstellationControlMsg::MediaSessionAction(pipeline_id, action) => {
self.handle_media_session_action(pipeline_id, action, can_gc)
@ -3828,7 +3828,7 @@ impl ScriptThread {
incomplete.canceller,
can_gc,
);
document.set_ready_state(DocumentReadyState::Loading);
document.set_ready_state(DocumentReadyState::Loading, can_gc);
self.documents
.borrow_mut()
@ -4278,6 +4278,7 @@ impl ScriptThread {
pipeline_id: PipelineId,
metric_type: ProgressiveWebMetricType,
metric_value: CrossProcessInstant,
can_gc: CanGc,
) {
let window = self.documents.borrow().find_window(pipeline_id);
if let Some(window) = window {
@ -4288,7 +4289,7 @@ impl ScriptThread {
);
window
.Performance()
.queue_entry(entry.upcast::<PerformanceEntry>());
.queue_entry(entry.upcast::<PerformanceEntry>(), can_gc);
}
}

View file

@ -222,7 +222,8 @@ impl FetchResponseListener for StylesheetContext {
} else {
atom!("load")
};
elem.upcast::<EventTarget>().fire_event(event);
elem.upcast::<EventTarget>()
.fire_event(event, CanGc::note());
}
}
@ -235,7 +236,7 @@ impl FetchResponseListener for StylesheetContext {
}
fn submit_resource_timing(&mut self) {
network_listener::submit_timing(self)
network_listener::submit_timing(self, CanGc::note())
}
}

View file

@ -1123,9 +1123,9 @@ pub fn handle_element_click(
// Steps 8.2 - 8.4
let event_target = parent_node.upcast::<EventTarget>();
event_target.fire_event(atom!("mouseover"));
event_target.fire_event(atom!("mousemove"));
event_target.fire_event(atom!("mousedown"));
event_target.fire_event(atom!("mouseover"), can_gc);
event_target.fire_event(atom!("mousemove"), can_gc);
event_target.fire_event(atom!("mousedown"), can_gc);
// Step 8.5
match parent_node.downcast::<HTMLElement>() {
@ -1136,7 +1136,7 @@ pub fn handle_element_click(
// Step 8.6
if !option_element.Disabled() {
// Step 8.6.1
event_target.fire_event(atom!("input"));
event_target.fire_event(atom!("input"), can_gc);
// Steps 8.6.2
let previous_selectedness = option_element.Selected();
@ -1153,13 +1153,13 @@ pub fn handle_element_click(
// Step 8.6.4
if !previous_selectedness {
event_target.fire_event(atom!("change"));
event_target.fire_event(atom!("change"), can_gc);
}
}
// Steps 8.7 - 8.8
event_target.fire_event(atom!("mouseup"));
event_target.fire_event(atom!("click"));
event_target.fire_event(atom!("mouseup"), can_gc);
event_target.fire_event(atom!("click"), can_gc);
Ok(None)
},