Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement basic <media> infrastructure #8454

Merged
merged 13 commits into from May 4, 2016

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

  • Loading branch information
jdm committed May 3, 2016
commit 5960fbe6048e74e6be5708f8326ef23f2708810e
@@ -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 {
@@ -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
}
}
@@ -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;
@@ -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;
@@ -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;
};
@@ -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

@@ -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

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.