diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs
index bcceffc11d4..13986728f32 100644
--- a/components/script/dom/htmlmediaelement.rs
+++ b/components/script/dom/htmlmediaelement.rs
@@ -85,7 +85,7 @@ pub struct HTMLMediaElement {
/// https://html.spec.whatwg.org/multipage/#dom-media-networkstate
#[derive(Clone, Copy, HeapSizeOf, JSTraceable, PartialEq)]
#[repr(u8)]
-enum NetworkState {
+pub enum NetworkState {
Empty = HTMLMediaElementConstants::NETWORK_EMPTY as u8,
Idle = HTMLMediaElementConstants::NETWORK_IDLE as u8,
Loading = HTMLMediaElementConstants::NETWORK_LOADING as u8,
@@ -443,12 +443,23 @@ impl HTMLMediaElement {
#[allow(dead_code)]
Object,
Attribute(String),
- // FIXME(nox): Support source element child.
- #[allow(dead_code)]
Children(Root),
}
- let mode = if let Some(attr) = self.upcast::().get_attribute(&ns!(), &local_name!("src")) {
- Mode::Attribute(attr.Value().into())
+ fn mode(media: &HTMLMediaElement) -> Option {
+ if let Some(attr) = media.upcast::().get_attribute(&ns!(), &local_name!("src")) {
+ return Some(Mode::Attribute(attr.Value().into()));
+ }
+ let source_child_element = media.upcast::()
+ .children()
+ .filter_map(Root::downcast::)
+ .next();
+ if let Some(element) = source_child_element {
+ return Some(Mode::Children(element));
+ }
+ None
+ }
+ let mode = if let Some(mode) = mode(self) {
+ mode
} else {
self.network_state.set(NetworkState::Empty);
return;
@@ -775,6 +786,19 @@ impl HTMLMediaElement {
}
}
}
+
+ /// Handles insertion of `source` children.
+ ///
+ /// https://html.spec.whatwg.org/multipage/#the-source-element:nodes-are-inserted
+ pub fn handle_source_child_insertion(&self) {
+ if self.upcast::().has_attribute(&local_name!("src")) {
+ return;
+ }
+ if self.network_state.get() != NetworkState::Empty {
+ return;
+ }
+ self.media_element_load_algorithm();
+ }
}
impl HTMLMediaElementMethods for HTMLMediaElement {
diff --git a/components/script/dom/htmlsourceelement.rs b/components/script/dom/htmlsourceelement.rs
index 84adbc16548..865b21d6acb 100644
--- a/components/script/dom/htmlsourceelement.rs
+++ b/components/script/dom/htmlsourceelement.rs
@@ -3,10 +3,14 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::Bindings::HTMLSourceElementBinding;
+use dom::bindings::codegen::Bindings::NodeBinding::NodeBinding::NodeMethods;
+use dom::bindings::inheritance::Castable;
use dom::bindings::js::Root;
use dom::document::Document;
use dom::htmlelement::HTMLElement;
+use dom::htmlmediaelement::HTMLMediaElement;
use dom::node::Node;
+use dom::virtualmethods::VirtualMethods;
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
@@ -34,3 +38,18 @@ impl HTMLSourceElement {
HTMLSourceElementBinding::Wrap)
}
}
+
+impl VirtualMethods for HTMLSourceElement {
+ fn super_type(&self) -> Option<&VirtualMethods> {
+ Some(self.upcast::() as &VirtualMethods)
+ }
+
+ /// https://html.spec.whatwg.org/multipage/#the-source-element:nodes-are-inserted
+ fn bind_to_tree(&self, tree_in_doc: bool) {
+ self.super_type().unwrap().bind_to_tree(tree_in_doc);
+ let parent = self.upcast::().GetParentNode().unwrap();
+ if let Some(media) = parent.downcast::() {
+ media.handle_source_child_insertion();
+ }
+ }
+}
diff --git a/components/script/dom/virtualmethods.rs b/components/script/dom/virtualmethods.rs
index 2e4376ab975..b9adcea198e 100644
--- a/components/script/dom/virtualmethods.rs
+++ b/components/script/dom/virtualmethods.rs
@@ -41,6 +41,7 @@ use dom::htmloptionelement::HTMLOptionElement;
use dom::htmloutputelement::HTMLOutputElement;
use dom::htmlscriptelement::HTMLScriptElement;
use dom::htmlselectelement::HTMLSelectElement;
+use dom::htmlsourceelement::HTMLSourceElement;
use dom::htmlstyleelement::HTMLStyleElement;
use dom::htmltablecellelement::HTMLTableCellElement;
use dom::htmltableelement::HTMLTableElement;
@@ -231,6 +232,9 @@ pub fn vtable_for(node: &Node) -> &VirtualMethods {
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLSelectElement)) => {
node.downcast::().unwrap() as &VirtualMethods
}
+ NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLSourceElement)) => {
+ node.downcast::().unwrap() as &VirtualMethods
+ }
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLStyleElement)) => {
node.downcast::().unwrap() as &VirtualMethods
}
diff --git a/tests/wpt/metadata/html/semantics/embedded-content/media-elements/loading-the-media-resource/load-removes-queued-error-event.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/media-elements/loading-the-media-resource/load-removes-queued-error-event.html.ini
index 731fe16fc1b..c19f8ec60ce 100644
--- a/tests/wpt/metadata/html/semantics/embedded-content/media-elements/loading-the-media-resource/load-removes-queued-error-event.html.ini
+++ b/tests/wpt/metadata/html/semantics/embedded-content/media-elements/loading-the-media-resource/load-removes-queued-error-event.html.ini
@@ -1,6 +1,5 @@
[load-removes-queued-error-event.html]
type: testharness
- expected: TIMEOUT
[source error event]
- expected: TIMEOUT
+ expected: FAIL
diff --git a/tests/wpt/metadata/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-insert-before.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-insert-before.html.ini
index 4908ff33efe..76c0a336069 100644
--- a/tests/wpt/metadata/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-insert-before.html.ini
+++ b/tests/wpt/metadata/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-insert-before.html.ini
@@ -1,6 +1,5 @@
[resource-selection-candidate-insert-before.html]
type: testharness
- expected: TIMEOUT
[inserting another source before the candidate]
- expected: TIMEOUT
+ expected: FAIL
diff --git a/tests/wpt/metadata/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source-not-in-document.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source-not-in-document.html.ini
deleted file mode 100644
index d6c3a5c9926..00000000000
--- a/tests/wpt/metadata/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source-not-in-document.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[resource-selection-invoke-insert-source-not-in-document.html]
- type: testharness
- [invoking resource selection by inserting in video not in a document]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source.html.ini
deleted file mode 100644
index e7fd87a4aa0..00000000000
--- a/tests/wpt/metadata/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[resource-selection-invoke-insert-source.html]
- type: testharness
- [invoking resource selection by inserting ]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-remove-source.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-remove-source.html.ini
deleted file mode 100644
index d827b0ad685..00000000000
--- a/tests/wpt/metadata/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-remove-source.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[resource-selection-remove-source.html]
- type: testharness
- [Changes to networkState when inserting and removing a ]
- expected: FAIL
-