diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs index b5cc9d9b1fd..bfc51227dc5 100644 --- a/components/script/dom/htmlmediaelement.rs +++ b/components/script/dom/htmlmediaelement.rs @@ -33,6 +33,7 @@ use crate::dom::mediaerror::MediaError; use crate::dom::node::{document_from_node, window_from_node, Node, NodeDamage, UnbindContext}; use crate::dom::performanceresourcetiming::InitiatorType; use crate::dom::promise::Promise; +use crate::dom::timeranges::{TimeRanges, TimeRangesContainer}; use crate::dom::virtualmethods::VirtualMethods; use crate::fetch::FetchCanceller; use crate::microtask::{Microtask, MicrotaskRunnable}; @@ -182,6 +183,9 @@ pub struct HTMLMediaElement { seeking: Cell, /// URL of the media resource, if any. resource_url: DomRefCell>, + /// https://html.spec.whatwg.org/multipage/#dom-media-played + #[ignore_malloc_size_of = "Rc"] + played: Rc>, } /// @@ -233,6 +237,7 @@ impl HTMLMediaElement { default_playback_start_position: Cell::new(0.), seeking: Cell::new(false), resource_url: DomRefCell::new(None), + played: Rc::new(DomRefCell::new(TimeRangesContainer::new())), } } @@ -1186,7 +1191,12 @@ impl HTMLMediaElement { // XXX Steps 12 and 13 require audio and video tracks support. }, PlayerEvent::PositionChanged(position) => { - self.playback_position.set(position as f64); + let position = position as f64; + let _ = self + .played + .borrow_mut() + .add(self.playback_position.get(), position); + self.playback_position.set(position); }, PlayerEvent::StateChanged(ref state) => match *state { PlaybackState::Paused => { @@ -1356,6 +1366,11 @@ impl HTMLMediaElementMethods for HTMLMediaElement { fn FastSeek(&self, time: Finite) { self.seek(*time, /* approximat_for_speed */ true); } + + // https://html.spec.whatwg.org/multipage/#dom-media-played + fn Played(&self) -> DomRoot { + TimeRanges::new(self.global().as_window(), self.played.clone()) + } } impl VirtualMethods for HTMLMediaElement { diff --git a/components/script/dom/timeranges.rs b/components/script/dom/timeranges.rs index b9d7397691c..c82daac23a7 100644 --- a/components/script/dom/timeranges.rs +++ b/components/script/dom/timeranges.rs @@ -12,6 +12,7 @@ use crate::dom::bindings::root::DomRoot; use crate::dom::window::Window; use dom_struct::dom_struct; use std::fmt; +use std::rc::Rc; #[derive(JSTraceable, MallocSizeOf)] struct TimeRange { @@ -127,23 +128,27 @@ impl TimeRangesContainer { #[dom_struct] pub struct TimeRanges { reflector_: Reflector, - ranges: DomRefCell, + #[ignore_malloc_size_of = "Rc"] + ranges: Rc>, } //XXX(ferjm) We'll get warnings about unused methods until we use this // on the media element implementation. #[allow(dead_code)] impl TimeRanges { - fn new_inherited() -> TimeRanges { + fn new_inherited(ranges: Rc>) -> TimeRanges { Self { reflector_: Reflector::new(), - ranges: DomRefCell::new(TimeRangesContainer::new()), + ranges, } } - pub fn new(window: &Window) -> DomRoot { + pub fn new( + window: &Window, + ranges: Rc>, + ) -> DomRoot { reflect_dom_object( - Box::new(TimeRanges::new_inherited()), + Box::new(TimeRanges::new_inherited(ranges)), window, TimeRangesBinding::Wrap, ) diff --git a/components/script/dom/webidls/HTMLMediaElement.webidl b/components/script/dom/webidls/HTMLMediaElement.webidl index b154e5197a2..fa0459e0921 100644 --- a/components/script/dom/webidls/HTMLMediaElement.webidl +++ b/components/script/dom/webidls/HTMLMediaElement.webidl @@ -44,7 +44,7 @@ interface HTMLMediaElement : HTMLElement { readonly attribute boolean paused; // attribute double defaultPlaybackRate; // attribute double playbackRate; - // readonly attribute TimeRanges played; + readonly attribute TimeRanges played; // readonly attribute TimeRanges seekable; // readonly attribute boolean ended; [CEReactions] attribute boolean autoplay; diff --git a/tests/wpt/metadata/html/dom/interfaces.https.html.ini b/tests/wpt/metadata/html/dom/interfaces.https.html.ini index e27465977fa..17898263fe7 100644 --- a/tests/wpt/metadata/html/dom/interfaces.https.html.ini +++ b/tests/wpt/metadata/html/dom/interfaces.https.html.ini @@ -6792,9 +6792,6 @@ [HTMLMediaElement interface: document.createElement("video") must inherit property "playbackRate" with the proper type] expected: FAIL - [HTMLMediaElement interface: document.createElement("video") must inherit property "played" with the proper type] - expected: FAIL - [HTMLMediaElement interface: document.createElement("video") must inherit property "seekable" with the proper type] expected: FAIL @@ -6849,9 +6846,6 @@ [HTMLMediaElement interface: document.createElement("audio") must inherit property "playbackRate" with the proper type] expected: FAIL - [HTMLMediaElement interface: document.createElement("audio") must inherit property "played" with the proper type] - expected: FAIL - [HTMLMediaElement interface: document.createElement("audio") must inherit property "seekable" with the proper type] expected: FAIL @@ -6906,9 +6900,6 @@ [HTMLMediaElement interface: new Audio() must inherit property "playbackRate" with the proper type] expected: FAIL - [HTMLMediaElement interface: new Audio() must inherit property "played" with the proper type] - expected: FAIL - [HTMLMediaElement interface: new Audio() must inherit property "seekable" with the proper type] expected: FAIL @@ -7038,9 +7029,6 @@ [HTMLMediaElement interface: attribute playbackRate] expected: FAIL - [HTMLMediaElement interface: attribute played] - expected: FAIL - [HTMLMediaElement interface: attribute seekable] expected: FAIL