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