diff --git a/components/atoms/static_atoms.txt b/components/atoms/static_atoms.txt index 7fbd043dc0fe..151ad41d9149 100644 --- a/components/atoms/static_atoms.txt +++ b/components/atoms/static_atoms.txt @@ -65,6 +65,7 @@ range readystatechange reftest-wait reset +resize right rtl sans-serif diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs index 60ba96322853..605b6cd8a999 100644 --- a/components/script/dom/htmlmediaelement.rs +++ b/components/script/dom/htmlmediaelement.rs @@ -25,6 +25,7 @@ use dom::element::{Element, AttributeMutation}; use dom::eventtarget::EventTarget; use dom::htmlelement::HTMLElement; use dom::htmlsourceelement::HTMLSourceElement; +use dom::htmlvideoelement::HTMLVideoElement; use dom::mediaerror::MediaError; use dom::node::{document_from_node, window_from_node, Node, NodeDamage, UnbindContext}; use dom::promise::Promise; @@ -177,9 +178,9 @@ pub enum NetworkState { } /// -#[derive(Clone, Copy, JSTraceable, MallocSizeOf, PartialEq, PartialOrd)] +#[derive(Clone, Copy, Debug, JSTraceable, MallocSizeOf, PartialEq, PartialOrd)] #[repr(u8)] -enum ReadyState { +pub enum ReadyState { HaveNothing = HTMLMediaElementConstants::HAVE_NOTHING as u8, HaveMetadata = HTMLMediaElementConstants::HAVE_METADATA as u8, HaveCurrentData = HTMLMediaElementConstants::HAVE_CURRENT_DATA as u8, @@ -213,6 +214,10 @@ impl HTMLMediaElement { } } + pub fn get_ready_state(&self) -> ReadyState { + self.ready_state.get() + } + fn media_type_id(&self) -> HTMLMediaElementTypeId { match self.upcast::().type_id() { NodeTypeId::Element(ElementTypeId::HTMLElement( @@ -952,8 +957,35 @@ impl HTMLMediaElement { if !self.have_metadata.get() { // https://html.spec.whatwg.org/multipage/#media-data-processing-steps-list // => "Once enough of the media data has been fetched to determine the duration..." + // Step 1. + // servo-media owns the media timeline. + + // Step 2. + // XXX(ferjm) Update the timeline offset. + + // Step 3. + // XXX(ferjm) Set the current and official playback positions + // to the earliest possible position. + + // Step 4. + // XXX(ferjm) Update duration. + + // Step 5. + if self.is::() { + assert_ne!(self.ready_state.get(), ReadyState::HaveNothing); + let video_elem = self.downcast::().unwrap(); + video_elem.set_video_width(metadata.width); + video_elem.set_video_height(metadata.height); + let window = window_from_node(self); + window.dom_manipulation_task_source().queue_simple_event( + self.upcast(), + atom!("resize"), + &window, + ); + } + if let Some(_dur) = metadata.duration { - // Setp 6. + // Step 6. self.change_ready_state(ReadyState::HaveMetadata); self.have_metadata.set(true); } diff --git a/components/script/dom/htmlvideoelement.rs b/components/script/dom/htmlvideoelement.rs index 8561aa051e1c..5ce8d941b61d 100644 --- a/components/script/dom/htmlvideoelement.rs +++ b/components/script/dom/htmlvideoelement.rs @@ -3,16 +3,20 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::Bindings::HTMLVideoElementBinding; +use dom::bindings::codegen::Bindings::HTMLVideoElementBinding::HTMLVideoElementMethods; use dom::bindings::root::DomRoot; use dom::document::Document; -use dom::htmlmediaelement::HTMLMediaElement; +use dom::htmlmediaelement::{HTMLMediaElement, ReadyState}; use dom::node::Node; use dom_struct::dom_struct; use html5ever::{LocalName, Prefix}; +use std::cell::Cell; #[dom_struct] pub struct HTMLVideoElement { htmlmediaelement: HTMLMediaElement, + video_width: Cell, + video_height: Cell, } impl HTMLVideoElement { @@ -23,6 +27,8 @@ impl HTMLVideoElement { ) -> HTMLVideoElement { HTMLVideoElement { htmlmediaelement: HTMLMediaElement::new_inherited(local_name, prefix, document), + video_width: Cell::new(0), + video_height: Cell::new(0), } } @@ -40,4 +46,28 @@ impl HTMLVideoElement { HTMLVideoElementBinding::Wrap, ) } + + pub fn set_video_width(&self, width: u32) { + self.video_width.set(width); + } + + pub fn set_video_height(&self, height: u32) { + self.video_height.set(height); + } +} + +impl HTMLVideoElementMethods for HTMLVideoElement { + fn VideoWidth(&self) -> u32 { + if self.htmlmediaelement.get_ready_state() == ReadyState::HaveNothing { + return 0; + } + self.video_width.get() + } + + fn VideoHeight(&self) -> u32 { + if self.htmlmediaelement.get_ready_state() == ReadyState::HaveNothing { + return 0; + } + self.video_height.get() + } } diff --git a/components/script/dom/webidls/HTMLVideoElement.webidl b/components/script/dom/webidls/HTMLVideoElement.webidl index bfd1be006eaf..a3a34e7c47e9 100644 --- a/components/script/dom/webidls/HTMLVideoElement.webidl +++ b/components/script/dom/webidls/HTMLVideoElement.webidl @@ -9,8 +9,8 @@ interface HTMLVideoElement : HTMLMediaElement { // attribute unsigned long width; // [CEReactions] // attribute unsigned long height; - // readonly attribute unsigned long videoWidth; - // readonly attribute unsigned long videoHeight; + readonly attribute unsigned long videoWidth; + readonly attribute unsigned long videoHeight; // [CEReactions] // attribute DOMString poster; };