diff options
Diffstat (limited to 'components/script/dom/htmlmediaelement.rs')
-rw-r--r-- | components/script/dom/htmlmediaelement.rs | 115 |
1 files changed, 58 insertions, 57 deletions
diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs index 8a5889cae8f..e9c0b1e8a35 100644 --- a/components/script/dom/htmlmediaelement.rs +++ b/components/script/dom/htmlmediaelement.rs @@ -101,6 +101,7 @@ use crate::fetch::{create_a_potential_cors_request, FetchCanceller}; use crate::microtask::{Microtask, MicrotaskRunnable}; use crate::network_listener::{self, NetworkListener, PreInvoke, ResourceTimingListener}; use crate::realms::{enter_realm, InRealm}; +use crate::script_runtime::CanGc; use crate::script_thread::ScriptThread; use crate::task_source::TaskSource; @@ -496,12 +497,12 @@ impl HTMLMediaElement { /// we pass true to that method again. /// /// <https://html.spec.whatwg.org/multipage/#delaying-the-load-event-flag> - pub fn delay_load_event(&self, delay: bool) { + pub fn delay_load_event(&self, delay: bool, can_gc: CanGc) { let mut blocker = self.delaying_the_load_event_flag.borrow_mut(); if delay && blocker.is_none() { *blocker = Some(LoadBlocker::new(&document_from_node(self), LoadType::Media)); } else if !delay && blocker.is_some() { - LoadBlocker::terminate(&mut blocker); + LoadBlocker::terminate(&mut blocker, can_gc); } } @@ -607,7 +608,7 @@ impl HTMLMediaElement { } // https://html.spec.whatwg.org/multipage/#ready-states - fn change_ready_state(&self, ready_state: ReadyState) { + fn change_ready_state(&self, ready_state: ReadyState, can_gc: CanGc) { let old_ready_state = self.ready_state.get(); self.ready_state.set(ready_state); @@ -638,7 +639,7 @@ impl HTMLMediaElement { task!(media_reached_current_data: move || { let this = this.root(); this.upcast::<EventTarget>().fire_event(atom!("loadeddata")); - this.delay_load_event(false); + this.delay_load_event(false, can_gc); }), window.upcast(), ); @@ -697,7 +698,7 @@ impl HTMLMediaElement { } // https://html.spec.whatwg.org/multipage/#concept-media-load-algorithm - fn invoke_resource_selection_algorithm(&self) { + fn invoke_resource_selection_algorithm(&self, can_gc: CanGc) { // Step 1. self.network_state.set(NetworkState::NoSource); @@ -705,7 +706,7 @@ impl HTMLMediaElement { self.set_show_poster(true); // Step 3. - self.delay_load_event(true); + self.delay_load_event(true, can_gc); // Step 4. // If the resource selection mode in the synchronous section is @@ -728,7 +729,7 @@ impl HTMLMediaElement { } // https://html.spec.whatwg.org/multipage/#concept-media-load-algorithm - fn resource_selection_algorithm_sync(&self, base_url: ServoUrl) { + fn resource_selection_algorithm_sync(&self, base_url: ServoUrl, can_gc: CanGc) { // Step 5. // FIXME(ferjm): Implement blocked_on_parser logic // https://html.spec.whatwg.org/multipage/#blocked-on-parser @@ -765,7 +766,7 @@ impl HTMLMediaElement { } else { self.network_state.set(NetworkState::Empty); // https://github.com/whatwg/html/issues/3065 - self.delay_load_event(false); + self.delay_load_event(false, can_gc); return; }; @@ -792,12 +793,12 @@ impl HTMLMediaElement { // Step 9.obj.3. // Note that the resource fetch algorithm itself takes care // of the cleanup in case of failure itself. - self.resource_fetch_algorithm(Resource::Object); + self.resource_fetch_algorithm(Resource::Object, can_gc); }, Mode::Attribute(src) => { // Step 9.attr.1. if src.is_empty() { - self.queue_dedicated_media_source_failure_steps(); + self.queue_dedicated_media_source_failure_steps(can_gc); return; } @@ -805,7 +806,7 @@ impl HTMLMediaElement { let url_record = match base_url.join(&src) { Ok(url) => url, Err(_) => { - self.queue_dedicated_media_source_failure_steps(); + self.queue_dedicated_media_source_failure_steps(can_gc); return; }, }; @@ -816,7 +817,7 @@ impl HTMLMediaElement { // Step 9.attr.4. // Note that the resource fetch algorithm itself takes care // of the cleanup in case of failure itself. - self.resource_fetch_algorithm(Resource::Url(url_record)); + self.resource_fetch_algorithm(Resource::Url(url_record), can_gc); }, // Step 9.children. Mode::Children(source) => { @@ -826,7 +827,7 @@ impl HTMLMediaElement { // Step 9.attr.2. if src.is_empty() { source.upcast::<EventTarget>().fire_event(atom!("error")); - self.queue_dedicated_media_source_failure_steps(); + self.queue_dedicated_media_source_failure_steps(can_gc); return; } // Step 9.attr.3. @@ -834,20 +835,20 @@ impl HTMLMediaElement { Ok(url) => url, Err(_) => { source.upcast::<EventTarget>().fire_event(atom!("error")); - self.queue_dedicated_media_source_failure_steps(); + self.queue_dedicated_media_source_failure_steps(can_gc); return; }, }; // Step 9.attr.8. - self.resource_fetch_algorithm(Resource::Url(url_record)); + self.resource_fetch_algorithm(Resource::Url(url_record), can_gc); }, } } - fn fetch_request(&self, offset: Option<u64>, seek_lock: Option<SeekLock>) { + fn fetch_request(&self, offset: Option<u64>, seek_lock: Option<SeekLock>, can_gc: CanGc) { if self.resource_url.borrow().is_none() && self.blob_url.borrow().is_none() { eprintln!("Missing request url"); - self.queue_dedicated_media_source_failure_steps(); + self.queue_dedicated_media_source_failure_steps(can_gc); return; } @@ -919,10 +920,10 @@ impl HTMLMediaElement { } // https://html.spec.whatwg.org/multipage/#concept-media-load-resource - fn resource_fetch_algorithm(&self, resource: Resource) { - if let Err(e) = self.setup_media_player(&resource) { + fn resource_fetch_algorithm(&self, resource: Resource, can_gc: CanGc) { + if let Err(e) = self.setup_media_player(&resource, CanGc::note()) { eprintln!("Setup media player error {:?}", e); - self.queue_dedicated_media_source_failure_steps(); + self.queue_dedicated_media_source_failure_steps(CanGc::note()); return; } @@ -955,7 +956,7 @@ impl HTMLMediaElement { .media_element_task_source() .queue( task!(set_media_delay_load_event_flag_to_false: move || { - this.root().delay_load_event(false); + this.root().delay_load_event(false, can_gc); }), window.upcast(), ) @@ -974,7 +975,7 @@ impl HTMLMediaElement { // Step 4.remote.2. *self.resource_url.borrow_mut() = Some(url); - self.fetch_request(None, None); + self.fetch_request(None, None, can_gc); }, Resource::Object => { if let Some(ref src_object) = *self.src_object.borrow() { @@ -983,7 +984,7 @@ impl HTMLMediaElement { let blob_url = URL::CreateObjectURL(&self.global(), blob); *self.blob_url.borrow_mut() = Some(ServoUrl::parse(&blob_url).expect("infallible")); - self.fetch_request(None, None); + self.fetch_request(None, None, can_gc); }, SrcObject::MediaStream(ref stream) => { let tracks = &*stream.get_tracks(); @@ -998,7 +999,7 @@ impl HTMLMediaElement { .set_stream(&track.id(), pos == tracks.len() - 1) .is_err() { - self.queue_dedicated_media_source_failure_steps(); + self.queue_dedicated_media_source_failure_steps(CanGc::note()); } } }, @@ -1011,7 +1012,7 @@ impl HTMLMediaElement { /// Queues a task to run the [dedicated media source failure steps][steps]. /// /// [steps]: https://html.spec.whatwg.org/multipage/#dedicated-media-source-failure-steps - fn queue_dedicated_media_source_failure_steps(&self) { + fn queue_dedicated_media_source_failure_steps(&self, can_gc: CanGc) { let window = window_from_node(self); let this = Trusted::new(self); let generation_id = self.generation_id.get(); @@ -1056,7 +1057,7 @@ impl HTMLMediaElement { }); // Step 7. - this.delay_load_event(false); + this.delay_load_event(false, can_gc); }), window.upcast(), ); @@ -1104,7 +1105,7 @@ impl HTMLMediaElement { } // https://html.spec.whatwg.org/multipage/#media-element-load-algorithm - fn media_element_load_algorithm(&self) { + fn media_element_load_algorithm(&self, can_gc: CanGc) { // Reset the flag that signals whether loadeddata was ever fired for // this invokation of the load algorithm. self.fired_loadeddata_event.set(false); @@ -1145,7 +1146,7 @@ impl HTMLMediaElement { // Step 6.5. if self.ready_state.get() != ReadyState::HaveNothing { - self.change_ready_state(ReadyState::HaveNothing); + self.change_ready_state(ReadyState::HaveNothing, can_gc); } // Step 6.6. @@ -1185,7 +1186,7 @@ impl HTMLMediaElement { self.autoplaying.set(true); // Step 9. - self.invoke_resource_selection_algorithm(); + self.invoke_resource_selection_algorithm(CanGc::note()); // Step 10. // FIXME(nox): Stop playback of any previously running media resource. @@ -1245,14 +1246,14 @@ impl HTMLMediaElement { /// Handles insertion of `source` children. /// /// <https://html.spec.whatwg.org/multipage/#the-source-element:nodes-are-inserted> - pub fn handle_source_child_insertion(&self) { + pub fn handle_source_child_insertion(&self, can_gc: CanGc) { if self.upcast::<Element>().has_attribute(&local_name!("src")) { return; } if self.network_state.get() != NetworkState::Empty { return; } - self.media_element_load_algorithm(); + self.media_element_load_algorithm(can_gc); } // https://html.spec.whatwg.org/multipage/#dom-media-seek @@ -1351,7 +1352,7 @@ impl HTMLMediaElement { } } - fn setup_media_player(&self, resource: &Resource) -> Result<(), ()> { + fn setup_media_player(&self, resource: &Resource, _can_gc: CanGc) -> Result<(), ()> { let stream_type = match *resource { Resource::Object => { if let Some(ref src_object) = *self.src_object.borrow() { @@ -1402,7 +1403,7 @@ impl HTMLMediaElement { let this = trusted_node.clone(); if let Err(err) = task_source.queue_with_canceller( task!(handle_player_event: move || { - this.root().handle_player_event(&event); + this.root().handle_player_event(&event, CanGc::note()); }), &canceller, ) { @@ -1495,14 +1496,14 @@ impl HTMLMediaElement { } } - fn handle_player_event(&self, event: &PlayerEvent) { + fn handle_player_event(&self, event: &PlayerEvent, can_gc: CanGc) { match *event { PlayerEvent::EndOfStream => { // https://html.spec.whatwg.org/multipage/#media-data-processing-steps-list // => "If the media data can be fetched but is found by inspection to be in // an unsupported format, or can otherwise not be rendered at all" if self.ready_state.get() < ReadyState::HaveMetadata { - self.queue_dedicated_media_source_failure_steps(); + self.queue_dedicated_media_source_failure_steps(can_gc); } else { // https://html.spec.whatwg.org/multipage/#reaches-the-end match self.direction_of_playback() { @@ -1548,7 +1549,7 @@ impl HTMLMediaElement { ); // https://html.spec.whatwg.org/multipage/#dom-media-have_current_data - self.change_ready_state(ReadyState::HaveCurrentData); + self.change_ready_state(ReadyState::HaveCurrentData, can_gc); } }, @@ -1592,7 +1593,7 @@ impl HTMLMediaElement { self.network_state.set(NetworkState::Idle); // 4. Set the element's delaying-the-load-event flag to false. This stops delaying the load event. - self.delay_load_event(false); + self.delay_load_event(false, can_gc); // 5. Fire an event named error at the media element. self.upcast::<EventTarget>().fire_event(atom!("error")); @@ -1752,7 +1753,7 @@ impl HTMLMediaElement { } // Step 6. - self.change_ready_state(ReadyState::HaveMetadata); + self.change_ready_state(ReadyState::HaveMetadata, can_gc); // Step 7. let mut jumped = false; @@ -1822,7 +1823,7 @@ impl HTMLMediaElement { } }, PlayerEvent::EnoughData => { - self.change_ready_state(ReadyState::HaveEnoughData); + self.change_ready_state(ReadyState::HaveEnoughData, can_gc); // The player has enough data and it is asking us to stop pushing // bytes, so we cancel the ongoing fetch request iff we are able @@ -1855,7 +1856,7 @@ impl HTMLMediaElement { )); }, PlayerEvent::SeekData(p, ref seek_lock) => { - self.fetch_request(Some(p), Some(seek_lock.clone())); + self.fetch_request(Some(p), Some(seek_lock.clone()), can_gc); }, PlayerEvent::SeekDone(_) => { // Continuation of @@ -1874,7 +1875,7 @@ impl HTMLMediaElement { PlaybackState::Paused => { media_session_playback_state = MediaSessionPlaybackState::Paused; if self.ready_state.get() == ReadyState::HaveMetadata { - self.change_ready_state(ReadyState::HaveEnoughData); + self.change_ready_state(ReadyState::HaveEnoughData, can_gc); } }, PlaybackState::Playing => { @@ -1984,13 +1985,13 @@ impl HTMLMediaElement { /// selected by the servo-media Player instance. However, in some cases, like /// the WebAudio MediaElementAudioSourceNode, we need to set a custom audio /// renderer. - pub fn set_audio_renderer(&self, audio_renderer: Arc<Mutex<dyn AudioRenderer>>) { + pub fn set_audio_renderer(&self, audio_renderer: Arc<Mutex<dyn AudioRenderer>>, can_gc: CanGc) { *self.audio_renderer.borrow_mut() = Some(audio_renderer); if let Some(ref player) = *self.player.borrow() { if let Err(e) = player.lock().unwrap().stop() { eprintln!("Could not stop player {:?}", e); } - self.media_element_load_algorithm(); + self.media_element_load_algorithm(can_gc); } } @@ -2141,9 +2142,9 @@ impl HTMLMediaElementMethods for HTMLMediaElement { } // https://html.spec.whatwg.org/multipage/#dom-media-srcobject - fn SetSrcObject(&self, value: Option<MediaStreamOrBlob>) { + fn SetSrcObject(&self, value: Option<MediaStreamOrBlob>, can_gc: CanGc) { *self.src_object.borrow_mut() = value.map(|value| value.into()); - self.media_element_load_algorithm(); + self.media_element_load_algorithm(can_gc); } // https://html.spec.whatwg.org/multipage/#attr-media-preload @@ -2158,8 +2159,8 @@ impl HTMLMediaElementMethods for HTMLMediaElement { } // https://html.spec.whatwg.org/multipage/#dom-media-load - fn Load(&self) { - self.media_element_load_algorithm(); + fn Load(&self, can_gc: CanGc) { + self.media_element_load_algorithm(can_gc); } // https://html.spec.whatwg.org/multipage/#dom-navigator-canplaytype @@ -2177,7 +2178,7 @@ impl HTMLMediaElementMethods for HTMLMediaElement { } // https://html.spec.whatwg.org/multipage/#dom-media-play - fn Play(&self, comp: InRealm) -> Rc<Promise> { + fn Play(&self, comp: InRealm, can_gc: CanGc) -> Rc<Promise> { let promise = Promise::new_in_current_realm(comp); // Step 1. // FIXME(nox): Reject promise if not allowed to play. @@ -2197,7 +2198,7 @@ impl HTMLMediaElementMethods for HTMLMediaElement { // Step 4. if self.network_state.get() == NetworkState::Empty { - self.invoke_resource_selection_algorithm(); + self.invoke_resource_selection_algorithm(can_gc); } // Step 5. @@ -2267,10 +2268,10 @@ impl HTMLMediaElementMethods for HTMLMediaElement { } // https://html.spec.whatwg.org/multipage/#dom-media-pause - fn Pause(&self) { + fn Pause(&self, can_gc: CanGc) { // Step 1 if self.network_state.get() == NetworkState::Empty { - self.invoke_resource_selection_algorithm(); + self.invoke_resource_selection_algorithm(can_gc); } // Step 2 @@ -2489,7 +2490,7 @@ impl VirtualMethods for HTMLMediaElement { if mutation.new_value(attr).is_none() { return; } - self.media_element_load_algorithm(); + self.media_element_load_algorithm(CanGc::note()); }, local_name!("controls") => { if mutation.new_value(attr).is_some() { @@ -2552,7 +2553,7 @@ pub enum MediaElementMicrotask { } impl MicrotaskRunnable for MediaElementMicrotask { - fn handler(&self) { + fn handler(&self, can_gc: CanGc) { match self { &MediaElementMicrotask::ResourceSelectionTask { ref elem, @@ -2560,7 +2561,7 @@ impl MicrotaskRunnable for MediaElementMicrotask { ref base_url, } => { if generation_id == elem.generation_id.get() { - elem.resource_selection_algorithm_sync(base_url.clone()); + elem.resource_selection_algorithm_sync(base_url.clone(), can_gc); } }, MediaElementMicrotask::PauseIfNotInDocumentTask { elem } => { @@ -2752,7 +2753,7 @@ impl FetchResponseListener for HTMLMediaElementFetchListener { if let Some(ref mut current_fetch_context) = *elem.current_fetch_context.borrow_mut() { current_fetch_context.cancel(CancelReason::Error); } - elem.queue_dedicated_media_source_failure_steps(); + elem.queue_dedicated_media_source_failure_steps(CanGc::note()); } } @@ -2878,13 +2879,13 @@ impl FetchResponseListener for HTMLMediaElementFetchListener { elem.network_state.set(NetworkState::Idle); // Step 4. - elem.delay_load_event(false); + elem.delay_load_event(false, CanGc::note()); // Step 5 elem.upcast::<EventTarget>().fire_event(atom!("error")); } else { // => "If the media data cannot be fetched at all..." - elem.queue_dedicated_media_source_failure_steps(); + elem.queue_dedicated_media_source_failure_steps(CanGc::note()); } } |