Implement load, canPlayType, and error APIs for media elements.

This commit is contained in:
Josh Matthews 2015-11-07 00:43:17 -05:00
parent eae27adc4a
commit 5960fbe604
13 changed files with 121 additions and 148 deletions

View file

@ -6,17 +6,20 @@ use document_loader::LoadType;
use dom::attr::Attr; use dom::attr::Attr;
use dom::bindings::cell::DOMRefCell; use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::AttrBinding::AttrMethods; use dom::bindings::codegen::Bindings::AttrBinding::AttrMethods;
use dom::bindings::codegen::Bindings::HTMLMediaElementBinding::CanPlayTypeResult;
use dom::bindings::codegen::Bindings::HTMLMediaElementBinding::HTMLMediaElementMethods; use dom::bindings::codegen::Bindings::HTMLMediaElementBinding::HTMLMediaElementMethods;
use dom::bindings::codegen::Bindings::HTMLMediaElementBinding::HTMLMediaElementConstants::*; use dom::bindings::codegen::Bindings::HTMLMediaElementBinding::HTMLMediaElementConstants::*;
use dom::bindings::codegen::Bindings::MediaErrorBinding::MediaErrorConstants::*;
use dom::bindings::global::GlobalRef; use dom::bindings::global::GlobalRef;
use dom::bindings::inheritance::Castable; use dom::bindings::inheritance::Castable;
use dom::bindings::js::Root; use dom::bindings::js::{Root, MutNullableHeap, JS};
use dom::bindings::refcounted::Trusted; use dom::bindings::refcounted::Trusted;
use dom::document::Document; use dom::document::Document;
use dom::element::{Element, AttributeMutation}; use dom::element::{Element, AttributeMutation};
use dom::event::{Event, EventBubbles, EventCancelable}; use dom::event::{Event, EventBubbles, EventCancelable};
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::htmlsourceelement::HTMLSourceElement; use dom::htmlsourceelement::HTMLSourceElement;
use dom::mediaerror::MediaError;
use dom::node::{window_from_node, document_from_node}; use dom::node::{window_from_node, document_from_node};
use dom::virtualmethods::VirtualMethods; use dom::virtualmethods::VirtualMethods;
use ipc_channel::ipc; use ipc_channel::ipc;
@ -110,6 +113,15 @@ impl AsyncResponseListener for HTMLMediaElementContext {
elem.network_state.set(NETWORK_IDLE); elem.network_state.set(NETWORK_IDLE);
elem.fire_simple_event("suspend"); elem.fire_simple_event("suspend");
} else if elem.ready_state.get() != HAVE_NOTHING {
elem.error.set(Some(&*MediaError::new(&*window_from_node(&*elem),
MEDIA_ERR_NETWORK)));
elem.network_state.set(NETWORK_IDLE);
// TODO: update delay load flag
elem.fire_simple_event("error");
} else { } else {
elem.queue_dedicated_media_source_failure_steps(); elem.queue_dedicated_media_source_failure_steps();
} }
@ -149,6 +161,7 @@ pub struct HTMLMediaElement {
current_src: DOMRefCell<String>, current_src: DOMRefCell<String>,
generation_id: Cell<u32>, generation_id: Cell<u32>,
first_data_load: Cell<bool>, first_data_load: Cell<bool>,
error: MutNullableHeap<JS<MediaError>>,
} }
impl HTMLMediaElement { impl HTMLMediaElement {
@ -163,6 +176,7 @@ impl HTMLMediaElement {
current_src: DOMRefCell::new("".to_owned()), current_src: DOMRefCell::new("".to_owned()),
generation_id: Cell::new(0), generation_id: Cell::new(0),
first_data_load: Cell::new(true), first_data_load: Cell::new(true),
error: Default::default(),
} }
} }
@ -372,7 +386,9 @@ impl HTMLMediaElement {
// https://html.spec.whatwg.org/multipage/#dedicated-media-source-failure-steps // https://html.spec.whatwg.org/multipage/#dedicated-media-source-failure-steps
fn dedicated_media_source_failure(&self) { fn dedicated_media_source_failure(&self) {
// TODO step 1 (error attribute) // Step 1
self.error.set(Some(&*MediaError::new(&*window_from_node(self),
MEDIA_ERR_SRC_NOT_SUPPORTED)));
// TODO step 2 (forget resource tracks) // TODO step 2 (forget resource tracks)
@ -426,7 +442,9 @@ impl HTMLMediaElement {
} }
// TODO step 5 (playback rate) // TODO step 5 (playback rate)
// TODO step 6 (error/autoplaying) // Step 6
self.error.set(None);
// TODO autoplay flag
// Step 7 // Step 7
let doc = document_from_node(self); let doc = document_from_node(self);
@ -454,6 +472,22 @@ impl HTMLMediaElementMethods for HTMLMediaElement {
fn CurrentSrc(&self) -> DOMString { fn CurrentSrc(&self) -> DOMString {
DOMString::from(self.current_src.borrow().clone()) DOMString::from(self.current_src.borrow().clone())
} }
// https://html.spec.whatwg.org/multipage/#dom-media-load
fn Load(&self) {
self.media_element_load_algorithm();
}
// https://html.spec.whatwg.org/multipage/#dom-navigator-canplaytype
fn CanPlayType(&self, _type_: DOMString) -> CanPlayTypeResult {
// TODO: application/octet-stream
CanPlayTypeResult::Maybe
}
// https://html.spec.whatwg.org/multipage/#dom-media-error
fn GetError(&self) -> Option<Root<MediaError>> {
self.error.get()
}
} }
impl VirtualMethods for HTMLMediaElement { impl VirtualMethods for HTMLMediaElement {

View file

@ -0,0 +1,36 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::Bindings::MediaErrorBinding::{self, MediaErrorMethods};
use dom::bindings::global::GlobalRef;
use dom::bindings::js::Root;
use dom::bindings::reflector::{Reflector, reflect_dom_object};
use dom::window::Window;
#[dom_struct]
pub struct MediaError {
reflector_: Reflector,
code: u16,
}
impl MediaError {
fn new_inherited(code: u16) -> MediaError {
MediaError {
reflector_: Reflector::new(),
code: code,
}
}
pub fn new(window: &Window, code: u16) -> Root<MediaError> {
reflect_dom_object(box MediaError::new_inherited(code),
GlobalRef::Window(window),
MediaErrorBinding::Wrap)
}
}
impl MediaErrorMethods for MediaError {
fn Code(&self) -> u16 {
self.code
}
}

View file

@ -341,6 +341,7 @@ pub mod htmlvideoelement;
pub mod imagedata; pub mod imagedata;
pub mod keyboardevent; pub mod keyboardevent;
pub mod location; pub mod location;
pub mod mediaerror;
pub mod messageevent; pub mod messageevent;
pub mod mimetype; pub mod mimetype;
pub mod mimetypearray; pub mod mimetypearray;

View file

@ -3,12 +3,12 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmlmediaelement // https://html.spec.whatwg.org/multipage/#htmlmediaelement
//enum CanPlayTypeResult { "" /* empty string */, "maybe", "probably" }; enum CanPlayTypeResult { "" /* empty string */, "maybe", "probably" };
[Abstract] [Abstract]
interface HTMLMediaElement : HTMLElement { interface HTMLMediaElement : HTMLElement {
// error state // error state
//readonly attribute MediaError? error; readonly attribute MediaError? error;
// network state // network state
attribute DOMString src; attribute DOMString src;
@ -21,8 +21,8 @@ interface HTMLMediaElement : HTMLElement {
readonly attribute unsigned short networkState; readonly attribute unsigned short networkState;
// attribute DOMString preload; // attribute DOMString preload;
//readonly attribute TimeRanges buffered; //readonly attribute TimeRanges buffered;
//void load(); void load();
//CanPlayTypeResult canPlayType(DOMString type); CanPlayTypeResult canPlayType(DOMString type);
// ready state // ready state
const unsigned short HAVE_NOTHING = 0; const unsigned short HAVE_NOTHING = 0;

View file

@ -0,0 +1,14 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/embedded-content.html#mediaerror
interface MediaError {
const unsigned short MEDIA_ERR_ABORTED = 1;
const unsigned short MEDIA_ERR_NETWORK = 2;
const unsigned short MEDIA_ERR_DECODE = 3;
const unsigned short MEDIA_ERR_SRC_NOT_SUPPORTED = 4;
readonly attribute unsigned short code;
};

View file

@ -2619,9 +2619,6 @@
[HTMLVideoElement interface: document.createElement("video") must inherit property "poster" with the proper type (4)] [HTMLVideoElement interface: document.createElement("video") must inherit property "poster" with the proper type (4)]
expected: FAIL expected: FAIL
[HTMLMediaElement interface: document.createElement("video") must inherit property "error" with the proper type (0)]
expected: FAIL
[HTMLMediaElement interface: document.createElement("video") must inherit property "crossOrigin" with the proper type (3)] [HTMLMediaElement interface: document.createElement("video") must inherit property "crossOrigin" with the proper type (3)]
expected: FAIL expected: FAIL
@ -2631,15 +2628,6 @@
[HTMLMediaElement interface: document.createElement("video") must inherit property "buffered" with the proper type (10)] [HTMLMediaElement interface: document.createElement("video") must inherit property "buffered" with the proper type (10)]
expected: FAIL expected: FAIL
[HTMLMediaElement interface: document.createElement("video") must inherit property "load" with the proper type (11)]
expected: FAIL
[HTMLMediaElement interface: document.createElement("video") must inherit property "canPlayType" with the proper type (12)]
expected: FAIL
[HTMLMediaElement interface: calling canPlayType(DOMString) on document.createElement("video") with too few arguments must throw TypeError]
expected: FAIL
[HTMLMediaElement interface: document.createElement("video") must inherit property "seeking" with the proper type (19)] [HTMLMediaElement interface: document.createElement("video") must inherit property "seeking" with the proper type (19)]
expected: FAIL expected: FAIL
@ -2721,9 +2709,6 @@
[HTMLMediaElement interface: calling addTextTrack(TextTrackKind,DOMString,DOMString) on document.createElement("video") with too few arguments must throw TypeError] [HTMLMediaElement interface: calling addTextTrack(TextTrackKind,DOMString,DOMString) on document.createElement("video") with too few arguments must throw TypeError]
expected: FAIL expected: FAIL
[HTMLMediaElement interface: document.createElement("audio") must inherit property "error" with the proper type (0)]
expected: FAIL
[HTMLMediaElement interface: document.createElement("audio") must inherit property "crossOrigin" with the proper type (3)] [HTMLMediaElement interface: document.createElement("audio") must inherit property "crossOrigin" with the proper type (3)]
expected: FAIL expected: FAIL
@ -2733,15 +2718,6 @@
[HTMLMediaElement interface: document.createElement("audio") must inherit property "buffered" with the proper type (10)] [HTMLMediaElement interface: document.createElement("audio") must inherit property "buffered" with the proper type (10)]
expected: FAIL expected: FAIL
[HTMLMediaElement interface: document.createElement("audio") must inherit property "load" with the proper type (11)]
expected: FAIL
[HTMLMediaElement interface: document.createElement("audio") must inherit property "canPlayType" with the proper type (12)]
expected: FAIL
[HTMLMediaElement interface: calling canPlayType(DOMString) on document.createElement("audio") with too few arguments must throw TypeError]
expected: FAIL
[HTMLMediaElement interface: document.createElement("audio") must inherit property "seeking" with the proper type (19)] [HTMLMediaElement interface: document.createElement("audio") must inherit property "seeking" with the proper type (19)]
expected: FAIL expected: FAIL
@ -3078,9 +3054,6 @@
[HTMLTrackElement interface: document.createElement("track") must inherit property "track" with the proper type (10)] [HTMLTrackElement interface: document.createElement("track") must inherit property "track" with the proper type (10)]
expected: FAIL expected: FAIL
[HTMLMediaElement interface: attribute error]
expected: FAIL
[HTMLMediaElement interface: attribute crossOrigin] [HTMLMediaElement interface: attribute crossOrigin]
expected: FAIL expected: FAIL
@ -3090,12 +3063,6 @@
[HTMLMediaElement interface: attribute buffered] [HTMLMediaElement interface: attribute buffered]
expected: FAIL expected: FAIL
[HTMLMediaElement interface: operation load()]
expected: FAIL
[HTMLMediaElement interface: operation canPlayType(DOMString)]
expected: FAIL
[HTMLMediaElement interface: attribute seeking] [HTMLMediaElement interface: attribute seeking]
expected: FAIL expected: FAIL
@ -3171,45 +3138,6 @@
[HTMLMediaElement interface: operation addTextTrack(TextTrackKind,DOMString,DOMString)] [HTMLMediaElement interface: operation addTextTrack(TextTrackKind,DOMString,DOMString)]
expected: FAIL expected: FAIL
[MediaError interface: existence and properties of interface object]
expected: FAIL
[MediaError interface object length]
expected: FAIL
[MediaError interface: existence and properties of interface prototype object]
expected: FAIL
[MediaError interface: existence and properties of interface prototype object's "constructor" property]
expected: FAIL
[MediaError interface: constant MEDIA_ERR_ABORTED on interface object]
expected: FAIL
[MediaError interface: constant MEDIA_ERR_ABORTED on interface prototype object]
expected: FAIL
[MediaError interface: constant MEDIA_ERR_NETWORK on interface object]
expected: FAIL
[MediaError interface: constant MEDIA_ERR_NETWORK on interface prototype object]
expected: FAIL
[MediaError interface: constant MEDIA_ERR_DECODE on interface object]
expected: FAIL
[MediaError interface: constant MEDIA_ERR_DECODE on interface prototype object]
expected: FAIL
[MediaError interface: constant MEDIA_ERR_SRC_NOT_SUPPORTED on interface object]
expected: FAIL
[MediaError interface: constant MEDIA_ERR_SRC_NOT_SUPPORTED on interface prototype object]
expected: FAIL
[MediaError interface: attribute code]
expected: FAIL
[MediaError must be primary interface of errorVideo.error] [MediaError must be primary interface of errorVideo.error]
expected: FAIL expected: FAIL
@ -8259,9 +8187,6 @@
[HTMLPictureElement interface object name] [HTMLPictureElement interface object name]
expected: FAIL expected: FAIL
[MediaError interface object name]
expected: FAIL
[AudioTrackList interface object name] [AudioTrackList interface object name]
expected: FAIL expected: FAIL

View file

@ -1,18 +1,12 @@
[error.html] [error.html]
type: testharness type: testharness
expected: TIMEOUT expected: TIMEOUT
[audio.error initial value]
expected: FAIL
[audio.error after successful load] [audio.error after successful load]
expected: TIMEOUT expected: TIMEOUT
[audio.error after setting src to the empty string] [audio.error after setting src to the empty string]
expected: TIMEOUT expected: TIMEOUT
[video.error initial value]
expected: FAIL
[video.error after successful load] [video.error after successful load]
expected: TIMEOUT expected: TIMEOUT

View file

@ -6,18 +6,12 @@
[video/x-new-fictional-format] [video/x-new-fictional-format]
expected: FAIL expected: FAIL
[audio/mp4 (optional)]
expected: FAIL
[audio/mp4; codecs="mp4a.40.2" (optional)] [audio/mp4; codecs="mp4a.40.2" (optional)]
expected: FAIL expected: FAIL
[audio/mp4 with bogus codec] [audio/mp4 with bogus codec]
expected: FAIL expected: FAIL
[audio/ogg (optional)]
expected: FAIL
[audio/ogg; codecs="opus" (optional)] [audio/ogg; codecs="opus" (optional)]
expected: FAIL expected: FAIL
@ -27,18 +21,12 @@
[audio/ogg with bogus codec] [audio/ogg with bogus codec]
expected: FAIL expected: FAIL
[audio/wav (optional)]
expected: FAIL
[audio/wav; codecs="1" (optional)] [audio/wav; codecs="1" (optional)]
expected: FAIL expected: FAIL
[audio/wav with bogus codec] [audio/wav with bogus codec]
expected: FAIL expected: FAIL
[audio/webm (optional)]
expected: FAIL
[audio/webm; codecs="opus" (optional)] [audio/webm; codecs="opus" (optional)]
expected: FAIL expected: FAIL
@ -48,27 +36,15 @@
[audio/webm with bogus codec] [audio/webm with bogus codec]
expected: FAIL expected: FAIL
[video/3gpp (optional)]
expected: FAIL
[video/3gpp; codecs="samr" (optional)] [video/3gpp; codecs="samr" (optional)]
expected: FAIL expected: FAIL
[video/3gpp; codecs="mp4v.20.8" (optional)] [video/3gpp; codecs="mp4v.20.8" (optional)]
expected: FAIL expected: FAIL
[video/3gpp codecs subset]
expected: FAIL
[video/3gpp codecs order]
expected: FAIL
[video/3gpp with bogus codec] [video/3gpp with bogus codec]
expected: FAIL expected: FAIL
[video/mp4 (optional)]
expected: FAIL
[video/mp4; codecs="mp4a.40.2" (optional)] [video/mp4; codecs="mp4a.40.2" (optional)]
expected: FAIL expected: FAIL
@ -90,18 +66,9 @@
[video/mp4; codecs="mp4v.20.240" (optional)] [video/mp4; codecs="mp4v.20.240" (optional)]
expected: FAIL expected: FAIL
[video/mp4 codecs subset]
expected: FAIL
[video/mp4 codecs order]
expected: FAIL
[video/mp4 with bogus codec] [video/mp4 with bogus codec]
expected: FAIL expected: FAIL
[video/ogg (optional)]
expected: FAIL
[video/ogg; codecs="opus" (optional)] [video/ogg; codecs="opus" (optional)]
expected: FAIL expected: FAIL
@ -111,18 +78,9 @@
[video/ogg; codecs="theora" (optional)] [video/ogg; codecs="theora" (optional)]
expected: FAIL expected: FAIL
[video/ogg codecs subset]
expected: FAIL
[video/ogg codecs order]
expected: FAIL
[video/ogg with bogus codec] [video/ogg with bogus codec]
expected: FAIL expected: FAIL
[video/webm (optional)]
expected: FAIL
[video/webm; codecs="opus" (optional)] [video/webm; codecs="opus" (optional)]
expected: FAIL expected: FAIL
@ -141,12 +99,30 @@
[video/webm; codecs="vp9.0" (optional)] [video/webm; codecs="vp9.0" (optional)]
expected: FAIL expected: FAIL
[video/webm codecs subset]
expected: FAIL
[video/webm codecs order]
expected: FAIL
[video/webm with bogus codec] [video/webm with bogus codec]
expected: FAIL expected: FAIL
[audio/mp4 with and without codecs]
expected: FAIL
[audio/ogg with and without codecs]
expected: FAIL
[audio/wav with and without codecs]
expected: FAIL
[audio/webm with and without codecs]
expected: FAIL
[video/3gpp with and without codecs]
expected: FAIL
[video/mp4 with and without codecs]
expected: FAIL
[video/ogg with and without codecs]
expected: FAIL
[video/webm with and without codecs]
expected: FAIL

View file

@ -1,5 +1,3 @@
[tex-image-and-sub-image-2d-with-video-rgb565.html] [tex-image-and-sub-image-2d-with-video-rgb565.html]
type: testharness type: testharness
[WebGL test #0: video.canPlayType required method missing] expected: TIMEOUT
expected: FAIL

View file

@ -1,5 +1,3 @@
[tex-image-and-sub-image-2d-with-video-rgba4444.html] [tex-image-and-sub-image-2d-with-video-rgba4444.html]
type: testharness type: testharness
[WebGL test #0: video.canPlayType required method missing] expected: TIMEOUT
expected: FAIL

View file

@ -1,8 +1,6 @@
[tex-image-and-sub-image-2d-with-video-rgba5551.html] [tex-image-and-sub-image-2d-with-video-rgba5551.html]
type: testharness type: testharness
[WebGL test #0: video.canPlayType required method missing] expected: TIMEOUT
expected: FAIL
[WebGL test #0: Unable to fetch WebGL rendering context for Canvas] [WebGL test #0: Unable to fetch WebGL rendering context for Canvas]
expected: FAIL expected: FAIL

View file

@ -1,8 +1,6 @@
[tex-image-and-sub-image-2d-with-video.html] [tex-image-and-sub-image-2d-with-video.html]
type: testharness type: testharness
[WebGL test #0: video.canPlayType required method missing] expected: TIMEOUT
expected: FAIL
[WebGL test #0: Unable to fetch WebGL rendering context for Canvas] [WebGL test #0: Unable to fetch WebGL rendering context for Canvas]
expected: FAIL expected: FAIL

View file

@ -192,6 +192,7 @@ var interfaceNamesInGlobalScope = [
"Image", "Image",
"KeyboardEvent", "KeyboardEvent",
"Location", "Location",
"MediaError",
"MessageEvent", "MessageEvent",
"MimeType", "MimeType",
"MimeTypeArray", "MimeTypeArray",