aboutsummaryrefslogtreecommitdiffstats
path: root/components/script
diff options
context:
space:
mode:
Diffstat (limited to 'components/script')
-rw-r--r--components/script/dom/audiotrack.rs15
-rw-r--r--components/script/dom/audiotracklist.rs5
-rw-r--r--components/script/dom/customelementregistry.rs11
-rw-r--r--components/script/dom/headers.rs130
-rwxr-xr-xcomponents/script/dom/htmlinputelement.rs3
-rw-r--r--components/script/dom/htmlmediaelement.rs1
-rw-r--r--components/script/dom/htmltrackelement.rs1
-rw-r--r--components/script/dom/texttrack.rs20
-rw-r--r--components/script/dom/texttracklist.rs4
-rw-r--r--components/script/dom/videotrack.rs15
-rw-r--r--components/script/dom/videotracklist.rs5
-rw-r--r--components/script/dom/webgl_validations/tex_image_2d.rs21
-rw-r--r--components/script/dom/webidls/CustomElementRegistry.webidl2
-rw-r--r--components/script/dom/xr.rs16
-rw-r--r--components/script/dom/xrsession.rs37
-rw-r--r--components/script/script_runtime.rs17
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.