aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom')
-rw-r--r--components/script/dom/audiobuffer.rs1
-rw-r--r--components/script/dom/bindings/trace.rs7
-rw-r--r--components/script/dom/customelementregistry.rs2
-rw-r--r--components/script/dom/element.rs4
-rw-r--r--components/script/dom/extendablemessageevent.rs1
-rw-r--r--components/script/dom/filereader.rs2
-rw-r--r--components/script/dom/gamepad.rs1
-rw-r--r--components/script/dom/globalscope.rs2
-rw-r--r--components/script/dom/history.rs1
-rw-r--r--components/script/dom/htmlmediaelement.rs31
-rw-r--r--components/script/dom/imagedata.rs1
-rw-r--r--components/script/dom/mediadevices.rs12
-rw-r--r--components/script/dom/mediastream.rs117
-rw-r--r--components/script/dom/mediastreamtrack.rs74
-rw-r--r--components/script/dom/messageevent.rs1
-rw-r--r--components/script/dom/mod.rs3
-rw-r--r--components/script/dom/paintworkletglobalscope.rs3
-rw-r--r--components/script/dom/rtcpeerconnection.rs37
-rw-r--r--components/script/dom/rtctrackevent.rs78
-rw-r--r--components/script/dom/vrdisplay.rs87
-rw-r--r--components/script/dom/vreyeparameters.rs1
-rw-r--r--components/script/dom/vrframedata.rs4
-rw-r--r--components/script/dom/vrpose.rs6
-rw-r--r--components/script/dom/vrstageparameters.rs1
-rw-r--r--components/script/dom/webidls/MediaStream.webidl24
-rw-r--r--components/script/dom/webidls/MediaStreamTrack.webidl24
-rw-r--r--components/script/dom/webidls/RTCPeerConnection.webidl12
-rw-r--r--components/script/dom/webidls/RTCTrackEvent.webidl23
-rw-r--r--components/script/dom/webidls/XRInputSource.webidl26
-rw-r--r--components/script/dom/webidls/XRSession.webidl5
-rw-r--r--components/script/dom/xmlhttprequest.rs1
-rw-r--r--components/script/dom/xrinputsource.rs83
-rw-r--r--components/script/dom/xrreferencespace.rs2
-rw-r--r--components/script/dom/xrrigidtransform.rs3
-rw-r--r--components/script/dom/xrsession.rs11
-rw-r--r--components/script/dom/xrspace.rs39
-rw-r--r--components/script/dom/xrstationaryreferencespace.rs4
-rw-r--r--components/script/dom/xrview.rs2
-rw-r--r--components/script/dom/xrviewerpose.rs1
39 files changed, 661 insertions, 76 deletions
diff --git a/components/script/dom/audiobuffer.rs b/components/script/dom/audiobuffer.rs
index a021b61ac8c..cabd281dc63 100644
--- a/components/script/dom/audiobuffer.rs
+++ b/components/script/dom/audiobuffer.rs
@@ -42,6 +42,7 @@ type JSAudioChannel = Heap<*mut JSObject>;
pub struct AudioBuffer {
reflector_: Reflector,
/// Float32Arrays returned by calls to GetChannelData.
+ #[ignore_malloc_size_of = "mozjs"]
js_channels: DomRefCell<Vec<JSAudioChannel>>,
/// Aggregates the data from js_channels.
/// This is Some<T> iff the buffers in js_channels are detached.
diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs
index 56805e4d9fe..023917c172c 100644
--- a/components/script/dom/bindings/trace.rs
+++ b/components/script/dom/bindings/trace.rs
@@ -105,6 +105,7 @@ use servo_media::audio::panner_node::{DistanceModel, PanningModel};
use servo_media::audio::param::ParamType;
use servo_media::player::Player;
use servo_media::streams::registry::MediaStreamId;
+use servo_media::streams::MediaStreamType;
use servo_media::webrtc::WebRtcController;
use servo_url::{ImmutableOrigin, MutableOrigin, ServoUrl};
use smallvec::SmallVec;
@@ -138,7 +139,7 @@ use tendril::{StrTendril, TendrilSink};
use time::{Duration, Timespec};
use uuid::Uuid;
use webrender_api::{DocumentId, ImageKey, RenderApiSender};
-use webvr_traits::WebVRGamepadHand;
+use webvr_traits::{WebVRGamepadData, WebVRGamepadHand, WebVRGamepadState};
/// A trait to allow tracing (only) DOM objects.
pub unsafe trait JSTraceable {
@@ -478,7 +479,7 @@ unsafe_no_jsmanaged_fields!(WebGLVertexArrayId);
unsafe_no_jsmanaged_fields!(WebGLVersion);
unsafe_no_jsmanaged_fields!(WebGLSLVersion);
unsafe_no_jsmanaged_fields!(MediaList);
-unsafe_no_jsmanaged_fields!(WebVRGamepadHand);
+unsafe_no_jsmanaged_fields!(WebVRGamepadData, WebVRGamepadState, WebVRGamepadHand);
unsafe_no_jsmanaged_fields!(ScriptToConstellationChan);
unsafe_no_jsmanaged_fields!(InteractiveMetrics);
unsafe_no_jsmanaged_fields!(InteractiveWindow);
@@ -490,7 +491,7 @@ unsafe_no_jsmanaged_fields!(NodeId);
unsafe_no_jsmanaged_fields!(AnalysisEngine, DistanceModel, PanningModel, ParamType);
unsafe_no_jsmanaged_fields!(dyn Player);
unsafe_no_jsmanaged_fields!(WebRtcController);
-unsafe_no_jsmanaged_fields!(MediaStreamId);
+unsafe_no_jsmanaged_fields!(MediaStreamId, MediaStreamType);
unsafe_no_jsmanaged_fields!(Mutex<MediaFrameRenderer>);
unsafe_no_jsmanaged_fields!(RenderApiSender);
unsafe_no_jsmanaged_fields!(ResourceFetchTiming);
diff --git a/components/script/dom/customelementregistry.rs b/components/script/dom/customelementregistry.rs
index 3d329119f4e..39824e334a2 100644
--- a/components/script/dom/customelementregistry.rs
+++ b/components/script/dom/customelementregistry.rs
@@ -719,7 +719,7 @@ pub enum CustomElementReaction {
Upgrade(#[ignore_malloc_size_of = "Rc"] Rc<CustomElementDefinition>),
Callback(
#[ignore_malloc_size_of = "Rc"] Rc<Function>,
- Box<[Heap<JSVal>]>,
+ #[ignore_malloc_size_of = "mozjs"] Box<[Heap<JSVal>]>,
),
}
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs
index 2d12e93774d..1b918c0537b 100644
--- a/components/script/dom/element.rs
+++ b/components/script/dom/element.rs
@@ -3075,6 +3075,10 @@ impl<'a> SelectorsElement for DomRoot<Element> {
.map_or(false, |atom| case_sensitivity.eq_atom(id, atom))
}
+ fn is_part(&self, _name: &Atom) -> bool {
+ false
+ }
+
fn has_class(&self, name: &Atom, case_sensitivity: CaseSensitivity) -> bool {
Element::has_class(&**self, name, case_sensitivity)
}
diff --git a/components/script/dom/extendablemessageevent.rs b/components/script/dom/extendablemessageevent.rs
index f9c2de13a4b..7fd16aafec4 100644
--- a/components/script/dom/extendablemessageevent.rs
+++ b/components/script/dom/extendablemessageevent.rs
@@ -24,6 +24,7 @@ use servo_atoms::Atom;
#[dom_struct]
pub struct ExtendableMessageEvent {
event: ExtendableEvent,
+ #[ignore_malloc_size_of = "mozjs"]
data: Heap<JSVal>,
origin: DOMString,
lastEventId: DOMString,
diff --git a/components/script/dom/filereader.rs b/components/script/dom/filereader.rs
index 6092dcc9935..55989078d4f 100644
--- a/components/script/dom/filereader.rs
+++ b/components/script/dom/filereader.rs
@@ -83,7 +83,7 @@ pub enum FileReaderReadyState {
#[derive(JSTraceable, MallocSizeOf)]
pub enum FileReaderResult {
- ArrayBuffer(Heap<JSVal>),
+ ArrayBuffer(#[ignore_malloc_size_of = "mozjs"] Heap<JSVal>),
String(DOMString),
}
diff --git a/components/script/dom/gamepad.rs b/components/script/dom/gamepad.rs
index 3e65b0a11f5..fe86a3b2329 100644
--- a/components/script/dom/gamepad.rs
+++ b/components/script/dom/gamepad.rs
@@ -32,6 +32,7 @@ pub struct Gamepad {
connected: Cell<bool>,
timestamp: Cell<f64>,
mapping_type: String,
+ #[ignore_malloc_size_of = "mozjs"]
axes: Heap<*mut JSObject>,
buttons: Dom<GamepadButtonList>,
pose: Option<Dom<VRPose>>,
diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs
index 91112299034..33458bf2ece 100644
--- a/components/script/dom/globalscope.rs
+++ b/components/script/dom/globalscope.rs
@@ -145,6 +145,7 @@ pub struct GlobalScope {
/// they're consumed before it'd be reported.
///
/// <https://html.spec.whatwg.org/multipage/#about-to-be-notified-rejected-promises-list>
+ #[ignore_malloc_size_of = "mozjs"]
uncaught_rejections: DomRefCell<Vec<Box<Heap<*mut JSObject>>>>,
/// Promises in this list have previously been reported as rejected
@@ -152,6 +153,7 @@ pub struct GlobalScope {
/// in the last turn of the event loop.
///
/// <https://html.spec.whatwg.org/multipage/#outstanding-rejected-promises-weak-set>
+ #[ignore_malloc_size_of = "mozjs"]
consumed_rejections: DomRefCell<Vec<Box<Heap<*mut JSObject>>>>,
}
diff --git a/components/script/dom/history.rs b/components/script/dom/history.rs
index e468b79440c..787591af8a3 100644
--- a/components/script/dom/history.rs
+++ b/components/script/dom/history.rs
@@ -40,6 +40,7 @@ enum PushOrReplace {
pub struct History {
reflector_: Reflector,
window: Dom<Window>,
+ #[ignore_malloc_size_of = "mozjs"]
state: Heap<JSVal>,
state_id: Cell<Option<HistoryStateId>>,
}
diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs
index 8d41a685b7b..9bbfb30d46c 100644
--- a/components/script/dom/htmlmediaelement.rs
+++ b/components/script/dom/htmlmediaelement.rs
@@ -62,7 +62,6 @@ use html5ever::{LocalName, Prefix};
use http::header::{self, HeaderMap, HeaderValue};
use ipc_channel::ipc;
use ipc_channel::router::ROUTER;
-use mime::{self, Mime};
use net_traits::image::base::Image;
use net_traits::image_cache::ImageResponse;
use net_traits::request::{CredentialsMode, Destination, Referrer, RequestBuilder};
@@ -73,7 +72,7 @@ use servo_config::pref;
use servo_media::player::context::{GlContext, NativeDisplay, PlayerGLContext};
use servo_media::player::frame::{Frame, FrameRenderer};
use servo_media::player::{PlaybackState, Player, PlayerError, PlayerEvent, StreamType};
-use servo_media::ServoMedia;
+use servo_media::{ServoMedia, SupportsMediaType};
use servo_url::ServoUrl;
use std::cell::Cell;
use std::collections::VecDeque;
@@ -840,9 +839,13 @@ impl HTMLMediaElement {
self.fetch_request(None);
},
SrcObject::MediaStream(ref stream) => {
- for stream in stream.get_tracks() {
- if let Err(_) =
- self.player.borrow().as_ref().unwrap().set_stream(&stream)
+ for stream in &*stream.get_tracks() {
+ if let Err(_) = self
+ .player
+ .borrow()
+ .as_ref()
+ .unwrap()
+ .set_stream(&stream.id())
{
self.queue_dedicated_media_source_failure_steps();
}
@@ -1674,20 +1677,10 @@ impl HTMLMediaElementMethods for HTMLMediaElement {
// https://html.spec.whatwg.org/multipage/#dom-navigator-canplaytype
fn CanPlayType(&self, type_: DOMString) -> CanPlayTypeResult {
- match type_.parse::<Mime>() {
- // XXX GStreamer is currently not very reliable playing OGG and most of
- // the media related WPTs uses OGG if we report that we are able to
- // play this type. So we report that we are unable to play it to force
- // the usage of other types.
- // https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/issues/520
- Ok(ref mime)
- if (mime.type_() == mime::APPLICATION && mime.subtype() == mime::OCTET_STREAM) ||
- (mime.subtype() == mime::OGG) =>
- {
- CanPlayTypeResult::_empty
- },
- Err(_) => CanPlayTypeResult::_empty,
- _ => CanPlayTypeResult::Maybe,
+ match ServoMedia::get().unwrap().can_play_type(&type_) {
+ SupportsMediaType::No => CanPlayTypeResult::_empty,
+ SupportsMediaType::Maybe => CanPlayTypeResult::Maybe,
+ SupportsMediaType::Probably => CanPlayTypeResult::Probably,
}
}
diff --git a/components/script/dom/imagedata.rs b/components/script/dom/imagedata.rs
index 9566c7b0f39..29c15f665a4 100644
--- a/components/script/dom/imagedata.rs
+++ b/components/script/dom/imagedata.rs
@@ -25,6 +25,7 @@ pub struct ImageData {
reflector_: Reflector,
width: u32,
height: u32,
+ #[ignore_malloc_size_of = "mozjs"]
data: Heap<*mut JSObject>,
}
diff --git a/components/script/dom/mediadevices.rs b/components/script/dom/mediadevices.rs
index 0a4f00e2472..bcc575a2ef6 100644
--- a/components/script/dom/mediadevices.rs
+++ b/components/script/dom/mediadevices.rs
@@ -14,9 +14,11 @@ use crate::dom::bindings::root::DomRoot;
use crate::dom::eventtarget::EventTarget;
use crate::dom::globalscope::GlobalScope;
use crate::dom::mediastream::MediaStream;
+use crate::dom::mediastreamtrack::MediaStreamTrack;
use crate::dom::promise::Promise;
use dom_struct::dom_struct;
use servo_media::streams::capture::{Constrain, ConstrainRange, MediaTrackConstraintSet};
+use servo_media::streams::MediaStreamType;
use servo_media::ServoMedia;
use std::rc::Rc;
@@ -51,18 +53,20 @@ impl MediaDevicesMethods for MediaDevices {
InCompartment::Already(&in_compartment_proof),
);
let media = ServoMedia::get().unwrap();
- let mut tracks = vec![];
+ let stream = MediaStream::new(&self.global());
if let Some(constraints) = convert_constraints(&constraints.audio) {
if let Some(audio) = media.create_audioinput_stream(constraints) {
- tracks.push(audio)
+ let track = MediaStreamTrack::new(&self.global(), audio, MediaStreamType::Audio);
+ stream.add_track(&track);
}
}
if let Some(constraints) = convert_constraints(&constraints.video) {
if let Some(video) = media.create_videoinput_stream(constraints) {
- tracks.push(video)
+ let track = MediaStreamTrack::new(&self.global(), video, MediaStreamType::Video);
+ stream.add_track(&track);
}
}
- let stream = MediaStream::new(&self.global(), tracks);
+
p.resolve_native(&stream);
p
}
diff --git a/components/script/dom/mediastream.rs b/components/script/dom/mediastream.rs
index 42588afc476..2ae573b290e 100644
--- a/components/script/dom/mediastream.rs
+++ b/components/script/dom/mediastream.rs
@@ -3,38 +3,131 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use crate::dom::bindings::cell::DomRefCell;
-use crate::dom::bindings::codegen::Bindings::MediaStreamBinding;
-use crate::dom::bindings::reflector::reflect_dom_object;
-use crate::dom::bindings::root::DomRoot;
+use crate::dom::bindings::codegen::Bindings::MediaStreamBinding::{self, MediaStreamMethods};
+use crate::dom::bindings::error::Fallible;
+use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
+use crate::dom::bindings::root::{Dom, DomRoot};
+use crate::dom::bindings::str::DOMString;
use crate::dom::eventtarget::EventTarget;
use crate::dom::globalscope::GlobalScope;
+use crate::dom::mediastreamtrack::MediaStreamTrack;
+use crate::dom::window::Window;
use dom_struct::dom_struct;
-use servo_media::streams::registry::MediaStreamId;
+use servo_media::streams::MediaStreamType;
+use std::cell::Ref;
#[dom_struct]
pub struct MediaStream {
eventtarget: EventTarget,
- #[ignore_malloc_size_of = "defined in servo-media"]
- tracks: DomRefCell<Vec<MediaStreamId>>,
+ tracks: DomRefCell<Vec<Dom<MediaStreamTrack>>>,
}
impl MediaStream {
- pub fn new_inherited(tracks: Vec<MediaStreamId>) -> MediaStream {
+ pub fn new_inherited() -> MediaStream {
MediaStream {
eventtarget: EventTarget::new_inherited(),
- tracks: DomRefCell::new(tracks),
+ tracks: DomRefCell::new(vec![]),
}
}
- pub fn new(global: &GlobalScope, tracks: Vec<MediaStreamId>) -> DomRoot<MediaStream> {
+ pub fn new(global: &GlobalScope) -> DomRoot<MediaStream> {
reflect_dom_object(
- Box::new(MediaStream::new_inherited(tracks)),
+ Box::new(MediaStream::new_inherited()),
global,
MediaStreamBinding::Wrap,
)
}
- pub fn get_tracks(&self) -> Vec<MediaStreamId> {
- self.tracks.borrow_mut().clone()
+ pub fn Constructor(global: &Window) -> Fallible<DomRoot<MediaStream>> {
+ Ok(MediaStream::new(&global.global()))
+ }
+
+ pub fn Constructor_(_: &Window, stream: &MediaStream) -> Fallible<DomRoot<MediaStream>> {
+ Ok(stream.Clone())
+ }
+
+ pub fn Constructor__(
+ global: &Window,
+ tracks: Vec<DomRoot<MediaStreamTrack>>,
+ ) -> Fallible<DomRoot<MediaStream>> {
+ let new = MediaStream::new(&global.global());
+ for track in tracks {
+ // this is quadratic, but shouldn't matter much
+ // if this becomes a problem we can use a hash map
+ new.AddTrack(&track)
+ }
+ Ok(new)
+ }
+
+ pub fn get_tracks(&self) -> Ref<[Dom<MediaStreamTrack>]> {
+ Ref::map(self.tracks.borrow(), |tracks| &**tracks)
+ }
+
+ pub fn add_track(&self, track: &MediaStreamTrack) {
+ self.tracks.borrow_mut().push(Dom::from_ref(track))
+ }
+}
+
+impl MediaStreamMethods for MediaStream {
+ /// https://w3c.github.io/mediacapture-main/#dom-mediastream-gettracks
+ fn GetTracks(&self) -> Vec<DomRoot<MediaStreamTrack>> {
+ self.tracks
+ .borrow()
+ .iter()
+ .map(|x| DomRoot::from_ref(&**x))
+ .collect()
+ }
+
+ /// https://w3c.github.io/mediacapture-main/#dom-mediastream-getaudiotracks
+ fn GetAudioTracks(&self) -> Vec<DomRoot<MediaStreamTrack>> {
+ self.tracks
+ .borrow()
+ .iter()
+ .filter(|x| x.ty() == MediaStreamType::Audio)
+ .map(|x| DomRoot::from_ref(&**x))
+ .collect()
+ }
+
+ /// https://w3c.github.io/mediacapture-main/#dom-mediastream-getvideotracks
+ fn GetVideoTracks(&self) -> Vec<DomRoot<MediaStreamTrack>> {
+ self.tracks
+ .borrow()
+ .iter()
+ .filter(|x| x.ty() == MediaStreamType::Video)
+ .map(|x| DomRoot::from_ref(&**x))
+ .collect()
+ }
+
+ /// https://w3c.github.io/mediacapture-main/#dom-mediastream-gettrackbyid
+ fn GetTrackById(&self, id: DOMString) -> Option<DomRoot<MediaStreamTrack>> {
+ self.tracks
+ .borrow()
+ .iter()
+ .find(|x| x.id().id().to_string() == &*id)
+ .map(|x| DomRoot::from_ref(&**x))
+ }
+
+ /// https://w3c.github.io/mediacapture-main/#dom-mediastream-addtrack
+ fn AddTrack(&self, track: &MediaStreamTrack) {
+ let existing = self.tracks.borrow().iter().find(|x| *x == &track).is_some();
+
+ if existing {
+ return;
+ }
+ self.add_track(track)
+ }
+
+ /// https://w3c.github.io/mediacapture-main/#dom-mediastream-removetrack
+ fn RemoveTrack(&self, track: &MediaStreamTrack) {
+ self.tracks.borrow_mut().retain(|x| *x != track);
+ }
+
+ /// https://w3c.github.io/mediacapture-main/#dom-mediastream-clone
+ fn Clone(&self) -> DomRoot<MediaStream> {
+ let new = MediaStream::new(&self.global());
+ for track in &*self.tracks.borrow() {
+ new.add_track(&track)
+ }
+ new
}
}
diff --git a/components/script/dom/mediastreamtrack.rs b/components/script/dom/mediastreamtrack.rs
new file mode 100644
index 00000000000..2cc0bde7442
--- /dev/null
+++ b/components/script/dom/mediastreamtrack.rs
@@ -0,0 +1,74 @@
+/* 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 https://mozilla.org/MPL/2.0/. */
+
+use crate::dom::bindings::codegen::Bindings::MediaStreamTrackBinding::{
+ self, MediaStreamTrackMethods,
+};
+use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
+use crate::dom::bindings::root::DomRoot;
+use crate::dom::bindings::str::DOMString;
+use crate::dom::eventtarget::EventTarget;
+use crate::dom::globalscope::GlobalScope;
+use dom_struct::dom_struct;
+use servo_media::streams::registry::MediaStreamId;
+use servo_media::streams::MediaStreamType;
+
+#[dom_struct]
+pub struct MediaStreamTrack {
+ eventtarget: EventTarget,
+ #[ignore_malloc_size_of = "defined in servo-media"]
+ id: MediaStreamId,
+ #[ignore_malloc_size_of = "defined in servo-media"]
+ ty: MediaStreamType,
+}
+
+impl MediaStreamTrack {
+ pub fn new_inherited(id: MediaStreamId, ty: MediaStreamType) -> MediaStreamTrack {
+ MediaStreamTrack {
+ eventtarget: EventTarget::new_inherited(),
+ id,
+ ty,
+ }
+ }
+
+ pub fn new(
+ global: &GlobalScope,
+ id: MediaStreamId,
+ ty: MediaStreamType,
+ ) -> DomRoot<MediaStreamTrack> {
+ reflect_dom_object(
+ Box::new(MediaStreamTrack::new_inherited(id, ty)),
+ global,
+ MediaStreamTrackBinding::Wrap,
+ )
+ }
+
+ pub fn id(&self) -> MediaStreamId {
+ self.id
+ }
+
+ pub fn ty(&self) -> MediaStreamType {
+ self.ty
+ }
+}
+
+impl MediaStreamTrackMethods for MediaStreamTrack {
+ /// https://w3c.github.io/mediacapture-main/#dom-mediastreamtrack-kind
+ fn Kind(&self) -> DOMString {
+ match self.ty {
+ MediaStreamType::Video => "video".into(),
+ MediaStreamType::Audio => "audio".into(),
+ }
+ }
+
+ /// https://w3c.github.io/mediacapture-main/#dom-mediastreamtrack-id
+ fn Id(&self) -> DOMString {
+ self.id.id().to_string().into()
+ }
+
+ /// https://w3c.github.io/mediacapture-main/#dom-mediastreamtrack-clone
+ fn Clone(&self) -> DomRoot<MediaStreamTrack> {
+ MediaStreamTrack::new(&self.global(), self.id, self.ty)
+ }
+}
diff --git a/components/script/dom/messageevent.rs b/components/script/dom/messageevent.rs
index edde48f95e6..c02df1e8e61 100644
--- a/components/script/dom/messageevent.rs
+++ b/components/script/dom/messageevent.rs
@@ -25,6 +25,7 @@ use std::ptr::NonNull;
#[dom_struct]
pub struct MessageEvent {
event: Event,
+ #[ignore_malloc_size_of = "mozjs"]
data: Heap<JSVal>,
origin: DOMString,
source: Option<Dom<WindowProxy>>,
diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs
index ff1688fb6c3..1dbc1383101 100644
--- a/components/script/dom/mod.rs
+++ b/components/script/dom/mod.rs
@@ -399,6 +399,7 @@ pub mod medialist;
pub mod mediaquerylist;
pub mod mediaquerylistevent;
pub mod mediastream;
+pub mod mediastreamtrack;
pub mod messageevent;
pub mod mimetype;
pub mod mimetypearray;
@@ -450,6 +451,7 @@ pub mod rtcicecandidate;
pub mod rtcpeerconnection;
pub mod rtcpeerconnectioniceevent;
pub mod rtcsessiondescription;
+pub mod rtctrackevent;
pub mod screen;
pub mod serviceworker;
pub mod serviceworkercontainer;
@@ -540,6 +542,7 @@ pub mod xmlhttprequestupload;
pub mod xmlserializer;
pub mod xr;
pub mod xrframe;
+pub mod xrinputsource;
pub mod xrlayer;
pub mod xrpose;
pub mod xrreferencespace;
diff --git a/components/script/dom/paintworkletglobalscope.rs b/components/script/dom/paintworkletglobalscope.rs
index fe119eefbf3..89b9907c95c 100644
--- a/components/script/dom/paintworkletglobalscope.rs
+++ b/components/script/dom/paintworkletglobalscope.rs
@@ -76,6 +76,7 @@ pub struct PaintWorkletGlobalScope {
/// <https://drafts.css-houdini.org/css-paint-api/#paint-definitions>
paint_definitions: DomRefCell<HashMap<Atom, Box<PaintDefinition>>>,
/// <https://drafts.css-houdini.org/css-paint-api/#paint-class-instances>
+ #[ignore_malloc_size_of = "mozjs"]
paint_class_instances: DomRefCell<HashMap<Atom, Box<Heap<JSVal>>>>,
/// The most recent name the worklet was called with
cached_name: DomRefCell<Atom>,
@@ -473,7 +474,9 @@ pub enum PaintWorkletTask {
#[derive(JSTraceable, MallocSizeOf)]
#[must_root]
struct PaintDefinition {
+ #[ignore_malloc_size_of = "mozjs"]
class_constructor: Heap<JSVal>,
+ #[ignore_malloc_size_of = "mozjs"]
paint_function: Heap<JSVal>,
constructor_valid_flag: Cell<bool>,
context_alpha_flag: bool,
diff --git a/components/script/dom/rtcpeerconnection.rs b/components/script/dom/rtcpeerconnection.rs
index 962eb0fb02c..9ec1940bbb3 100644
--- a/components/script/dom/rtcpeerconnection.rs
+++ b/components/script/dom/rtcpeerconnection.rs
@@ -26,10 +26,12 @@ use crate::dom::event::{Event, EventBubbles, EventCancelable};
use crate::dom::eventtarget::EventTarget;
use crate::dom::globalscope::GlobalScope;
use crate::dom::mediastream::MediaStream;
+use crate::dom::mediastreamtrack::MediaStreamTrack;
use crate::dom::promise::Promise;
use crate::dom::rtcicecandidate::RTCIceCandidate;
use crate::dom::rtcpeerconnectioniceevent::RTCPeerConnectionIceEvent;
use crate::dom::rtcsessiondescription::RTCSessionDescription;
+use crate::dom::rtctrackevent::RTCTrackEvent;
use crate::dom::window::Window;
use crate::task::TaskCanceller;
use crate::task_source::networking::NetworkingTaskSource;
@@ -37,6 +39,7 @@ use crate::task_source::TaskSource;
use dom_struct::dom_struct;
use servo_media::streams::registry::MediaStreamId;
+use servo_media::streams::MediaStreamType;
use servo_media::webrtc::{
BundlePolicy, GatheringState, IceCandidate, IceConnectionState, SdpType, SessionDescription,
SignalingState, WebRtcController, WebRtcSignaller,
@@ -128,7 +131,17 @@ impl WebRtcSignaller for RTCSignaller {
);
}
- fn on_add_stream(&self, _: &MediaStreamId) {}
+ fn on_add_stream(&self, id: &MediaStreamId, ty: MediaStreamType) {
+ let this = self.trusted.clone();
+ let id = *id;
+ let _ = self.task_source.queue_with_canceller(
+ task!(on_add_stream: move || {
+ let this = this.root();
+ this.on_add_stream(id, ty);
+ }),
+ &self.canceller,
+ );
+ }
fn close(&self) {
// do nothing
@@ -238,6 +251,15 @@ impl RTCPeerConnection {
event.upcast::<Event>().fire(self.upcast());
}
+ fn on_add_stream(&self, id: MediaStreamId, ty: MediaStreamType) {
+ if self.closed.get() {
+ return;
+ }
+ let track = MediaStreamTrack::new(&self.global(), id, ty);
+ let event = RTCTrackEvent::new(&self.global(), atom!("track"), false, false, &track);
+ event.upcast::<Event>().fire(self.upcast());
+ }
+
/// https://www.w3.org/TR/webrtc/#update-ice-gathering-state
fn update_gathering_state(&self, state: GatheringState) {
// step 1
@@ -399,6 +421,9 @@ impl RTCPeerConnectionMethods for RTCPeerConnection {
/// https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-icecandidate
event_handler!(icecandidate, GetOnicecandidate, SetOnicecandidate);
+ /// https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-ontrack
+ event_handler!(track, GetOntrack, SetOntrack);
+
/// https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-iceconnectionstatechange
event_handler!(
iceconnectionstatechange,
@@ -584,10 +609,12 @@ impl RTCPeerConnectionMethods for RTCPeerConnection {
// https://w3c.github.io/webrtc-pc/#legacy-interface-extensions
fn AddStream(&self, stream: &MediaStream) {
- let mut tracks = stream.get_tracks();
-
- for ref track in tracks.drain(..) {
- self.controller.borrow().as_ref().unwrap().add_stream(track);
+ for track in &*stream.get_tracks() {
+ self.controller
+ .borrow()
+ .as_ref()
+ .unwrap()
+ .add_stream(&track.id());
}
}
diff --git a/components/script/dom/rtctrackevent.rs b/components/script/dom/rtctrackevent.rs
new file mode 100644
index 00000000000..9c5d7bec362
--- /dev/null
+++ b/components/script/dom/rtctrackevent.rs
@@ -0,0 +1,78 @@
+/* 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 https://mozilla.org/MPL/2.0/. */
+
+use crate::dom::bindings::codegen::Bindings::EventBinding::EventBinding::EventMethods;
+use crate::dom::bindings::codegen::Bindings::RTCTrackEventBinding::{self, RTCTrackEventMethods};
+use crate::dom::bindings::error::Fallible;
+use crate::dom::bindings::inheritance::Castable;
+use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
+use crate::dom::bindings::root::{Dom, DomRoot};
+use crate::dom::bindings::str::DOMString;
+use crate::dom::event::Event;
+use crate::dom::globalscope::GlobalScope;
+use crate::dom::mediastreamtrack::MediaStreamTrack;
+use crate::dom::window::Window;
+use dom_struct::dom_struct;
+use servo_atoms::Atom;
+
+#[dom_struct]
+pub struct RTCTrackEvent {
+ event: Event,
+ track: Dom<MediaStreamTrack>,
+}
+
+impl RTCTrackEvent {
+ #[allow(unrooted_must_root)]
+ fn new_inherited(track: &MediaStreamTrack) -> RTCTrackEvent {
+ RTCTrackEvent {
+ event: Event::new_inherited(),
+ track: Dom::from_ref(track),
+ }
+ }
+
+ pub fn new(
+ global: &GlobalScope,
+ type_: Atom,
+ bubbles: bool,
+ cancelable: bool,
+ track: &MediaStreamTrack,
+ ) -> DomRoot<RTCTrackEvent> {
+ let trackevent = reflect_dom_object(
+ Box::new(RTCTrackEvent::new_inherited(&track)),
+ global,
+ RTCTrackEventBinding::Wrap,
+ );
+ {
+ let event = trackevent.upcast::<Event>();
+ event.init_event(type_, bubbles, cancelable);
+ }
+ trackevent
+ }
+
+ pub fn Constructor(
+ window: &Window,
+ type_: DOMString,
+ init: &RTCTrackEventBinding::RTCTrackEventInit,
+ ) -> Fallible<DomRoot<RTCTrackEvent>> {
+ Ok(RTCTrackEvent::new(
+ &window.global(),
+ Atom::from(type_),
+ init.parent.bubbles,
+ init.parent.cancelable,
+ &init.track,
+ ))
+ }
+}
+
+impl RTCTrackEventMethods for RTCTrackEvent {
+ // https://w3c.github.io/webrtc-pc/#dom-rtctrackevent-track
+ fn Track(&self) -> DomRoot<MediaStreamTrack> {
+ DomRoot::from_ref(&*self.track)
+ }
+
+ // https://dom.spec.whatwg.org/#dom-event-istrusted
+ fn IsTrusted(&self) -> bool {
+ self.event.IsTrusted()
+ }
+}
diff --git a/components/script/dom/vrdisplay.rs b/components/script/dom/vrdisplay.rs
index a8cb594a2b1..77817bae2fc 100644
--- a/components/script/dom/vrdisplay.rs
+++ b/components/script/dom/vrdisplay.rs
@@ -22,7 +22,7 @@ use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::num::Finite;
use crate::dom::bindings::refcounted::{Trusted, TrustedPromise};
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
-use crate::dom::bindings::root::{DomRoot, MutDom, MutNullableDom};
+use crate::dom::bindings::root::{Dom, DomRoot, MutDom, MutNullableDom};
use crate::dom::bindings::str::DOMString;
use crate::dom::event::Event;
use crate::dom::eventtarget::EventTarget;
@@ -36,6 +36,7 @@ use crate::dom::vrpose::VRPose;
use crate::dom::vrstageparameters::VRStageParameters;
use crate::dom::webglrenderingcontext::WebGLRenderingContext;
use crate::dom::xrframe::XRFrame;
+use crate::dom::xrinputsource::XRInputSource;
use crate::dom::xrsession::XRSession;
use crate::dom::xrwebgllayer::XRWebGLLayer;
use crate::script_runtime::CommonScriptMsg;
@@ -47,11 +48,12 @@ use dom_struct::dom_struct;
use ipc_channel::ipc::IpcSender;
use profile_traits::ipc;
use std::cell::Cell;
+use std::collections::HashMap;
use std::mem;
use std::ops::Deref;
use std::rc::Rc;
use std::thread;
-use webvr_traits::{WebVRDisplayData, WebVRDisplayEvent, WebVRFrameData, WebVRFutureFrameData};
+use webvr_traits::{WebVRDisplayData, WebVRDisplayEvent, WebVRFrameData, WebVRPoseInformation};
use webvr_traits::{WebVRLayer, WebVRMsg};
#[dom_struct]
@@ -86,12 +88,16 @@ pub struct VRDisplay {
// Compositor VRFrameData synchonization
frame_data_status: Cell<VRFrameDataStatus>,
#[ignore_malloc_size_of = "closures are hard"]
- frame_data_receiver: DomRefCell<Option<WebGLReceiver<Result<WebVRFutureFrameData, ()>>>>,
+ frame_data_receiver: DomRefCell<Option<WebGLReceiver<Result<WebVRPoseInformation, ()>>>>,
running_display_raf: Cell<bool>,
paused: Cell<bool>,
stopped_on_pause: Cell<bool>,
/// Whether or not this is XR mode, and the session
xr_session: MutNullableDom<XRSession>,
+ /// Have inputs been initialized? (i.e, has getInputSources() been called?)
+ /// XR only
+ initialized_inputs: Cell<bool>,
+ input_sources: DomRefCell<HashMap<u32, Dom<XRInputSource>>>,
}
unsafe_no_jsmanaged_fields!(WebVRDisplayData);
@@ -115,6 +121,8 @@ struct VRRAFUpdate {
/// Number uniquely identifying the WebGL context
/// so that we may setup/tear down VR compositors as things change
context_id: usize,
+ /// Do we need input data?
+ needs_inputs: bool,
}
type VRRAFUpdateSender = Sender<Result<VRRAFUpdate, ()>>;
@@ -164,6 +172,8 @@ impl VRDisplay {
// When the VR Resume event is received and the flag is set, VR presentation automatically restarts.
stopped_on_pause: Cell::new(false),
xr_session: MutNullableDom::default(),
+ initialized_inputs: Cell::new(false),
+ input_sources: DomRefCell::new(HashMap::new()),
}
}
@@ -627,6 +637,7 @@ impl VRDisplay {
depth_far: self.depth_far.get(),
api_sender: self.api_sender(),
context_id: self.context_id(),
+ needs_inputs: self.initialized_inputs.get(),
}
}
@@ -690,6 +701,7 @@ impl VRDisplay {
let (raf_sender, raf_receiver) = unbounded();
let (wakeup_sender, wakeup_receiver) = unbounded();
*self.raf_wakeup_sender.borrow_mut() = Some(wakeup_sender);
+ let mut needs_inputs = false;
// The render loop at native headset frame rate is implemented using a dedicated thread.
// Every loop iteration syncs pose data with the HMD, submits the pixels to the display and waits for Vsync.
@@ -726,8 +738,13 @@ impl VRDisplay {
.unwrap();
// Run Sync Poses in parallell on Render thread
- let msg =
- WebVRCommand::SyncPoses(display_id, near, far, sync_sender.clone());
+ let msg = WebVRCommand::SyncPoses(
+ display_id,
+ near,
+ far,
+ needs_inputs,
+ sync_sender.clone(),
+ );
api_sender.send_vr(msg).unwrap();
} else {
let _ = wakeup_receiver.recv();
@@ -752,6 +769,7 @@ impl VRDisplay {
if let Ok(update) = raf_receiver.recv().unwrap() {
near = update.depth_near;
far = update.depth_far;
+ needs_inputs = update.needs_inputs;
if update.context_id != context_id {
if let Some(ref api_sender) = update.api_sender {
api_sender
@@ -808,8 +826,16 @@ impl VRDisplay {
fn sync_frame_data(&self) {
let status = if let Some(receiver) = self.frame_data_receiver.borrow().as_ref() {
match receiver.recv().unwrap() {
- Ok(future_data) => {
- *self.frame_data.borrow_mut() = future_data.block();
+ Ok(pose) => {
+ *self.frame_data.borrow_mut() = pose.frame.block();
+ if self.initialized_inputs.get() {
+ let inputs = self.input_sources.borrow();
+ for (id, state) in pose.gamepads {
+ if let Some(input) = inputs.get(&id) {
+ input.update_state(state);
+ }
+ }
+ }
VRFrameDataStatus::Synced
},
Err(()) => VRFrameDataStatus::Exit,
@@ -909,6 +935,53 @@ impl VRDisplay {
pair.1 = None;
}
}
+
+ /// Initialize XRInputSources
+ fn initialize_inputs(&self) {
+ if self.initialized_inputs.get() {
+ return;
+ }
+ self.initialized_inputs.set(true);
+
+ let (sender, receiver) = ipc::channel(self.global().time_profiler_chan().clone()).unwrap();
+ let display = self.display.borrow().display_id;
+ self.webvr_thread()
+ .send(WebVRMsg::GetGamepadsForDisplay(display, sender))
+ .unwrap();
+ match receiver.recv().unwrap() {
+ Ok(gamepads) => {
+ let global = self.global();
+ let session = self
+ .xr_session
+ .get()
+ .expect("initialize_inputs called on a VR session");
+ let roots: Vec<_> = gamepads
+ .into_iter()
+ .map(|g| {
+ (
+ g.1.gamepad_id,
+ XRInputSource::new(&global, &session, g.0, g.1),
+ )
+ })
+ .collect();
+
+ let mut inputs = self.input_sources.borrow_mut();
+ for (id, root) in &roots {
+ inputs.insert(*id, Dom::from_ref(&root));
+ }
+ },
+ Err(_) => {},
+ }
+ }
+
+ pub fn get_input_sources(&self) -> Vec<DomRoot<XRInputSource>> {
+ self.initialize_inputs();
+ self.input_sources
+ .borrow()
+ .iter()
+ .map(|(_, x)| DomRoot::from_ref(&**x))
+ .collect()
+ }
}
// WebVR Spec: If the number of values in the leftBounds/rightBounds arrays
diff --git a/components/script/dom/vreyeparameters.rs b/components/script/dom/vreyeparameters.rs
index 2a212ab48bc..b7ea63bbd3e 100644
--- a/components/script/dom/vreyeparameters.rs
+++ b/components/script/dom/vreyeparameters.rs
@@ -22,6 +22,7 @@ pub struct VREyeParameters {
reflector_: Reflector,
#[ignore_malloc_size_of = "Defined in rust-webvr"]
parameters: DomRefCell<WebVREyeParameters>,
+ #[ignore_malloc_size_of = "mozjs"]
offset: Heap<*mut JSObject>,
fov: Dom<VRFieldOfView>,
}
diff --git a/components/script/dom/vrframedata.rs b/components/script/dom/vrframedata.rs
index 08acd74bb42..25f6af821a7 100644
--- a/components/script/dom/vrframedata.rs
+++ b/components/script/dom/vrframedata.rs
@@ -22,9 +22,13 @@ use webvr_traits::WebVRFrameData;
#[dom_struct]
pub struct VRFrameData {
reflector_: Reflector,
+ #[ignore_malloc_size_of = "mozjs"]
left_proj: Heap<*mut JSObject>,
+ #[ignore_malloc_size_of = "mozjs"]
left_view: Heap<*mut JSObject>,
+ #[ignore_malloc_size_of = "mozjs"]
right_proj: Heap<*mut JSObject>,
+ #[ignore_malloc_size_of = "mozjs"]
right_view: Heap<*mut JSObject>,
pose: Dom<VRPose>,
timestamp: Cell<f64>,
diff --git a/components/script/dom/vrpose.rs b/components/script/dom/vrpose.rs
index c807ab72c91..90bca0956ee 100644
--- a/components/script/dom/vrpose.rs
+++ b/components/script/dom/vrpose.rs
@@ -17,11 +17,17 @@ use webvr_traits::webvr;
#[dom_struct]
pub struct VRPose {
reflector_: Reflector,
+ #[ignore_malloc_size_of = "mozjs"]
position: Heap<*mut JSObject>,
+ #[ignore_malloc_size_of = "mozjs"]
orientation: Heap<*mut JSObject>,
+ #[ignore_malloc_size_of = "mozjs"]
linear_vel: Heap<*mut JSObject>,
+ #[ignore_malloc_size_of = "mozjs"]
angular_vel: Heap<*mut JSObject>,
+ #[ignore_malloc_size_of = "mozjs"]
linear_acc: Heap<*mut JSObject>,
+ #[ignore_malloc_size_of = "mozjs"]
angular_acc: Heap<*mut JSObject>,
}
diff --git a/components/script/dom/vrstageparameters.rs b/components/script/dom/vrstageparameters.rs
index ffbe6ce0f3f..41184091232 100644
--- a/components/script/dom/vrstageparameters.rs
+++ b/components/script/dom/vrstageparameters.rs
@@ -21,6 +21,7 @@ pub struct VRStageParameters {
reflector_: Reflector,
#[ignore_malloc_size_of = "Defined in rust-webvr"]
parameters: DomRefCell<WebVRStageParameters>,
+ #[ignore_malloc_size_of = "mozjs"]
transform: Heap<*mut JSObject>,
}
diff --git a/components/script/dom/webidls/MediaStream.webidl b/components/script/dom/webidls/MediaStream.webidl
index 0257e3c6061..b1d5664a7f7 100644
--- a/components/script/dom/webidls/MediaStream.webidl
+++ b/components/script/dom/webidls/MediaStream.webidl
@@ -4,20 +4,20 @@
// https://w3c.github.io/mediacapture-main/#dom-mediastream
-// [Exposed=Window,
-// Constructor,
-// Constructor(MediaStream stream),
-// Constructor(sequence<MediaStreamTrack> tracks)]
-[Exposed=Window, Pref="dom.webrtc.enabled"]
+[Exposed=Window,
+ Constructor,
+ Constructor(MediaStream stream),
+ Constructor(sequence<MediaStreamTrack> tracks),
+Pref="dom.webrtc.enabled"]
interface MediaStream : EventTarget {
// readonly attribute DOMString id;
- // sequence<MediaStreamTrack> getAudioTracks();
- // sequence<MediaStreamTrack> getVideoTracks();
- // sequence<MediaStreamTrack> getTracks();
- // MediaStreamTrack? getTrackById(DOMString trackId);
- // void addTrack(MediaStreamTrack track);
- // void removeTrack(MediaStreamTrack track);
- // MediaStream clone();
+ sequence<MediaStreamTrack> getAudioTracks();
+ sequence<MediaStreamTrack> getVideoTracks();
+ sequence<MediaStreamTrack> getTracks();
+ MediaStreamTrack? getTrackById(DOMString trackId);
+ void addTrack(MediaStreamTrack track);
+ void removeTrack(MediaStreamTrack track);
+ MediaStream clone();
// readonly attribute boolean active;
// attribute EventHandler onaddtrack;
// attribute EventHandler onremovetrack;
diff --git a/components/script/dom/webidls/MediaStreamTrack.webidl b/components/script/dom/webidls/MediaStreamTrack.webidl
new file mode 100644
index 00000000000..2f8bfb0bbec
--- /dev/null
+++ b/components/script/dom/webidls/MediaStreamTrack.webidl
@@ -0,0 +1,24 @@
+/* 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 https://mozilla.org/MPL/2.0/. */
+
+// https://w3c.github.io/mediacapture-main/#dom-mediastreamtrack
+
+[Exposed=Window, Pref="dom.webrtc.enabled"]
+interface MediaStreamTrack : EventTarget {
+ readonly attribute DOMString kind;
+ readonly attribute DOMString id;
+ // readonly attribute DOMString label;
+ // attribute boolean enabled;
+ // readonly attribute boolean muted;
+ // attribute EventHandler onmute;
+ // attribute EventHandler onunmute;
+ // readonly attribute MediaStreamTrackState readyState;
+ // attribute EventHandler onended;
+ MediaStreamTrack clone();
+ // void stop();
+ // MediaTrackCapabilities getCapabilities();
+ // MediaTrackConstraints getConstraints();
+ // MediaTrackSettings getSettings();
+ // Promise<void> applyConstraints(optional MediaTrackConstraints constraints);
+};
diff --git a/components/script/dom/webidls/RTCPeerConnection.webidl b/components/script/dom/webidls/RTCPeerConnection.webidl
index 0f00f3b5b95..58cb7301ea3 100644
--- a/components/script/dom/webidls/RTCPeerConnection.webidl
+++ b/components/script/dom/webidls/RTCPeerConnection.webidl
@@ -114,3 +114,15 @@ enum RTCSignalingState {
"have-remote-pranswer",
"closed"
};
+
+partial interface RTCPeerConnection {
+ // sequence<RTCRtpSender> getSenders();
+ // sequence<RTCRtpReceiver> getReceivers();
+ // sequence<RTCRtpTransceiver> getTransceivers();
+ // RTCRtpSender addTrack(MediaStreamTrack track,
+ // MediaStream... streams);
+ // void removeTrack(RTCRtpSender sender);
+ // RTCRtpTransceiver addTransceiver((MediaStreamTrack or DOMString) trackOrKind,
+ // optional RTCRtpTransceiverInit init);
+ attribute EventHandler ontrack;
+};
diff --git a/components/script/dom/webidls/RTCTrackEvent.webidl b/components/script/dom/webidls/RTCTrackEvent.webidl
new file mode 100644
index 00000000000..fa07f36b9f5
--- /dev/null
+++ b/components/script/dom/webidls/RTCTrackEvent.webidl
@@ -0,0 +1,23 @@
+/* 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 https://mozilla.org/MPL/2.0/. */
+
+// https://w3c.github.io/webrtc-pc/#dom-rtctrackevent
+
+[Constructor(DOMString type, RTCTrackEventInit eventInitDict),
+ Exposed=Window, Pref="dom.webrtc.enabled"]
+interface RTCTrackEvent : Event {
+ // readonly attribute RTCRtpReceiver receiver;
+ readonly attribute MediaStreamTrack track;
+ // [SameObject]
+ // readonly attribute FrozenArray<MediaStream> streams;
+ // readonly attribute RTCRtpTransceiver transceiver;
+};
+
+// https://www.w3.org/TR/webrtc/#dom-rtctrackeventinit
+dictionary RTCTrackEventInit : EventInit {
+ // required RTCRtpReceiver receiver;
+ required MediaStreamTrack track;
+ // sequence<MediaStream> streams = [];
+ // required RTCRtpTransceiver transceiver;
+};
diff --git a/components/script/dom/webidls/XRInputSource.webidl b/components/script/dom/webidls/XRInputSource.webidl
new file mode 100644
index 00000000000..5ad1e48628f
--- /dev/null
+++ b/components/script/dom/webidls/XRInputSource.webidl
@@ -0,0 +1,26 @@
+/* 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 https://mozilla.org/MPL/2.0/. */
+
+// https://immersive-web.github.io/webxr/#xrinputsource-interface
+
+enum XRHandedness {
+ "none",
+ "left",
+ "right"
+};
+
+enum XRTargetRayMode {
+ "gaze",
+ "tracked-pointer",
+ "screen"
+};
+
+[SecureContext, Exposed=Window, Pref="dom.webxr.enabled"]
+interface XRInputSource {
+ readonly attribute XRHandedness handedness;
+ // [SameObject] readonly attribute XRTargetRayMode targetRayMode;
+ [SameObject] readonly attribute XRSpace targetRaySpace;
+ // [SameObject] readonly attribute XRSpace? gripSpace;
+ // [SameObject] readonly attribute Gamepad? gamepad;
+};
diff --git a/components/script/dom/webidls/XRSession.webidl b/components/script/dom/webidls/XRSession.webidl
index f22918d469d..0399f2d0bc1 100644
--- a/components/script/dom/webidls/XRSession.webidl
+++ b/components/script/dom/webidls/XRSession.webidl
@@ -20,12 +20,15 @@ interface XRSession : EventTarget {
readonly attribute XREnvironmentBlendMode environmentBlendMode;
readonly attribute XRRenderState renderState;
- readonly attribute XRSpace viewerSpace;
+ [SameObject] readonly attribute XRSpace viewerSpace;
// // Methods
Promise<XRReferenceSpace> requestReferenceSpace(XRReferenceSpaceOptions options);
+ // workaround until we have FrozenArray
+ // see https://github.com/servo/servo/issues/10427#issuecomment-449593626
// FrozenArray<XRInputSource> getInputSources();
+ sequence<XRInputSource> getInputSources();
Promise<void> updateRenderState(optional XRRenderStateInit state);
long requestAnimationFrame(XRFrameRequestCallback callback);
diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs
index 0b86f0eeb1c..3b9622b3cfb 100644
--- a/components/script/dom/xmlhttprequest.rs
+++ b/components/script/dom/xmlhttprequest.rs
@@ -137,6 +137,7 @@ pub struct XMLHttpRequest {
response_type: Cell<XMLHttpRequestResponseType>,
response_xml: MutNullableDom<Document>,
response_blob: MutNullableDom<Blob>,
+ #[ignore_malloc_size_of = "mozjs"]
response_arraybuffer: Heap<*mut JSObject>,
#[ignore_malloc_size_of = "Defined in rust-mozjs"]
response_json: Heap<JSVal>,
diff --git a/components/script/dom/xrinputsource.rs b/components/script/dom/xrinputsource.rs
new file mode 100644
index 00000000000..2b623864d56
--- /dev/null
+++ b/components/script/dom/xrinputsource.rs
@@ -0,0 +1,83 @@
+/* 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 https://mozilla.org/MPL/2.0/. */
+
+use crate::dom::bindings::cell::DomRefCell;
+use crate::dom::bindings::codegen::Bindings::XRInputSourceBinding;
+use crate::dom::bindings::codegen::Bindings::XRInputSourceBinding::{
+ XRHandedness, XRInputSourceMethods,
+};
+use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
+use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom};
+use crate::dom::globalscope::GlobalScope;
+use crate::dom::xrsession::XRSession;
+use crate::dom::xrspace::XRSpace;
+use dom_struct::dom_struct;
+use webvr_traits::{WebVRGamepadData, WebVRGamepadHand, WebVRGamepadState, WebVRPose};
+
+#[dom_struct]
+pub struct XRInputSource {
+ reflector: Reflector,
+ session: Dom<XRSession>,
+ #[ignore_malloc_size_of = "Defined in rust-webvr"]
+ data: WebVRGamepadData,
+ #[ignore_malloc_size_of = "Defined in rust-webvr"]
+ state: DomRefCell<WebVRGamepadState>,
+ target_ray_space: MutNullableDom<XRSpace>,
+}
+
+impl XRInputSource {
+ pub fn new_inherited(
+ session: &XRSession,
+ data: WebVRGamepadData,
+ state: WebVRGamepadState,
+ ) -> XRInputSource {
+ XRInputSource {
+ reflector: Reflector::new(),
+ session: Dom::from_ref(session),
+ data,
+ state: DomRefCell::new(state),
+ target_ray_space: Default::default(),
+ }
+ }
+
+ pub fn new(
+ global: &GlobalScope,
+ session: &XRSession,
+ data: WebVRGamepadData,
+ state: WebVRGamepadState,
+ ) -> DomRoot<XRInputSource> {
+ reflect_dom_object(
+ Box::new(XRInputSource::new_inherited(session, data, state)),
+ global,
+ XRInputSourceBinding::Wrap,
+ )
+ }
+
+ pub fn update_state(&self, state: WebVRGamepadState) {
+ *self.state.borrow_mut() = state;
+ }
+
+ pub fn pose(&self) -> WebVRPose {
+ self.state.borrow().pose
+ }
+}
+
+impl XRInputSourceMethods for XRInputSource {
+ /// https://immersive-web.github.io/webxr/#dom-xrinputsource-handedness
+ fn Handedness(&self) -> XRHandedness {
+ match self.data.hand {
+ WebVRGamepadHand::Unknown => XRHandedness::None,
+ WebVRGamepadHand::Left => XRHandedness::Left,
+ WebVRGamepadHand::Right => XRHandedness::Right,
+ }
+ }
+
+ /// https://immersive-web.github.io/webxr/#dom-xrinputsource-targetrayspace
+ fn TargetRaySpace(&self) -> DomRoot<XRSpace> {
+ self.target_ray_space.or_init(|| {
+ let global = self.global();
+ XRSpace::new_inputspace(&global, &self.session, &self)
+ })
+ }
+}
diff --git a/components/script/dom/xrreferencespace.rs b/components/script/dom/xrreferencespace.rs
index 664dc4f0e23..932f917b5a5 100644
--- a/components/script/dom/xrreferencespace.rs
+++ b/components/script/dom/xrreferencespace.rs
@@ -110,7 +110,7 @@ impl XRReferenceSpace {
// non-subclassed XRReferenceSpaces exist, obtained via the "identity"
// type. These are equivalent to the viewer pose and follow the headset
// around
- XRSpace::viewer_pose_from_frame_data(base_pose)
+ XRSpace::pose_to_transform(&base_pose.pose)
}
}
}
diff --git a/components/script/dom/xrrigidtransform.rs b/components/script/dom/xrrigidtransform.rs
index 969ec839292..f75d3f085fb 100644
--- a/components/script/dom/xrrigidtransform.rs
+++ b/components/script/dom/xrrigidtransform.rs
@@ -27,6 +27,7 @@ pub struct XRRigidTransform {
#[ignore_malloc_size_of = "defined in euclid"]
transform: RigidTransform3D<f64>,
inverse: MutNullableDom<XRRigidTransform>,
+ #[ignore_malloc_size_of = "defined in mozjs"]
matrix: Heap<*mut JSObject>,
}
@@ -93,7 +94,7 @@ impl XRRigidTransformMethods for XRRigidTransform {
}
// https://immersive-web.github.io/webxr/#dom-xrrigidtransform-orientation
fn Orientation(&self) -> DomRoot<DOMPointReadOnly> {
- self.position.or_init(|| {
+ self.orientation.or_init(|| {
let r = &self.transform.rotation;
DOMPointReadOnly::new(&self.global(), r.i, r.j, r.k, r.r)
})
diff --git a/components/script/dom/xrsession.rs b/components/script/dom/xrsession.rs
index 4b855cba4c8..5aab6341ca4 100644
--- a/components/script/dom/xrsession.rs
+++ b/components/script/dom/xrsession.rs
@@ -19,6 +19,7 @@ use crate::dom::eventtarget::EventTarget;
use crate::dom::globalscope::GlobalScope;
use crate::dom::promise::Promise;
use crate::dom::vrdisplay::VRDisplay;
+use crate::dom::xrinputsource::XRInputSource;
use crate::dom::xrlayer::XRLayer;
use crate::dom::xrreferencespace::XRReferenceSpace;
use crate::dom::xrrenderstate::XRRenderState;
@@ -33,6 +34,7 @@ pub struct XRSession {
display: Dom<VRDisplay>,
base_layer: MutNullableDom<XRLayer>,
blend_mode: XREnvironmentBlendMode,
+ viewer_space: MutNullableDom<XRSpace>,
}
impl XRSession {
@@ -43,6 +45,7 @@ impl XRSession {
base_layer: Default::default(),
// we don't yet support any AR devices
blend_mode: XREnvironmentBlendMode::Opaque,
+ viewer_space: Default::default(),
}
}
@@ -86,7 +89,8 @@ impl XRSessionMethods for XRSession {
// https://immersive-web.github.io/webxr/#dom-xrsession-viewerspace
fn ViewerSpace(&self) -> DomRoot<XRSpace> {
- XRSpace::new_viewerspace(&self.global(), &self)
+ self.viewer_space
+ .or_init(|| XRSpace::new_viewerspace(&self.global(), &self))
}
/// https://immersive-web.github.io/webxr/#dom-xrsession-requestanimationframe
@@ -153,4 +157,9 @@ impl XRSessionMethods for XRSession {
p
}
+
+ /// https://immersive-web.github.io/webxr/#dom-xrsession-getinputsources
+ fn GetInputSources(&self) -> Vec<DomRoot<XRInputSource>> {
+ self.display.get_input_sources()
+ }
}
diff --git a/components/script/dom/xrspace.rs b/components/script/dom/xrspace.rs
index 8948ac03c8e..30f9246c354 100644
--- a/components/script/dom/xrspace.rs
+++ b/components/script/dom/xrspace.rs
@@ -5,20 +5,22 @@
use crate::dom::bindings::codegen::Bindings::XRSpaceBinding;
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::reflector::reflect_dom_object;
-use crate::dom::bindings::root::{Dom, DomRoot};
+use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom};
use crate::dom::eventtarget::EventTarget;
use crate::dom::globalscope::GlobalScope;
+use crate::dom::xrinputsource::XRInputSource;
use crate::dom::xrreferencespace::XRReferenceSpace;
use crate::dom::xrsession::XRSession;
use dom_struct::dom_struct;
use euclid::{RigidTransform3D, Rotation3D, Vector3D};
-use webvr_traits::WebVRFrameData;
+use webvr_traits::{WebVRFrameData, WebVRPose};
#[dom_struct]
pub struct XRSpace {
eventtarget: EventTarget,
session: Dom<XRSession>,
is_viewerspace: bool,
+ input_source: MutNullableDom<XRInputSource>,
}
impl XRSpace {
@@ -27,6 +29,7 @@ impl XRSpace {
eventtarget: EventTarget::new_inherited(),
session: Dom::from_ref(session),
is_viewerspace: false,
+ input_source: Default::default(),
}
}
@@ -35,6 +38,7 @@ impl XRSpace {
eventtarget: EventTarget::new_inherited(),
session: Dom::from_ref(session),
is_viewerspace: true,
+ input_source: Default::default(),
}
}
@@ -45,6 +49,27 @@ impl XRSpace {
XRSpaceBinding::Wrap,
)
}
+
+ fn new_inputspace_inner(session: &XRSession, input: &XRInputSource) -> XRSpace {
+ XRSpace {
+ eventtarget: EventTarget::new_inherited(),
+ session: Dom::from_ref(session),
+ is_viewerspace: false,
+ input_source: MutNullableDom::new(Some(input)),
+ }
+ }
+
+ pub fn new_inputspace(
+ global: &GlobalScope,
+ session: &XRSession,
+ input: &XRInputSource,
+ ) -> DomRoot<XRSpace> {
+ reflect_dom_object(
+ Box::new(XRSpace::new_inputspace_inner(session, input)),
+ global,
+ XRSpaceBinding::Wrap,
+ )
+ }
}
impl XRSpace {
@@ -57,16 +82,18 @@ impl XRSpace {
if let Some(reference) = self.downcast::<XRReferenceSpace>() {
reference.get_pose(base_pose)
} else if self.is_viewerspace {
- XRSpace::viewer_pose_from_frame_data(base_pose)
+ XRSpace::pose_to_transform(&base_pose.pose)
+ } else if let Some(source) = self.input_source.get() {
+ XRSpace::pose_to_transform(&source.pose())
} else {
unreachable!()
}
}
- pub fn viewer_pose_from_frame_data(data: &WebVRFrameData) -> RigidTransform3D<f64> {
- let pos = data.pose.position.unwrap_or([0., 0., 0.]);
+ pub fn pose_to_transform(pose: &WebVRPose) -> RigidTransform3D<f64> {
+ let pos = pose.position.unwrap_or([0., 0., 0.]);
let translation = Vector3D::new(pos[0] as f64, pos[1] as f64, pos[2] as f64);
- let orient = data.pose.orientation.unwrap_or([0., 0., 0., 0.]);
+ let orient = pose.orientation.unwrap_or([0., 0., 0., 0.]);
let rotation = Rotation3D::quaternion(
orient[0] as f64,
orient[1] as f64,
diff --git a/components/script/dom/xrstationaryreferencespace.rs b/components/script/dom/xrstationaryreferencespace.rs
index a867aa0d976..65a0aebb790 100644
--- a/components/script/dom/xrstationaryreferencespace.rs
+++ b/components/script/dom/xrstationaryreferencespace.rs
@@ -55,7 +55,7 @@ impl XRStationaryReferenceSpace {
///
/// Does not apply originOffset, use get_viewer_pose on XRReferenceSpace instead
pub fn get_unoffset_viewer_pose(&self, viewer_pose: &WebVRFrameData) -> RigidTransform3D<f64> {
- let viewer_pose = XRSpace::viewer_pose_from_frame_data(viewer_pose);
+ let viewer_pose = XRSpace::pose_to_transform(&viewer_pose.pose);
// all math is in column-vector notation
// we use the following equation to verify correctness here:
// get_viewer_pose(space) = get_pose(space).inverse() * get_pose(viewer_space)
@@ -113,7 +113,7 @@ impl XRStationaryReferenceSpace {
},
XRStationaryReferenceSpaceSubtype::Position_disabled => {
// This space follows the user around, but does not mirror the user's orientation
- let viewer_pose = XRSpace::viewer_pose_from_frame_data(viewer_pose);
+ let viewer_pose = XRSpace::pose_to_transform(&viewer_pose.pose);
viewer_pose.translation.into()
},
}
diff --git a/components/script/dom/xrview.rs b/components/script/dom/xrview.rs
index a2eee03581d..c53eb8cb947 100644
--- a/components/script/dom/xrview.rs
+++ b/components/script/dom/xrview.rs
@@ -21,7 +21,9 @@ pub struct XRView {
reflector_: Reflector,
session: Dom<XRSession>,
eye: XREye,
+ #[ignore_malloc_size_of = "mozjs"]
proj: Heap<*mut JSObject>,
+ #[ignore_malloc_size_of = "mozjs"]
view: Heap<*mut JSObject>,
transform: Dom<XRRigidTransform>,
}
diff --git a/components/script/dom/xrviewerpose.rs b/components/script/dom/xrviewerpose.rs
index 717fdcea16e..92caa7f037b 100644
--- a/components/script/dom/xrviewerpose.rs
+++ b/components/script/dom/xrviewerpose.rs
@@ -22,6 +22,7 @@ use webvr_traits::WebVRFrameData;
#[dom_struct]
pub struct XRViewerPose {
pose: XRPose,
+ #[ignore_malloc_size_of = "mozjs"]
views: Heap<JSVal>,
}