diff options
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/dom/audiotrack.rs | 15 | ||||
-rw-r--r-- | components/script/dom/audiotracklist.rs | 5 | ||||
-rw-r--r-- | components/script/dom/customelementregistry.rs | 11 | ||||
-rw-r--r-- | components/script/dom/headers.rs | 130 | ||||
-rwxr-xr-x | components/script/dom/htmlinputelement.rs | 3 | ||||
-rw-r--r-- | components/script/dom/htmlmediaelement.rs | 1 | ||||
-rw-r--r-- | components/script/dom/htmltrackelement.rs | 1 | ||||
-rw-r--r-- | components/script/dom/texttrack.rs | 20 | ||||
-rw-r--r-- | components/script/dom/texttracklist.rs | 4 | ||||
-rw-r--r-- | components/script/dom/videotrack.rs | 15 | ||||
-rw-r--r-- | components/script/dom/videotracklist.rs | 5 | ||||
-rw-r--r-- | components/script/dom/webgl_validations/tex_image_2d.rs | 21 | ||||
-rw-r--r-- | components/script/dom/webidls/CustomElementRegistry.webidl | 2 | ||||
-rw-r--r-- | components/script/dom/xr.rs | 16 | ||||
-rw-r--r-- | components/script/dom/xrsession.rs | 37 | ||||
-rw-r--r-- | components/script/script_runtime.rs | 17 |
16 files changed, 166 insertions, 137 deletions
diff --git a/components/script/dom/audiotrack.rs b/components/script/dom/audiotrack.rs index b66ea5bf4cc..af237bc8b1a 100644 --- a/components/script/dom/audiotrack.rs +++ b/components/script/dom/audiotrack.rs @@ -3,6 +3,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use crate::dom::audiotracklist::AudioTrackList; +use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::codegen::Bindings::AudioTrackBinding::{self, AudioTrackMethods}; use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; use crate::dom::bindings::root::{Dom, DomRoot}; @@ -19,7 +20,7 @@ pub struct AudioTrack { label: DOMString, language: DOMString, enabled: Cell<bool>, - track_list: Option<Dom<AudioTrackList>>, + track_list: DomRefCell<Option<Dom<AudioTrackList>>>, } impl AudioTrack { @@ -37,7 +38,7 @@ impl AudioTrack { label: label.into(), language: language.into(), enabled: Cell::new(false), - track_list: track_list.map(|t| Dom::from_ref(t)), + track_list: DomRefCell::new(track_list.map(|t| Dom::from_ref(t))), } } @@ -73,6 +74,14 @@ impl AudioTrack { pub fn set_enabled(&self, value: bool) { self.enabled.set(value); } + + pub fn add_track_list(&self, track_list: &AudioTrackList) { + *self.track_list.borrow_mut() = Some(Dom::from_ref(track_list)); + } + + pub fn remove_track_list(&self) { + *self.track_list.borrow_mut() = None; + } } impl AudioTrackMethods for AudioTrack { @@ -103,7 +112,7 @@ impl AudioTrackMethods for AudioTrack { // https://html.spec.whatwg.org/multipage/#dom-audiotrack-enabled fn SetEnabled(&self, value: bool) { - if let Some(list) = self.track_list.as_ref() { + if let Some(list) = self.track_list.borrow().as_ref() { if let Some(idx) = list.find(self) { list.set_enabled(idx, value); } diff --git a/components/script/dom/audiotracklist.rs b/components/script/dom/audiotracklist.rs index e26f23cb2a8..5191221b7d9 100644 --- a/components/script/dom/audiotracklist.rs +++ b/components/script/dom/audiotracklist.rs @@ -104,9 +104,14 @@ impl AudioTrackList { pub fn add(&self, track: &AudioTrack) { self.tracks.borrow_mut().push(Dom::from_ref(track)); + track.add_track_list(self); } pub fn clear(&self) { + self.tracks + .borrow() + .iter() + .for_each(|t| t.remove_track_list()); self.tracks.borrow_mut().clear(); } } diff --git a/components/script/dom/customelementregistry.rs b/components/script/dom/customelementregistry.rs index dbeacdc7ebb..392cf49cce5 100644 --- a/components/script/dom/customelementregistry.rs +++ b/components/script/dom/customelementregistry.rs @@ -448,6 +448,17 @@ impl CustomElementRegistryMethods for CustomElementRegistry { // Step 6 promise } + /// https://html.spec.whatwg.org/multipage/#dom-customelementregistry-upgrade + fn Upgrade(&self, node: &Node) { + // Spec says to make a list first and then iterate the list, but + // try-to-upgrade only queues upgrade reactions and doesn't itself + // modify the tree, so that's not an observable distinction. + node.traverse_preorder(ShadowIncluding::Yes).for_each(|n| { + if let Some(element) = n.downcast::<Element>() { + try_upgrade_element(element); + } + }); + } } #[derive(Clone, JSTraceable, MallocSizeOf)] diff --git a/components/script/dom/headers.rs b/components/script/dom/headers.rs index 61c6fc1f98e..a75b0292d6f 100644 --- a/components/script/dom/headers.rs +++ b/components/script/dom/headers.rs @@ -100,10 +100,20 @@ impl HeadersMethods for Headers { combined_value.push(b','); } combined_value.extend(valid_value.iter().cloned()); - self.header_list.borrow_mut().insert( - HeaderName::from_str(&valid_name).unwrap(), - HeaderValue::from_bytes(&combined_value).unwrap(), - ); + match HeaderValue::from_bytes(&combined_value) { + Ok(value) => { + self.header_list + .borrow_mut() + .insert(HeaderName::from_str(&valid_name).unwrap(), value); + }, + Err(_) => { + // can't add the header, but we don't need to panic the browser over it + warn!( + "Servo thinks \"{:?}\" is a valid HTTP header value but HeaderValue doesn't.", + combined_value + ); + }, + }; Ok(()) } @@ -197,7 +207,7 @@ impl Headers { for (name, value) in h.header_list.borrow().iter() { self.Append( ByteString::new(Vec::from(name.as_str())), - ByteString::new(Vec::from(value.to_str().unwrap().as_bytes())), + ByteString::new(Vec::from(value.as_bytes())), )?; } Ok(()) @@ -267,13 +277,13 @@ impl Headers { .map_or(vec![], |v| v.as_bytes().to_owned()) } - pub fn sort_header_list(&self) -> Vec<(String, String)> { + pub fn sort_header_list(&self) -> Vec<(String, Vec<u8>)> { let borrowed_header_list = self.header_list.borrow(); let headers_iter = borrowed_header_list.iter(); let mut header_vec = vec![]; for (name, value) in headers_iter { let name = name.as_str().to_owned(); - let value = value.to_str().unwrap().to_owned(); + let value = value.as_bytes().to_vec(); let name_value = (name, value); header_vec.push(name_value); } @@ -293,7 +303,7 @@ impl Iterable for Headers { fn get_value_at_index(&self, n: u32) -> ByteString { let sorted_header_vec = self.sort_header_list(); let value = sorted_header_vec[n as usize].1.clone(); - ByteString::new(value.into_bytes().to_vec()) + ByteString::new(value) } fn get_key_at_index(&self, n: u32) -> ByteString { @@ -345,40 +355,19 @@ pub fn is_forbidden_header_name(name: &str) -> bool { } // There is some unresolved confusion over the definition of a name and a value. -// The fetch spec [1] defines a name as "a case-insensitive byte -// sequence that matches the field-name token production. The token -// productions are viewable in [2]." A field-name is defined as a -// token, which is defined in [3]. -// ISSUE 1: -// It defines a value as "a byte sequence that matches the field-content token production." -// To note, there is a difference between field-content and -// field-value (which is made up of field-content and obs-fold). The -// current definition does not allow for obs-fold (which are white -// space and newlines) in values. So perhaps a value should be defined -// as "a byte sequence that matches the field-value token production." -// However, this would then allow values made up entirely of white space and newlines. -// RELATED ISSUE 2: -// According to a previously filed Errata ID: 4189 in [4], "the -// specified field-value rule does not allow single field-vchar -// surrounded by whitespace anywhere". They provided a fix for the -// field-content production, but ISSUE 1 has still not been resolved. -// The production definitions likely need to be re-written. -// [1] https://fetch.spec.whatwg.org/#concept-header-value -// [2] https://tools.ietf.org/html/rfc7230#section-3.2 -// [3] https://tools.ietf.org/html/rfc7230#section-3.2.6 -// [4] https://www.rfc-editor.org/errata_search.php?rfc=7230 // -// As of December 2019 WHATWG, isn't even using grammar productions for value; +// As of December 2019, WHATWG has no formal grammar production for value; // https://fetch.spec.whatg.org/#concept-header-value just says not to have -// newlines, nulls, or leading/trailing whitespace. +// newlines, nulls, or leading/trailing whitespace. It even allows +// octets that aren't a valid UTF-8 encoding, and WPT tests reflect this. +// The HeaderValue class does not fully reflect this, so headers +// containing bytes with values 1..31 or 127 can't be created, failing +// WPT tests but probably not affecting anything important on the real Internet. fn validate_name_and_value(name: ByteString, value: ByteString) -> Fallible<(String, Vec<u8>)> { let valid_name = validate_name(name)?; - - // this is probably out of date - if !is_field_content(&value) { - return Err(Error::Type("Value is not valid".to_string())); + if !is_legal_header_value(&value) { + return Err(Error::Type("Header value is not valid".to_string())); } - Ok((valid_name, value.into())) } @@ -431,47 +420,40 @@ fn is_field_name(name: &ByteString) -> bool { is_token(&*name) } -// https://tools.ietf.org/html/rfc7230#section-3.2 -// http://www.rfc-editor.org/errata_search.php?rfc=7230 -// Errata ID: 4189 -// field-content = field-vchar [ 1*( SP / HTAB / field-vchar ) -// field-vchar ] -fn is_field_content(value: &ByteString) -> bool { +// https://fetch.spec.whatg.org/#concept-header-value +fn is_legal_header_value(value: &ByteString) -> bool { let value_len = value.len(); - if value_len == 0 { - return false; - } - if !is_field_vchar(value[0]) { - return false; - } - - if value_len > 2 { - for &ch in &value[1..value_len - 1] { - if !is_field_vchar(ch) && !is_space(ch) && !is_htab(ch) { - return false; - } + return true; + } + match value[0] { + b' ' | b'\t' => return false, + _ => {}, + }; + match value[value_len - 1] { + b' ' | b'\t' => return false, + _ => {}, + }; + for &ch in &value[..] { + match ch { + b'\0' | b'\n' | b'\r' => return false, + _ => {}, } } - - if !is_field_vchar(value[value_len - 1]) { - return false; - } - - return true; -} - -fn is_space(x: u8) -> bool { - x == b' ' -} - -fn is_htab(x: u8) -> bool { - x == b'\t' -} - -// https://tools.ietf.org/html/rfc7230#section-3.2 -fn is_field_vchar(x: u8) -> bool { - is_vchar(x) || is_obs_text(x) + true + // If accepting non-UTF8 header values causes breakage, + // removing the above "true" and uncommenting the below code + // would ameliorate it while still accepting most reasonable headers: + //match str::from_utf8(value) { + // Ok(_) => true, + // Err(_) => { + // warn!( + // "Rejecting spec-legal but non-UTF8 header value: {:?}", + // value + // ); + // false + // }, + // } } // https://tools.ietf.org/html/rfc5234#appendix-B.1 diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs index 9018f05813a..0cef0a10535 100755 --- a/components/script/dom/htmlinputelement.rs +++ b/components/script/dom/htmlinputelement.rs @@ -46,7 +46,6 @@ use crate::textinput::KeyReaction::{ }; use crate::textinput::Lines::Single; use crate::textinput::{Direction, SelectionDirection, TextInput, UTF16CodeUnits, UTF8Bytes}; -use caseless::compatibility_caseless_match_str; use dom_struct::dom_struct; use embedder_traits::FilterPattern; use encoding_rs::Encoding; @@ -917,7 +916,7 @@ fn in_same_group( // TODO Both a and b are in the same home subtree. other.form_owner().as_deref() == owner && match (other.radio_group_name(), group) { - (Some(ref s1), Some(s2)) => compatibility_caseless_match_str(s1, s2) && s2 != &atom!(""), + (Some(ref s1), Some(s2)) => s1 == s2 && s2 != &atom!(""), _ => false } } diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs index 91acd4b97e7..cb93a77a90d 100644 --- a/components/script/dom/htmlmediaelement.rs +++ b/components/script/dom/htmlmediaelement.rs @@ -2362,6 +2362,7 @@ impl HTMLMediaElementMethods for HTMLMediaElement { label, language, TextTrackMode::Hidden, + None, ); // Step 3 & 4 self.TextTracks().add(&track); diff --git a/components/script/dom/htmltrackelement.rs b/components/script/dom/htmltrackelement.rs index caa8932b415..c67701b3894 100644 --- a/components/script/dom/htmltrackelement.rs +++ b/components/script/dom/htmltrackelement.rs @@ -59,6 +59,7 @@ impl HTMLTrackElement { Default::default(), Default::default(), Default::default(), + None, ); Node::reflect_node( Box::new(HTMLTrackElement::new_inherited( diff --git a/components/script/dom/texttrack.rs b/components/script/dom/texttrack.rs index 88c4859e05e..7c2b54adcd9 100644 --- a/components/script/dom/texttrack.rs +++ b/components/script/dom/texttrack.rs @@ -2,16 +2,18 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::codegen::Bindings::TextTrackBinding::{ self, TextTrackKind, TextTrackMethods, TextTrackMode, }; use crate::dom::bindings::error::{Error, ErrorResult}; use crate::dom::bindings::reflector::{reflect_dom_object, DomObject}; -use crate::dom::bindings::root::{DomRoot, MutNullableDom}; +use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom}; use crate::dom::bindings::str::DOMString; use crate::dom::eventtarget::EventTarget; use crate::dom::texttrackcue::TextTrackCue; use crate::dom::texttrackcuelist::TextTrackCueList; +use crate::dom::texttracklist::TextTrackList; use crate::dom::window::Window; use dom_struct::dom_struct; use std::cell::Cell; @@ -25,6 +27,7 @@ pub struct TextTrack { id: String, mode: Cell<TextTrackMode>, cue_list: MutNullableDom<TextTrackCueList>, + track_list: DomRefCell<Option<Dom<TextTrackList>>>, } impl TextTrack { @@ -34,6 +37,7 @@ impl TextTrack { label: DOMString, language: DOMString, mode: TextTrackMode, + track_list: Option<&TextTrackList>, ) -> TextTrack { TextTrack { eventtarget: EventTarget::new_inherited(), @@ -43,6 +47,7 @@ impl TextTrack { id: id.into(), mode: Cell::new(mode), cue_list: Default::default(), + track_list: DomRefCell::new(track_list.map(|t| Dom::from_ref(t))), } } @@ -53,9 +58,12 @@ impl TextTrack { label: DOMString, language: DOMString, mode: TextTrackMode, + track_list: Option<&TextTrackList>, ) -> DomRoot<TextTrack> { reflect_dom_object( - Box::new(TextTrack::new_inherited(id, kind, label, language, mode)), + Box::new(TextTrack::new_inherited( + id, kind, label, language, mode, track_list, + )), window, TextTrackBinding::Wrap, ) @@ -69,6 +77,14 @@ impl TextTrack { pub fn id(&self) -> &str { &self.id } + + pub fn add_track_list(&self, track_list: &TextTrackList) { + *self.track_list.borrow_mut() = Some(Dom::from_ref(track_list)); + } + + pub fn remove_track_list(&self) { + *self.track_list.borrow_mut() = None; + } } impl TextTrackMethods for TextTrack { diff --git a/components/script/dom/texttracklist.rs b/components/script/dom/texttracklist.rs index f6f9037902e..0e978972d69 100644 --- a/components/script/dom/texttracklist.rs +++ b/components/script/dom/texttracklist.rs @@ -94,6 +94,7 @@ impl TextTrackList { }), &canceller, ); + track.add_track_list(self); } } @@ -101,6 +102,9 @@ impl TextTrackList { // removed from the TextTrackList. #[allow(dead_code)] pub fn remove(&self, idx: usize) { + if let Some(track) = self.dom_tracks.borrow().get(idx) { + track.remove_track_list(); + } self.dom_tracks.borrow_mut().remove(idx); self.upcast::<EventTarget>() .fire_event(atom!("removetrack")); diff --git a/components/script/dom/videotrack.rs b/components/script/dom/videotrack.rs index b1453da0df4..18a383ab816 100644 --- a/components/script/dom/videotrack.rs +++ b/components/script/dom/videotrack.rs @@ -2,6 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::codegen::Bindings::VideoTrackBinding::{self, VideoTrackMethods}; use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; use crate::dom::bindings::root::{Dom, DomRoot}; @@ -19,7 +20,7 @@ pub struct VideoTrack { label: DOMString, language: DOMString, selected: Cell<bool>, - track_list: Option<Dom<VideoTrackList>>, + track_list: DomRefCell<Option<Dom<VideoTrackList>>>, } impl VideoTrack { @@ -37,7 +38,7 @@ impl VideoTrack { label: label.into(), language: language.into(), selected: Cell::new(false), - track_list: track_list.map(|t| Dom::from_ref(t)), + track_list: DomRefCell::new(track_list.map(|t| Dom::from_ref(t))), } } @@ -73,6 +74,14 @@ impl VideoTrack { pub fn set_selected(&self, value: bool) { self.selected.set(value); } + + pub fn add_track_list(&self, track_list: &VideoTrackList) { + *self.track_list.borrow_mut() = Some(Dom::from_ref(track_list)); + } + + pub fn remove_track_list(&self) { + *self.track_list.borrow_mut() = None; + } } impl VideoTrackMethods for VideoTrack { @@ -103,7 +112,7 @@ impl VideoTrackMethods for VideoTrack { // https://html.spec.whatwg.org/multipage/#dom-videotrack-selected fn SetSelected(&self, value: bool) { - if let Some(list) = self.track_list.as_ref() { + if let Some(list) = self.track_list.borrow().as_ref() { if let Some(idx) = list.find(self) { list.set_selected(idx, value); } diff --git a/components/script/dom/videotracklist.rs b/components/script/dom/videotracklist.rs index 9654123d3f3..98fa495bfdd 100644 --- a/components/script/dom/videotracklist.rs +++ b/components/script/dom/videotracklist.rs @@ -113,9 +113,14 @@ impl VideoTrackList { self.set_selected(idx, false); } } + track.add_track_list(self); } pub fn clear(&self) { + self.tracks + .borrow() + .iter() + .for_each(|t| t.remove_track_list()); self.tracks.borrow_mut().clear(); } } diff --git a/components/script/dom/webgl_validations/tex_image_2d.rs b/components/script/dom/webgl_validations/tex_image_2d.rs index fc5919132cf..54643e7a2da 100644 --- a/components/script/dom/webgl_validations/tex_image_2d.rs +++ b/components/script/dom/webgl_validations/tex_image_2d.rs @@ -47,10 +47,12 @@ pub enum TexImageValidationError { InvalidOffsets, } -impl std::error::Error for TexImageValidationError { - fn description(&self) -> &str { +impl std::error::Error for TexImageValidationError {} + +impl fmt::Display for TexImageValidationError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { use self::TexImageValidationError::*; - match *self { + let description = match *self { InvalidTextureTarget(_) => "Invalid texture target", TextureTargetNotBound(_) => "Texture was not bound", InvalidCubicTextureDimensions => { @@ -68,17 +70,8 @@ impl std::error::Error for TexImageValidationError { NonPotTexture => "Expected a power of two texture", InvalidCompressionFormat => "Unrecognized texture compression format", InvalidOffsets => "Invalid X/Y texture offset parameters", - } - } -} - -impl fmt::Display for TexImageValidationError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!( - f, - "TexImageValidationError({})", - std::error::Error::description(self) - ) + }; + write!(f, "TexImageValidationError({})", description) } } diff --git a/components/script/dom/webidls/CustomElementRegistry.webidl b/components/script/dom/webidls/CustomElementRegistry.webidl index 6d3a7b436de..3ba49a2082c 100644 --- a/components/script/dom/webidls/CustomElementRegistry.webidl +++ b/components/script/dom/webidls/CustomElementRegistry.webidl @@ -11,6 +11,8 @@ interface CustomElementRegistry { any get(DOMString name); Promise<void> whenDefined(DOMString name); + + [CEReactions] void upgrade(Node root); }; callback CustomElementConstructor = HTMLElement(); diff --git a/components/script/dom/xr.rs b/components/script/dom/xr.rs index 72cc573d645..5804918a532 100644 --- a/components/script/dom/xr.rs +++ b/components/script/dom/xr.rs @@ -26,14 +26,14 @@ use crate::dom::xrtest::XRTest; use crate::script_thread::ScriptThread; use crate::task_source::TaskSource; use dom_struct::dom_struct; -use ipc_channel::ipc::IpcSender; +use ipc_channel::ipc::{self as ipc_crate, IpcReceiver, IpcSender}; use ipc_channel::router::ROUTER; use profile_traits::ipc; use std::cell::Cell; use std::rc::Rc; use webvr_traits::{WebVRDisplayData, WebVRDisplayEvent, WebVREvent, WebVRMsg}; use webvr_traits::{WebVRGamepadData, WebVRGamepadEvent, WebVRGamepadState}; -use webxr_api::{Error as XRError, Session, SessionMode}; +use webxr_api::{Error as XRError, Frame, Session, SessionMode}; #[dom_struct] pub struct XR { @@ -185,12 +185,15 @@ impl XRMethods for XR { .task_manager() .dom_manipulation_task_source_with_canceller(); let (sender, receiver) = ipc::channel(global.time_profiler_chan().clone()).unwrap(); + let (frame_sender, frame_receiver) = ipc_crate::channel().unwrap(); + let mut frame_receiver = Some(frame_receiver); ROUTER.add_route( receiver.to_opaque(), Box::new(move |message| { // router doesn't know this is only called once let trusted = trusted.take().unwrap(); let this = this.clone(); + let frame_receiver = frame_receiver.take().unwrap(); let message: Result<Session, webxr_api::Error> = if let Ok(message) = message.to() { message } else { @@ -199,13 +202,15 @@ impl XRMethods for XR { }; let _ = task_source.queue_with_canceller( task!(request_session: move || { - this.root().session_obtained(message, trusted.root(), mode); + this.root().session_obtained(message, trusted.root(), mode, frame_receiver); }), &canceller, ); }), ); - window.webxr_registry().request_session(mode.into(), sender); + window + .webxr_registry() + .request_session(mode.into(), sender, frame_sender); promise } @@ -222,6 +227,7 @@ impl XR { response: Result<Session, XRError>, promise: Rc<Promise>, mode: XRSessionMode, + frame_receiver: IpcReceiver<Frame>, ) { let session = match response { Ok(session) => session, @@ -231,7 +237,7 @@ impl XR { }, }; - let session = XRSession::new(&self.global(), session, mode); + let session = XRSession::new(&self.global(), session, mode, frame_receiver); if mode == XRSessionMode::Inline { self.active_inline_sessions .borrow_mut() diff --git a/components/script/dom/xrsession.rs b/components/script/dom/xrsession.rs index 6e076b6daba..a4ced8689a5 100644 --- a/components/script/dom/xrsession.rs +++ b/components/script/dom/xrsession.rs @@ -41,7 +41,7 @@ use crate::dom::xrwebgllayer::XRWebGLLayer; use crate::task_source::TaskSource; use dom_struct::dom_struct; use euclid::{Rect, RigidTransform3D, Transform3D}; -use ipc_channel::ipc::IpcSender; +use ipc_channel::ipc::IpcReceiver; use ipc_channel::router::ROUTER; use metrics::ToMs; use profile_traits::ipc; @@ -73,8 +73,6 @@ pub struct XRSession { next_raf_id: Cell<i32>, #[ignore_malloc_size_of = "closures are hard"] raf_callback_list: DomRefCell<Vec<(i32, Option<Rc<XRFrameRequestCallback>>)>>, - #[ignore_malloc_size_of = "defined in ipc-channel"] - raf_sender: DomRefCell<Option<IpcSender<Frame>>>, input_sources: Dom<XRInputSourceArray>, // Any promises from calling end() #[ignore_malloc_size_of = "promises are hard"] @@ -108,7 +106,6 @@ impl XRSession { next_raf_id: Cell::new(0), raf_callback_list: DomRefCell::new(vec![]), - raf_sender: DomRefCell::new(None), input_sources: Dom::from_ref(input_sources), end_promises: DomRefCell::new(vec![]), ended: Cell::new(false), @@ -116,7 +113,12 @@ impl XRSession { } } - pub fn new(global: &GlobalScope, session: Session, mode: XRSessionMode) -> DomRoot<XRSession> { + pub fn new( + global: &GlobalScope, + session: Session, + mode: XRSessionMode, + frame_receiver: IpcReceiver<Frame>, + ) -> DomRoot<XRSession> { let ivfov = if mode == XRSessionMode::Inline { Some(FRAC_PI_2) } else { @@ -136,7 +138,7 @@ impl XRSession { ); input_sources.set_initial_inputs(&ret); ret.attach_event_handler(); - ret.setup_raf_loop(); + ret.setup_raf_loop(frame_receiver); ret } @@ -153,21 +155,15 @@ impl XRSession { self.mode != XRSessionMode::Inline } - fn setup_raf_loop(&self) { - assert!( - self.raf_sender.borrow().is_none(), - "RAF loop already set up" - ); + fn setup_raf_loop(&self, frame_receiver: IpcReceiver<Frame>) { let this = Trusted::new(self); let global = self.global(); let window = global.as_window(); let (task_source, canceller) = window .task_manager() .dom_manipulation_task_source_with_canceller(); - let (sender, receiver) = ipc::channel(global.time_profiler_chan().clone()).unwrap(); - *self.raf_sender.borrow_mut() = Some(sender); ROUTER.add_route( - receiver.to_opaque(), + frame_receiver.to_opaque(), Box::new(move |message| { let this = this.clone(); let _ = task_source.queue_with_canceller( @@ -179,15 +175,7 @@ impl XRSession { }), ); - self.request_new_xr_frame(); - } - - /// Requests a new https://immersive-web.github.io/webxr/#xr-animation-frame - /// - /// This happens regardless of the presense of rAF callbacks - fn request_new_xr_frame(&self) { - let sender = self.raf_sender.borrow().clone().unwrap(); - self.session.borrow_mut().request_animation_frame(sender); + self.session.borrow_mut().start_render_loop(); } pub fn is_outside_raf(&self) -> bool { @@ -360,8 +348,9 @@ impl XRSession { if self.is_immersive() { base_layer.swap_buffers(); self.session.borrow_mut().render_animation_frame(); + } else { + self.session.borrow_mut().start_render_loop(); } - self.request_new_xr_frame(); // If the canvas element is attached to the DOM, it is now dirty, // and we need to trigger a reflow. diff --git a/components/script/script_runtime.rs b/components/script/script_runtime.rs index 02a6b42b854..3f82e3496e6 100644 --- a/components/script/script_runtime.rs +++ b/components/script/script_runtime.rs @@ -915,16 +915,13 @@ unsafe extern "C" fn consume_stream( let mimetype = unwrapped_source.Headers().extract_mime_type(); //Step 2.3 If mimeType is not `application/wasm`, return with a TypeError and abort these substeps. - match &mimetype[..] { - b"application/wasm" | b"APPLICATION/wasm" | b"APPLICATION/WASM" => {}, - _ => { - throw_dom_exception( - cx, - &global, - Error::Type("Response has unsupported MIME type".to_string()), - ); - return false; - }, + if !&mimetype[..].eq_ignore_ascii_case(b"application/wasm") { + throw_dom_exception( + cx, + &global, + Error::Type("Response has unsupported MIME type".to_string()), + ); + return false; } //Step 2.4 If response is not CORS-same-origin, return with a TypeError and abort these substeps. |