mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Auto merge of #22348 - germangb:html_media_ended, r=ferjm
Implement Ended media attribute <!-- Please describe your changes on the following line: --> This PR should implement: * New method `HTMLMediaElement::earliest_possible_position()` for the [earliest possible position](https://html.spec.whatwg.org/multipage/media.html#earliest-possible-position) * `Ended` attribute following https://html.spec.whatwg.org/multipage/media.html#ended-playback * Queue steps for when the playback position reaches the end This PR contains placeholders for the following issues (I can rebase changes after the corresponding PRs get merged) - #22321 (Define the Loop attribute) - #22293 (To identify playback direction. Either forwards or backwards) --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [x] These changes fix #22294. <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/22348) <!-- Reviewable:end -->
This commit is contained in:
commit
1f9b134794
3 changed files with 104 additions and 25 deletions
|
@ -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);
|
||||
|
|
|
@ -46,7 +46,7 @@ interface HTMLMediaElement : HTMLElement {
|
|||
[Throws] attribute double playbackRate;
|
||||
readonly attribute TimeRanges played;
|
||||
// readonly attribute TimeRanges seekable;
|
||||
// readonly attribute boolean ended;
|
||||
readonly attribute boolean ended;
|
||||
[CEReactions] attribute boolean autoplay;
|
||||
// [CEReactions] attribute boolean loop;
|
||||
Promise<void> play();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue