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::bindings::cell::DOMRefCell;
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::HTMLMediaElementConstants::*;
use dom::bindings::codegen::Bindings::MediaErrorBinding::MediaErrorConstants::*;
use dom::bindings::global::GlobalRef;
use dom::bindings::inheritance::Castable;
use dom::bindings::js::Root;
use dom::bindings::js::{Root, MutNullableHeap, JS};
use dom::bindings::refcounted::Trusted;
use dom::document::Document;
use dom::element::{Element, AttributeMutation};
use dom::event::{Event, EventBubbles, EventCancelable};
use dom::htmlelement::HTMLElement;
use dom::htmlsourceelement::HTMLSourceElement;
use dom::mediaerror::MediaError;
use dom::node::{window_from_node, document_from_node};
use dom::virtualmethods::VirtualMethods;
use ipc_channel::ipc;
@ -110,6 +113,15 @@ impl AsyncResponseListener for HTMLMediaElementContext {
elem.network_state.set(NETWORK_IDLE);
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 {
elem.queue_dedicated_media_source_failure_steps();
}
@ -149,6 +161,7 @@ pub struct HTMLMediaElement {
current_src: DOMRefCell<String>,
generation_id: Cell<u32>,
first_data_load: Cell<bool>,
error: MutNullableHeap<JS<MediaError>>,
}
impl HTMLMediaElement {
@ -163,6 +176,7 @@ impl HTMLMediaElement {
current_src: DOMRefCell::new("".to_owned()),
generation_id: Cell::new(0),
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
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)
@ -426,7 +442,9 @@ impl HTMLMediaElement {
}
// TODO step 5 (playback rate)
// TODO step 6 (error/autoplaying)
// Step 6
self.error.set(None);
// TODO autoplay flag
// Step 7
let doc = document_from_node(self);
@ -454,6 +472,22 @@ impl HTMLMediaElementMethods for HTMLMediaElement {
fn CurrentSrc(&self) -> DOMString {
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 {

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 keyboardevent;
pub mod location;
pub mod mediaerror;
pub mod messageevent;
pub mod mimetype;
pub mod mimetypearray;

View file

@ -3,12 +3,12 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmlmediaelement
//enum CanPlayTypeResult { "" /* empty string */, "maybe", "probably" };
enum CanPlayTypeResult { "" /* empty string */, "maybe", "probably" };
[Abstract]
interface HTMLMediaElement : HTMLElement {
// error state
//readonly attribute MediaError? error;
readonly attribute MediaError? error;
// network state
attribute DOMString src;
@ -21,8 +21,8 @@ interface HTMLMediaElement : HTMLElement {
readonly attribute unsigned short networkState;
// attribute DOMString preload;
//readonly attribute TimeRanges buffered;
//void load();
//CanPlayTypeResult canPlayType(DOMString type);
void load();
CanPlayTypeResult canPlayType(DOMString type);
// ready state
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)]
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)]
expected: FAIL
@ -2631,15 +2628,6 @@
[HTMLMediaElement interface: document.createElement("video") must inherit property "buffered" with the proper type (10)]
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)]
expected: FAIL
@ -2721,9 +2709,6 @@
[HTMLMediaElement interface: calling addTextTrack(TextTrackKind,DOMString,DOMString) on document.createElement("video") with too few arguments must throw TypeError]
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)]
expected: FAIL
@ -2733,15 +2718,6 @@
[HTMLMediaElement interface: document.createElement("audio") must inherit property "buffered" with the proper type (10)]
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)]
expected: FAIL
@ -3078,9 +3054,6 @@
[HTMLTrackElement interface: document.createElement("track") must inherit property "track" with the proper type (10)]
expected: FAIL
[HTMLMediaElement interface: attribute error]
expected: FAIL
[HTMLMediaElement interface: attribute crossOrigin]
expected: FAIL
@ -3090,12 +3063,6 @@
[HTMLMediaElement interface: attribute buffered]
expected: FAIL
[HTMLMediaElement interface: operation load()]
expected: FAIL
[HTMLMediaElement interface: operation canPlayType(DOMString)]
expected: FAIL
[HTMLMediaElement interface: attribute seeking]
expected: FAIL
@ -3171,45 +3138,6 @@
[HTMLMediaElement interface: operation addTextTrack(TextTrackKind,DOMString,DOMString)]
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]
expected: FAIL
@ -8259,9 +8187,6 @@
[HTMLPictureElement interface object name]
expected: FAIL
[MediaError interface object name]
expected: FAIL
[AudioTrackList interface object name]
expected: FAIL

View file

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

View file

@ -6,18 +6,12 @@
[video/x-new-fictional-format]
expected: FAIL
[audio/mp4 (optional)]
expected: FAIL
[audio/mp4; codecs="mp4a.40.2" (optional)]
expected: FAIL
[audio/mp4 with bogus codec]
expected: FAIL
[audio/ogg (optional)]
expected: FAIL
[audio/ogg; codecs="opus" (optional)]
expected: FAIL
@ -27,18 +21,12 @@
[audio/ogg with bogus codec]
expected: FAIL
[audio/wav (optional)]
expected: FAIL
[audio/wav; codecs="1" (optional)]
expected: FAIL
[audio/wav with bogus codec]
expected: FAIL
[audio/webm (optional)]
expected: FAIL
[audio/webm; codecs="opus" (optional)]
expected: FAIL
@ -48,27 +36,15 @@
[audio/webm with bogus codec]
expected: FAIL
[video/3gpp (optional)]
expected: FAIL
[video/3gpp; codecs="samr" (optional)]
expected: FAIL
[video/3gpp; codecs="mp4v.20.8" (optional)]
expected: FAIL
[video/3gpp codecs subset]
expected: FAIL
[video/3gpp codecs order]
expected: FAIL
[video/3gpp with bogus codec]
expected: FAIL
[video/mp4 (optional)]
expected: FAIL
[video/mp4; codecs="mp4a.40.2" (optional)]
expected: FAIL
@ -90,18 +66,9 @@
[video/mp4; codecs="mp4v.20.240" (optional)]
expected: FAIL
[video/mp4 codecs subset]
expected: FAIL
[video/mp4 codecs order]
expected: FAIL
[video/mp4 with bogus codec]
expected: FAIL
[video/ogg (optional)]
expected: FAIL
[video/ogg; codecs="opus" (optional)]
expected: FAIL
@ -111,18 +78,9 @@
[video/ogg; codecs="theora" (optional)]
expected: FAIL
[video/ogg codecs subset]
expected: FAIL
[video/ogg codecs order]
expected: FAIL
[video/ogg with bogus codec]
expected: FAIL
[video/webm (optional)]
expected: FAIL
[video/webm; codecs="opus" (optional)]
expected: FAIL
@ -141,12 +99,30 @@
[video/webm; codecs="vp9.0" (optional)]
expected: FAIL
[video/webm codecs subset]
expected: FAIL
[video/webm codecs order]
expected: FAIL
[video/webm with bogus codec]
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]
type: testharness
[WebGL test #0: video.canPlayType required method missing]
expected: FAIL
expected: TIMEOUT

View file

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

View file

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

View file

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

View file

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