aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/htmlmediaelement.rs
diff options
context:
space:
mode:
authorgerman gomez <germangb42@gmail.com>2018-12-11 01:16:34 +0100
committergerman gomez <germangb42@gmail.com>2019-01-11 18:13:11 +0100
commit5605f235c696ba42c33745531bbcb996a49a4b19 (patch)
tree38aab94b6084d2e6cd273b8e7f03e378becdaf67 /components/script/dom/htmlmediaelement.rs
parentb49e7517a37f31c6b867093bc1a20469f55da24b (diff)
downloadservo-5605f235c696ba42c33745531bbcb996a49a4b19.tar.gz
servo-5605f235c696ba42c33745531bbcb996a49a4b19.zip
Implement Ended media attribute
Signed-off-by: german gomez <germangb42@gmail.com>
Diffstat (limited to 'components/script/dom/htmlmediaelement.rs')
-rw-r--r--components/script/dom/htmlmediaelement.rs103
1 files changed, 103 insertions, 0 deletions
diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs
index 64c36f1d017..dd83c2061de 100644
--- a/components/script/dom/htmlmediaelement.rs
+++ b/components/script/dom/htmlmediaelement.rs
@@ -1119,6 +1119,63 @@ impl HTMLMediaElement {
// 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();
+ } else {
+ // https://html.spec.whatwg.org/multipage/#reaches-the-end
+ match self.direction_of_playback() {
+ PlaybackDirection::Forwards => {
+ // Step 1.
+ if self.Loop() {
+ self.seek(
+ self.earliest_possible_position(),
+ /* approximate_for_speed*/ false,
+ );
+ } else {
+ // Step 2.
+ // The **ended playback** condition is implemented inside of
+ // the HTMLMediaElementMethods::Ended method
+
+ // Step 3.
+ let window = window_from_node(self);
+ let this = Trusted::new(self);
+
+ let _ = window.task_manager().media_element_task_source().queue(
+ task!(reaches_the_end_steps: move || {
+ let this = this.root();
+ // Step 3.1.
+ this.upcast::<EventTarget>().fire_event(atom!("timeupdate"));
+
+ // Step 3.2.
+ if this.Ended() && !this.Paused() {
+ // Step 3.2.1.
+ this.paused.set(true);
+
+ // Step 3.2.2.
+ this.upcast::<EventTarget>().fire_event(atom!("pause"));
+
+ // Step 3.2.3.
+ this.take_pending_play_promises(Err(Error::Abort));
+ this.fulfill_in_flight_play_promises(|| ());
+ }
+
+ // Step 3.3.
+ this.upcast::<EventTarget>().fire_event(atom!("ended"));
+ }),
+ window.upcast(),
+ );
+ }
+ },
+
+ PlaybackDirection::Backwards => {
+ if self.playback_position.get() <= self.earliest_possible_position() {
+ let window = window_from_node(self);
+
+ window
+ .task_manager()
+ .media_element_task_source()
+ .queue_simple_event(self.upcast(), atom!("ended"), &window);
+ }
+ },
+ }
}
},
PlayerEvent::Error => {
@@ -1261,6 +1318,38 @@ impl HTMLMediaElement {
},
}
}
+
+ // https://html.spec.whatwg.org/multipage/#earliest-possible-position
+ fn earliest_possible_position(&self) -> f64 {
+ self.played
+ .borrow()
+ .start(0)
+ .unwrap_or_else(|_| self.playback_position.get())
+ }
+}
+
+// XXX Placeholder for [https://github.com/servo/servo/issues/22293]
+#[derive(Clone, Copy, JSTraceable, MallocSizeOf, PartialEq)]
+enum PlaybackDirection {
+ Forwards,
+ #[allow(dead_code)]
+ Backwards,
+}
+
+// XXX Placeholder implementations for:
+//
+// - https://github.com/servo/servo/issues/22293
+// - https://github.com/servo/servo/issues/22321
+impl HTMLMediaElement {
+ // https://github.com/servo/servo/issues/22293
+ fn direction_of_playback(&self) -> PlaybackDirection {
+ PlaybackDirection::Forwards
+ }
+
+ // https://github.com/servo/servo/pull/22321
+ fn Loop(&self) -> bool {
+ false
+ }
}
impl HTMLMediaElementMethods for HTMLMediaElement {
@@ -1514,6 +1603,20 @@ impl HTMLMediaElementMethods for HTMLMediaElement {
self.seeking.get()
}
+ // https://html.spec.whatwg.org/multipage/#ended-playback
+ fn Ended(&self) -> bool {
+ if self.ready_state.get() < ReadyState::HaveMetadata {
+ return false;
+ }
+
+ let playback_pos = self.playback_position.get();
+
+ match self.direction_of_playback() {
+ PlaybackDirection::Forwards => playback_pos >= self.Duration() && !self.Loop(),
+ PlaybackDirection::Backwards => playback_pos <= self.earliest_possible_position(),
+ }
+ }
+
// https://html.spec.whatwg.org/multipage/#dom-media-fastseek
fn FastSeek(&self, time: Finite<f64>) {
self.seek(*time, /* approximate_for_speed */ true);