diff options
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/dom/htmlmediaelement.rs | 137 |
1 files changed, 78 insertions, 59 deletions
diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs index 79560fce4ba..965599e93c3 100644 --- a/components/script/dom/htmlmediaelement.rs +++ b/components/script/dom/htmlmediaelement.rs @@ -19,7 +19,7 @@ use dom::bindings::reflector::DomObject; use dom::bindings::str::DOMString; use dom::document::Document; use dom::element::{Element, AttributeMutation}; -use dom::event::{Event, EventBubbles, EventCancelable}; +use dom::eventtarget::EventTarget; use dom::htmlaudioelement::HTMLAudioElement; use dom::htmlelement::HTMLElement; use dom::htmlsourceelement::HTMLSourceElement; @@ -36,7 +36,6 @@ use net_traits::{FetchResponseListener, FetchMetadata, Metadata, NetworkError}; use net_traits::request::{CredentialsMode, Destination, RequestInit, Type as RequestType}; use network_listener::{NetworkListener, PreInvoke}; use script_thread::{Runnable, ScriptThread}; -use servo_atoms::Atom; use servo_url::ServoUrl; use std::cell::Cell; use std::sync::{Arc, Mutex}; @@ -111,7 +110,12 @@ impl FetchResponseListener for HTMLMediaElementContext { // https://html.spec.whatwg.org/multipage/#concept-media-load-resource step 4, // => "If mode is remote" step 2 if time::get_time() > self.next_progress_event { - elem.queue_fire_simple_event("progress"); + let window = window_from_node(&*elem); + window.dom_manipulation_task_source().queue_simple_event( + elem.upcast(), + atom!("progress"), + &window, + ); self.next_progress_event = time::get_time() + Duration::milliseconds(350); } } @@ -129,11 +133,11 @@ impl FetchResponseListener for HTMLMediaElementContext { else if status.is_ok() { elem.change_ready_state(HAVE_ENOUGH_DATA); - elem.fire_simple_event("progress"); + elem.upcast::<EventTarget>().fire_event(atom!("progress")); elem.network_state.set(NETWORK_IDLE); - elem.fire_simple_event("suspend"); + elem.upcast::<EventTarget>().fire_event(atom!("suspend")); } // => "If the connection is interrupted after some media data has been received..." else if elem.ready_state.get() != HAVE_NOTHING { @@ -147,7 +151,7 @@ impl FetchResponseListener for HTMLMediaElementContext { // TODO: Step 4 - update delay load flag // Step 5 - elem.fire_simple_event("error"); + elem.upcast::<EventTarget>().fire_event(atom!("error")); } else { // => "If the media data cannot be fetched at all..." elem.queue_dedicated_media_source_failure_steps(); @@ -267,7 +271,7 @@ impl HTMLMediaElement { // https://html.spec.whatwg.org/multipage/#notify-about-playing fn notify_about_playing(&self) { // Step 1 - self.fire_simple_event("playing"); + self.upcast::<EventTarget>().fire_event(atom!("playing")); // TODO Step 2 } @@ -297,11 +301,11 @@ impl HTMLMediaElement { impl Runnable for Task { fn handler(self: Box<Task>) { - let elem = self.elem.root(); + let target = Root::upcast::<EventTarget>(self.elem.root()); // 2.2.1 - elem.fire_simple_event("timeupdate"); + target.fire_event(atom!("timeupdate")); // 2.2.2 - elem.fire_simple_event("pause"); + target.fire_event(atom!("pause")); // TODO 2.2.3 } } @@ -313,21 +317,6 @@ impl HTMLMediaElement { let _ = win.dom_manipulation_task_source().queue(task, win.upcast()); } - fn queue_fire_simple_event(&self, type_: &'static str) { - let win = window_from_node(self); - let task = box FireSimpleEventTask::new(self, type_); - let _ = win.dom_manipulation_task_source().queue(task, win.upcast()); - } - - fn fire_simple_event(&self, type_: &str) { - let window = window_from_node(self); - let event = Event::new(window.upcast(), - Atom::from(type_), - EventBubbles::DoesNotBubble, - EventCancelable::NotCancelable); - event.fire(self.upcast()); - } - // https://html.spec.whatwg.org/multipage/#ready-states fn change_ready_state(&self, ready_state: u16) { let old_ready_state = self.ready_state.get(); @@ -337,12 +326,19 @@ impl HTMLMediaElement { return; } + let window = window_from_node(self); + let task_source = window.dom_manipulation_task_source(); + // Step 1 match (old_ready_state, ready_state) { // previous ready state was HAVE_NOTHING, and the new ready state is // HAVE_METADATA (HAVE_NOTHING, HAVE_METADATA) => { - self.queue_fire_simple_event("loadedmetadata"); + task_source.queue_simple_event( + self.upcast(), + atom!("loadedmetadata"), + &window, + ); } // previous ready state was HAVE_METADATA and the new ready state is @@ -352,7 +348,11 @@ impl HTMLMediaElement { (HAVE_METADATA, HAVE_ENOUGH_DATA) => { if self.first_data_load.get() { self.first_data_load.set(false); - self.queue_fire_simple_event("loadeddata"); + task_source.queue_simple_event( + self.upcast(), + atom!("loadeddata"), + &window, + ); } } @@ -379,7 +379,11 @@ impl HTMLMediaElement { (HAVE_CURRENT_DATA, HAVE_FUTURE_DATA) | (HAVE_METADATA, HAVE_FUTURE_DATA) | (HAVE_NOTHING, HAVE_FUTURE_DATA) => { - self.queue_fire_simple_event("canplay"); + task_source.queue_simple_event( + self.upcast(), + atom!("canplay"), + &window, + ); if !self.Paused() { self.queue_notify_about_playing(); @@ -389,7 +393,11 @@ impl HTMLMediaElement { // new ready state is HAVE_ENOUGH_DATA (_, HAVE_ENOUGH_DATA) => { if old_ready_state <= HAVE_CURRENT_DATA { - self.queue_fire_simple_event("canplay"); + task_source.queue_simple_event( + self.upcast(), + atom!("canplay"), + &window, + ); if !self.Paused() { self.queue_notify_about_playing(); @@ -404,14 +412,22 @@ impl HTMLMediaElement { self.paused.set(false); // TODO step 2: show poster // Step 3 - self.queue_fire_simple_event("play"); + task_source.queue_simple_event( + self.upcast(), + atom!("play"), + &window, + ); // Step 4 self.queue_notify_about_playing(); // Step 5 self.autoplaying.set(false); } - self.queue_fire_simple_event("canplaythrough"); + task_source.queue_simple_event( + self.upcast(), + atom!("canplaythrough"), + &window, + ); } _ => (), @@ -460,7 +476,12 @@ impl HTMLMediaElement { self.network_state.set(NETWORK_LOADING); // Step 8 - self.queue_fire_simple_event("loadstart"); + let window = window_from_node(self); + window.dom_manipulation_task_source().queue_simple_event( + self.upcast(), + atom!("loadstart"), + &window, + ); // Step 9 match mode { @@ -511,7 +532,12 @@ impl HTMLMediaElement { self.network_state.set(NETWORK_IDLE); // 4.1.2 - self.queue_fire_simple_event("suspend"); + let window = window_from_node(self); + window.dom_manipulation_task_source().queue_simple_event( + self.upcast(), + atom!("suspend"), + &window, + ); // TODO 4.1.3 (delay load flag) @@ -584,7 +610,7 @@ impl HTMLMediaElement { // TODO step 4 (show poster) // Step 5 - self.fire_simple_event("error"); + self.upcast::<EventTarget>().fire_event(atom!("error")); // TODO step 6 (resolve pending play promises) // TODO step 7 (delay load event) @@ -600,16 +626,23 @@ impl HTMLMediaElement { self.generation_id.set(self.generation_id.get() + 1); // TODO reject pending play promises + let window = window_from_node(self); + let task_source = window.dom_manipulation_task_source(); + // Step 3 let network_state = self.NetworkState(); if network_state == NETWORK_LOADING || network_state == NETWORK_IDLE { - self.queue_fire_simple_event("abort"); + task_source.queue_simple_event( + self.upcast(), + atom!("abort"), + &window, + ); } // Step 4 if network_state != NETWORK_EMPTY { // 4.1 - self.queue_fire_simple_event("emptied"); + task_source.queue_simple_event(self.upcast(), atom!("emptied"), &window); // TODO 4.2 (abort in-progress fetch) @@ -721,14 +754,21 @@ impl HTMLMediaElementMethods for HTMLMediaElement { // TODO 7.2 (show poster) + let window = window_from_node(self); + let task_source = window.dom_manipulation_task_source(); + // 7.3 - self.queue_fire_simple_event("play"); + task_source.queue_simple_event(self.upcast(), atom!("play"), &window); // 7.4 if state == HAVE_NOTHING || state == HAVE_METADATA || state == HAVE_CURRENT_DATA { - self.queue_fire_simple_event("waiting"); + task_source.queue_simple_event( + self.upcast(), + atom!("waiting"), + &window, + ); } else { self.queue_notify_about_playing(); } @@ -820,27 +860,6 @@ impl MicrotaskRunnable for MediaElementMicrotask { } } -struct FireSimpleEventTask { - elem: Trusted<HTMLMediaElement>, - type_: &'static str, -} - -impl FireSimpleEventTask { - fn new(target: &HTMLMediaElement, type_: &'static str) -> FireSimpleEventTask { - FireSimpleEventTask { - elem: Trusted::new(target), - type_: type_, - } - } -} - -impl Runnable for FireSimpleEventTask { - fn handler(self: Box<FireSimpleEventTask>) { - let elem = self.elem.root(); - elem.fire_simple_event(self.type_); - } -} - struct DedicatedMediaSourceFailureTask { elem: Trusted<HTMLMediaElement>, } |