diff options
Diffstat (limited to 'components/script/dom')
45 files changed, 1402 insertions, 699 deletions
diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index 97fffe52853..c2543cc984b 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -157,8 +157,8 @@ use webgpu::{ WebGPUPipelineLayout, WebGPUQueue, WebGPUShaderModule, }; use webrender_api::{DocumentId, ImageKey}; -use webxr_api::Ray; use webxr_api::SwapChainId as WebXRSwapChainId; +use webxr_api::{Finger, Hand, Ray}; unsafe_no_jsmanaged_fields!(Tm); @@ -554,6 +554,7 @@ unsafe_no_jsmanaged_fields!( webxr_api::Frame, webxr_api::InputSource, webxr_api::InputId, + webxr_api::Joint, webxr_api::HitTestId, webxr_api::HitTestResult ); @@ -881,6 +882,58 @@ where } } +unsafe impl<J> JSTraceable for Hand<J> +where + J: JSTraceable, +{ + #[inline] + unsafe fn trace(&self, trc: *mut JSTracer) { + // exhaustive match so we don't miss new fields + let Hand { + ref wrist, + ref thumb_metacarpal, + ref thumb_phalanx_proximal, + ref thumb_phalanx_distal, + ref thumb_phalanx_tip, + ref index, + ref middle, + ref ring, + ref little, + } = *self; + wrist.trace(trc); + thumb_metacarpal.trace(trc); + thumb_phalanx_proximal.trace(trc); + thumb_phalanx_distal.trace(trc); + thumb_phalanx_tip.trace(trc); + index.trace(trc); + middle.trace(trc); + ring.trace(trc); + little.trace(trc); + } +} + +unsafe impl<J> JSTraceable for Finger<J> +where + J: JSTraceable, +{ + #[inline] + unsafe fn trace(&self, trc: *mut JSTracer) { + // exhaustive match so we don't miss new fields + let Finger { + ref metacarpal, + ref phalanx_proximal, + ref phalanx_intermediate, + ref phalanx_distal, + ref phalanx_tip, + } = *self; + metacarpal.trace(trc); + phalanx_proximal.trace(trc); + phalanx_intermediate.trace(trc); + phalanx_distal.trace(trc); + phalanx_tip.trace(trc); + } +} + /// Holds a set of JSTraceables that need to be rooted struct RootedTraceableSet { set: Vec<*const dyn JSTraceable>, diff --git a/components/script/dom/console.rs b/components/script/dom/console.rs index 22caa2993bd..cf6eb1668f8 100644 --- a/components/script/dom/console.rs +++ b/components/script/dom/console.rs @@ -7,15 +7,24 @@ use crate::dom::bindings::str::DOMString; use crate::dom::globalscope::GlobalScope; use crate::dom::workerglobalscope::WorkerGlobalScope; use devtools_traits::{ConsoleMessage, LogLevel, ScriptToDevtoolsControlMsg}; +use js::rust::describe_scripted_caller; use std::io; // https://developer.mozilla.org/en-US/docs/Web/API/Console pub struct Console(()); impl Console { + #[allow(unsafe_code)] fn send_to_devtools(global: &GlobalScope, level: LogLevel, message: DOMString) { if let Some(chan) = global.devtools_chan() { - let console_message = prepare_message(level, message); + let caller = unsafe { describe_scripted_caller(*global.get_cx()) }.unwrap_or_default(); + let console_message = ConsoleMessage { + message: String::from(message), + logLevel: level, + filename: caller.filename, + lineNumber: caller.line as usize, + columnNumber: caller.col as usize, + }; let worker_id = global .downcast::<WorkerGlobalScope>() .map(|worker| worker.get_worker_id()); @@ -128,14 +137,3 @@ impl Console { }) } } - -fn prepare_message(log_level: LogLevel, message: DOMString) -> ConsoleMessage { - // TODO: Sending fake values for filename, lineNumber and columnNumber in LogMessage; adjust later - ConsoleMessage { - message: String::from(message), - logLevel: log_level, - filename: "test".to_owned(), - lineNumber: 1, - columnNumber: 1, - } -} diff --git a/components/script/dom/dedicatedworkerglobalscope.rs b/components/script/dom/dedicatedworkerglobalscope.rs index 150f7920fff..a4970afcca4 100644 --- a/components/script/dom/dedicatedworkerglobalscope.rs +++ b/components/script/dom/dedicatedworkerglobalscope.rs @@ -43,7 +43,7 @@ use js::jsapi::JS_AddInterruptCallback; use js::jsapi::{Heap, JSContext, JSObject}; use js::jsval::UndefinedValue; use js::rust::{CustomAutoRooter, CustomAutoRooterGuard, HandleValue}; -use msg::constellation_msg::{PipelineId, TopLevelBrowsingContextId}; +use msg::constellation_msg::{BrowsingContextId, PipelineId, TopLevelBrowsingContextId}; use net_traits::image_cache::ImageCache; use net_traits::request::{CredentialsMode, Destination, ParserMetadata}; use net_traits::request::{Referrer, RequestBuilder, RequestMode}; @@ -180,6 +180,7 @@ pub struct DedicatedWorkerGlobalScope { parent_sender: Box<dyn ScriptChan + Send>, #[ignore_malloc_size_of = "Arc"] image_cache: Arc<dyn ImageCache>, + browsing_context: Option<BrowsingContextId>, } impl WorkerEventLoopMethods for DedicatedWorkerGlobalScope { @@ -221,6 +222,7 @@ impl DedicatedWorkerGlobalScope { receiver: Receiver<DedicatedWorkerScriptMsg>, closing: Arc<AtomicBool>, image_cache: Arc<dyn ImageCache>, + browsing_context: Option<BrowsingContextId>, ) -> DedicatedWorkerGlobalScope { DedicatedWorkerGlobalScope { workerglobalscope: WorkerGlobalScope::new_inherited( @@ -237,6 +239,7 @@ impl DedicatedWorkerGlobalScope { parent_sender: parent_sender, worker: DomRefCell::new(None), image_cache: image_cache, + browsing_context, } } @@ -253,6 +256,7 @@ impl DedicatedWorkerGlobalScope { receiver: Receiver<DedicatedWorkerScriptMsg>, closing: Arc<AtomicBool>, image_cache: Arc<dyn ImageCache>, + browsing_context: Option<BrowsingContextId>, ) -> DomRoot<DedicatedWorkerGlobalScope> { let cx = runtime.cx(); let scope = Box::new(DedicatedWorkerGlobalScope::new_inherited( @@ -267,6 +271,7 @@ impl DedicatedWorkerGlobalScope { receiver, closing, image_cache, + browsing_context, )); unsafe { DedicatedWorkerGlobalScopeBinding::Wrap(SafeJSContext::from_ptr(cx), scope) } } @@ -286,6 +291,7 @@ impl DedicatedWorkerGlobalScope { worker_type: WorkerType, closing: Arc<AtomicBool>, image_cache: Arc<dyn ImageCache>, + browsing_context: Option<BrowsingContextId>, ) { let serialized_worker_url = worker_url.to_string(); let name = format!("WebWorker for {}", serialized_worker_url); @@ -354,6 +360,7 @@ impl DedicatedWorkerGlobalScope { receiver, closing, image_cache, + browsing_context, ); // FIXME(njn): workers currently don't have a unique ID suitable for using in reporter // registration (#6631), so we instead use a random number and cross our fingers. @@ -467,6 +474,7 @@ impl DedicatedWorkerGlobalScope { } fn handle_mixed_message(&self, msg: MixedMessage) { + // FIXME(#26324): `self.worker` is None in devtools messages. match msg { MixedMessage::FromDevtools(msg) => match msg { DevtoolScriptControlMsg::EvaluateJS(_pipe_id, string, sender) => { @@ -551,6 +559,10 @@ impl DedicatedWorkerGlobalScope { .expect("Sending to parent failed"); Ok(()) } + + pub(crate) fn browsing_context(&self) -> Option<BrowsingContextId> { + self.browsing_context + } } #[allow(unsafe_code)] diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 2d0f2ce1c26..3606ffc7c9d 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -934,6 +934,14 @@ impl Document { pub fn title_changed(&self) { if self.browsing_context().is_some() { self.send_title_to_embedder(); + let global = self.window.upcast::<GlobalScope>(); + if let Some(ref chan) = global.devtools_chan() { + let title = String::from(self.Title()); + let _ = chan.send(ScriptToDevtoolsControlMsg::TitleChanged( + global.pipeline_id(), + title, + )); + } } } diff --git a/components/script/dom/event.rs b/components/script/dom/event.rs index aba0179a59b..3a0e7490fc9 100644 --- a/components/script/dom/event.rs +++ b/components/script/dom/event.rs @@ -647,6 +647,7 @@ fn invoke( atom!("animationiteration") => Some(atom!("webkitAnimationIteration")), atom!("animationstart") => Some(atom!("webkitAnimationStart")), atom!("transitionend") => Some(atom!("webkitTransitionEnd")), + atom!("transitionrun") => Some(atom!("webkitTransitionRun")), _ => None, } { let original_type = event.type_(); diff --git a/components/script/dom/fakexrdevice.rs b/components/script/dom/fakexrdevice.rs index 5b1ca75fb3d..811a7e01b42 100644 --- a/components/script/dom/fakexrdevice.rs +++ b/components/script/dom/fakexrdevice.rs @@ -269,6 +269,7 @@ impl FakeXRDeviceMethods for FakeXRDevice { id, supports_grip: true, profiles, + hand_support: None, }; let init = MockInputInit { diff --git a/components/script/dom/htmlelement.rs b/components/script/dom/htmlelement.rs index 695cdbe6a49..4c4d86f1642 100644 --- a/components/script/dom/htmlelement.rs +++ b/components/script/dom/htmlelement.rs @@ -568,6 +568,27 @@ impl HTMLElementMethods for HTMLElement { }, ); } + + // https://html.spec.whatwg.org/multipage/#dom-contenteditable + fn ContentEditable(&self) -> DOMString { + // TODO: https://github.com/servo/servo/issues/12776 + self.upcast::<Element>() + .get_attribute(&ns!(), &local_name!("contenteditable")) + .map(|attr| DOMString::from(&**attr.value())) + .unwrap_or_else(|| DOMString::from("inherit")) + } + + // https://html.spec.whatwg.org/multipage/#dom-contenteditable + fn SetContentEditable(&self, _: DOMString) { + // TODO: https://github.com/servo/servo/issues/12776 + warn!("The contentEditable attribute is not implemented yet"); + } + + // https://html.spec.whatwg.org/multipage/#dom-contenteditable + fn IsContentEditable(&self) -> bool { + // TODO: https://github.com/servo/servo/issues/12776 + false + } } fn append_text_node_to_fragment(document: &Document, fragment: &DocumentFragment, text: String) { diff --git a/components/script/dom/location.rs b/components/script/dom/location.rs index aac4cc30b97..e57ecf6cd39 100644 --- a/components/script/dom/location.rs +++ b/components/script/dom/location.rs @@ -9,6 +9,7 @@ use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::bindings::str::USVString; +use crate::dom::document::Document; use crate::dom::globalscope::GlobalScope; use crate::dom::urlhelper::UrlHelper; use crate::dom::window::Window; @@ -62,17 +63,10 @@ impl Location { self.window.get_url() } - fn set_url_component(&self, value: USVString, setter: fn(&mut ServoUrl, USVString)) { - let mut url = self.window.get_url(); - let referrer = Referrer::ReferrerUrl(url.clone()); - setter(&mut url, value); - self.navigate(url, referrer, HistoryEntryReplacement::Disabled, false); - } - fn check_same_origin_domain(&self) -> ErrorResult { - let entry_document = GlobalScope::entry().as_window().Document(); let this_document = self.window.Document(); - if entry_document + if self + .entry_document() .origin() .same_origin_domain(this_document.origin()) { @@ -82,6 +76,10 @@ impl Location { } } + fn entry_document(&self) -> DomRoot<Document> { + GlobalScope::entry().as_window().Document() + } + // https://html.spec.whatwg.org/multipage/#dom-location-reload pub fn reload_without_origin_check(&self) { let url = self.get_url(); @@ -98,17 +96,24 @@ impl Location { impl LocationMethods for Location { // https://html.spec.whatwg.org/multipage/#dom-location-assign fn Assign(&self, url: USVString) -> ErrorResult { - self.check_same_origin_domain()?; - // TODO: per spec, we should use the _API base URL_ specified by the - // _entry settings object_. - let base_url = self.window.get_url(); - if let Ok(url) = base_url.join(&url.0) { - let referrer = Referrer::ReferrerUrl(base_url.clone()); + // Step 1: If this Location object's relevant Document is null, then return. + if self.window.has_document() { + // Step 2: If this Location object's relevant Document's origin is not same + // origin-domain with the entry settings object's origin, then throw a + // "SecurityError" DOMException. + self.check_same_origin_domain()?; + // Step 3: Parse url relative to the entry settings object. If that failed, + // throw a "SyntaxError" DOMException. + let base_url = self.entry_document().url(); + let url = match base_url.join(&url.0) { + Ok(url) => url, + Err(_) => return Err(Error::Syntax), + }; + // Step 4: Location-object navigate to the resulting URL record. + let referrer = Referrer::ReferrerUrl(self.get_url()); self.navigate(url, referrer, HistoryEntryReplacement::Disabled, false); - Ok(()) - } else { - Err(Error::Syntax) } + Ok(()) } // https://html.spec.whatwg.org/multipage/#dom-location-reload @@ -122,17 +127,21 @@ impl LocationMethods for Location { // https://html.spec.whatwg.org/multipage/#dom-location-replace fn Replace(&self, url: USVString) -> ErrorResult { - // Note: no call to self.check_same_origin_domain() - // TODO: per spec, we should use the _API base URL_ specified by the - // _entry settings object_. - let base_url = self.window.get_url(); - if let Ok(url) = base_url.join(&url.0) { - let referrer = Referrer::ReferrerUrl(base_url.clone()); + // Step 1: If this Location object's relevant Document is null, then return. + if self.window.has_document() { + // Step 2: Parse url relative to the entry settings object. If that failed, + // throw a "SyntaxError" DOMException. + let base_url = self.entry_document().url(); + let url = match base_url.join(&url.0) { + Ok(url) => url, + Err(_) => return Err(Error::Syntax), + }; + // Step 3: Location-object navigate to the resulting URL record with + // the replacement flag set. + let referrer = Referrer::ReferrerUrl(self.get_url()); self.navigate(url, referrer, HistoryEntryReplacement::Enabled, false); - Ok(()) - } else { - Err(Error::Syntax) } + Ok(()) } // https://html.spec.whatwg.org/multipage/#dom-location-hash @@ -142,12 +151,28 @@ impl LocationMethods for Location { } // https://html.spec.whatwg.org/multipage/#dom-location-hash - fn SetHash(&self, mut value: USVString) -> ErrorResult { - if value.0.is_empty() { - value = USVString("#".to_owned()); + fn SetHash(&self, value: USVString) -> ErrorResult { + // Step 1: If this Location object's relevant Document is null, then return. + if self.window.has_document() { + // Step 2: If this Location object's relevant Document's origin is not + // same origin-domain with the entry settings object's origin, then + // throw a "SecurityError" DOMException. + self.check_same_origin_domain()?; + // Step 3: Let copyURL be a copy of this Location object's url. + let mut copy_url = self.get_url(); + // Step 4: Let input be the given value with a single leading "#" removed, if any. + // Step 5: Set copyURL's fragment to the empty string. + // Step 6: Basic URL parse input, with copyURL as url and fragment state as + // state override. + copy_url.as_mut_url().set_fragment(match value.0.as_str() { + "" => Some("#"), + _ if value.0.starts_with('#') => Some(&value.0[1..]), + _ => Some(&value.0), + }); + // Step 7: Location-object-setter navigate to copyURL. + let referrer = Referrer::ReferrerUrl(self.get_url()); + self.navigate(copy_url, referrer, HistoryEntryReplacement::Disabled, false); } - self.check_same_origin_domain()?; - self.set_url_component(value, UrlHelper::SetHash); Ok(()) } @@ -159,8 +184,24 @@ impl LocationMethods for Location { // https://html.spec.whatwg.org/multipage/#dom-location-host fn SetHost(&self, value: USVString) -> ErrorResult { - self.check_same_origin_domain()?; - self.set_url_component(value, UrlHelper::SetHost); + // Step 1: If this Location object's relevant Document is null, then return. + if self.window.has_document() { + // Step 2: If this Location object's relevant Document's origin is not + // same origin-domain with the entry settings object's origin, then + // throw a "SecurityError" DOMException. + self.check_same_origin_domain()?; + // Step 3: Let copyURL be a copy of this Location object's url. + let mut copy_url = self.get_url(); + // Step 4: If copyURL's cannot-be-a-base-URL flag is set, terminate these steps. + if !copy_url.cannot_be_a_base() { + // Step 5: Basic URL parse the given value, with copyURL as url and host state + // as state override. + let _ = copy_url.as_mut_url().set_host(Some(&value.0)); + // Step 6: Location-object-setter navigate to copyURL. + let referrer = Referrer::ReferrerUrl(self.get_url()); + self.navigate(copy_url, referrer, HistoryEntryReplacement::Disabled, false); + } + } Ok(()) } @@ -178,8 +219,24 @@ impl LocationMethods for Location { // https://html.spec.whatwg.org/multipage/#dom-location-hostname fn SetHostname(&self, value: USVString) -> ErrorResult { - self.check_same_origin_domain()?; - self.set_url_component(value, UrlHelper::SetHostname); + // Step 1: If this Location object's relevant Document is null, then return. + if self.window.has_document() { + // Step 2: If this Location object's relevant Document's origin is not + // same origin-domain with the entry settings object's origin, then + // throw a "SecurityError" DOMException. + self.check_same_origin_domain()?; + // Step 3: Let copyURL be a copy of this Location object's url. + let mut copy_url = self.get_url(); + // Step 4: If copyURL's cannot-be-a-base-URL flag is set, terminate these steps. + if !copy_url.cannot_be_a_base() { + // Step 5: Basic URL parse the given value, with copyURL as url and hostname + // state as state override. + let _ = copy_url.as_mut_url().set_host(Some(&value.0)); + // Step 6: Location-object-setter navigate to copyURL. + let referrer = Referrer::ReferrerUrl(self.get_url()); + self.navigate(copy_url, referrer, HistoryEntryReplacement::Disabled, false); + } + } Ok(()) } @@ -191,14 +248,20 @@ impl LocationMethods for Location { // https://html.spec.whatwg.org/multipage/#dom-location-href fn SetHref(&self, value: USVString) -> ErrorResult { - // Note: no call to self.check_same_origin_domain() - let current_url = self.window.get_url(); - let url = match current_url.join(&value.0) { - Ok(url) => url, - Err(e) => return Err(Error::Type(format!("Couldn't parse URL: {}", e))), - }; - let referrer = Referrer::ReferrerUrl(current_url.clone()); - self.navigate(url, referrer, HistoryEntryReplacement::Disabled, false); + // Step 1: If this Location object's relevant Document is null, then return. + if self.window.has_document() { + // Note: no call to self.check_same_origin_domain() + // Step 2: Parse the given value relative to the entry settings object. + // If that failed, throw a TypeError exception. + let base_url = self.entry_document().url(); + let url = match base_url.join(&value.0) { + Ok(url) => url, + Err(e) => return Err(Error::Type(format!("Couldn't parse URL: {}", e))), + }; + // Step 3: Location-object-setter navigate to the resulting URL record. + let referrer = Referrer::ReferrerUrl(self.get_url()); + self.navigate(url, referrer, HistoryEntryReplacement::Disabled, false); + } Ok(()) } @@ -210,8 +273,25 @@ impl LocationMethods for Location { // https://html.spec.whatwg.org/multipage/#dom-location-pathname fn SetPathname(&self, value: USVString) -> ErrorResult { - self.check_same_origin_domain()?; - self.set_url_component(value, UrlHelper::SetPathname); + // Step 1: If this Location object's relevant Document is null, then return. + if self.window.has_document() { + // Step 2: If this Location object's relevant Document's origin is not + // same origin-domain with the entry settings object's origin, then + // throw a "SecurityError" DOMException. + self.check_same_origin_domain()?; + // Step 3: Let copyURL be a copy of this Location object's url. + let mut copy_url = self.get_url(); + // Step 4: If copyURL's cannot-be-a-base-URL flag is set, terminate these steps. + if !copy_url.cannot_be_a_base() { + // Step 5: Set copyURL's path to the empty list. + // Step 6: Basic URL parse the given value, with copyURL as url and path + // start state as state override. + copy_url.as_mut_url().set_path(&value.0); + // Step 7: Location-object-setter navigate to copyURL. + let referrer = Referrer::ReferrerUrl(self.get_url()); + self.navigate(copy_url, referrer, HistoryEntryReplacement::Disabled, false); + } + } Ok(()) } @@ -223,8 +303,30 @@ impl LocationMethods for Location { // https://html.spec.whatwg.org/multipage/#dom-location-port fn SetPort(&self, value: USVString) -> ErrorResult { - self.check_same_origin_domain()?; - self.set_url_component(value, UrlHelper::SetPort); + // Step 1: If this Location object's relevant Document is null, then return. + if self.window.has_document() { + // Step 2: If this Location object's relevant Document's origin is not + // same origin-domain with the entry settings object's origin, then + // throw a "SecurityError" DOMException. + self.check_same_origin_domain()?; + // Step 3: Let copyURL be a copy of this Location object's url. + let mut copy_url = self.get_url(); + // Step 4: If copyURL cannot have a username/password/port, then return. + // https://url.spec.whatwg.org/#cannot-have-a-username-password-port + if copy_url.host().is_some() && + !copy_url.cannot_be_a_base() && + copy_url.scheme() != "file" + { + // Step 5: If the given value is the empty string, then set copyURL's + // port to null. + // Step 6: Otherwise, basic URL parse the given value, with copyURL as url + // and port state as state override. + let _ = url::quirks::set_port(copy_url.as_mut_url(), &value.0); + // Step 7: Location-object-setter navigate to copyURL. + let referrer = Referrer::ReferrerUrl(self.get_url()); + self.navigate(copy_url, referrer, HistoryEntryReplacement::Disabled, false); + } + } Ok(()) } @@ -236,8 +338,34 @@ impl LocationMethods for Location { // https://html.spec.whatwg.org/multipage/#dom-location-protocol fn SetProtocol(&self, value: USVString) -> ErrorResult { - self.check_same_origin_domain()?; - self.set_url_component(value, UrlHelper::SetProtocol); + // Step 1: If this Location object's relevant Document is null, then return. + if self.window.has_document() { + // Step 2: If this Location object's relevant Document's origin is not + // same origin-domain with the entry settings object's origin, then + // throw a "SecurityError" DOMException. + self.check_same_origin_domain()?; + // Step 3: Let copyURL be a copy of this Location object's url. + let mut copy_url = self.get_url(); + // Step 4: Let possibleFailure be the result of basic URL parsing the given + // value, followed by ":", with copyURL as url and scheme start state as + // state override. + let scheme = match value.0.find(':') { + Some(position) => &value.0[..position], + None => &value.0, + }; + if let Err(_) = copy_url.as_mut_url().set_scheme(scheme) { + // Step 5: If possibleFailure is failure, then throw a "SyntaxError" DOMException. + return Err(Error::Syntax); + } + // Step 6: If copyURL's scheme is not an HTTP(S) scheme, then terminate these steps. + if copy_url.scheme().eq_ignore_ascii_case("http") || + copy_url.scheme().eq_ignore_ascii_case("https") + { + // Step 7: Location-object-setter navigate to copyURL. + let referrer = Referrer::ReferrerUrl(self.get_url()); + self.navigate(copy_url, referrer, HistoryEntryReplacement::Disabled, false); + } + } Ok(()) } @@ -249,8 +377,30 @@ impl LocationMethods for Location { // https://html.spec.whatwg.org/multipage/#dom-location-search fn SetSearch(&self, value: USVString) -> ErrorResult { - self.check_same_origin_domain()?; - self.set_url_component(value, UrlHelper::SetSearch); + // Step 1: If this Location object's relevant Document is null, then return. + if self.window.has_document() { + // Step 2: If this Location object's relevant Document's origin is not + // same origin-domain with the entry settings object's origin, then + // throw a "SecurityError" DOMException. + self.check_same_origin_domain()?; + // Step 3: Let copyURL be a copy of this Location object's url. + let mut copy_url = self.get_url(); + // Step 4: If the given value is the empty string, set copyURL's query to null. + // Step 5: Otherwise, run these substeps: + // 1. Let input be the given value with a single leading "?" removed, if any. + // 2. Set copyURL's query to the empty string. + // 3. Basic URL parse input, with copyURL as url and query state as state + // override, and the relevant Document's document's character encoding as + // encoding override. + copy_url.as_mut_url().set_query(match value.0.as_str() { + "" => None, + _ if value.0.starts_with('?') => Some(&value.0[1..]), + _ => Some(&value.0), + }); + // Step 6: Location-object-setter navigate to copyURL. + let referrer = Referrer::ReferrerUrl(self.get_url()); + self.navigate(copy_url, referrer, HistoryEntryReplacement::Disabled, false); + } Ok(()) } } diff --git a/components/script/dom/macros.rs b/components/script/dom/macros.rs index b27c02208be..b1ea4f5cde2 100644 --- a/components/script/dom/macros.rs +++ b/components/script/dom/macros.rs @@ -496,7 +496,9 @@ macro_rules! global_event_handlers( event_handler!(suspend, GetOnsuspend, SetOnsuspend); event_handler!(timeupdate, GetOntimeupdate, SetOntimeupdate); event_handler!(toggle, GetOntoggle, SetOntoggle); + event_handler!(transitioncancel, GetOntransitioncancel, SetOntransitioncancel); event_handler!(transitionend, GetOntransitionend, SetOntransitionend); + event_handler!(transitionrun, GetOntransitionrun, SetOntransitionrun); event_handler!(volumechange, GetOnvolumechange, SetOnvolumechange); event_handler!(waiting, GetOnwaiting, SetOnwaiting); ) diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index a410220b427..a0f6241d55e 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -572,12 +572,15 @@ pub mod xmlhttprequesteventtarget; pub mod xmlhttprequestupload; pub mod xmlserializer; pub mod xrframe; +pub mod xrhand; pub mod xrhittestresult; pub mod xrhittestsource; pub mod xrinputsource; pub mod xrinputsourcearray; pub mod xrinputsourceevent; pub mod xrinputsourceschangeevent; +pub mod xrjointpose; +pub mod xrjointspace; pub mod xrlayer; pub mod xrmediabinding; pub mod xrpose; diff --git a/components/script/dom/serviceworkerregistration.rs b/components/script/dom/serviceworkerregistration.rs index f242da12404..9bb578e0d59 100644 --- a/components/script/dom/serviceworkerregistration.rs +++ b/components/script/dom/serviceworkerregistration.rs @@ -112,7 +112,7 @@ impl ServiceWorkerRegistration { let worker_id = WorkerId(Uuid::new_v4()); let devtools_chan = global.devtools_chan().cloned(); - let init = prepare_workerscope_init(&global, None); + let init = prepare_workerscope_init(&global, None, None); ScopeThings { script_url: script_url, init: init, diff --git a/components/script/dom/vertexarrayobject.rs b/components/script/dom/vertexarrayobject.rs index 34ef5b428bb..fcf6461e2a8 100644 --- a/components/script/dom/vertexarrayobject.rs +++ b/components/script/dom/vertexarrayobject.rs @@ -7,7 +7,7 @@ use crate::dom::bindings::codegen::Bindings::WebGL2RenderingContextBinding::WebG use crate::dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants; use crate::dom::bindings::root::{Dom, MutNullableDom}; use crate::dom::webglbuffer::WebGLBuffer; -use crate::dom::webglrenderingcontext::WebGLRenderingContext; +use crate::dom::webglrenderingcontext::{Operation, WebGLRenderingContext}; use canvas_traits::webgl::{ ActiveAttribInfo, WebGLCommand, WebGLError, WebGLResult, WebGLVersion, WebGLVertexArrayId, }; @@ -45,26 +45,25 @@ impl VertexArrayObject { self.is_deleted.get() } - pub fn delete(&self, fallible: bool) { + pub fn delete(&self, operation_fallibility: Operation) { assert!(self.id.is_some()); if self.is_deleted.get() { return; } self.is_deleted.set(true); let cmd = WebGLCommand::DeleteVertexArray(self.id.unwrap()); - if fallible { - self.context.send_command_ignored(cmd); - } else { - self.context.send_command(cmd); + match operation_fallibility { + Operation::Fallible => self.context.send_command_ignored(cmd), + Operation::Infallible => self.context.send_command(cmd), } for attrib_data in &**self.vertex_attribs.borrow() { if let Some(buffer) = attrib_data.buffer() { - buffer.decrement_attached_counter(fallible); + buffer.decrement_attached_counter(operation_fallibility); } } if let Some(buffer) = self.element_array_buffer.get() { - buffer.decrement_attached_counter(fallible); + buffer.decrement_attached_counter(operation_fallibility); } } @@ -156,7 +155,7 @@ impl VertexArrayObject { offset as u32, )); if let Some(old) = data.buffer() { - old.decrement_attached_counter(false); + old.decrement_attached_counter(Operation::Infallible); } *data = VertexAttribData { @@ -188,7 +187,7 @@ impl VertexArrayObject { if b.id() != buffer.id() { continue; } - b.decrement_attached_counter(false); + b.decrement_attached_counter(Operation::Infallible); } attrib.buffer = None; } @@ -197,7 +196,7 @@ impl VertexArrayObject { .get() .map_or(false, |b| buffer == &*b) { - buffer.decrement_attached_counter(false); + buffer.decrement_attached_counter(Operation::Infallible); self.element_array_buffer.set(None); } } @@ -256,7 +255,7 @@ impl VertexArrayObject { impl Drop for VertexArrayObject { fn drop(&mut self) { if self.id.is_some() { - self.delete(true); + self.delete(Operation::Fallible); } } } diff --git a/components/script/dom/webgl2renderingcontext.rs b/components/script/dom/webgl2renderingcontext.rs index 949f3a3bbdc..6ed42deea01 100644 --- a/components/script/dom/webgl2renderingcontext.rs +++ b/components/script/dom/webgl2renderingcontext.rs @@ -18,7 +18,6 @@ use crate::dom::bindings::root::{Dom, DomRoot, LayoutDom, MutNullableDom}; use crate::dom::bindings::str::DOMString; use crate::dom::globalscope::GlobalScope; use crate::dom::htmlcanvaselement::HTMLCanvasElement; -use crate::dom::htmliframeelement::HTMLIFrameElement; use crate::dom::webglactiveinfo::WebGLActiveInfo; use crate::dom::webglbuffer::WebGLBuffer; use crate::dom::webglframebuffer::{WebGLFramebuffer, WebGLFramebufferAttachmentRoot}; @@ -26,7 +25,7 @@ use crate::dom::webglprogram::WebGLProgram; use crate::dom::webglquery::WebGLQuery; use crate::dom::webglrenderbuffer::WebGLRenderbuffer; use crate::dom::webglrenderingcontext::{ - uniform_get, uniform_typed, LayoutCanvasWebGLRenderingContextHelpers, VertexAttrib, + uniform_get, uniform_typed, LayoutCanvasWebGLRenderingContextHelpers, Operation, VertexAttrib, WebGLRenderingContext, }; use crate::dom::webglsampler::{WebGLSampler, WebGLSamplerValue}; @@ -339,7 +338,7 @@ impl WebGL2RenderingContext { fn unbind_from(&self, slot: &MutNullableDom<WebGLBuffer>, buffer: &WebGLBuffer) { if slot.get().map_or(false, |b| buffer == &*b) { - buffer.decrement_attached_counter(false); + buffer.decrement_attached_counter(Operation::Infallible); slot.set(None); } } @@ -868,8 +867,10 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { } /// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5 - fn GetBufferParameter(&self, cx: JSContext, target: u32, parameter: u32) -> JSVal { - self.base.GetBufferParameter(cx, target, parameter) + fn GetBufferParameter(&self, _cx: JSContext, target: u32, parameter: u32) -> JSVal { + let buffer = + handle_potential_webgl_error!(self.base, self.bound_buffer(target), return NullValue()); + self.base.get_buffer_param(buffer, parameter) } #[allow(unsafe_code)] @@ -1225,7 +1226,7 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { } /// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5 - fn BufferData(&self, target: u32, data: Option<ArrayBufferViewOrArrayBuffer>, usage: u32) { + fn BufferData_(&self, target: u32, data: Option<ArrayBufferViewOrArrayBuffer>, usage: u32) { let usage = handle_potential_webgl_error!(self.base, self.buffer_usage(usage), return); let bound_buffer = handle_potential_webgl_error!(self.base, self.bound_buffer(target), return); @@ -1233,7 +1234,7 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { } /// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5 - fn BufferData_(&self, target: u32, size: i64, usage: u32) { + fn BufferData(&self, target: u32, size: i64, usage: u32) { let usage = handle_potential_webgl_error!(self.base, self.buffer_usage(usage), return); let bound_buffer = handle_potential_webgl_error!(self.base, self.bound_buffer(target), return); @@ -1457,7 +1458,8 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { } } - /// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8 + /// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.6 + #[allow(unsafe_code)] fn CompressedTexImage2D( &self, target: u32, @@ -1467,19 +1469,32 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { height: i32, border: i32, pixels: CustomAutoRooterGuard<ArrayBufferView>, + src_offset: u32, + src_length_override: u32, ) { - self.base.CompressedTexImage2D( + let mut data = unsafe { pixels.as_slice() }; + let start = src_offset as usize; + let end = (src_offset + src_length_override) as usize; + if start > data.len() || end > data.len() { + self.base.webgl_error(InvalidValue); + return; + } + if src_length_override != 0 { + data = &data[start..end]; + } + self.base.compressed_tex_image_2d( target, level, internal_format, width, height, border, - pixels, + data, ) } /// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8 + #[allow(unsafe_code)] fn CompressedTexSubImage2D( &self, target: u32, @@ -1490,9 +1505,21 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { height: i32, format: u32, pixels: CustomAutoRooterGuard<ArrayBufferView>, + src_offset: u32, + src_length_override: u32, ) { - self.base.CompressedTexSubImage2D( - target, level, xoffset, yoffset, width, height, format, pixels, + let mut data = unsafe { pixels.as_slice() }; + let start = src_offset as usize; + let end = (src_offset + src_length_override) as usize; + if start > data.len() || end > data.len() { + self.base.webgl_error(InvalidValue); + return; + } + if src_length_override != 0 { + data = &data[start..end]; + } + self.base.compressed_tex_sub_image_2d( + target, level, xoffset, yoffset, width, height, format, data, ) } @@ -1665,7 +1692,7 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { self.unbind_from(&binding.buffer, &buffer); } - buffer.mark_for_deletion(false); + buffer.mark_for_deletion(Operation::Infallible); } /// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.6 @@ -2136,7 +2163,7 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { src_offset: u32, src_length: u32, ) { - self.base.Uniform1iv(location, v, src_offset, src_length) + self.base.uniform1iv(location, v, src_offset, src_length) } // https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.8 @@ -2198,7 +2225,7 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { src_offset: u32, src_length: u32, ) { - self.base.Uniform1fv(location, v, src_offset, src_length); + self.base.uniform1fv(location, v, src_offset, src_length); } /// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 @@ -2214,7 +2241,7 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { src_offset: u32, src_length: u32, ) { - self.base.Uniform2fv(location, v, src_offset, src_length); + self.base.uniform2fv(location, v, src_offset, src_length); } /// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 @@ -2230,7 +2257,7 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { src_offset: u32, src_length: u32, ) { - self.base.Uniform2iv(location, v, src_offset, src_length) + self.base.uniform2iv(location, v, src_offset, src_length) } // https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.8 @@ -2279,7 +2306,7 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { src_offset: u32, src_length: u32, ) { - self.base.Uniform3fv(location, v, src_offset, src_length); + self.base.uniform3fv(location, v, src_offset, src_length); } /// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 @@ -2295,7 +2322,7 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { src_offset: u32, src_length: u32, ) { - self.base.Uniform3iv(location, v, src_offset, src_length) + self.base.uniform3iv(location, v, src_offset, src_length) } // https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.8 @@ -2344,7 +2371,7 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { src_offset: u32, src_length: u32, ) { - self.base.Uniform4iv(location, v, src_offset, src_length) + self.base.uniform4iv(location, v, src_offset, src_length) } // https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.8 @@ -2393,7 +2420,7 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { src_offset: u32, src_length: u32, ) { - self.base.Uniform4fv(location, v, src_offset, src_length); + self.base.uniform4fv(location, v, src_offset, src_length); } /// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 @@ -2406,7 +2433,7 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { src_length: u32, ) { self.base - .UniformMatrix2fv(location, transpose, v, src_offset, src_length) + .uniform_matrix_2fv(location, transpose, v, src_offset, src_length) } /// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 @@ -2419,7 +2446,7 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { src_length: u32, ) { self.base - .UniformMatrix3fv(location, transpose, v, src_offset, src_length) + .uniform_matrix_3fv(location, transpose, v, src_offset, src_length) } /// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 @@ -2432,7 +2459,7 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { src_length: u32, ) { self.base - .UniformMatrix4fv(location, transpose, v, src_offset, src_length) + .uniform_matrix_4fv(location, transpose, v, src_offset, src_length) } /// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.8 @@ -2798,7 +2825,7 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { &self, target: u32, level: i32, - internal_format: u32, + internal_format: i32, width: i32, height: i32, border: i32, @@ -2824,7 +2851,7 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { &self, target: u32, level: i32, - internal_format: u32, + internal_format: i32, format: u32, data_type: u32, source: ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement, @@ -2834,30 +2861,6 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { } /// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8 - fn TexImageDOM( - &self, - target: u32, - level: i32, - internal_format: u32, - width: i32, - height: i32, - format: u32, - data_type: u32, - source: &HTMLIFrameElement, - ) -> Fallible<()> { - self.base.TexImageDOM( - target, - level, - internal_format, - width, - height, - format, - data_type, - source, - ) - } - - /// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8 fn TexSubImage2D( &self, target: u32, @@ -3086,7 +3089,7 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { } } - query.delete(false); + query.delete(Operation::Infallible); } } @@ -3112,7 +3115,7 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { slot.set(None); } } - sampler.delete(false); + sampler.delete(Operation::Infallible); } } @@ -3343,7 +3346,7 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { fn DeleteSync(&self, sync: Option<&WebGLSync>) { if let Some(sync) = sync { handle_potential_webgl_error!(self.base, self.base.validate_ownership(sync), return); - sync.delete(false); + sync.delete(Operation::Infallible); } } @@ -3422,7 +3425,7 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { self.base.webgl_error(InvalidOperation); return; } - tf.delete(false); + tf.delete(Operation::Infallible); self.current_transform_feedback.set(None); } } @@ -3656,7 +3659,7 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { for slot in &[&generic_slot, &indexed_binding.buffer] { if let Some(old) = slot.get() { - old.decrement_attached_counter(false); + old.decrement_attached_counter(Operation::Infallible); } slot.set(buffer); } @@ -3734,7 +3737,7 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { for slot in &[&generic_slot, &indexed_binding.buffer] { if let Some(old) = slot.get() { - old.decrement_attached_counter(false); + old.decrement_attached_counter(Operation::Infallible); } slot.set(buffer); } @@ -3998,7 +4001,7 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { } if width < 0 || height < 0 { - return; + return self.base.webgl_error(InvalidValue); } self.base diff --git a/components/script/dom/webglbuffer.rs b/components/script/dom/webglbuffer.rs index 5ee1e7e1373..f81270d8240 100644 --- a/components/script/dom/webglbuffer.rs +++ b/components/script/dom/webglbuffer.rs @@ -9,7 +9,7 @@ use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::reflector::{reflect_dom_object, DomObject}; use crate::dom::bindings::root::DomRoot; use crate::dom::webglobject::WebGLObject; -use crate::dom::webglrenderingcontext::WebGLRenderingContext; +use crate::dom::webglrenderingcontext::{Operation, WebGLRenderingContext}; use canvas_traits::webgl::webgl_channel; use canvas_traits::webgl::{WebGLBufferId, WebGLCommand, WebGLError, WebGLResult}; use dom_struct::dom_struct; @@ -97,24 +97,23 @@ impl WebGLBuffer { self.capacity.get() } - pub fn mark_for_deletion(&self, fallible: bool) { + pub fn mark_for_deletion(&self, operation_fallibility: Operation) { if self.marked_for_deletion.get() { return; } self.marked_for_deletion.set(true); if self.is_deleted() { - self.delete(fallible); + self.delete(operation_fallibility); } } - fn delete(&self, fallible: bool) { + fn delete(&self, operation_fallibility: Operation) { assert!(self.is_deleted()); let context = self.upcast::<WebGLObject>().context(); let cmd = WebGLCommand::DeleteBuffer(self.id); - if fallible { - context.send_command_ignored(cmd); - } else { - context.send_command(cmd); + match operation_fallibility { + Operation::Fallible => context.send_command_ignored(cmd), + Operation::Infallible => context.send_command(cmd), } } @@ -164,7 +163,7 @@ impl WebGLBuffer { ); } - pub fn decrement_attached_counter(&self, fallible: bool) { + pub fn decrement_attached_counter(&self, operation_fallibility: Operation) { self.attached_counter.set( self.attached_counter .get() @@ -172,7 +171,7 @@ impl WebGLBuffer { .expect("refcount underflowed"), ); if self.is_deleted() { - self.delete(fallible); + self.delete(operation_fallibility); } } @@ -183,6 +182,6 @@ impl WebGLBuffer { impl Drop for WebGLBuffer { fn drop(&mut self) { - self.mark_for_deletion(true); + self.mark_for_deletion(Operation::Fallible); } } diff --git a/components/script/dom/webglframebuffer.rs b/components/script/dom/webglframebuffer.rs index 4b2f7c7d56e..9f38365c4c7 100644 --- a/components/script/dom/webglframebuffer.rs +++ b/components/script/dom/webglframebuffer.rs @@ -11,7 +11,7 @@ use crate::dom::bindings::reflector::{reflect_dom_object, DomObject}; use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom}; use crate::dom::webglobject::WebGLObject; use crate::dom::webglrenderbuffer::WebGLRenderbuffer; -use crate::dom::webglrenderingcontext::WebGLRenderingContext; +use crate::dom::webglrenderingcontext::{Operation, WebGLRenderingContext}; use crate::dom::webgltexture::WebGLTexture; use crate::dom::xrsession::XRSession; use canvas_traits::webgl::{webgl_channel, WebGLError, WebGLResult, WebGLVersion}; @@ -207,15 +207,14 @@ impl WebGLFramebuffer { )); } - pub fn delete(&self, fallible: bool) { + pub fn delete(&self, operation_fallibility: Operation) { if !self.is_deleted.get() { self.is_deleted.set(true); let context = self.upcast::<WebGLObject>().context(); let cmd = WebGLCommand::DeleteFramebuffer(self.id); - if fallible { - context.send_command_ignored(cmd); - } else { - context.send_command(cmd); + match operation_fallibility { + Operation::Fallible => context.send_command_ignored(cmd), + Operation::Infallible => context.send_command(cmd), } } } @@ -977,7 +976,7 @@ impl WebGLFramebuffer { impl Drop for WebGLFramebuffer { fn drop(&mut self) { - let _ = self.delete(true); + let _ = self.delete(Operation::Fallible); } } diff --git a/components/script/dom/webglprogram.rs b/components/script/dom/webglprogram.rs index 79598f7f5c1..88cecf0296f 100644 --- a/components/script/dom/webglprogram.rs +++ b/components/script/dom/webglprogram.rs @@ -12,7 +12,7 @@ use crate::dom::bindings::root::{DomRoot, MutNullableDom}; use crate::dom::bindings::str::DOMString; use crate::dom::webglactiveinfo::WebGLActiveInfo; use crate::dom::webglobject::WebGLObject; -use crate::dom::webglrenderingcontext::WebGLRenderingContext; +use crate::dom::webglrenderingcontext::{Operation, WebGLRenderingContext}; use crate::dom::webglshader::WebGLShader; use crate::dom::webgluniformlocation::WebGLUniformLocation; use canvas_traits::webgl::{webgl_channel, WebGLProgramId, WebGLResult}; @@ -84,17 +84,16 @@ impl WebGLProgram { } /// glDeleteProgram - pub fn mark_for_deletion(&self, fallible: bool) { + pub fn mark_for_deletion(&self, operation_fallibility: Operation) { if self.marked_for_deletion.get() { return; } self.marked_for_deletion.set(true); let cmd = WebGLCommand::DeleteProgram(self.id); let context = self.upcast::<WebGLObject>().context(); - if fallible { - context.send_command_ignored(cmd); - } else { - context.send_command(cmd); + match operation_fallibility { + Operation::Fallible => context.send_command_ignored(cmd), + Operation::Infallible => context.send_command(cmd), } if self.is_deleted() { self.detach_shaders(); @@ -639,7 +638,7 @@ impl WebGLProgram { impl Drop for WebGLProgram { fn drop(&mut self) { self.in_use(false); - self.mark_for_deletion(true); + self.mark_for_deletion(Operation::Fallible); } } diff --git a/components/script/dom/webglquery.rs b/components/script/dom/webglquery.rs index d7418471936..454fe72954e 100644 --- a/components/script/dom/webglquery.rs +++ b/components/script/dom/webglquery.rs @@ -8,7 +8,7 @@ use crate::dom::bindings::refcounted::Trusted; use crate::dom::bindings::reflector::{reflect_dom_object, DomObject}; use crate::dom::bindings::root::DomRoot; use crate::dom::webglobject::WebGLObject; -use crate::dom::webglrenderingcontext::WebGLRenderingContext; +use crate::dom::webglrenderingcontext::{Operation, WebGLRenderingContext}; use crate::task_source::TaskSource; use canvas_traits::webgl::WebGLError::*; use canvas_traits::webgl::{webgl_channel, WebGLCommand, WebGLQueryId}; @@ -96,16 +96,15 @@ impl WebGLQuery { Ok(()) } - pub fn delete(&self, fallible: bool) { + pub fn delete(&self, operation_fallibility: Operation) { if !self.marked_for_deletion.get() { self.marked_for_deletion.set(true); let context = self.upcast::<WebGLObject>().context(); let command = WebGLCommand::DeleteQuery(self.gl_id); - if fallible { - context.send_command_ignored(command); - } else { - context.send_command(command); + match operation_fallibility { + Operation::Fallible => context.send_command_ignored(command), + Operation::Infallible => context.send_command(command), } } } @@ -187,6 +186,6 @@ impl WebGLQuery { impl Drop for WebGLQuery { fn drop(&mut self) { - self.delete(true); + self.delete(Operation::Fallible); } } diff --git a/components/script/dom/webglrenderbuffer.rs b/components/script/dom/webglrenderbuffer.rs index f1a3ba99c53..204fe9ab46e 100644 --- a/components/script/dom/webglrenderbuffer.rs +++ b/components/script/dom/webglrenderbuffer.rs @@ -11,7 +11,7 @@ use crate::dom::bindings::reflector::{reflect_dom_object, DomObject}; use crate::dom::bindings::root::{DomRoot, MutNullableDom}; use crate::dom::webglframebuffer::WebGLFramebuffer; use crate::dom::webglobject::WebGLObject; -use crate::dom::webglrenderingcontext::WebGLRenderingContext; +use crate::dom::webglrenderingcontext::{Operation, WebGLRenderingContext}; use canvas_traits::webgl::{ webgl_channel, GlType, InternalFormatIntVec, WebGLCommand, WebGLError, WebGLRenderbufferId, WebGLResult, WebGLVersion, @@ -90,7 +90,7 @@ impl WebGLRenderbuffer { .send_command(WebGLCommand::BindRenderbuffer(target, Some(self.id))); } - pub fn delete(&self, fallible: bool) { + pub fn delete(&self, operation_fallibility: Operation) { if !self.is_deleted.get() { self.is_deleted.set(true); @@ -113,10 +113,9 @@ impl WebGLRenderbuffer { } let cmd = WebGLCommand::DeleteRenderbuffer(self.id); - if fallible { - context.send_command_ignored(cmd); - } else { - context.send_command(cmd); + match operation_fallibility { + Operation::Fallible => context.send_command_ignored(cmd), + Operation::Infallible => context.send_command(cmd), } } } @@ -277,6 +276,6 @@ impl WebGLRenderbuffer { impl Drop for WebGLRenderbuffer { fn drop(&mut self) { - self.delete(true); + self.delete(Operation::Fallible); } } diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index 53dff84c6ec..e616410b31d 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -155,6 +155,12 @@ pub enum VertexAttrib { Uint(u32, u32, u32, u32), } +#[derive(Clone, Copy, Debug)] +pub enum Operation { + Fallible, + Infallible, +} + #[dom_struct] pub struct WebGLRenderingContext { reflector_: Reflector, @@ -1142,7 +1148,7 @@ impl WebGLRenderingContext { self.current_vao.set(None); self.send_command(WebGLCommand::BindVertexArray(None)); } - vao.delete(false); + vao.delete(Operation::Infallible); } } @@ -1160,7 +1166,7 @@ impl WebGLRenderingContext { self.current_vao_webgl2.set(None); self.send_command(WebGLCommand::BindVertexArray(None)); } - vao.delete(false); + vao.delete(Operation::Infallible); } } @@ -1335,7 +1341,7 @@ impl WebGLRenderingContext { self.send_command(WebGLCommand::BindBuffer(target, buffer.map(|b| b.id()))); if let Some(old) = slot.get() { - old.decrement_attached_counter(false); + old.decrement_attached_counter(Operation::Infallible); } slot.set(buffer); @@ -1533,6 +1539,354 @@ impl WebGLRenderingContext { let last_slot = constants::COLOR_ATTACHMENT0 + self.limits().max_color_attachments - 1; constants::COLOR_ATTACHMENT0 <= attachment && attachment <= last_slot } + + pub fn compressed_tex_image_2d<'a>( + &self, + target: u32, + level: i32, + internal_format: u32, + width: i32, + height: i32, + border: i32, + data: &'a [u8], + ) { + let validator = CompressedTexImage2DValidator::new( + self, + target, + level, + width, + height, + border, + internal_format, + data.len(), + ); + let CommonCompressedTexImage2DValidatorResult { + texture, + target, + level, + width, + height, + compression, + } = match validator.validate() { + Ok(result) => result, + Err(_) => return, + }; + + let size = Size2D::new(width, height); + let buff = IpcSharedMemory::from_bytes(data); + let pixels = TexPixels::from_array(buff, size); + let data = pixels.data; + + handle_potential_webgl_error!( + self, + texture.initialize( + target, + size.width, + size.height, + 1, + compression.format, + level, + Some(TexDataType::UnsignedByte) + ) + ); + + self.send_command(WebGLCommand::CompressedTexImage2D { + target: target.as_gl_constant(), + level, + internal_format, + size: Size2D::new(width, height), + data: data.into(), + }); + + if let Some(fb) = self.bound_draw_framebuffer.get() { + fb.invalidate_texture(&*texture); + } + } + + pub fn compressed_tex_sub_image_2d<'a>( + &self, + target: u32, + level: i32, + xoffset: i32, + yoffset: i32, + width: i32, + height: i32, + format: u32, + data: &'a [u8], + ) { + let validator = CompressedTexSubImage2DValidator::new( + self, + target, + level, + xoffset, + yoffset, + width, + height, + format, + data.len(), + ); + let CommonCompressedTexImage2DValidatorResult { + texture: _, + target, + level, + width, + height, + .. + } = match validator.validate() { + Ok(result) => result, + Err(_) => return, + }; + + let buff = IpcSharedMemory::from_bytes(data); + let pixels = TexPixels::from_array(buff, Size2D::new(width, height)); + let data = pixels.data; + + self.send_command(WebGLCommand::CompressedTexSubImage2D { + target: target.as_gl_constant(), + level: level as i32, + xoffset, + yoffset, + size: Size2D::new(width, height), + format, + data: data.into(), + }); + } + + pub fn uniform1iv( + &self, + location: Option<&WebGLUniformLocation>, + val: Int32ArrayOrLongSequence, + src_offset: u32, + src_length: u32, + ) { + self.with_location(location, |location| { + match location.type_() { + constants::BOOL | + constants::INT | + constants::SAMPLER_2D | + constants::SAMPLER_CUBE => {}, + _ => return Err(InvalidOperation), + } + + let val = self.uniform_vec_section_int(val, src_offset, src_length, 1, location)?; + + match location.type_() { + constants::SAMPLER_2D | constants::SAMPLER_CUBE => { + for &v in val + .iter() + .take(cmp::min(location.size().unwrap_or(1) as usize, val.len())) + { + if v < 0 || v as u32 >= self.limits.max_combined_texture_image_units { + return Err(InvalidValue); + } + } + }, + _ => {}, + } + self.send_command(WebGLCommand::Uniform1iv(location.id(), val)); + Ok(()) + }); + } + + pub fn uniform1fv( + &self, + location: Option<&WebGLUniformLocation>, + val: Float32ArrayOrUnrestrictedFloatSequence, + src_offset: u32, + src_length: u32, + ) { + self.with_location(location, |location| { + match location.type_() { + constants::BOOL | constants::FLOAT => {}, + _ => return Err(InvalidOperation), + } + let val = self.uniform_vec_section_float(val, src_offset, src_length, 1, location)?; + self.send_command(WebGLCommand::Uniform1fv(location.id(), val)); + Ok(()) + }); + } + + pub fn uniform2fv( + &self, + location: Option<&WebGLUniformLocation>, + val: Float32ArrayOrUnrestrictedFloatSequence, + src_offset: u32, + src_length: u32, + ) { + self.with_location(location, |location| { + match location.type_() { + constants::BOOL_VEC2 | constants::FLOAT_VEC2 => {}, + _ => return Err(InvalidOperation), + } + let val = self.uniform_vec_section_float(val, src_offset, src_length, 2, location)?; + self.send_command(WebGLCommand::Uniform2fv(location.id(), val)); + Ok(()) + }); + } + + pub fn uniform2iv( + &self, + location: Option<&WebGLUniformLocation>, + val: Int32ArrayOrLongSequence, + src_offset: u32, + src_length: u32, + ) { + self.with_location(location, |location| { + match location.type_() { + constants::BOOL_VEC2 | constants::INT_VEC2 => {}, + _ => return Err(InvalidOperation), + } + let val = self.uniform_vec_section_int(val, src_offset, src_length, 2, location)?; + self.send_command(WebGLCommand::Uniform2iv(location.id(), val)); + Ok(()) + }); + } + + pub fn uniform3fv( + &self, + location: Option<&WebGLUniformLocation>, + val: Float32ArrayOrUnrestrictedFloatSequence, + src_offset: u32, + src_length: u32, + ) { + self.with_location(location, |location| { + match location.type_() { + constants::BOOL_VEC3 | constants::FLOAT_VEC3 => {}, + _ => return Err(InvalidOperation), + } + let val = self.uniform_vec_section_float(val, src_offset, src_length, 3, location)?; + self.send_command(WebGLCommand::Uniform3fv(location.id(), val)); + Ok(()) + }); + } + + pub fn uniform3iv( + &self, + location: Option<&WebGLUniformLocation>, + val: Int32ArrayOrLongSequence, + src_offset: u32, + src_length: u32, + ) { + self.with_location(location, |location| { + match location.type_() { + constants::BOOL_VEC3 | constants::INT_VEC3 => {}, + _ => return Err(InvalidOperation), + } + let val = self.uniform_vec_section_int(val, src_offset, src_length, 3, location)?; + self.send_command(WebGLCommand::Uniform3iv(location.id(), val)); + Ok(()) + }); + } + + pub fn uniform4iv( + &self, + location: Option<&WebGLUniformLocation>, + val: Int32ArrayOrLongSequence, + src_offset: u32, + src_length: u32, + ) { + self.with_location(location, |location| { + match location.type_() { + constants::BOOL_VEC4 | constants::INT_VEC4 => {}, + _ => return Err(InvalidOperation), + } + let val = self.uniform_vec_section_int(val, src_offset, src_length, 4, location)?; + self.send_command(WebGLCommand::Uniform4iv(location.id(), val)); + Ok(()) + }); + } + + pub fn uniform4fv( + &self, + location: Option<&WebGLUniformLocation>, + val: Float32ArrayOrUnrestrictedFloatSequence, + src_offset: u32, + src_length: u32, + ) { + self.with_location(location, |location| { + match location.type_() { + constants::BOOL_VEC4 | constants::FLOAT_VEC4 => {}, + _ => return Err(InvalidOperation), + } + let val = self.uniform_vec_section_float(val, src_offset, src_length, 4, location)?; + self.send_command(WebGLCommand::Uniform4fv(location.id(), val)); + Ok(()) + }); + } + + pub fn uniform_matrix_2fv( + &self, + location: Option<&WebGLUniformLocation>, + transpose: bool, + val: Float32ArrayOrUnrestrictedFloatSequence, + src_offset: u32, + src_length: u32, + ) { + self.with_location(location, |location| { + match location.type_() { + constants::FLOAT_MAT2 => {}, + _ => return Err(InvalidOperation), + } + let val = + self.uniform_matrix_section(val, src_offset, src_length, transpose, 4, location)?; + self.send_command(WebGLCommand::UniformMatrix2fv(location.id(), val)); + Ok(()) + }); + } + + pub fn uniform_matrix_3fv( + &self, + location: Option<&WebGLUniformLocation>, + transpose: bool, + val: Float32ArrayOrUnrestrictedFloatSequence, + src_offset: u32, + src_length: u32, + ) { + self.with_location(location, |location| { + match location.type_() { + constants::FLOAT_MAT3 => {}, + _ => return Err(InvalidOperation), + } + let val = + self.uniform_matrix_section(val, src_offset, src_length, transpose, 9, location)?; + self.send_command(WebGLCommand::UniformMatrix3fv(location.id(), val)); + Ok(()) + }); + } + + pub fn uniform_matrix_4fv( + &self, + location: Option<&WebGLUniformLocation>, + transpose: bool, + val: Float32ArrayOrUnrestrictedFloatSequence, + src_offset: u32, + src_length: u32, + ) { + self.with_location(location, |location| { + match location.type_() { + constants::FLOAT_MAT4 => {}, + _ => return Err(InvalidOperation), + } + let val = + self.uniform_matrix_section(val, src_offset, src_length, transpose, 16, location)?; + self.send_command(WebGLCommand::UniformMatrix4fv(location.id(), val)); + Ok(()) + }); + } + + pub fn get_buffer_param(&self, buffer: Option<DomRoot<WebGLBuffer>>, parameter: u32) -> JSVal { + let buffer = + handle_potential_webgl_error!(self, buffer.ok_or(InvalidOperation), return NullValue()); + + match parameter { + constants::BUFFER_SIZE => Int32Value(buffer.capacity() as i32), + constants::BUFFER_USAGE => Int32Value(buffer.usage() as i32), + _ => { + self.webgl_error(InvalidEnum); + NullValue() + }, + } + } } #[cfg(not(feature = "webgl_backtrace"))] @@ -1594,21 +1948,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5 fn GetBufferParameter(&self, _cx: SafeJSContext, target: u32, parameter: u32) -> JSVal { - let buffer = handle_potential_webgl_error!( - self, - self.bound_buffer(target) - .and_then(|buf| buf.ok_or(InvalidOperation)), - return NullValue() - ); - - match parameter { - constants::BUFFER_SIZE => Int32Value(buffer.capacity() as i32), - constants::BUFFER_USAGE => Int32Value(buffer.usage() as i32), - _ => { - self.webgl_error(InvalidEnum); - NullValue() - }, - } + let buffer = + handle_potential_webgl_error!(self, self.bound_buffer(target), return NullValue()); + self.get_buffer_param(buffer, parameter) } #[allow(unsafe_code)] @@ -2110,14 +2452,14 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5 - fn BufferData(&self, target: u32, data: Option<ArrayBufferViewOrArrayBuffer>, usage: u32) { + fn BufferData_(&self, target: u32, data: Option<ArrayBufferViewOrArrayBuffer>, usage: u32) { let usage = handle_potential_webgl_error!(self, self.buffer_usage(usage), return); let bound_buffer = handle_potential_webgl_error!(self, self.bound_buffer(target), return); self.buffer_data(target, data, usage, bound_buffer) } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5 - fn BufferData_(&self, target: u32, size: i64, usage: u32) { + fn BufferData(&self, target: u32, size: i64, usage: u32) { let usage = handle_potential_webgl_error!(self, self.buffer_usage(usage), return); let bound_buffer = handle_potential_webgl_error!(self, self.bound_buffer(target), return); self.buffer_data_(target, size, usage, bound_buffer) @@ -2142,55 +2484,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { border: i32, data: CustomAutoRooterGuard<ArrayBufferView>, ) { - let validator = CompressedTexImage2DValidator::new( - self, - target, - level, - width, - height, - border, - internal_format, - data.len(), - ); - let CommonCompressedTexImage2DValidatorResult { - texture, - target, - level, - width, - height, - compression, - } = match validator.validate() { - Ok(result) => result, - Err(_) => return, - }; - - let buff = IpcSharedMemory::from_bytes(unsafe { data.as_slice() }); - let pixels = TexPixels::from_array(buff, Size2D::new(width, height)); - - handle_potential_webgl_error!( - self, - texture.initialize( - target, - pixels.size.width, - pixels.size.height, - 1, - compression.format, - level, - Some(TexDataType::UnsignedByte) - ) - ); - - self.send_command(WebGLCommand::CompressedTexImage2D { - target: target.as_gl_constant(), - level, - internal_format, - size: Size2D::new(width, height), - data: pixels.data.into(), - }); - - if let Some(fb) = self.bound_draw_framebuffer.get() { - fb.invalidate_texture(&*texture); - } + let data = unsafe { data.as_slice() }; + self.compressed_tex_image_2d(target, level, internal_format, width, height, border, data) } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8 @@ -2206,41 +2501,10 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { format: u32, data: CustomAutoRooterGuard<ArrayBufferView>, ) { - let validator = CompressedTexSubImage2DValidator::new( - self, - target, - level, - xoffset, - yoffset, - width, - height, - format, - data.len(), - ); - let CommonCompressedTexImage2DValidatorResult { - texture: _, - target, - level, - width, - height, - .. - } = match validator.validate() { - Ok(result) => result, - Err(_) => return, - }; - - let buff = IpcSharedMemory::from_bytes(unsafe { data.as_slice() }); - let pixels = TexPixels::from_array(buff, Size2D::new(width, height)); - - self.send_command(WebGLCommand::CompressedTexSubImage2D { - target: target.as_gl_constant(), - level: level as i32, - xoffset, - yoffset, - size: Size2D::new(width, height), - format, - data: pixels.data.into(), - }); + let data = unsafe { data.as_slice() }; + self.compressed_tex_sub_image_2d( + target, level, xoffset, yoffset, width, height, format, data, + ) } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8 @@ -2583,9 +2847,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { .map_or(false, |b| buffer == &*b) { self.bound_buffer_array.set(None); - buffer.decrement_attached_counter(false); + buffer.decrement_attached_counter(Operation::Infallible); } - buffer.mark_for_deletion(false); + buffer.mark_for_deletion(Operation::Infallible); } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.6 @@ -2605,7 +2869,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { WebGLFramebufferBindingRequest::Default )) ); - framebuffer.delete(false) + framebuffer.delete(Operation::Infallible) } } @@ -2622,7 +2886,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { None )) ); - renderbuffer.delete(false) + renderbuffer.delete(Operation::Infallible) } } @@ -2657,7 +2921,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { )); } - texture.delete(false) + texture.delete(Operation::Infallible) } } @@ -2665,7 +2929,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { fn DeleteProgram(&self, program: Option<&WebGLProgram>) { if let Some(program) = program { handle_potential_webgl_error!(self, self.validate_ownership(program), return); - program.mark_for_deletion(false) + program.mark_for_deletion(Operation::Infallible) } } @@ -2673,7 +2937,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { fn DeleteShader(&self, shader: Option<&WebGLShader>) { if let Some(shader) = shader { handle_potential_webgl_error!(self, self.validate_ownership(shader), return); - shader.mark_for_deletion(false) + shader.mark_for_deletion(Operation::Infallible) } } @@ -3548,40 +3812,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 - fn Uniform1iv( - &self, - location: Option<&WebGLUniformLocation>, - val: Int32ArrayOrLongSequence, - src_offset: u32, - src_length: u32, - ) { - self.with_location(location, |location| { - match location.type_() { - constants::BOOL | - constants::INT | - constants::SAMPLER_2D | - constants::SAMPLER_CUBE => {}, - _ => return Err(InvalidOperation), - } - - let val = self.uniform_vec_section_int(val, src_offset, src_length, 1, location)?; - - match location.type_() { - constants::SAMPLER_2D | constants::SAMPLER_CUBE => { - for &v in val - .iter() - .take(cmp::min(location.size().unwrap_or(1) as usize, val.len())) - { - if v < 0 || v as u32 >= self.limits.max_combined_texture_image_units { - return Err(InvalidValue); - } - } - }, - _ => {}, - } - self.send_command(WebGLCommand::Uniform1iv(location.id(), val)); - Ok(()) - }); + fn Uniform1iv(&self, location: Option<&WebGLUniformLocation>, val: Int32ArrayOrLongSequence) { + self.uniform1iv(location, val, 0, 0) } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 @@ -3589,18 +3821,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { &self, location: Option<&WebGLUniformLocation>, val: Float32ArrayOrUnrestrictedFloatSequence, - src_offset: u32, - src_length: u32, ) { - self.with_location(location, |location| { - match location.type_() { - constants::BOOL | constants::FLOAT => {}, - _ => return Err(InvalidOperation), - } - let val = self.uniform_vec_section_float(val, src_offset, src_length, 1, location)?; - self.send_command(WebGLCommand::Uniform1fv(location.id(), val)); - Ok(()) - }); + self.uniform1fv(location, val, 0, 0) } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 @@ -3620,18 +3842,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { &self, location: Option<&WebGLUniformLocation>, val: Float32ArrayOrUnrestrictedFloatSequence, - src_offset: u32, - src_length: u32, ) { - self.with_location(location, |location| { - match location.type_() { - constants::BOOL_VEC2 | constants::FLOAT_VEC2 => {}, - _ => return Err(InvalidOperation), - } - let val = self.uniform_vec_section_float(val, src_offset, src_length, 2, location)?; - self.send_command(WebGLCommand::Uniform2fv(location.id(), val)); - Ok(()) - }); + self.uniform2fv(location, val, 0, 0) } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 @@ -3647,22 +3859,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 - fn Uniform2iv( - &self, - location: Option<&WebGLUniformLocation>, - val: Int32ArrayOrLongSequence, - src_offset: u32, - src_length: u32, - ) { - self.with_location(location, |location| { - match location.type_() { - constants::BOOL_VEC2 | constants::INT_VEC2 => {}, - _ => return Err(InvalidOperation), - } - let val = self.uniform_vec_section_int(val, src_offset, src_length, 2, location)?; - self.send_command(WebGLCommand::Uniform2iv(location.id(), val)); - Ok(()) - }); + fn Uniform2iv(&self, location: Option<&WebGLUniformLocation>, val: Int32ArrayOrLongSequence) { + self.uniform2iv(location, val, 0, 0) } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 @@ -3682,18 +3880,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { &self, location: Option<&WebGLUniformLocation>, val: Float32ArrayOrUnrestrictedFloatSequence, - src_offset: u32, - src_length: u32, ) { - self.with_location(location, |location| { - match location.type_() { - constants::BOOL_VEC3 | constants::FLOAT_VEC3 => {}, - _ => return Err(InvalidOperation), - } - let val = self.uniform_vec_section_float(val, src_offset, src_length, 3, location)?; - self.send_command(WebGLCommand::Uniform3fv(location.id(), val)); - Ok(()) - }); + self.uniform3fv(location, val, 0, 0) } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 @@ -3709,22 +3897,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 - fn Uniform3iv( - &self, - location: Option<&WebGLUniformLocation>, - val: Int32ArrayOrLongSequence, - src_offset: u32, - src_length: u32, - ) { - self.with_location(location, |location| { - match location.type_() { - constants::BOOL_VEC3 | constants::INT_VEC3 => {}, - _ => return Err(InvalidOperation), - } - let val = self.uniform_vec_section_int(val, src_offset, src_length, 3, location)?; - self.send_command(WebGLCommand::Uniform3iv(location.id(), val)); - Ok(()) - }); + fn Uniform3iv(&self, location: Option<&WebGLUniformLocation>, val: Int32ArrayOrLongSequence) { + self.uniform3iv(location, val, 0, 0) } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 @@ -3740,22 +3914,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 - fn Uniform4iv( - &self, - location: Option<&WebGLUniformLocation>, - val: Int32ArrayOrLongSequence, - src_offset: u32, - src_length: u32, - ) { - self.with_location(location, |location| { - match location.type_() { - constants::BOOL_VEC4 | constants::INT_VEC4 => {}, - _ => return Err(InvalidOperation), - } - let val = self.uniform_vec_section_int(val, src_offset, src_length, 4, location)?; - self.send_command(WebGLCommand::Uniform4iv(location.id(), val)); - Ok(()) - }); + fn Uniform4iv(&self, location: Option<&WebGLUniformLocation>, val: Int32ArrayOrLongSequence) { + self.uniform4iv(location, val, 0, 0) } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 @@ -3775,18 +3935,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { &self, location: Option<&WebGLUniformLocation>, val: Float32ArrayOrUnrestrictedFloatSequence, - src_offset: u32, - src_length: u32, ) { - self.with_location(location, |location| { - match location.type_() { - constants::BOOL_VEC4 | constants::FLOAT_VEC4 => {}, - _ => return Err(InvalidOperation), - } - let val = self.uniform_vec_section_float(val, src_offset, src_length, 4, location)?; - self.send_command(WebGLCommand::Uniform4fv(location.id(), val)); - Ok(()) - }); + self.uniform4fv(location, val, 0, 0) } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 @@ -3795,19 +3945,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { location: Option<&WebGLUniformLocation>, transpose: bool, val: Float32ArrayOrUnrestrictedFloatSequence, - src_offset: u32, - src_length: u32, ) { - self.with_location(location, |location| { - match location.type_() { - constants::FLOAT_MAT2 => {}, - _ => return Err(InvalidOperation), - } - let val = - self.uniform_matrix_section(val, src_offset, src_length, transpose, 4, location)?; - self.send_command(WebGLCommand::UniformMatrix2fv(location.id(), val)); - Ok(()) - }); + self.uniform_matrix_2fv(location, transpose, val, 0, 0) } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 @@ -3816,19 +3955,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { location: Option<&WebGLUniformLocation>, transpose: bool, val: Float32ArrayOrUnrestrictedFloatSequence, - src_offset: u32, - src_length: u32, ) { - self.with_location(location, |location| { - match location.type_() { - constants::FLOAT_MAT3 => {}, - _ => return Err(InvalidOperation), - } - let val = - self.uniform_matrix_section(val, src_offset, src_length, transpose, 9, location)?; - self.send_command(WebGLCommand::UniformMatrix3fv(location.id(), val)); - Ok(()) - }); + self.uniform_matrix_3fv(location, transpose, val, 0, 0) } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 @@ -3837,19 +3965,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { location: Option<&WebGLUniformLocation>, transpose: bool, val: Float32ArrayOrUnrestrictedFloatSequence, - src_offset: u32, - src_length: u32, ) { - self.with_location(location, |location| { - match location.type_() { - constants::FLOAT_MAT4 => {}, - _ => return Err(InvalidOperation), - } - let val = - self.uniform_matrix_section(val, src_offset, src_length, transpose, 16, location)?; - self.send_command(WebGLCommand::UniformMatrix4fv(location.id(), val)); - Ok(()) - }); + self.uniform_matrix_4fv(location, transpose, val, 0, 0) } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 @@ -4055,7 +4172,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { &self, target: u32, level: i32, - internal_format: u32, + internal_format: i32, width: i32, height: i32, border: i32, @@ -4071,7 +4188,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { self, target, level, - internal_format, + internal_format as u32, width, height, border, @@ -4153,7 +4270,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { &self, target: u32, level: i32, - internal_format: u32, + internal_format: i32, format: u32, data_type: u32, source: TexImageSource, @@ -4171,7 +4288,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { self, target, level, - internal_format, + internal_format as u32, pixels.size.width as i32, pixels.size.height as i32, 0, diff --git a/components/script/dom/webglsampler.rs b/components/script/dom/webglsampler.rs index c80e2a6a508..063decffe8f 100644 --- a/components/script/dom/webglsampler.rs +++ b/components/script/dom/webglsampler.rs @@ -7,7 +7,7 @@ use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::reflector::{reflect_dom_object, DomObject}; use crate::dom::bindings::root::DomRoot; use crate::dom::webglobject::WebGLObject; -use crate::dom::webglrenderingcontext::WebGLRenderingContext; +use crate::dom::webglrenderingcontext::{Operation, WebGLRenderingContext}; use canvas_traits::webgl::WebGLError::*; use canvas_traits::webgl::{webgl_channel, WebGLCommand, WebGLSamplerId}; use dom_struct::dom_struct; @@ -90,16 +90,15 @@ impl WebGLSampler { ) } - pub fn delete(&self, fallible: bool) { + pub fn delete(&self, operation_fallibility: Operation) { if !self.marked_for_deletion.get() { self.marked_for_deletion.set(true); let command = WebGLCommand::DeleteSampler(self.gl_id); let context = self.upcast::<WebGLObject>().context(); - if fallible { - context.send_command_ignored(command); - } else { - context.send_command(command); + match operation_fallibility { + Operation::Fallible => context.send_command_ignored(command), + Operation::Infallible => context.send_command(command), } } } @@ -180,6 +179,6 @@ impl WebGLSampler { impl Drop for WebGLSampler { fn drop(&mut self) { - self.delete(true); + self.delete(Operation::Fallible); } } diff --git a/components/script/dom/webglshader.rs b/components/script/dom/webglshader.rs index 9be334f6595..0e2a8253968 100644 --- a/components/script/dom/webglshader.rs +++ b/components/script/dom/webglshader.rs @@ -12,7 +12,7 @@ use crate::dom::webgl_extensions::ext::extshadertexturelod::EXTShaderTextureLod; use crate::dom::webgl_extensions::ext::oesstandardderivatives::OESStandardDerivatives; use crate::dom::webgl_extensions::WebGLExtensions; use crate::dom::webglobject::WebGLObject; -use crate::dom::webglrenderingcontext::WebGLRenderingContext; +use crate::dom::webglrenderingcontext::{Operation, WebGLRenderingContext}; use canvas_traits::webgl::{webgl_channel, GlType, WebGLVersion}; use canvas_traits::webgl::{GLLimits, WebGLCommand, WebGLError}; use canvas_traits::webgl::{WebGLResult, WebGLSLVersion, WebGLShaderId}; @@ -344,15 +344,14 @@ impl WebGLShader { /// Mark this shader as deleted (if it wasn't previously) /// and delete it as if calling glDeleteShader. /// Currently does not check if shader is attached - pub fn mark_for_deletion(&self, fallible: bool) { + pub fn mark_for_deletion(&self, operation_fallibility: Operation) { if !self.marked_for_deletion.get() { self.marked_for_deletion.set(true); let context = self.upcast::<WebGLObject>().context(); let cmd = WebGLCommand::DeleteShader(self.id); - if fallible { - context.send_command_ignored(cmd); - } else { - context.send_command(cmd); + match operation_fallibility { + Operation::Fallible => context.send_command_ignored(cmd), + Operation::Infallible => context.send_command(cmd), } } } @@ -400,6 +399,6 @@ impl WebGLShader { impl Drop for WebGLShader { fn drop(&mut self) { - self.mark_for_deletion(true); + self.mark_for_deletion(Operation::Fallible); } } diff --git a/components/script/dom/webglsync.rs b/components/script/dom/webglsync.rs index dd6acb5be9a..a6288f69c1e 100644 --- a/components/script/dom/webglsync.rs +++ b/components/script/dom/webglsync.rs @@ -8,7 +8,7 @@ use crate::dom::bindings::refcounted::Trusted; use crate::dom::bindings::reflector::{reflect_dom_object, DomObject}; use crate::dom::bindings::root::DomRoot; use crate::dom::webglobject::WebGLObject; -use crate::dom::webglrenderingcontext::WebGLRenderingContext; +use crate::dom::webglrenderingcontext::{Operation, WebGLRenderingContext}; use crate::task_source::TaskSource; use canvas_traits::webgl::{webgl_channel, WebGLCommand, WebGLSyncId}; use dom_struct::dom_struct; @@ -82,15 +82,14 @@ impl WebGLSync { self.client_wait_status.get() } - pub fn delete(&self, fallible: bool) { + pub fn delete(&self, operation_fallibility: Operation) { if self.is_valid() { self.marked_for_deletion.set(true); let context = self.upcast::<WebGLObject>().context(); let cmd = WebGLCommand::DeleteSync(self.sync_id); - if fallible { - context.send_command_ignored(cmd); - } else { - context.send_command(cmd); + match operation_fallibility { + Operation::Fallible => context.send_command_ignored(cmd), + Operation::Infallible => context.send_command(cmd), } } } @@ -131,6 +130,6 @@ impl WebGLSync { impl Drop for WebGLSync { fn drop(&mut self) { - self.delete(true); + self.delete(Operation::Fallible); } } diff --git a/components/script/dom/webgltexture.rs b/components/script/dom/webgltexture.rs index 682920df96e..3059dc7bf4e 100644 --- a/components/script/dom/webgltexture.rs +++ b/components/script/dom/webgltexture.rs @@ -13,7 +13,7 @@ use crate::dom::bindings::root::{DomRoot, MutNullableDom}; use crate::dom::webgl_validations::types::TexImageTarget; use crate::dom::webglframebuffer::WebGLFramebuffer; use crate::dom::webglobject::WebGLObject; -use crate::dom::webglrenderingcontext::WebGLRenderingContext; +use crate::dom::webglrenderingcontext::{Operation, WebGLRenderingContext}; use canvas_traits::webgl::{webgl_channel, TexDataType, TexFormat, WebGLResult, WebGLTextureId}; use canvas_traits::webgl::{DOMToTextureCommand, WebGLCommand, WebGLError}; use dom_struct::dom_struct; @@ -183,7 +183,7 @@ impl WebGLTexture { self.populate_mip_chain(self.base_mipmap_level, last_level) } - pub fn delete(&self, fallible: bool) { + pub fn delete(&self, operation_fallibility: Operation) { if !self.is_deleted.get() { self.is_deleted.set(true); let context = self.upcast::<WebGLObject>().context(); @@ -210,10 +210,9 @@ impl WebGLTexture { } let cmd = WebGLCommand::DeleteTexture(self.id); - if fallible { - context.send_command_ignored(cmd); - } else { - context.send_command(cmd); + match operation_fallibility { + Operation::Fallible => context.send_command_ignored(cmd), + Operation::Infallible => context.send_command(cmd), } } } @@ -420,7 +419,7 @@ impl WebGLTexture { impl Drop for WebGLTexture { fn drop(&mut self) { - self.delete(true); + self.delete(Operation::Fallible); } } diff --git a/components/script/dom/webgltransformfeedback.rs b/components/script/dom/webgltransformfeedback.rs index fe4b0753843..3b0b2abf0a2 100644 --- a/components/script/dom/webgltransformfeedback.rs +++ b/components/script/dom/webgltransformfeedback.rs @@ -6,7 +6,7 @@ use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::reflector::{reflect_dom_object, DomObject}; use crate::dom::bindings::root::DomRoot; use crate::dom::webglobject::WebGLObject; -use crate::dom::webglrenderingcontext::WebGLRenderingContext; +use crate::dom::webglrenderingcontext::{Operation, WebGLRenderingContext}; use canvas_traits::webgl::{webgl_channel, WebGLCommand}; use dom_struct::dom_struct; use std::cell::Cell; @@ -98,15 +98,14 @@ impl WebGLTransformFeedback { self.is_paused.get() } - pub fn delete(&self, fallible: bool) { + pub fn delete(&self, operation_fallibility: Operation) { if self.is_valid() && self.id() != 0 { self.marked_for_deletion.set(true); let context = self.upcast::<WebGLObject>().context(); let cmd = WebGLCommand::DeleteTransformFeedback(self.id); - if fallible { - context.send_command_ignored(cmd); - } else { - context.send_command(cmd); + match operation_fallibility { + Operation::Fallible => context.send_command_ignored(cmd), + Operation::Infallible => context.send_command(cmd), } } } @@ -126,6 +125,6 @@ impl WebGLTransformFeedback { impl Drop for WebGLTransformFeedback { fn drop(&mut self) { - self.delete(true); + self.delete(Operation::Fallible); } } diff --git a/components/script/dom/webglvertexarrayobject.rs b/components/script/dom/webglvertexarrayobject.rs index b425a7c4219..07f53af0316 100644 --- a/components/script/dom/webglvertexarrayobject.rs +++ b/components/script/dom/webglvertexarrayobject.rs @@ -8,7 +8,7 @@ use crate::dom::bindings::root::{DomRoot, MutNullableDom}; use crate::dom::vertexarrayobject::{VertexArrayObject, VertexAttribData}; use crate::dom::webglbuffer::WebGLBuffer; use crate::dom::webglobject::WebGLObject; -use crate::dom::webglrenderingcontext::WebGLRenderingContext; +use crate::dom::webglrenderingcontext::{Operation, WebGLRenderingContext}; use canvas_traits::webgl::{ActiveAttribInfo, WebGLResult, WebGLVertexArrayId}; use dom_struct::dom_struct; @@ -41,8 +41,8 @@ impl WebGLVertexArrayObject { self.array_object.is_deleted() } - pub fn delete(&self, fallible: bool) { - self.array_object.delete(fallible); + pub fn delete(&self, operation_fallibility: Operation) { + self.array_object.delete(operation_fallibility); } pub fn ever_bound(&self) -> bool { diff --git a/components/script/dom/webglvertexarrayobjectoes.rs b/components/script/dom/webglvertexarrayobjectoes.rs index f10c10d949b..215d39c1a5a 100644 --- a/components/script/dom/webglvertexarrayobjectoes.rs +++ b/components/script/dom/webglvertexarrayobjectoes.rs @@ -8,7 +8,7 @@ use crate::dom::bindings::root::{DomRoot, MutNullableDom}; use crate::dom::vertexarrayobject::{VertexArrayObject, VertexAttribData}; use crate::dom::webglbuffer::WebGLBuffer; use crate::dom::webglobject::WebGLObject; -use crate::dom::webglrenderingcontext::WebGLRenderingContext; +use crate::dom::webglrenderingcontext::{Operation, WebGLRenderingContext}; use canvas_traits::webgl::{ActiveAttribInfo, WebGLResult, WebGLVertexArrayId}; use dom_struct::dom_struct; @@ -41,8 +41,8 @@ impl WebGLVertexArrayObjectOES { self.array_object.is_deleted() } - pub fn delete(&self, fallible: bool) { - self.array_object.delete(fallible); + pub fn delete(&self, operation_fallibility: Operation) { + self.array_object.delete(operation_fallibility); } pub fn ever_bound(&self) -> bool { diff --git a/components/script/dom/webidls/ElementContentEditable.webidl b/components/script/dom/webidls/ElementContentEditable.webidl index ba7966c225d..8429700e93e 100644 --- a/components/script/dom/webidls/ElementContentEditable.webidl +++ b/components/script/dom/webidls/ElementContentEditable.webidl @@ -5,7 +5,7 @@ // https://html.spec.whatwg.org/multipage/#elementcontenteditable [Exposed=Window] interface mixin ElementContentEditable { - // [CEReactions] - // attribute DOMString contentEditable; - // readonly attribute boolean isContentEditable; + [CEReactions] + attribute DOMString contentEditable; + readonly attribute boolean isContentEditable; }; diff --git a/components/script/dom/webidls/EventHandler.webidl b/components/script/dom/webidls/EventHandler.webidl index 99be904979b..a3514182806 100644 --- a/components/script/dom/webidls/EventHandler.webidl +++ b/components/script/dom/webidls/EventHandler.webidl @@ -92,7 +92,9 @@ interface mixin GlobalEventHandlers { // https://drafts.csswg.org/css-transitions/#interface-globaleventhandlers-idl partial interface mixin GlobalEventHandlers { + attribute EventHandler ontransitionrun; attribute EventHandler ontransitionend; + attribute EventHandler ontransitioncancel; }; // https://w3c.github.io/selection-api/#extensions-to-globaleventhandlers-interface diff --git a/components/script/dom/webidls/WebGL2RenderingContext.webidl b/components/script/dom/webidls/WebGL2RenderingContext.webidl index f6278370cce..926d42292a2 100644 --- a/components/script/dom/webidls/WebGL2RenderingContext.webidl +++ b/components/script/dom/webidls/WebGL2RenderingContext.webidl @@ -286,17 +286,6 @@ interface mixin WebGL2RenderingContextBase const GLenum MAX_CLIENT_WAIT_TIMEOUT_WEBGL = 0x9247; /* Buffer objects */ - // WebGL1: - // BUG: https://github.com/KhronosGroup/WebGL/issues/2216 - void bufferData(GLenum target, /*[AllowShared]*/ BufferSource? data, GLenum usage); - void bufferData(GLenum target, GLsizeiptr size, GLenum usage); - void bufferSubData(GLenum target, GLintptr dstByteOffset, /*[AllowShared]*/ BufferSource srcData); - // WebGL2: - void bufferData(GLenum target, /*[AllowShared]*/ ArrayBufferView srcData, GLenum usage, GLuint srcOffset, - optional GLuint length = 0); - void bufferSubData(GLenum target, GLintptr dstByteOffset, /*[AllowShared]*/ ArrayBufferView srcData, - GLuint srcOffset, optional GLuint length = 0); - void copyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); // MapBufferRange, in particular its read-only and write-only modes, @@ -326,96 +315,51 @@ interface mixin WebGL2RenderingContextBase // void texStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, // GLsizei height, GLsizei depth); - // WebGL1 legacy entrypoints: - // BUG: https://github.com/KhronosGroup/WebGL/issues/2216 - [Throws] - void texImage2D(GLenum target, GLint level, GLenum internalformat, - GLsizei width, GLsizei height, GLint border, GLenum format, - GLenum type, /*[AllowShared]*/ ArrayBufferView? pixels); - [Throws] - void texImage2D(GLenum target, GLint level, GLenum internalformat, - GLenum format, GLenum type, TexImageSource source); // May throw DOMException - - // BUG: https://github.com/KhronosGroup/WebGL/issues/2216 - [Throws] - void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, - GLenum format, GLenum type, /*[AllowShared]*/ ArrayBufferView? pixels); - [Throws] - void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, - GLenum format, GLenum type, TexImageSource source); // May throw DOMException - - // WebGL2 entrypoints: - // void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, - // GLint border, GLenum format, GLenum type, GLintptr pboOffset); - // void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, - // GLint border, GLenum format, GLenum type, - // TexImageSource source); // May throw DOMException - // void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, - // GLint border, GLenum format, GLenum type, [AllowShared] ArrayBufferView srcData, - // GLuint srcOffset); - - // void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, - // GLsizei depth, GLint border, GLenum format, GLenum type, GLintptr pboOffset); - // void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, - // GLsizei depth, GLint border, GLenum format, GLenum type, - // TexImageSource source); // May throw DOMException - // void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, - // GLsizei depth, GLint border, GLenum format, GLenum type, [AllowShared] ArrayBufferView? srcData); - // void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, - // GLsizei depth, GLint border, GLenum format, GLenum type, [AllowShared] ArrayBufferView srcData, - // GLuint srcOffset); - - // void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, - // GLsizei height, GLenum format, GLenum type, GLintptr pboOffset); - // void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, - // GLsizei height, GLenum format, GLenum type, - // TexImageSource source); // May throw DOMException - // void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, - // GLsizei height, GLenum format, GLenum type, [AllowShared] ArrayBufferView srcData, - // GLuint srcOffset); - - // void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, - // GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, - // GLintptr pboOffset); - // void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, - // GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, - // TexImageSource source); // May throw DOMException - // void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, - // GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, - // [AllowShared] ArrayBufferView? srcData, optional GLuint srcOffset = 0); - - // void copyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, - // GLint x, GLint y, GLsizei width, GLsizei height); - - // void compressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, - // GLsizei height, GLint border, GLsizei imageSize, GLintptr offset); - // void compressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, - // GLsizei height, GLint border, [AllowShared] ArrayBufferView srcData, - // optional GLuint srcOffset = 0, optional GLuint srcLengthOverride = 0); - - // void compressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, - // GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, GLintptr offset); - // void compressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, - // GLsizei height, GLsizei depth, GLint border, [AllowShared] ArrayBufferView srcData, - // optional GLuint srcOffset = 0, optional GLuint srcLengthOverride = 0); - - // void compressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, - // GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, GLintptr offset); - // void compressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, - // GLsizei width, GLsizei height, GLenum format, - // [AllowShared] ArrayBufferView srcData, - // optional GLuint srcOffset = 0, - // optional GLuint srcLengthOverride = 0); - - // void compressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, - // GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, - // GLenum format, GLsizei imageSize, GLintptr offset); - // void compressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, - // GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, - // GLenum format, [AllowShared] ArrayBufferView srcData, - // optional GLuint srcOffset = 0, - // optional GLuint srcLengthOverride = 0); + //[Throws] + //void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, + // GLsizei depth, GLint border, GLenum format, GLenum type, GLintptr pboOffset); + //[Throws] + //void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, + // GLsizei depth, GLint border, GLenum format, GLenum type, + // TexImageSource source); // May throw DOMException + //[Throws] + //void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, + // GLsizei depth, GLint border, GLenum format, GLenum type, [AllowShared] ArrayBufferView? srcData); + //[Throws] + //void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, + // GLsizei depth, GLint border, GLenum format, GLenum type, [AllowShared] ArrayBufferView srcData, + // GLuint srcOffset); + + //[Throws] + //void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, + // GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, + // GLintptr pboOffset); + //[Throws] + //void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, + // GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, + // TexImageSource source); // May throw DOMException + //[Throws] + //void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, + // GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, + // [AllowShared] ArrayBufferView? srcData, optional GLuint srcOffset = 0); + + //void copyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, + // GLint x, GLint y, GLsizei width, GLsizei height); + + //void compressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, + // GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, GLintptr offset); + //void compressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, + // GLsizei height, GLsizei depth, GLint border, [AllowShared] ArrayBufferView srcData, + // optional GLuint srcOffset = 0, optional GLuint srcLengthOverride = 0); + + //void compressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, + // GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + // GLenum format, GLsizei imageSize, GLintptr offset); + //void compressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, + // GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + // GLenum format, [AllowShared] ArrayBufferView srcData, + // optional GLuint srcOffset = 0, + // optional GLuint srcLengthOverride = 0); /* Programs and shaders */ [WebGLHandlesContextLoss] GLint getFragDataLocation(WebGLProgram program, DOMString name); @@ -463,17 +407,6 @@ interface mixin WebGL2RenderingContextBase void drawElementsInstanced(GLenum mode, GLsizei count, GLenum type, GLintptr offset, GLsizei instanceCount); void drawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, GLintptr offset); - /* Reading back pixels */ - // WebGL1: - // BUG: https://github.com/KhronosGroup/WebGL/issues/2216 - void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, - /*[AllowShared]*/ ArrayBufferView? dstData); - // WebGL2: - void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, - GLintptr offset); - void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, - /*[AllowShared]*/ ArrayBufferView dstData, GLuint dstOffset); - /* Multiple Render Targets */ void drawBuffers(sequence<GLenum> buffers); @@ -542,9 +475,114 @@ interface mixin WebGL2RenderingContextBase void bindVertexArray(WebGLVertexArrayObject? array); }; +interface mixin WebGL2RenderingContextOverloads +{ + // WebGL1: + void bufferData(GLenum target, GLsizeiptr size, GLenum usage); + void bufferData(GLenum target, /*[AllowShared]*/ BufferSource? srcData, GLenum usage); + void bufferSubData(GLenum target, GLintptr dstByteOffset, /*[AllowShared]*/ BufferSource srcData); + // WebGL2: + void bufferData(GLenum target, /*[AllowShared]*/ ArrayBufferView srcData, GLenum usage, GLuint srcOffset, + optional GLuint length = 0); + void bufferSubData(GLenum target, GLintptr dstByteOffset, /*[AllowShared]*/ ArrayBufferView srcData, + GLuint srcOffset, optional GLuint length = 0); + + // WebGL1 legacy entrypoints: + [Throws] + void texImage2D(GLenum target, GLint level, GLint internalformat, + GLsizei width, GLsizei height, GLint border, GLenum format, + GLenum type, /*[AllowShared]*/ ArrayBufferView? pixels); + [Throws] + void texImage2D(GLenum target, GLint level, GLint internalformat, + GLenum format, GLenum type, TexImageSource source); // May throw DOMException + + [Throws] + void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, /*[AllowShared]*/ ArrayBufferView? pixels); + [Throws] + void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLenum format, GLenum type, TexImageSource source); // May throw DOMException + + // WebGL2 entrypoints: + //[Throws] + //void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, + // GLint border, GLenum format, GLenum type, GLintptr pboOffset); + //[Throws] + //void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, + // GLint border, GLenum format, GLenum type, + // TexImageSource source); // May throw DOMException + //[Throws] + //void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, + // GLint border, GLenum format, GLenum type, /*[AllowShared]*/ ArrayBufferView srcData, + // GLuint srcOffset); + + //[Throws] + //void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, + // GLsizei height, GLenum format, GLenum type, GLintptr pboOffset); + //[Throws] + //void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, + // GLsizei height, GLenum format, GLenum type, + // TexImageSource source); // May throw DOMException + //[Throws] + //void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, + // GLsizei height, GLenum format, GLenum type, /*[AllowShared]*/ ArrayBufferView srcData, + // GLuint srcOffset); + + //void compressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, + // GLsizei height, GLint border, GLsizei imageSize, GLintptr offset); + void compressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, + GLsizei height, GLint border, /*[AllowShared]*/ ArrayBufferView srcData, + optional GLuint srcOffset = 0, optional GLuint srcLengthOverride = 0); + + //void compressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, + // GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, GLintptr offset); + void compressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, GLenum format, + /*[AllowShared]*/ ArrayBufferView srcData, + optional GLuint srcOffset = 0, + optional GLuint srcLengthOverride = 0); + + void uniform1fv(WebGLUniformLocation? location, Float32List data, optional GLuint srcOffset = 0, + optional GLuint srcLength = 0); + void uniform2fv(WebGLUniformLocation? location, Float32List data, optional GLuint srcOffset = 0, + optional GLuint srcLength = 0); + void uniform3fv(WebGLUniformLocation? location, Float32List data, optional GLuint srcOffset = 0, + optional GLuint srcLength = 0); + void uniform4fv(WebGLUniformLocation? location, Float32List data, optional GLuint srcOffset = 0, + optional GLuint srcLength = 0); + + void uniform1iv(WebGLUniformLocation? location, Int32List data, optional GLuint srcOffset = 0, + optional GLuint srcLength = 0); + void uniform2iv(WebGLUniformLocation? location, Int32List data, optional GLuint srcOffset = 0, + optional GLuint srcLength = 0); + void uniform3iv(WebGLUniformLocation? location, Int32List data, optional GLuint srcOffset = 0, + optional GLuint srcLength = 0); + void uniform4iv(WebGLUniformLocation? location, Int32List data, optional GLuint srcOffset = 0, + optional GLuint srcLength = 0); + + void uniformMatrix2fv(WebGLUniformLocation? location, GLboolean transpose, Float32List data, + optional GLuint srcOffset = 0, optional GLuint srcLength = 0); + void uniformMatrix3fv(WebGLUniformLocation? location, GLboolean transpose, Float32List data, + optional GLuint srcOffset = 0, optional GLuint srcLength = 0); + void uniformMatrix4fv(WebGLUniformLocation? location, GLboolean transpose, Float32List data, + optional GLuint srcOffset = 0, optional GLuint srcLength = 0); + + /* Reading back pixels */ + // WebGL1: + void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, + /*[AllowShared]*/ ArrayBufferView? dstData); + // WebGL2: + void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, + GLintptr offset); + void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, + /*[AllowShared]*/ ArrayBufferView dstData, GLuint dstOffset); +}; + [Exposed=Window, Func="WebGL2RenderingContext::is_webgl2_enabled"] interface WebGL2RenderingContext { }; WebGL2RenderingContext includes WebGLRenderingContextBase; WebGL2RenderingContext includes WebGL2RenderingContextBase; +WebGL2RenderingContext includes WebGL2RenderingContextOverloads; diff --git a/components/script/dom/webidls/WebGLRenderingContext.webidl b/components/script/dom/webidls/WebGLRenderingContext.webidl index a9af389b042..ac00757ef3f 100644 --- a/components/script/dom/webidls/WebGLRenderingContext.webidl +++ b/components/script/dom/webidls/WebGLRenderingContext.webidl @@ -421,8 +421,6 @@ interface mixin WebGLRenderingContextBase const GLenum RGB5_A1 = 0x8057; const GLenum RGB565 = 0x8D62; const GLenum DEPTH_COMPONENT16 = 0x81A5; - // https://github.com/KhronosGroup/WebGL/pull/2371 - // const GLenum STENCIL_INDEX = 0x1901; const GLenum STENCIL_INDEX8 = 0x8D48; const GLenum DEPTH_STENCIL = 0x84F9; @@ -492,11 +490,6 @@ interface mixin WebGLRenderingContextBase void blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); - // BUG: https://github.com/KhronosGroup/WebGL/issues/2216 - // void bufferData(GLenum target, object? data, GLenum usage); - // void bufferData(GLenum target, GLsizeiptr size, GLenum usage); - // void bufferSubData(GLenum target, GLintptr offset, /*[AllowShared]*/ BufferSource data); - [WebGLHandlesContextLoss] GLenum checkFramebufferStatus(GLenum target); void clear(GLbitfield mask); void clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); @@ -505,14 +498,6 @@ interface mixin WebGLRenderingContextBase void colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); void compileShader(WebGLShader shader); - void compressedTexImage2D(GLenum target, GLint level, GLenum internalformat, - GLsizei width, GLsizei height, GLint border, - /*[AllowShared]*/ ArrayBufferView data); - void compressedTexSubImage2D(GLenum target, GLint level, - GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, GLenum format, - /*[AllowShared]*/ ArrayBufferView data); - void copyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); @@ -602,10 +587,6 @@ interface mixin WebGLRenderingContextBase void pixelStorei(GLenum pname, GLint param); void polygonOffset(GLfloat factor, GLfloat units); - // BUG: https://github.com/KhronosGroup/WebGL/issues/2216 - // void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, - // GLenum format, GLenum type, /*[AllowShared]*/ ArrayBufferView? pixels); - void renderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); void sampleCoverage(GLclampf value, GLboolean invert); @@ -620,26 +601,9 @@ interface mixin WebGLRenderingContextBase void stencilOp(GLenum fail, GLenum zfail, GLenum zpass); void stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass); - // BUG: https://github.com/KhronosGroup/WebGL/issues/2216 - // void texImage2D(GLenum target, GLint level, GLenum internalformat, - // GLsizei width, GLsizei height, GLint border, GLenum format, - // GLenum type, /*[AllowShared]*/ ArrayBufferView? pixels); - // void texImage2D(GLenum target, GLint level, GLenum internalformat, - // GLenum format, GLenum type, TexImageSource source); // May throw DOMException - [Throws, Pref="dom.webgl.dom_to_texture.enabled"] - void texImageDOM(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, - GLenum format, GLenum type, HTMLIFrameElement source); // May throw DOMException - void texParameterf(GLenum target, GLenum pname, GLfloat param); void texParameteri(GLenum target, GLenum pname, GLint param); - // BUG: https://github.com/KhronosGroup/WebGL/issues/2216 - // void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, - // GLsizei width, GLsizei height, - // GLenum format, GLenum type, /*[AllowShared]*/ ArrayBufferView? pixels); - // void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, - // GLenum format, GLenum type, TexImageSource source); // May throw DOMException - void uniform1f(WebGLUniformLocation? location, GLfloat x); void uniform2f(WebGLUniformLocation? location, GLfloat x, GLfloat y); void uniform3f(WebGLUniformLocation? location, GLfloat x, GLfloat y, GLfloat z); @@ -650,31 +614,6 @@ interface mixin WebGLRenderingContextBase void uniform3i(WebGLUniformLocation? location, GLint x, GLint y, GLint z); void uniform4i(WebGLUniformLocation? location, GLint x, GLint y, GLint z, GLint w); - void uniform1fv(WebGLUniformLocation? location, Float32List data, optional GLuint srcOffset = 0, - optional GLuint srcLength = 0); - void uniform2fv(WebGLUniformLocation? location, Float32List data, optional GLuint srcOffset = 0, - optional GLuint srcLength = 0); - void uniform3fv(WebGLUniformLocation? location, Float32List data, optional GLuint srcOffset = 0, - optional GLuint srcLength = 0); - void uniform4fv(WebGLUniformLocation? location, Float32List data, optional GLuint srcOffset = 0, - optional GLuint srcLength = 0); - - void uniform1iv(WebGLUniformLocation? location, Int32List data, optional GLuint srcOffset = 0, - optional GLuint srcLength = 0); - void uniform2iv(WebGLUniformLocation? location, Int32List data, optional GLuint srcOffset = 0, - optional GLuint srcLength = 0); - void uniform3iv(WebGLUniformLocation? location, Int32List data, optional GLuint srcOffset = 0, - optional GLuint srcLength = 0); - void uniform4iv(WebGLUniformLocation? location, Int32List data, optional GLuint srcOffset = 0, - optional GLuint srcLength = 0); - - void uniformMatrix2fv(WebGLUniformLocation? location, GLboolean transpose, Float32List data, - optional GLuint srcOffset = 0, optional GLuint srcLength = 0); - void uniformMatrix3fv(WebGLUniformLocation? location, GLboolean transpose, Float32List data, - optional GLuint srcOffset = 0, optional GLuint srcLength = 0); - void uniformMatrix4fv(WebGLUniformLocation? location, GLboolean transpose, Float32List data, - optional GLuint srcOffset = 0, optional GLuint srcLength = 0); - void useProgram(WebGLProgram? program); void validateProgram(WebGLProgram program); @@ -694,34 +633,64 @@ interface mixin WebGLRenderingContextBase void viewport(GLint x, GLint y, GLsizei width, GLsizei height); }; -[Exposed=Window] -interface WebGLRenderingContext +interface mixin WebGLRenderingContextOverloads { - // BUG: https://github.com/KhronosGroup/WebGL/issues/2216 - - void bufferData(GLenum target, /*[AllowShared]*/ BufferSource? data, GLenum usage); void bufferData(GLenum target, GLsizeiptr size, GLenum usage); + void bufferData(GLenum target, /*[AllowShared]*/ BufferSource? data, GLenum usage); void bufferSubData(GLenum target, GLintptr offset, /*[AllowShared]*/ BufferSource data); - // FIXME: https://github.com/servo/servo/issues/20516 + void compressedTexImage2D(GLenum target, GLint level, GLenum internalformat, + GLsizei width, GLsizei height, GLint border, + /*[AllowShared]*/ ArrayBufferView data); + void compressedTexSubImage2D(GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, GLenum format, + /*[AllowShared]*/ ArrayBufferView data); + + void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, /*[AllowShared]*/ ArrayBufferView? pixels); + [Throws] - void texImage2D(GLenum target, GLint level, GLenum internalformat, + void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, /*[AllowShared]*/ ArrayBufferView? pixels); [Throws] - void texImage2D(GLenum target, GLint level, GLenum internalformat, + void texImage2D(GLenum target, GLint level, GLint internalformat, GLenum format, GLenum type, TexImageSource source); // May throw DOMException - // FIXME: https://github.com/servo/servo/issues/20516 [Throws] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, - GLenum format, GLenum type, /*[AllowShared]*/ ArrayBufferView? pixels); + GLsizei width, GLsizei height, + GLenum format, GLenum type, /*[AllowShared]*/ ArrayBufferView? pixels); [Throws] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLenum format, GLenum type, TexImageSource source); // May throw DOMException - void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, /*[AllowShared]*/ ArrayBufferView? pixels); + void uniform1fv(WebGLUniformLocation? location, Float32List v); + void uniform2fv(WebGLUniformLocation? location, Float32List v); + void uniform3fv(WebGLUniformLocation? location, Float32List v); + void uniform4fv(WebGLUniformLocation? location, Float32List v); + + void uniform1iv(WebGLUniformLocation? location, Int32List v); + void uniform2iv(WebGLUniformLocation? location, Int32List v); + void uniform3iv(WebGLUniformLocation? location, Int32List v); + void uniform4iv(WebGLUniformLocation? location, Int32List v); + + void uniformMatrix2fv(WebGLUniformLocation? location, GLboolean transpose, Float32List value); + void uniformMatrix3fv(WebGLUniformLocation? location, GLboolean transpose, Float32List value); + void uniformMatrix4fv(WebGLUniformLocation? location, GLboolean transpose, Float32List value); +}; + +interface mixin WebGLRenderingContextExtensions { + [Throws, Pref="dom.webgl.dom_to_texture.enabled"] + void texImageDOM(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, + GLenum format, GLenum type, HTMLIFrameElement source); // May throw DOMException +}; + +[Exposed=(Window)] +interface WebGLRenderingContext +{ }; WebGLRenderingContext includes WebGLRenderingContextBase; +WebGLRenderingContext includes WebGLRenderingContextOverloads; +WebGLRenderingContext includes WebGLRenderingContextExtensions; diff --git a/components/script/dom/webidls/XRFrame.webidl b/components/script/dom/webidls/XRFrame.webidl index 3c202d5e061..e7a4eef1ddd 100644 --- a/components/script/dom/webidls/XRFrame.webidl +++ b/components/script/dom/webidls/XRFrame.webidl @@ -10,5 +10,6 @@ interface XRFrame { [Throws] XRViewerPose? getViewerPose(XRReferenceSpace referenceSpace); [Throws] XRPose? getPose(XRSpace space, XRSpace relativeTo); + [Pref="dom.webxr.hands.enabled", Throws] XRJointPose? getJointPose(XRJointSpace space, XRSpace relativeTo); sequence<XRHitTestResult> getHitTestResults(XRHitTestSource hitTestSource); }; diff --git a/components/script/dom/webidls/XRHand.webidl b/components/script/dom/webidls/XRHand.webidl new file mode 100644 index 00000000000..cff30268ba6 --- /dev/null +++ b/components/script/dom/webidls/XRHand.webidl @@ -0,0 +1,41 @@ +/* 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://github.com/immersive-web/webxr-hands-input/blob/master/explainer.md + +[SecureContext, Exposed=Window, Pref="dom.webxr.hands.enabled"] +interface XRHand { + readonly attribute long length; + getter XRJointSpace(unsigned long index); + + const unsigned long WRIST = 0; + const unsigned long THUMB_METACARPAL = 1; + const unsigned long THUMB_PHALANX_PROXIMAL = 2; + const unsigned long THUMB_PHALANX_DISTAL = 3; + const unsigned long THUMB_PHALANX_TIP = 4; + + const unsigned long INDEX_METACARPAL = 5; + const unsigned long INDEX_PHALANX_PROXIMAL = 6; + const unsigned long INDEX_PHALANX_INTERMEDIATE = 7; + const unsigned long INDEX_PHALANX_DISTAL = 8; + const unsigned long INDEX_PHALANX_TIP = 9; + + const unsigned long MIDDLE_METACARPAL = 10; + const unsigned long MIDDLE_PHALANX_PROXIMAL = 11; + const unsigned long MIDDLE_PHALANX_INTERMEDIATE = 12; + const unsigned long MIDDLE_PHALANX_DISTAL = 13; + const unsigned long MIDDLE_PHALANX_TIP = 14; + + const unsigned long RING_METACARPAL = 15; + const unsigned long RING_PHALANX_PROXIMAL = 16; + const unsigned long RING_PHALANX_INTERMEDIATE = 17; + const unsigned long RING_PHALANX_DISTAL = 18; + const unsigned long RING_PHALANX_TIP = 19; + + const unsigned long LITTLE_METACARPAL = 20; + const unsigned long LITTLE_PHALANX_PROXIMAL = 21; + const unsigned long LITTLE_PHALANX_INTERMEDIATE = 22; + const unsigned long LITTLE_PHALANX_DISTAL = 23; + const unsigned long LITTLE_PHALANX_TIP = 24; +}; diff --git a/components/script/dom/webidls/XRInputSource.webidl b/components/script/dom/webidls/XRInputSource.webidl index 487c959859d..b663666c872 100644 --- a/components/script/dom/webidls/XRInputSource.webidl +++ b/components/script/dom/webidls/XRInputSource.webidl @@ -24,4 +24,7 @@ interface XRInputSource { [SameObject] readonly attribute XRSpace? gripSpace; // [SameObject] readonly attribute Gamepad? gamepad; /* [SameObject] */ readonly attribute /* FrozenArray<DOMString> */ any profiles; + + [Pref="dom.webxr.hands.enabled"] + readonly attribute XRHand? hand; }; diff --git a/components/script/dom/webidls/XRJointPose.webidl b/components/script/dom/webidls/XRJointPose.webidl new file mode 100644 index 00000000000..70750b66cc4 --- /dev/null +++ b/components/script/dom/webidls/XRJointPose.webidl @@ -0,0 +1,10 @@ +/* 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://github.com/immersive-web/webxr-hands-input/blob/master/explainer.md + +[SecureContext, Exposed=Window, Pref="dom.webxr.hands.enabled"] +interface XRJointPose: XRPose { + readonly attribute float? radius; +}; diff --git a/components/script/dom/webidls/XRJointSpace.webidl b/components/script/dom/webidls/XRJointSpace.webidl new file mode 100644 index 00000000000..0815a73ec58 --- /dev/null +++ b/components/script/dom/webidls/XRJointSpace.webidl @@ -0,0 +1,8 @@ +/* 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://github.com/immersive-web/webxr-hands-input/blob/master/explainer.md + +[SecureContext, Exposed=Window, Pref="dom.webxr.hands.enabled"] +interface XRJointSpace: XRSpace {}; diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index 9f37ec2240a..c23efc961ee 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -2008,15 +2008,21 @@ impl Window { // Step 8 if doc.prompt_to_unload(false) { - if self.window_proxy().parent().is_some() { + let window_proxy = self.window_proxy(); + if window_proxy.parent().is_some() { // Step 10 // If browsingContext is a nested browsing context, // then put it in the delaying load events mode. - self.window_proxy().start_delaying_load_events_mode(); + window_proxy.start_delaying_load_events_mode(); } // TODO: step 11, navigationType. // Step 12, 13 - ScriptThread::navigate(pipeline_id, load_data, replace); + ScriptThread::navigate( + window_proxy.browsing_context_id(), + pipeline_id, + load_data, + replace, + ); }; } diff --git a/components/script/dom/worker.rs b/components/script/dom/worker.rs index d040d7d7468..c9555c88517 100644 --- a/components/script/dom/worker.rs +++ b/components/script/dom/worker.rs @@ -20,6 +20,7 @@ use crate::dom::dedicatedworkerglobalscope::{ use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; use crate::dom::messageevent::MessageEvent; +use crate::dom::window::Window; use crate::dom::workerglobalscope::prepare_workerscope_init; use crate::realms::enter_realm; use crate::script_runtime::JSContext; @@ -95,23 +96,34 @@ impl Worker { pipeline_id: global.pipeline_id(), }; + let browsing_context = global + .downcast::<Window>() + .map(|w| w.window_proxy().browsing_context_id()) + .or_else(|| { + global + .downcast::<DedicatedWorkerGlobalScope>() + .and_then(|w| w.browsing_context()) + }); + let (devtools_sender, devtools_receiver) = ipc::channel().unwrap(); let worker_id = WorkerId(Uuid::new_v4()); if let Some(ref chan) = global.devtools_chan() { let pipeline_id = global.pipeline_id(); let title = format!("Worker for {}", worker_url); - let page_info = DevtoolsPageInfo { - title: title, - url: worker_url.clone(), - }; - let _ = chan.send(ScriptToDevtoolsControlMsg::NewGlobal( - (pipeline_id, Some(worker_id)), - devtools_sender.clone(), - page_info, - )); + if let Some(browsing_context) = browsing_context { + let page_info = DevtoolsPageInfo { + title: title, + url: worker_url.clone(), + }; + let _ = chan.send(ScriptToDevtoolsControlMsg::NewGlobal( + (browsing_context, pipeline_id, Some(worker_id)), + devtools_sender.clone(), + page_info, + )); + } } - let init = prepare_workerscope_init(global, Some(devtools_sender)); + let init = prepare_workerscope_init(global, Some(devtools_sender), Some(worker_id)); DedicatedWorkerGlobalScope::run_worker_scope( init, @@ -126,6 +138,7 @@ impl Worker { worker_options.type_, closing, global.image_cache(), + browsing_context, ); Ok(worker) diff --git a/components/script/dom/workerglobalscope.rs b/components/script/dom/workerglobalscope.rs index 15eb79858fe..684760c3197 100644 --- a/components/script/dom/workerglobalscope.rs +++ b/components/script/dom/workerglobalscope.rs @@ -62,6 +62,7 @@ use uuid::Uuid; pub fn prepare_workerscope_init( global: &GlobalScope, devtools_sender: Option<IpcSender<DevtoolScriptControlMsg>>, + worker_id: Option<WorkerId>, ) -> WorkerGlobalScopeInit { let init = WorkerGlobalScopeInit { resource_threads: global.resource_threads().clone(), @@ -71,7 +72,7 @@ pub fn prepare_workerscope_init( from_devtools_sender: devtools_sender, script_to_constellation_chan: global.script_to_constellation_chan().clone(), scheduler_chan: global.scheduler_chan().clone(), - worker_id: WorkerId(Uuid::new_v4()), + worker_id: worker_id.unwrap_or_else(|| WorkerId(Uuid::new_v4())), pipeline_id: global.pipeline_id(), origin: global.origin().immutable().clone(), is_headless: global.is_headless(), diff --git a/components/script/dom/xrframe.rs b/components/script/dom/xrframe.rs index fdafd932e8a..1526a1c387c 100644 --- a/components/script/dom/xrframe.rs +++ b/components/script/dom/xrframe.rs @@ -10,6 +10,8 @@ use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::globalscope::GlobalScope; use crate::dom::xrhittestresult::XRHitTestResult; use crate::dom::xrhittestsource::XRHitTestSource; +use crate::dom::xrjointpose::XRJointPose; +use crate::dom::xrjointspace::XRJointSpace; use crate::dom::xrpose::XRPose; use crate::dom::xrreferencespace::XRReferenceSpace; use crate::dom::xrsession::{ApiPose, XRSession}; @@ -112,6 +114,38 @@ impl XRFrameMethods for XRFrame { Ok(Some(XRPose::new(&self.global(), pose))) } + /// https://immersive-web.github.io/webxr/#dom-xrframe-getpose + fn GetJointPose( + &self, + space: &XRJointSpace, + relative_to: &XRSpace, + ) -> Result<Option<DomRoot<XRJointPose>>, Error> { + if self.session != space.upcast::<XRSpace>().session() || + self.session != relative_to.session() + { + return Err(Error::InvalidState); + } + if !self.active.get() { + return Err(Error::InvalidState); + } + let joint_frame = if let Some(frame) = space.frame(&self.data) { + frame + } else { + return Ok(None); + }; + let relative_to = if let Some(r) = self.get_pose(relative_to) { + r + } else { + return Ok(None); + }; + let pose = relative_to.inverse().pre_transform(&joint_frame.pose); + Ok(Some(XRJointPose::new( + &self.global(), + pose.cast_unit(), + Some(joint_frame.radius), + ))) + } + /// https://immersive-web.github.io/hit-test/#dom-xrframe-gethittestresults fn GetHitTestResults(&self, source: &XRHitTestSource) -> Vec<DomRoot<XRHitTestResult>> { self.data diff --git a/components/script/dom/xrhand.rs b/components/script/dom/xrhand.rs new file mode 100644 index 00000000000..a7457526242 --- /dev/null +++ b/components/script/dom/xrhand.rs @@ -0,0 +1,88 @@ +/* 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::XRHandBinding::{XRHandConstants, XRHandMethods}; +use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; +use crate::dom::bindings::root::{Dom, DomRoot}; +use crate::dom::globalscope::GlobalScope; +use crate::dom::xrinputsource::XRInputSource; +use crate::dom::xrjointspace::XRJointSpace; +use dom_struct::dom_struct; +use webxr_api::{FingerJoint, Hand, Joint}; + +#[dom_struct] +pub struct XRHand { + reflector_: Reflector, + #[ignore_malloc_size_of = "defined in webxr"] + source: Dom<XRInputSource>, + #[ignore_malloc_size_of = "partially defind in webxr"] + spaces: Hand<Dom<XRJointSpace>>, +} + +impl XRHand { + fn new_inherited(source: &XRInputSource, spaces: &Hand<DomRoot<XRJointSpace>>) -> XRHand { + XRHand { + reflector_: Reflector::new(), + source: Dom::from_ref(source), + spaces: spaces.map(|j, _| j.as_ref().map(|j| Dom::from_ref(&**j))), + } + } + + pub fn new(global: &GlobalScope, source: &XRInputSource, support: Hand<()>) -> DomRoot<XRHand> { + let id = source.id(); + let session = source.session(); + let spaces = support + .map(|field, joint| field.map(|_| XRJointSpace::new(global, session, id, joint))); + reflect_dom_object(Box::new(XRHand::new_inherited(source, &spaces)), global) + } +} + +impl XRHandMethods for XRHand { + /// https://github.com/immersive-web/webxr-hands-input/blob/master/explainer.md + fn Length(&self) -> i32 { + XRHandConstants::LITTLE_PHALANX_TIP as i32 + 1 + } + + /// https://github.com/immersive-web/webxr-hands-input/blob/master/explainer.md + fn IndexedGetter(&self, joint_index: u32) -> Option<DomRoot<XRJointSpace>> { + let joint = match joint_index { + XRHandConstants::WRIST => Joint::Wrist, + XRHandConstants::THUMB_METACARPAL => Joint::ThumbMetacarpal, + XRHandConstants::THUMB_PHALANX_PROXIMAL => Joint::ThumbPhalanxProximal, + XRHandConstants::THUMB_PHALANX_DISTAL => Joint::ThumbPhalanxDistal, + XRHandConstants::THUMB_PHALANX_TIP => Joint::ThumbPhalanxTip, + XRHandConstants::INDEX_METACARPAL => Joint::Index(FingerJoint::Metacarpal), + XRHandConstants::INDEX_PHALANX_PROXIMAL => Joint::Index(FingerJoint::PhalanxProximal), + XRHandConstants::INDEX_PHALANX_INTERMEDIATE => { + Joint::Index(FingerJoint::PhalanxIntermediate) + }, + XRHandConstants::INDEX_PHALANX_DISTAL => Joint::Index(FingerJoint::PhalanxDistal), + XRHandConstants::INDEX_PHALANX_TIP => Joint::Index(FingerJoint::PhalanxTip), + XRHandConstants::MIDDLE_METACARPAL => Joint::Middle(FingerJoint::Metacarpal), + XRHandConstants::MIDDLE_PHALANX_PROXIMAL => Joint::Middle(FingerJoint::PhalanxProximal), + XRHandConstants::MIDDLE_PHALANX_INTERMEDIATE => { + Joint::Middle(FingerJoint::PhalanxIntermediate) + }, + XRHandConstants::MIDDLE_PHALANX_DISTAL => Joint::Middle(FingerJoint::PhalanxDistal), + XRHandConstants::MIDDLE_PHALANX_TIP => Joint::Middle(FingerJoint::PhalanxTip), + XRHandConstants::RING_METACARPAL => Joint::Ring(FingerJoint::Metacarpal), + XRHandConstants::RING_PHALANX_PROXIMAL => Joint::Ring(FingerJoint::PhalanxProximal), + XRHandConstants::RING_PHALANX_INTERMEDIATE => { + Joint::Ring(FingerJoint::PhalanxIntermediate) + }, + XRHandConstants::RING_PHALANX_DISTAL => Joint::Ring(FingerJoint::PhalanxDistal), + XRHandConstants::RING_PHALANX_TIP => Joint::Ring(FingerJoint::PhalanxTip), + XRHandConstants::LITTLE_METACARPAL => Joint::Little(FingerJoint::Metacarpal), + XRHandConstants::LITTLE_PHALANX_PROXIMAL => Joint::Little(FingerJoint::PhalanxProximal), + XRHandConstants::LITTLE_PHALANX_INTERMEDIATE => { + Joint::Little(FingerJoint::PhalanxIntermediate) + }, + XRHandConstants::LITTLE_PHALANX_DISTAL => Joint::Little(FingerJoint::PhalanxDistal), + XRHandConstants::LITTLE_PHALANX_TIP => Joint::Little(FingerJoint::PhalanxTip), + // XXXManishearth should this be a TypeError? + _ => return None, + }; + self.spaces.get(joint).map(|j| DomRoot::from_ref(&**j)) + } +} diff --git a/components/script/dom/xrinputsource.rs b/components/script/dom/xrinputsource.rs index ed8a3e6f1a5..248fb6d737a 100644 --- a/components/script/dom/xrinputsource.rs +++ b/components/script/dom/xrinputsource.rs @@ -8,6 +8,7 @@ use crate::dom::bindings::codegen::Bindings::XRInputSourceBinding::{ 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::xrhand::XRHand; use crate::dom::xrsession::XRSession; use crate::dom::xrspace::XRSpace; use crate::realms::enter_realm; @@ -24,10 +25,9 @@ pub struct XRInputSource { session: Dom<XRSession>, #[ignore_malloc_size_of = "Defined in rust-webxr"] info: InputSource, - #[ignore_malloc_size_of = "Defined in rust-webxr"] target_ray_space: MutNullableDom<XRSpace>, - #[ignore_malloc_size_of = "Defined in rust-webxr"] grip_space: MutNullableDom<XRSpace>, + hand: MutNullableDom<XRHand>, #[ignore_malloc_size_of = "mozjs"] profiles: Heap<JSVal>, } @@ -40,6 +40,7 @@ impl XRInputSource { info, target_ray_space: Default::default(), grip_space: Default::default(), + hand: Default::default(), profiles: Heap::default(), } } @@ -68,6 +69,10 @@ impl XRInputSource { pub fn id(&self) -> InputId { self.info.id } + + pub fn session(&self) -> &XRSession { + &self.session + } } impl XRInputSourceMethods for XRInputSource { @@ -112,4 +117,16 @@ impl XRInputSourceMethods for XRInputSource { fn Profiles(&self, _cx: JSContext) -> JSVal { self.profiles.get() } + + // https://github.com/immersive-web/webxr-hands-input/blob/master/explainer.md + fn GetHand(&self) -> Option<DomRoot<XRHand>> { + if let Some(ref hand) = self.info.hand_support { + Some( + self.hand + .or_init(|| XRHand::new(&self.global(), &self, hand.clone())), + ) + } else { + None + } + } } diff --git a/components/script/dom/xrjointpose.rs b/components/script/dom/xrjointpose.rs new file mode 100644 index 00000000000..c4b610b3327 --- /dev/null +++ b/components/script/dom/xrjointpose.rs @@ -0,0 +1,48 @@ +/* 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::XRJointPoseBinding::XRJointPoseMethods; +use crate::dom::bindings::num::Finite; +use crate::dom::bindings::reflector::reflect_dom_object; +use crate::dom::bindings::root::DomRoot; +use crate::dom::globalscope::GlobalScope; +use crate::dom::xrpose::XRPose; +use crate::dom::xrrigidtransform::XRRigidTransform; +use crate::dom::xrsession::ApiRigidTransform; +use dom_struct::dom_struct; + +#[dom_struct] +pub struct XRJointPose { + pose: XRPose, + radius: Option<f32>, +} + +impl XRJointPose { + fn new_inherited(transform: &XRRigidTransform, radius: Option<f32>) -> XRJointPose { + XRJointPose { + pose: XRPose::new_inherited(transform), + radius, + } + } + + #[allow(unsafe_code)] + pub fn new( + global: &GlobalScope, + pose: ApiRigidTransform, + radius: Option<f32>, + ) -> DomRoot<XRJointPose> { + let transform = XRRigidTransform::new(global, pose); + reflect_dom_object( + Box::new(XRJointPose::new_inherited(&transform, radius)), + global, + ) + } +} + +impl XRJointPoseMethods for XRJointPose { + /// https://immersive-web.github.io/webxr/#dom-XRJointPose-views + fn GetRadius(&self) -> Option<Finite<f32>> { + self.radius.map(Finite::wrap) + } +} diff --git a/components/script/dom/xrjointspace.rs b/components/script/dom/xrjointspace.rs new file mode 100644 index 00000000000..4b31b0bc6a2 --- /dev/null +++ b/components/script/dom/xrjointspace.rs @@ -0,0 +1,60 @@ +/* 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::reflector::reflect_dom_object; +use crate::dom::bindings::root::DomRoot; +use crate::dom::globalscope::GlobalScope; +use crate::dom::xrsession::{ApiPose, XRSession}; +use crate::dom::xrspace::XRSpace; +use dom_struct::dom_struct; +use euclid::RigidTransform3D; +use webxr_api::{BaseSpace, Frame, InputId, Joint, JointFrame, Space}; + +#[dom_struct] +pub struct XRJointSpace { + xrspace: XRSpace, + #[ignore_malloc_size_of = "defined in rust-webxr"] + input: InputId, + #[ignore_malloc_size_of = "defined in rust-webxr"] + joint: Joint, +} + +impl XRJointSpace { + pub fn new_inherited(session: &XRSession, input: InputId, joint: Joint) -> XRJointSpace { + XRJointSpace { + xrspace: XRSpace::new_inherited(session), + input, + joint, + } + } + + #[allow(unused)] + pub fn new( + global: &GlobalScope, + session: &XRSession, + input: InputId, + joint: Joint, + ) -> DomRoot<XRJointSpace> { + reflect_dom_object(Box::new(Self::new_inherited(session, input, joint)), global) + } + + pub fn space(&self) -> Space { + let base = BaseSpace::Joint(self.input, self.joint); + let offset = RigidTransform3D::identity(); + Space { base, offset } + } + + pub fn frame<'a>(&self, frame: &'a Frame) -> Option<&'a JointFrame> { + frame + .inputs + .iter() + .find(|i| i.id == self.input) + .and_then(|i| i.hand.as_ref()) + .and_then(|h| h.get(self.joint)) + } + + pub fn get_pose(&self, frame: &Frame) -> Option<ApiPose> { + self.frame(frame).map(|f| f.pose).map(|t| t.cast_unit()) + } +} diff --git a/components/script/dom/xrspace.rs b/components/script/dom/xrspace.rs index b4a26b7b8bb..66dd5b44e70 100644 --- a/components/script/dom/xrspace.rs +++ b/components/script/dom/xrspace.rs @@ -8,6 +8,7 @@ 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::xrjointspace::XRJointSpace; use crate::dom::xrreferencespace::XRReferenceSpace; use crate::dom::xrsession::{cast_transform, ApiPose, XRSession}; use dom_struct::dom_struct; @@ -61,6 +62,8 @@ impl XRSpace { pub fn space(&self) -> Space { if let Some(rs) = self.downcast::<XRReferenceSpace>() { rs.space() + } else if let Some(j) = self.downcast::<XRJointSpace>() { + j.space() } else if let Some(source) = self.input_source.get() { let base = if self.is_grip_space { BaseSpace::Grip(source.id()) @@ -86,6 +89,8 @@ impl XRSpace { pub fn get_pose(&self, base_pose: &Frame) -> Option<ApiPose> { if let Some(reference) = self.downcast::<XRReferenceSpace>() { reference.get_pose(base_pose) + } else if let Some(joint) = self.downcast::<XRJointSpace>() { + joint.get_pose(base_pose) } else if let Some(source) = self.input_source.get() { // XXXManishearth we should be able to request frame information // for inputs when necessary instead of always loading it diff --git a/components/script/dom/xrsystem.rs b/components/script/dom/xrsystem.rs index 0fc4ab108e2..a2ba7946e62 100644 --- a/components/script/dom/xrsystem.rs +++ b/components/script/dom/xrsystem.rs @@ -267,7 +267,8 @@ impl XRSystem { ) { let session = match response { Ok(session) => session, - Err(_) => { + Err(e) => { + warn!("Error requesting XR session: {:?}", e); if mode != XRSessionMode::Inline { self.pending_immersive_session.set(false); } |