mirror of
https://github.com/servo/servo.git
synced 2025-06-19 14:48:59 +01:00
Do not NIH queueing a task to fire an event in htmlmediaelement
This commit is contained in:
parent
6168e898c1
commit
62c73b61b7
2 changed files with 89 additions and 59 deletions
|
@ -2,6 +2,8 @@ abort
|
|||
activate
|
||||
beforeunload
|
||||
button
|
||||
canplay
|
||||
canplaythrough
|
||||
center
|
||||
change
|
||||
characteristicvaluechanged
|
||||
|
@ -16,6 +18,7 @@ datetime-local
|
|||
dir
|
||||
DOMContentLoaded
|
||||
email
|
||||
emptied
|
||||
error
|
||||
fantasy
|
||||
fetch
|
||||
|
@ -31,6 +34,8 @@ keydown
|
|||
keypress
|
||||
left
|
||||
load
|
||||
loadeddata
|
||||
loadedmetadata
|
||||
loadend
|
||||
loadstart
|
||||
message
|
||||
|
@ -43,6 +48,9 @@ number
|
|||
onchange
|
||||
open
|
||||
password
|
||||
pause
|
||||
play
|
||||
playing
|
||||
print
|
||||
progress
|
||||
radio
|
||||
|
@ -58,11 +66,14 @@ serif
|
|||
statechange
|
||||
storage
|
||||
submit
|
||||
suspend
|
||||
tel
|
||||
text
|
||||
time
|
||||
timeupdate
|
||||
toggle
|
||||
transitionend
|
||||
url
|
||||
waiting
|
||||
webglcontextcreationerror
|
||||
week
|
||||
|
|
|
@ -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>,
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue