aboutsummaryrefslogtreecommitdiffstats
path: root/components/script
diff options
context:
space:
mode:
Diffstat (limited to 'components/script')
-rw-r--r--components/script/dom/audionode.rs6
-rw-r--r--components/script/dom/bindings/callback.rs12
-rw-r--r--components/script/dom/bindings/import.rs3
-rw-r--r--components/script/dom/bindings/inheritance.rs9
-rw-r--r--components/script/dom/bindings/interface.rs4
-rw-r--r--components/script/dom/bindings/iterable.rs5
-rw-r--r--components/script/dom/bindings/mod.rs1
-rw-r--r--components/script/dom/bindings/principals.rs13
-rw-r--r--components/script/dom/bindings/proxyhandler.rs484
-rw-r--r--components/script/dom/bindings/root.rs20
-rw-r--r--components/script/dom/bindings/utils.rs132
-rw-r--r--components/script/dom/blob.rs4
-rw-r--r--components/script/dom/bluetooth/bluetooth.rs2
-rw-r--r--components/script/dom/characterdata.rs2
-rw-r--r--components/script/dom/clipboardevent.rs2
-rw-r--r--components/script/dom/document.rs4
-rw-r--r--components/script/dom/globalscope.rs2
-rw-r--r--components/script/dom/htmlmediaelement.rs6
-rw-r--r--components/script/dom/htmlslotelement.rs4
-rw-r--r--components/script/dom/mediadevices.rs2
-rw-r--r--components/script/dom/mod.rs1
-rw-r--r--components/script/dom/node.rs2
-rw-r--r--components/script/dom/permissions.rs2
-rw-r--r--components/script/dom/window.rs11
-rw-r--r--components/script/realms.rs15
25 files changed, 175 insertions, 573 deletions
diff --git a/components/script/dom/audionode.rs b/components/script/dom/audionode.rs
index 422b517bc94..4e572dda437 100644
--- a/components/script/dom/audionode.rs
+++ b/components/script/dom/audionode.rs
@@ -5,6 +5,9 @@
use std::cell::Cell;
use dom_struct::dom_struct;
+use script_bindings::codegen::InheritTypes::{
+ AudioNodeTypeId, AudioScheduledSourceNodeTypeId, EventTargetTypeId,
+};
use servo_media::audio::graph::NodeId;
use servo_media::audio::node::{
AudioNodeInit, AudioNodeMessage, ChannelCountMode as ServoMediaChannelCountMode, ChannelInfo,
@@ -17,9 +20,6 @@ use crate::dom::baseaudiocontext::BaseAudioContext;
use crate::dom::bindings::codegen::Bindings::AudioNodeBinding::{
AudioNodeMethods, AudioNodeOptions, ChannelCountMode, ChannelInterpretation,
};
-use crate::dom::bindings::codegen::InheritTypes::{
- AudioNodeTypeId, AudioScheduledSourceNodeTypeId, EventTargetTypeId,
-};
use crate::dom::bindings::error::{Error, ErrorResult, Fallible};
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::root::{Dom, DomRoot};
diff --git a/components/script/dom/bindings/callback.rs b/components/script/dom/bindings/callback.rs
index 7a28451763f..6a54255822f 100644
--- a/components/script/dom/bindings/callback.rs
+++ b/components/script/dom/bindings/callback.rs
@@ -16,14 +16,15 @@ use js::jsval::{JSVal, ObjectValue, UndefinedValue};
use js::rust::wrappers::{JS_GetProperty, JS_WrapObject};
use js::rust::{MutableHandleValue, Runtime};
use script_bindings::interfaces::DocumentHelpers;
+use script_bindings::utils::AsCCharPtrPtr;
use crate::DomTypes;
use crate::dom::bindings::codegen::Bindings::WindowBinding::Window_Binding::WindowMethods;
-use crate::dom::bindings::error::{Error, Fallible, report_pending_exception};
+use crate::dom::bindings::error::{Error, Fallible};
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::settings_stack::{GenericAutoEntryScript, GenericAutoIncumbentScript};
-use crate::dom::bindings::utils::AsCCharPtrPtr;
+use crate::dom::bindings::utils::DomHelpers;
use crate::dom::globalscope::GlobalScopeHelpers;
use crate::realms::{InRealm, enter_realm};
use crate::script_runtime::{CanGc, JSContext};
@@ -281,7 +282,12 @@ impl<D: DomTypes> Drop for CallSetup<D> {
}
if self.handling == ExceptionHandling::Report {
let ar = enter_realm(&*self.exception_global);
- report_pending_exception(self.cx, true, InRealm::Entered(&ar), CanGc::note());
+ <D as DomHelpers<D>>::report_pending_exception(
+ self.cx,
+ true,
+ InRealm::Entered(&ar),
+ CanGc::note(),
+ );
}
drop(self.incumbent_script.take());
drop(self.entry_script.take().unwrap());
diff --git a/components/script/dom/bindings/import.rs b/components/script/dom/bindings/import.rs
index fb893af33f4..71ba5e4c994 100644
--- a/components/script/dom/bindings/import.rs
+++ b/components/script/dom/bindings/import.rs
@@ -107,6 +107,7 @@ pub(crate) mod module {
};
pub(crate) use script_bindings::interfaces::*;
pub(crate) use script_bindings::record::Record;
+ pub(crate) use script_bindings::reflector::DomObject;
pub(crate) use servo_config::pref;
pub(crate) use super::base::*;
@@ -140,7 +141,7 @@ pub(crate) mod module {
define_guarded_properties, get_desired_proto, get_per_interface_object_handle,
is_exposed_in,
};
- pub(crate) use crate::dom::bindings::iterable::{Iterable, IteratorType};
+ pub(crate) use crate::dom::bindings::iterable::{Iterable, IterableIterator, IteratorType};
pub(crate) use crate::dom::bindings::like::{Maplike, Setlike};
pub(crate) use crate::dom::bindings::namespace::{
NamespaceObjectClass, create_namespace_object,
diff --git a/components/script/dom/bindings/inheritance.rs b/components/script/dom/bindings/inheritance.rs
index ef60378d55b..bb68b4b08f1 100644
--- a/components/script/dom/bindings/inheritance.rs
+++ b/components/script/dom/bindings/inheritance.rs
@@ -3,11 +3,4 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
pub(crate) use script_bindings::codegen::InheritTypes::*;
-pub(crate) use script_bindings::inheritance::Castable;
-
-#[allow(missing_docs)]
-pub(crate) trait HasParent {
- #[cfg_attr(crown, crown::unrooted_must_root_lint::must_root)]
- type Parent;
- fn as_parent(&self) -> &Self::Parent;
-}
+pub(crate) use script_bindings::inheritance::{Castable, HasParent};
diff --git a/components/script/dom/bindings/interface.rs b/components/script/dom/bindings/interface.rs
index 835d2f7f0be..d1c191be3a4 100644
--- a/components/script/dom/bindings/interface.rs
+++ b/components/script/dom/bindings/interface.rs
@@ -135,7 +135,7 @@ impl InterfaceConstructorBehavior {
pub(crate) type TraceHook = unsafe extern "C" fn(trc: *mut JSTracer, obj: *mut JSObject);
/// Create a global object with the given class.
-pub(crate) unsafe fn create_global_object(
+pub(crate) unsafe fn create_global_object<D: DomTypes>(
cx: SafeJSContext,
class: &'static JSClass,
private: *const libc::c_void,
@@ -150,7 +150,7 @@ pub(crate) unsafe fn create_global_object(
options.creationOptions_.sharedMemoryAndAtomics_ = false;
select_compartment(cx, &mut options);
- let principal = ServoJSPrincipals::new(origin);
+ let principal = ServoJSPrincipals::new::<D>(origin);
rval.set(JS_NewGlobalObject(
*cx,
diff --git a/components/script/dom/bindings/iterable.rs b/components/script/dom/bindings/iterable.rs
index d97dfeeddbe..c81551f7960 100644
--- a/components/script/dom/bindings/iterable.rs
+++ b/components/script/dom/bindings/iterable.rs
@@ -26,10 +26,11 @@ use crate::dom::bindings::codegen::Bindings::IterableIteratorBinding::{
};
use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::reflector::{
- DomGlobalGeneric, DomObjectIteratorWrap, DomObjectWrap, Reflector, reflect_dom_object,
+ DomGlobalGeneric, DomObjectIteratorWrap, DomObjectWrap, Reflector,
};
use crate::dom::bindings::root::{Dom, DomRoot, Root};
use crate::dom::bindings::trace::{JSTraceable, NoTrace, RootedTraceableBox};
+use crate::dom::bindings::utils::DomHelpers;
use crate::realms::InRealm;
use crate::script_runtime::{CanGc, JSContext};
@@ -79,7 +80,7 @@ impl<D: DomTypes, T: DomObjectIteratorWrap<D> + JSTraceable + Iterable + DomGlob
index: Cell::new(0),
_marker: NoTrace(PhantomData),
});
- reflect_dom_object(iterator, &*iterable.global_(realm), CanGc::note())
+ <D as DomHelpers<D>>::reflect_dom_object(iterator, &*iterable.global_(realm), CanGc::note())
}
/// Return the next value from the iterable object.
diff --git a/components/script/dom/bindings/mod.rs b/components/script/dom/bindings/mod.rs
index 833915c0b98..b4234e0cc39 100644
--- a/components/script/dom/bindings/mod.rs
+++ b/components/script/dom/bindings/mod.rs
@@ -191,7 +191,6 @@ pub(crate) mod codegen {
include!(concat!(env!("BINDINGS_OUT_DIR"), "/InterfaceObjectMap.rs"));
pub(crate) use script_bindings::codegen::Globals::Globals;
}
- pub(crate) use script_bindings::codegen::InheritTypes;
#[allow(dead_code)]
pub(crate) mod ConcreteInheritTypes {
include!(concat!(
diff --git a/components/script/dom/bindings/principals.rs b/components/script/dom/bindings/principals.rs
index b037fcb0709..e51a98e454a 100644
--- a/components/script/dom/bindings/principals.rs
+++ b/components/script/dom/bindings/principals.rs
@@ -19,16 +19,21 @@ use js::rust::Runtime;
use servo_url::MutableOrigin;
use super::structuredclone::StructuredCloneTags;
+use crate::dom::bindings::utils::DomHelpers;
+use crate::{DomTypeHolder, DomTypes};
/// An owned reference to Servo's `JSPrincipals` instance.
#[repr(transparent)]
pub(crate) struct ServoJSPrincipals(NonNull<JSPrincipals>);
impl ServoJSPrincipals {
- pub(crate) fn new(origin: &MutableOrigin) -> Self {
+ pub(crate) fn new<D: DomTypes>(origin: &MutableOrigin) -> Self {
unsafe {
let private: Box<MutableOrigin> = Box::new(origin.clone());
- let raw = CreateRustJSPrincipals(&PRINCIPALS_CALLBACKS, Box::into_raw(private) as _);
+ let raw = CreateRustJSPrincipals(
+ <D as DomHelpers<D>>::principals_callbacks(),
+ Box::into_raw(private) as _,
+ );
// The created `JSPrincipals` object has an initial reference
// count of zero, so the following code will set it to one
Self::from_raw_nonnull(NonNull::new_unchecked(raw))
@@ -175,14 +180,14 @@ pub(crate) unsafe extern "C" fn read_jsprincipal(
let Ok(origin) = bincode::deserialize(&bytes[..]) else {
return false;
};
- let principal = ServoJSPrincipals::new(&origin);
+ let principal = ServoJSPrincipals::new::<DomTypeHolder>(&origin);
*principals = principal.as_raw();
// we transferred ownership of principal to the caller
std::mem::forget(principal);
true
}
-const PRINCIPALS_CALLBACKS: JSPrincipalsCallbacks = JSPrincipalsCallbacks {
+pub(crate) const PRINCIPALS_CALLBACKS: JSPrincipalsCallbacks = JSPrincipalsCallbacks {
write: Some(write_jsprincipal),
isSystemOrAddonPrincipal: Some(principals_is_system_or_addon_principal),
};
diff --git a/components/script/dom/bindings/proxyhandler.rs b/components/script/dom/bindings/proxyhandler.rs
index 1ef83119e53..5dfe0839502 100644
--- a/components/script/dom/bindings/proxyhandler.rs
+++ b/components/script/dom/bindings/proxyhandler.rs
@@ -6,199 +6,31 @@
#![deny(missing_docs)]
-use std::ffi::CStr;
-use std::os::raw::c_char;
use std::ptr;
use js::conversions::ToJSValConvertible;
-use js::glue::{
- GetProxyHandler, GetProxyHandlerFamily, GetProxyPrivate, InvokeGetOwnPropertyDescriptor,
- SetProxyPrivate,
-};
+use js::glue::{GetProxyHandler, InvokeGetOwnPropertyDescriptor};
use js::jsapi;
use js::jsapi::{
- DOMProxyShadowsResult, GetObjectRealmOrNull, GetRealmPrincipals, GetStaticPrototype,
- GetWellKnownSymbol, Handle as RawHandle, HandleId as RawHandleId,
- HandleObject as RawHandleObject, HandleValue as RawHandleValue, JS_AtomizeAndPinString,
- JS_DefinePropertyById, JS_GetOwnPropertyDescriptorById, JS_IsExceptionPending, JSAutoRealm,
- JSContext, JSErrNum, JSFunctionSpec, JSObject, JSPropertySpec,
- MutableHandle as RawMutableHandle, MutableHandleIdVector as RawMutableHandleIdVector,
+ GetObjectRealmOrNull, GetRealmPrincipals, HandleId as RawHandleId,
+ HandleObject as RawHandleObject, HandleValue as RawHandleValue, JS_IsExceptionPending,
+ JSAutoRealm, JSContext, JSObject, MutableHandle as RawMutableHandle,
MutableHandleObject as RawMutableHandleObject, MutableHandleValue as RawMutableHandleValue,
- ObjectOpResult, PropertyDescriptor, SetDOMProxyInformation, SymbolCode, jsid,
-};
-use js::jsid::SymbolId;
-use js::jsval::{ObjectValue, UndefinedValue};
-use js::rust::wrappers::{
- AppendToIdVector, JS_AlreadyHasOwnPropertyById, JS_NewObjectWithGivenProto,
- RUST_INTERNED_STRING_TO_JSID, SetDataPropertyDescriptor,
-};
-use js::rust::{
- Handle, HandleObject, HandleValue, MutableHandle, MutableHandleObject, get_context_realm,
+ ObjectOpResult, PropertyDescriptor,
};
+use js::jsval::UndefinedValue;
+use js::rust::{HandleObject, HandleValue, MutableHandle, MutableHandleObject, get_context_realm};
+pub(crate) use script_bindings::proxyhandler::*;
-use crate::dom::bindings::conversions::{is_dom_proxy, jsid_to_string, jsstring_to_str};
-use crate::dom::bindings::error::{Error, throw_dom_exception};
+use crate::DomTypes;
+use crate::dom::bindings::error::Error;
use crate::dom::bindings::principals::ServoJSPrincipalsRef;
use crate::dom::bindings::reflector::DomObject;
-use crate::dom::bindings::str::DOMString;
-use crate::dom::bindings::utils::delete_property_by_id;
-use crate::dom::globalscope::{GlobalScope, GlobalScopeHelpers};
+use crate::dom::bindings::utils::DomHelpers;
+use crate::dom::globalscope::GlobalScopeHelpers;
use crate::realms::{AlreadyInRealm, InRealm};
use crate::script_runtime::{CanGc, JSContext as SafeJSContext};
-/// Determine if this id shadows any existing properties for this proxy.
-pub(crate) unsafe extern "C" fn shadow_check_callback(
- cx: *mut JSContext,
- object: RawHandleObject,
- id: RawHandleId,
-) -> DOMProxyShadowsResult {
- // TODO: support OverrideBuiltins when #12978 is fixed.
-
- rooted!(in(cx) let mut expando = ptr::null_mut::<JSObject>());
- get_expando_object(object, expando.handle_mut());
- if !expando.get().is_null() {
- let mut has_own = false;
- let raw_id = Handle::from_raw(id);
-
- if !JS_AlreadyHasOwnPropertyById(cx, expando.handle(), raw_id, &mut has_own) {
- return DOMProxyShadowsResult::ShadowCheckFailed;
- }
-
- if has_own {
- return DOMProxyShadowsResult::ShadowsViaDirectExpando;
- }
- }
-
- // Our expando, if any, didn't shadow, so we're not shadowing at all.
- DOMProxyShadowsResult::DoesntShadow
-}
-
-/// Initialize the infrastructure for DOM proxy objects.
-pub(crate) unsafe fn init() {
- SetDOMProxyInformation(
- GetProxyHandlerFamily(),
- Some(shadow_check_callback),
- ptr::null(),
- );
-}
-
-/// Defines an expando on the given `proxy`.
-pub(crate) unsafe extern "C" fn define_property(
- cx: *mut JSContext,
- proxy: RawHandleObject,
- id: RawHandleId,
- desc: RawHandle<PropertyDescriptor>,
- result: *mut ObjectOpResult,
-) -> bool {
- rooted!(in(cx) let mut expando = ptr::null_mut::<JSObject>());
- ensure_expando_object(cx, proxy, expando.handle_mut());
- JS_DefinePropertyById(cx, expando.handle().into(), id, desc, result)
-}
-
-/// Deletes an expando off the given `proxy`.
-pub(crate) unsafe extern "C" fn delete(
- cx: *mut JSContext,
- proxy: RawHandleObject,
- id: RawHandleId,
- bp: *mut ObjectOpResult,
-) -> bool {
- rooted!(in(cx) let mut expando = ptr::null_mut::<JSObject>());
- get_expando_object(proxy, expando.handle_mut());
- if expando.is_null() {
- (*bp).code_ = 0 /* OkCode */;
- return true;
- }
-
- delete_property_by_id(cx, expando.handle(), Handle::from_raw(id), bp)
-}
-
-/// Controls whether the Extensible bit can be changed
-pub(crate) unsafe extern "C" fn prevent_extensions(
- _cx: *mut JSContext,
- _proxy: RawHandleObject,
- result: *mut ObjectOpResult,
-) -> bool {
- (*result).code_ = JSErrNum::JSMSG_CANT_PREVENT_EXTENSIONS as ::libc::uintptr_t;
- true
-}
-
-/// Reports whether the object is Extensible
-pub(crate) unsafe extern "C" fn is_extensible(
- _cx: *mut JSContext,
- _proxy: RawHandleObject,
- succeeded: *mut bool,
-) -> bool {
- *succeeded = true;
- true
-}
-
-/// If `proxy` (underneath any functionally-transparent wrapper proxies) has as
-/// its `[[GetPrototypeOf]]` trap the ordinary `[[GetPrototypeOf]]` behavior
-/// defined for ordinary objects, set `*is_ordinary` to true and store `obj`'s
-/// prototype in `proto`. Otherwise set `*isOrdinary` to false. In case of
-/// error, both outparams have unspecified value.
-///
-/// This implementation always handles the case of the ordinary
-/// `[[GetPrototypeOf]]` behavior. An alternative implementation will be
-/// necessary for maybe-cross-origin objects.
-pub(crate) unsafe extern "C" fn get_prototype_if_ordinary(
- _: *mut JSContext,
- proxy: RawHandleObject,
- is_ordinary: *mut bool,
- proto: RawMutableHandleObject,
-) -> bool {
- *is_ordinary = true;
- proto.set(GetStaticPrototype(proxy.get()));
- true
-}
-
-/// Get the expando object, or null if there is none.
-pub(crate) unsafe fn get_expando_object(obj: RawHandleObject, mut expando: MutableHandleObject) {
- assert!(is_dom_proxy(obj.get()));
- let val = &mut UndefinedValue();
- GetProxyPrivate(obj.get(), val);
- expando.set(if val.is_undefined() {
- ptr::null_mut()
- } else {
- val.to_object()
- });
-}
-
-/// Get the expando object, or create it if it doesn't exist yet.
-/// Fails on JSAPI failure.
-pub(crate) unsafe fn ensure_expando_object(
- cx: *mut JSContext,
- obj: RawHandleObject,
- mut expando: MutableHandleObject,
-) {
- assert!(is_dom_proxy(obj.get()));
- get_expando_object(obj, expando.reborrow());
- if expando.is_null() {
- expando.set(JS_NewObjectWithGivenProto(
- cx,
- ptr::null_mut(),
- HandleObject::null(),
- ));
- assert!(!expando.is_null());
-
- SetProxyPrivate(obj.get(), &ObjectValue(expando.get()));
- }
-}
-
-/// Set the property descriptor's object to `obj` and set it to enumerable,
-/// and writable if `readonly` is true.
-pub(crate) fn set_property_descriptor(
- desc: MutableHandle<PropertyDescriptor>,
- value: HandleValue,
- attrs: u32,
- is_none: &mut bool,
-) {
- unsafe {
- SetDataPropertyDescriptor(desc, value, attrs);
- }
- *is_none = false;
-}
-
/// <https://html.spec.whatwg.org/multipage/#isplatformobjectsameorigin-(-o-)>
pub(crate) unsafe fn is_platform_object_same_origin(
cx: SafeJSContext,
@@ -239,7 +71,7 @@ pub(crate) unsafe fn is_platform_object_same_origin(
/// What this function does corresponds to the operations in
/// <https://html.spec.whatwg.org/multipage/#the-location-interface> denoted as
/// "Throw a `SecurityError` DOMException".
-pub(crate) unsafe fn report_cross_origin_denial(
+pub(crate) unsafe fn report_cross_origin_denial<D: DomTypes>(
cx: SafeJSContext,
id: RawHandleId,
access: &str,
@@ -251,75 +83,17 @@ pub(crate) unsafe fn report_cross_origin_denial(
);
let in_realm_proof = AlreadyInRealm::assert_for_cx(cx);
if !JS_IsExceptionPending(*cx) {
- let global = GlobalScope::from_context(*cx, InRealm::Already(&in_realm_proof));
+ let global = D::GlobalScope::from_context(*cx, InRealm::Already(&in_realm_proof));
// TODO: include `id` and `access` in the exception message
- throw_dom_exception(cx, &global, Error::Security, CanGc::note());
+ <D as DomHelpers<D>>::throw_dom_exception(cx, &global, Error::Security, CanGc::note());
}
false
}
-unsafe fn id_to_source(cx: SafeJSContext, id: RawHandleId) -> Option<DOMString> {
- rooted!(in(*cx) let mut value = UndefinedValue());
- rooted!(in(*cx) let mut jsstr = ptr::null_mut::<jsapi::JSString>());
- jsapi::JS_IdToValue(*cx, id.get(), value.handle_mut().into())
- .then(|| {
- jsstr.set(jsapi::JS_ValueToSource(*cx, value.handle().into()));
- jsstr.get()
- })
- .and_then(ptr::NonNull::new)
- .map(|jsstr| jsstring_to_str(*cx, jsstr))
-}
-
-/// Property and method specs that correspond to the elements of
-/// [`CrossOriginProperties(O)`].
-///
-/// [`CrossOriginProperties(O)`]: https://html.spec.whatwg.org/multipage/#crossoriginproperties-(-o-)
-pub(crate) struct CrossOriginProperties {
- pub(crate) attributes: &'static [JSPropertySpec],
- pub(crate) methods: &'static [JSFunctionSpec],
-}
-
-impl CrossOriginProperties {
- /// Enumerate the property keys defined by `self`.
- fn keys(&self) -> impl Iterator<Item = *const c_char> + '_ {
- // Safety: All cross-origin property keys are strings, not symbols
- self.attributes
- .iter()
- .map(|spec| unsafe { spec.name.string_ })
- .chain(self.methods.iter().map(|spec| unsafe { spec.name.string_ }))
- .filter(|ptr| !ptr.is_null())
- }
-}
-
-/// Implementation of [`CrossOriginOwnPropertyKeys`].
-///
-/// [`CrossOriginOwnPropertyKeys`]: https://html.spec.whatwg.org/multipage/#crossoriginownpropertykeys-(-o-)
-pub(crate) unsafe fn cross_origin_own_property_keys(
- cx: SafeJSContext,
- _proxy: RawHandleObject,
- cross_origin_properties: &'static CrossOriginProperties,
- props: RawMutableHandleIdVector,
-) -> bool {
- // > 2. For each `e` of `! CrossOriginProperties(O)`, append
- // > `e.[[Property]]` to `keys`.
- for key in cross_origin_properties.keys() {
- rooted!(in(*cx) let rooted = JS_AtomizeAndPinString(*cx, key));
- rooted!(in(*cx) let mut rooted_jsid: jsid);
- RUST_INTERNED_STRING_TO_JSID(*cx, rooted.handle().get(), rooted_jsid.handle_mut());
- AppendToIdVector(props, rooted_jsid.handle());
- }
-
- // > 3. Return the concatenation of `keys` and `« "then", @@toStringTag,
- // > @@hasInstance, @@isConcatSpreadable »`.
- append_cross_origin_allowlisted_prop_keys(cx, props);
-
- true
-}
-
/// Implementation of `[[Set]]` for [`Location`].
///
/// [`Location`]: https://html.spec.whatwg.org/multipage/#location-set
-pub(crate) unsafe extern "C" fn maybe_cross_origin_set_rawcx(
+pub(crate) unsafe extern "C" fn maybe_cross_origin_set_rawcx<D: DomTypes>(
cx: *mut JSContext,
proxy: RawHandleObject,
id: RawHandleId,
@@ -329,8 +103,8 @@ pub(crate) unsafe extern "C" fn maybe_cross_origin_set_rawcx(
) -> bool {
let cx = SafeJSContext::from_ptr(cx);
- if !is_platform_object_same_origin(cx, proxy) {
- return cross_origin_set(cx, proxy, id, v, receiver, result);
+ if !<D as DomHelpers<D>>::is_platform_object_same_origin(cx, proxy) {
+ return cross_origin_set::<D>(cx, proxy, id, v, receiver, result);
}
// Safe to enter the Realm of proxy now.
@@ -362,21 +136,10 @@ pub(crate) unsafe extern "C" fn maybe_cross_origin_set_rawcx(
)
}
-pub(crate) unsafe extern "C" fn maybe_cross_origin_get_prototype_if_ordinary_rawcx(
- _: *mut JSContext,
- _proxy: RawHandleObject,
- is_ordinary: *mut bool,
- _proto: RawMutableHandleObject,
-) -> bool {
- // We have a custom `[[GetPrototypeOf]]`, so return `false`
- *is_ordinary = false;
- true
-}
-
/// Implementation of `[[GetPrototypeOf]]` for [`Location`].
///
/// [`Location`]: https://html.spec.whatwg.org/multipage/#location-getprototypeof
-pub(crate) unsafe fn maybe_cross_origin_get_prototype<D: crate::DomTypes>(
+pub(crate) unsafe fn maybe_cross_origin_get_prototype<D: DomTypes>(
cx: SafeJSContext,
proxy: RawHandleObject,
get_proto_object: unsafe fn(cx: SafeJSContext, global: HandleObject, rval: MutableHandleObject),
@@ -399,46 +162,13 @@ pub(crate) unsafe fn maybe_cross_origin_get_prototype<D: crate::DomTypes>(
true
}
-/// Implementation of `[[SetPrototypeOf]]` for [`Location`] and [`WindowProxy`].
-///
-/// [`Location`]: https://html.spec.whatwg.org/multipage/#location-setprototypeof
-/// [`WindowProxy`]: https://html.spec.whatwg.org/multipage/#windowproxy-setprototypeof
-pub(crate) unsafe extern "C" fn maybe_cross_origin_set_prototype_rawcx(
- cx: *mut JSContext,
- proxy: RawHandleObject,
- proto: RawHandleObject,
- result: *mut ObjectOpResult,
-) -> bool {
- // > 1. Return `! SetImmutablePrototype(this, V)`.
- //
- // <https://tc39.es/ecma262/#sec-set-immutable-prototype>:
- //
- // > 1. Assert: Either `Type(V)` is Object or `Type(V)` is Null.
- //
- // > 2. Let current be `? O.[[GetPrototypeOf]]()`.
- rooted!(in(cx) let mut current = ptr::null_mut::<JSObject>());
- if !jsapi::GetObjectProto(cx, proxy, current.handle_mut().into()) {
- return false;
- }
-
- // > 3. If `SameValue(V, current)` is true, return true.
- if proto.get() == current.get() {
- (*result).code_ = 0 /* OkCode */;
- return true;
- }
-
- // > 4. Return false.
- (*result).code_ = JSErrNum::JSMSG_CANT_SET_PROTO as usize;
- true
-}
-
/// Implementation of [`CrossOriginGet`].
///
/// `cx` and `proxy` are expected to be different-Realm here. `proxy` is a proxy
/// for a maybe-cross-origin object.
///
/// [`CrossOriginGet`]: https://html.spec.whatwg.org/multipage/#crossoriginget-(-o,-p,-receiver-)
-pub(crate) unsafe fn cross_origin_get(
+pub(crate) unsafe fn cross_origin_get<D: DomTypes>(
cx: SafeJSContext,
proxy: RawHandleObject,
receiver: RawHandleValue,
@@ -482,7 +212,7 @@ pub(crate) unsafe fn cross_origin_get(
rooted!(in(*cx) let mut getter = ptr::null_mut::<JSObject>());
get_getter_object(&descriptor, getter.handle_mut().into());
if getter.get().is_null() {
- return report_cross_origin_denial(cx, id, "get");
+ return report_cross_origin_denial::<D>(cx, id, "get");
}
rooted!(in(*cx) let mut getter_jsval = UndefinedValue());
@@ -504,7 +234,7 @@ pub(crate) unsafe fn cross_origin_get(
/// for a maybe-cross-origin object.
///
/// [`CrossOriginSet`]: https://html.spec.whatwg.org/multipage/#crossoriginset-(-o,-p,-v,-receiver-)
-pub(crate) unsafe fn cross_origin_set(
+pub(crate) unsafe fn cross_origin_set<D: DomTypes>(
cx: SafeJSContext,
proxy: RawHandleObject,
id: RawHandleId,
@@ -539,7 +269,7 @@ pub(crate) unsafe fn cross_origin_set(
get_setter_object(&descriptor, setter.handle_mut().into());
if setter.get().is_null() {
// > 4. Throw a "SecurityError" DOMException.
- return report_cross_origin_denial(cx, id, "set");
+ return report_cross_origin_denial::<D>(cx, id, "set");
}
rooted!(in(*cx) let mut setter_jsval = UndefinedValue());
@@ -568,86 +298,13 @@ pub(crate) unsafe fn cross_origin_set(
true
}
-unsafe fn get_getter_object(d: &PropertyDescriptor, out: RawMutableHandleObject) {
- if d.hasGetter_() {
- out.set(d.getter_);
- }
-}
-
-unsafe fn get_setter_object(d: &PropertyDescriptor, out: RawMutableHandleObject) {
- if d.hasSetter_() {
- out.set(d.setter_);
- }
-}
-
-/// <https://tc39.es/ecma262/#sec-isaccessordescriptor>
-fn is_accessor_descriptor(d: &PropertyDescriptor) -> bool {
- d.hasSetter_() || d.hasGetter_()
-}
-
-/// <https://tc39.es/ecma262/#sec-isdatadescriptor>
-fn is_data_descriptor(d: &PropertyDescriptor) -> bool {
- d.hasWritable_() || d.hasValue_()
-}
-
-/// Evaluate `CrossOriginGetOwnPropertyHelper(proxy, id) != null`.
-/// SpiderMonkey-specific.
-///
-/// `cx` and `proxy` are expected to be different-Realm here. `proxy` is a proxy
-/// for a maybe-cross-origin object.
-pub(crate) unsafe fn cross_origin_has_own(
- cx: SafeJSContext,
- _proxy: RawHandleObject,
- cross_origin_properties: &'static CrossOriginProperties,
- id: RawHandleId,
- bp: *mut bool,
-) -> bool {
- // TODO: Once we have the slot for the holder, it'd be more efficient to
- // use `ensure_cross_origin_property_holder`. We'll need `_proxy` to
- // do that.
- *bp = jsid_to_string(*cx, Handle::from_raw(id)).is_some_and(|key| {
- cross_origin_properties.keys().any(|defined_key| {
- let defined_key = CStr::from_ptr(defined_key);
- defined_key.to_bytes() == key.as_bytes()
- })
- });
-
- true
-}
-
-/// Implementation of [`CrossOriginGetOwnPropertyHelper`].
-///
-/// `cx` and `proxy` are expected to be different-Realm here. `proxy` is a proxy
-/// for a maybe-cross-origin object.
-///
-/// [`CrossOriginGetOwnPropertyHelper`]: https://html.spec.whatwg.org/multipage/#crossorigingetownpropertyhelper-(-o,-p-)
-pub(crate) unsafe fn cross_origin_get_own_property_helper(
- cx: SafeJSContext,
- proxy: RawHandleObject,
- cross_origin_properties: &'static CrossOriginProperties,
- id: RawHandleId,
- desc: RawMutableHandle<PropertyDescriptor>,
- is_none: &mut bool,
-) -> bool {
- rooted!(in(*cx) let mut holder = ptr::null_mut::<JSObject>());
-
- ensure_cross_origin_property_holder(
- cx,
- proxy,
- cross_origin_properties,
- holder.handle_mut().into(),
- );
-
- JS_GetOwnPropertyDescriptorById(*cx, holder.handle().into(), id, desc, is_none)
-}
-
/// Implementation of [`CrossOriginPropertyFallback`].
///
/// `cx` and `proxy` are expected to be different-Realm here. `proxy` is a proxy
/// for a maybe-cross-origin object.
///
/// [`CrossOriginPropertyFallback`]: https://html.spec.whatwg.org/multipage/#crossoriginpropertyfallback-(-p-)
-pub(crate) unsafe fn cross_origin_property_fallback(
+pub(crate) unsafe fn cross_origin_property_fallback<D: DomTypes>(
cx: SafeJSContext,
_proxy: RawHandleObject,
id: RawHandleId,
@@ -671,96 +328,5 @@ pub(crate) unsafe fn cross_origin_property_fallback(
}
// > 2. Throw a `SecurityError` `DOMException`.
- report_cross_origin_denial(cx, id, "access")
-}
-
-const ALLOWLISTED_SYMBOL_CODES: &[SymbolCode] = &[
- SymbolCode::toStringTag,
- SymbolCode::hasInstance,
- SymbolCode::isConcatSpreadable,
-];
-
-unsafe fn is_cross_origin_allowlisted_prop(cx: SafeJSContext, id: RawHandleId) -> bool {
- if jsid_to_string(*cx, Handle::from_raw(id)).is_some_and(|st| st == "then") {
- return true;
- }
-
- rooted!(in(*cx) let mut allowed_id: jsid);
- ALLOWLISTED_SYMBOL_CODES.iter().any(|&allowed_code| {
- allowed_id.set(SymbolId(GetWellKnownSymbol(*cx, allowed_code)));
- // `jsid`s containing `JS::Symbol *` can be compared by
- // referential equality
- allowed_id.get().asBits_ == id.asBits_
- })
-}
-
-/// Append `« "then", @@toStringTag, @@hasInstance, @@isConcatSpreadable »` to
-/// `props`. This is used to implement [`CrossOriginOwnPropertyKeys`].
-///
-/// [`CrossOriginOwnPropertyKeys`]: https://html.spec.whatwg.org/multipage/#crossoriginownpropertykeys-(-o-)
-unsafe fn append_cross_origin_allowlisted_prop_keys(
- cx: SafeJSContext,
- props: RawMutableHandleIdVector,
-) {
- rooted!(in(*cx) let mut id: jsid);
-
- let jsstring = JS_AtomizeAndPinString(*cx, c"then".as_ptr());
- rooted!(in(*cx) let rooted = jsstring);
- RUST_INTERNED_STRING_TO_JSID(*cx, rooted.handle().get(), id.handle_mut());
- AppendToIdVector(props, id.handle());
-
- for &allowed_code in ALLOWLISTED_SYMBOL_CODES.iter() {
- id.set(SymbolId(GetWellKnownSymbol(*cx, allowed_code)));
- AppendToIdVector(props, id.handle());
- }
-}
-
-/// Get the holder for cross-origin properties for the current global of the
-/// `JSContext`, creating one and storing it in a slot of the proxy object if it
-/// doesn't exist yet.
-///
-/// This essentially creates a cache of [`CrossOriginGetOwnPropertyHelper`]'s
-/// results for all property keys.
-///
-/// `cx` and `proxy` are expected to be different-Realm here. `proxy` is a proxy
-/// for a maybe-cross-origin object. The `out_holder` return value will always
-/// be in the Realm of `cx`.
-///
-/// [`CrossOriginGetOwnPropertyHelper`]: https://html.spec.whatwg.org/multipage/#crossorigingetownpropertyhelper-(-o,-p-)
-unsafe fn ensure_cross_origin_property_holder(
- cx: SafeJSContext,
- _proxy: RawHandleObject,
- cross_origin_properties: &'static CrossOriginProperties,
- out_holder: RawMutableHandleObject,
-) -> bool {
- // TODO: We don't have the slot to store the holder yet. For now,
- // the holder is constructed every time this function is called,
- // which is not only inefficient but also deviates from the
- // specification in a subtle yet observable way.
-
- // Create a holder for the current Realm
- out_holder.set(jsapi::JS_NewObjectWithGivenProto(
- *cx,
- ptr::null_mut(),
- RawHandleObject::null(),
- ));
-
- if out_holder.get().is_null() ||
- !jsapi::JS_DefineProperties(
- *cx,
- out_holder.handle(),
- cross_origin_properties.attributes.as_ptr(),
- ) ||
- !jsapi::JS_DefineFunctions(
- *cx,
- out_holder.handle(),
- cross_origin_properties.methods.as_ptr(),
- )
- {
- return false;
- }
-
- // TODO: Store the holder in the slot that we don't have yet.
-
- true
+ report_cross_origin_denial::<D>(cx, id, "access")
}
diff --git a/components/script/dom/bindings/root.rs b/components/script/dom/bindings/root.rs
index 4e8cbf21882..923aa51351d 100644
--- a/components/script/dom/bindings/root.rs
+++ b/components/script/dom/bindings/root.rs
@@ -57,26 +57,6 @@ impl Drop for ThreadLocalStackRoots<'_> {
}
}
-/// Get a slice of references to DOM objects.
-pub(crate) trait DomSlice<T>
-where
- T: JSTraceable + DomObject,
-{
- /// Returns the slice of `T` references.
- fn r(&self) -> &[&T];
-}
-
-impl<T> DomSlice<T> for [Dom<T>]
-where
- T: JSTraceable + DomObject,
-{
- #[inline]
- fn r(&self) -> &[&T] {
- let _ = mem::transmute::<Dom<T>, &T>;
- unsafe { &*(self as *const [Dom<T>] as *const [&T]) }
- }
-}
-
pub(crate) trait ToLayout<T> {
/// Returns `LayoutDom<T>` containing the same pointer.
///
diff --git a/components/script/dom/bindings/utils.rs b/components/script/dom/bindings/utils.rs
index f97c7188f32..5f16d3a96d2 100644
--- a/components/script/dom/bindings/utils.rs
+++ b/components/script/dom/bindings/utils.rs
@@ -5,29 +5,34 @@
//! Various utilities to glue JavaScript and the DOM implementation together.
use std::cell::RefCell;
-use std::os::raw::c_char;
use std::thread::LocalKey;
use std::{ptr, slice};
use js::conversions::ToJSValConvertible;
-use js::glue::{IsWrapper, UnwrapObjectDynamic, UnwrapObjectStatic};
+use js::glue::{IsWrapper, JSPrincipalsCallbacks, UnwrapObjectDynamic, UnwrapObjectStatic};
use js::jsapi::{
- CallArgs, DOMCallbacks, HandleId as RawHandleId, HandleObject as RawHandleObject, Heap,
+ CallArgs, DOMCallbacks, HandleId as RawHandleId, HandleObject as RawHandleObject,
JS_DeprecatedStringHasLatin1Chars, JS_EnumerateStandardClasses, JS_FreezeObject,
JS_GetLatin1StringCharsAndLength, JS_IsGlobalObject, JS_ResolveStandardClass, JSContext,
- JSObject, JSTracer, MutableHandleIdVector as RawMutableHandleIdVector,
+ JSObject, MutableHandleIdVector as RawMutableHandleIdVector,
};
use js::rust::{Handle, HandleObject, MutableHandleValue, get_object_class, is_dom_class};
use crate::DomTypes;
use crate::dom::bindings::codegen::{InterfaceObjectMap, PrototypeList};
-use crate::dom::bindings::constructor::call_html_constructor;
+use crate::dom::bindings::constructor::{
+ call_html_constructor, pop_current_element_queue, push_new_element_queue,
+};
use crate::dom::bindings::conversions::DerivedFrom;
-use crate::dom::bindings::error::{Error, throw_dom_exception};
-use crate::dom::bindings::reflector::DomObject;
+use crate::dom::bindings::error::{Error, report_pending_exception, throw_dom_exception};
+use crate::dom::bindings::principals::PRINCIPALS_CALLBACKS;
+use crate::dom::bindings::proxyhandler::is_platform_object_same_origin;
+use crate::dom::bindings::reflector::{DomObject, DomObjectWrap, reflect_dom_object};
+use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::settings_stack::{self, StackEntry};
-use crate::dom::bindings::trace::trace_object;
+use crate::dom::globalscope::GlobalScope;
use crate::dom::windowproxy::WindowProxyHandler;
+use crate::realms::InRealm;
use crate::script_runtime::{CanGc, JSContext as SafeJSContext};
#[derive(JSTraceable, MallocSizeOf)]
@@ -100,22 +105,8 @@ fn is_platform_object(
}
}
-/// Trace the resources held by reserved slots of a global object
-pub(crate) unsafe fn trace_global(tracer: *mut JSTracer, obj: *mut JSObject) {
- let array = get_proto_or_iface_array(obj);
- for proto in (*array).iter() {
- if !proto.is_null() {
- trace_object(
- tracer,
- "prototype",
- &*(proto as *const *mut JSObject as *const Heap<*mut JSObject>),
- );
- }
- }
-}
-
/// Enumerate lazy properties of a global object.
-pub(crate) unsafe extern "C" fn enumerate_global(
+pub(crate) unsafe extern "C" fn enumerate_global<D: DomTypes>(
cx: *mut JSContext,
obj: RawHandleObject,
_props: RawMutableHandleIdVector,
@@ -125,14 +116,14 @@ pub(crate) unsafe extern "C" fn enumerate_global(
if !JS_EnumerateStandardClasses(cx, obj) {
return false;
}
- for init_fun in InterfaceObjectMap::MAP.values() {
+ for init_fun in <D as DomHelpers<D>>::interface_map().values() {
init_fun(SafeJSContext::from_ptr(cx), Handle::from_raw(obj));
}
true
}
/// Resolve a lazy global property, for interface objects and named constructors.
-pub(crate) unsafe extern "C" fn resolve_global(
+pub(crate) unsafe extern "C" fn resolve_global<D: DomTypes>(
cx: *mut JSContext,
obj: RawHandleObject,
id: RawHandleId,
@@ -160,7 +151,7 @@ pub(crate) unsafe extern "C" fn resolve_global(
assert!(!ptr.is_null());
let bytes = slice::from_raw_parts(ptr, length);
- if let Some(init_fun) = InterfaceObjectMap::MAP.get(bytes) {
+ if let Some(init_fun) = <D as DomHelpers<D>>::interface_map().get(bytes) {
init_fun(SafeJSContext::from_ptr(cx), Handle::from_raw(obj));
*rval = true;
} else {
@@ -184,30 +175,14 @@ pub(crate) const DOM_CALLBACKS: DOMCallbacks = DOMCallbacks {
instanceClassMatchesProto: Some(instance_class_has_proto_at_depth),
};
-// Generic method for returning libc::c_void from caller
-pub(crate) trait AsVoidPtr {
- fn as_void_ptr(&self) -> *const libc::c_void;
-}
-impl<T> AsVoidPtr for T {
- fn as_void_ptr(&self) -> *const libc::c_void {
- self as *const T as *const libc::c_void
- }
-}
-
-// Generic method for returning c_char from caller
-pub(crate) trait AsCCharPtrPtr {
- fn as_c_char_ptr(&self) -> *const c_char;
-}
-
-impl AsCCharPtrPtr for [u8] {
- fn as_c_char_ptr(&self) -> *const c_char {
- self as *const [u8] as *const c_char
- }
-}
-
/// Operations that must be invoked from the generated bindings.
pub(crate) trait DomHelpers<D: DomTypes> {
- fn throw_dom_exception(cx: SafeJSContext, global: &D::GlobalScope, result: Error);
+ fn throw_dom_exception(
+ cx: SafeJSContext,
+ global: &D::GlobalScope,
+ result: Error,
+ can_gc: CanGc,
+ );
unsafe fn call_html_constructor<T: DerivedFrom<D::Element> + DomObject>(
cx: SafeJSContext,
@@ -219,6 +194,27 @@ pub(crate) trait DomHelpers<D: DomTypes> {
) -> bool;
fn settings_stack() -> &'static LocalKey<RefCell<Vec<StackEntry<D>>>>;
+
+ fn principals_callbacks() -> &'static JSPrincipalsCallbacks;
+
+ fn is_platform_object_same_origin(cx: SafeJSContext, obj: RawHandleObject) -> bool;
+
+ fn interface_map() -> &'static phf::Map<&'static [u8], for<'a> fn(SafeJSContext, HandleObject)>;
+
+ fn push_new_element_queue();
+ fn pop_current_element_queue(can_gc: CanGc);
+
+ fn reflect_dom_object<T, U>(obj: Box<T>, global: &U, can_gc: CanGc) -> DomRoot<T>
+ where
+ T: DomObject + DomObjectWrap<D>,
+ U: DerivedFrom<D::GlobalScope>;
+
+ fn report_pending_exception(
+ cx: SafeJSContext,
+ dispatch_event: bool,
+ realm: InRealm,
+ can_gc: CanGc,
+ );
}
impl DomHelpers<crate::DomTypeHolder> for crate::DomTypeHolder {
@@ -226,8 +222,9 @@ impl DomHelpers<crate::DomTypeHolder> for crate::DomTypeHolder {
cx: SafeJSContext,
global: &<crate::DomTypeHolder as DomTypes>::GlobalScope,
result: Error,
+ can_gc: CanGc,
) {
- throw_dom_exception(cx, global, result, CanGc::note())
+ throw_dom_exception(cx, global, result, can_gc)
}
unsafe fn call_html_constructor<
@@ -246,4 +243,41 @@ impl DomHelpers<crate::DomTypeHolder> for crate::DomTypeHolder {
fn settings_stack() -> &'static LocalKey<RefCell<Vec<StackEntry<crate::DomTypeHolder>>>> {
&settings_stack::STACK
}
+
+ fn principals_callbacks() -> &'static JSPrincipalsCallbacks {
+ &PRINCIPALS_CALLBACKS
+ }
+
+ fn is_platform_object_same_origin(cx: SafeJSContext, obj: RawHandleObject) -> bool {
+ unsafe { is_platform_object_same_origin(cx, obj) }
+ }
+
+ fn interface_map() -> &'static phf::Map<&'static [u8], for<'a> fn(SafeJSContext, HandleObject)>
+ {
+ &InterfaceObjectMap::MAP
+ }
+
+ fn push_new_element_queue() {
+ push_new_element_queue()
+ }
+ fn pop_current_element_queue(can_gc: CanGc) {
+ pop_current_element_queue(can_gc)
+ }
+
+ fn reflect_dom_object<T, U>(obj: Box<T>, global: &U, can_gc: CanGc) -> DomRoot<T>
+ where
+ T: DomObject + DomObjectWrap<crate::DomTypeHolder>,
+ U: DerivedFrom<GlobalScope>,
+ {
+ reflect_dom_object(obj, global, can_gc)
+ }
+
+ fn report_pending_exception(
+ cx: SafeJSContext,
+ dispatch_event: bool,
+ realm: InRealm,
+ can_gc: CanGc,
+ ) {
+ report_pending_exception(cx, dispatch_event, realm, can_gc)
+ }
}
diff --git a/components/script/dom/blob.rs b/components/script/dom/blob.rs
index 75fa65deff0..d23cb62002e 100644
--- a/components/script/dom/blob.rs
+++ b/components/script/dom/blob.rs
@@ -243,7 +243,7 @@ impl BlobMethods<crate::DomTypeHolder> for Blob {
// https://w3c.github.io/FileAPI/#text-method-algo
fn Text(&self, can_gc: CanGc) -> Rc<Promise> {
let global = self.global();
- let in_realm_proof = AlreadyInRealm::assert();
+ let in_realm_proof = AlreadyInRealm::assert::<crate::DomTypeHolder>();
let p = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof), can_gc);
let id = self.get_blob_url_id();
global.read_file_async(
@@ -266,7 +266,7 @@ impl BlobMethods<crate::DomTypeHolder> for Blob {
// https://w3c.github.io/FileAPI/#arraybuffer-method-algo
fn ArrayBuffer(&self, can_gc: CanGc) -> Rc<Promise> {
let global = self.global();
- let in_realm_proof = AlreadyInRealm::assert();
+ let in_realm_proof = AlreadyInRealm::assert::<crate::DomTypeHolder>();
let p = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof), can_gc);
let id = self.get_blob_url_id();
diff --git a/components/script/dom/bluetooth/bluetooth.rs b/components/script/dom/bluetooth/bluetooth.rs
index c2732f2e9fb..91b07732630 100644
--- a/components/script/dom/bluetooth/bluetooth.rs
+++ b/components/script/dom/bluetooth/bluetooth.rs
@@ -300,7 +300,7 @@ where
T: AsyncBluetoothListener + DomObject + 'static,
F: FnOnce(StringOrUnsignedLong) -> Fallible<UUID>,
{
- let in_realm_proof = AlreadyInRealm::assert();
+ let in_realm_proof = AlreadyInRealm::assert::<crate::DomTypeHolder>();
let p = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof), can_gc);
let result_uuid = if let Some(u) = uuid {
diff --git a/components/script/dom/characterdata.rs b/components/script/dom/characterdata.rs
index fe677a6b7b2..d161fddd8d8 100644
--- a/components/script/dom/characterdata.rs
+++ b/components/script/dom/characterdata.rs
@@ -6,12 +6,12 @@
use std::cell::LazyCell;
use dom_struct::dom_struct;
+use script_bindings::codegen::InheritTypes::{CharacterDataTypeId, NodeTypeId, TextTypeId};
use crate::dom::bindings::cell::{DomRefCell, Ref};
use crate::dom::bindings::codegen::Bindings::CharacterDataBinding::CharacterDataMethods;
use crate::dom::bindings::codegen::Bindings::NodeBinding::Node_Binding::NodeMethods;
use crate::dom::bindings::codegen::Bindings::ProcessingInstructionBinding::ProcessingInstructionMethods;
-use crate::dom::bindings::codegen::InheritTypes::{CharacterDataTypeId, NodeTypeId, TextTypeId};
use crate::dom::bindings::codegen::UnionTypes::NodeOrString;
use crate::dom::bindings::error::{Error, ErrorResult, Fallible};
use crate::dom::bindings::inheritance::Castable;
diff --git a/components/script/dom/clipboardevent.rs b/components/script/dom/clipboardevent.rs
index eccf590e792..3cacb18a28a 100644
--- a/components/script/dom/clipboardevent.rs
+++ b/components/script/dom/clipboardevent.rs
@@ -41,7 +41,7 @@ impl ClipboardEventType {
}
#[dom_struct]
-pub struct ClipboardEvent {
+pub(crate) struct ClipboardEvent {
event: Event,
clipboard_data: MutNullableDom<DataTransfer>,
}
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index 146ef3ffacb..dd521776702 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -4384,7 +4384,7 @@ impl Document {
// https://fullscreen.spec.whatwg.org/#dom-element-requestfullscreen
pub(crate) fn enter_fullscreen(&self, pending: &Element, can_gc: CanGc) -> Rc<Promise> {
// Step 1
- let in_realm_proof = AlreadyInRealm::assert();
+ let in_realm_proof = AlreadyInRealm::assert::<crate::DomTypeHolder>();
let promise = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof), can_gc);
let mut error = false;
@@ -4452,7 +4452,7 @@ impl Document {
pub(crate) fn exit_fullscreen(&self, can_gc: CanGc) -> Rc<Promise> {
let global = self.global();
// Step 1
- let in_realm_proof = AlreadyInRealm::assert();
+ let in_realm_proof = AlreadyInRealm::assert::<crate::DomTypeHolder>();
let promise = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof), can_gc);
// Step 2
if self.fullscreen_element.get().is_none() {
diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs
index cb700d7d4c2..7b8169a06a6 100644
--- a/components/script/dom/globalscope.rs
+++ b/components/script/dom/globalscope.rs
@@ -2696,7 +2696,7 @@ impl GlobalScope {
options: &ImageBitmapOptions,
can_gc: CanGc,
) -> Rc<Promise> {
- let in_realm_proof = AlreadyInRealm::assert();
+ let in_realm_proof = AlreadyInRealm::assert::<crate::DomTypeHolder>();
let p = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof), can_gc);
if options.resizeWidth.is_some_and(|w| w == 0) {
p.reject_error(Error::InvalidState, can_gc);
diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs
index 94c962968dc..31b0d5c6d5d 100644
--- a/components/script/dom/htmlmediaelement.rs
+++ b/components/script/dom/htmlmediaelement.rs
@@ -27,6 +27,9 @@ use net_traits::{
ResourceTimingType,
};
use pixels::Image;
+use script_bindings::codegen::InheritTypes::{
+ ElementTypeId, HTMLElementTypeId, HTMLMediaElementTypeId, NodeTypeId,
+};
use script_layout_interface::MediaFrame;
use servo_config::pref;
use servo_media::player::audio::AudioRenderer;
@@ -60,9 +63,6 @@ use crate::dom::bindings::codegen::Bindings::ShadowRootBinding::{
use crate::dom::bindings::codegen::Bindings::TextTrackBinding::{TextTrackKind, TextTrackMode};
use crate::dom::bindings::codegen::Bindings::URLBinding::URLMethods;
use crate::dom::bindings::codegen::Bindings::WindowBinding::Window_Binding::WindowMethods;
-use crate::dom::bindings::codegen::InheritTypes::{
- ElementTypeId, HTMLElementTypeId, HTMLMediaElementTypeId, NodeTypeId,
-};
use crate::dom::bindings::codegen::UnionTypes::{
MediaStreamOrBlob, VideoTrackOrAudioTrackOrTextTrack,
};
diff --git a/components/script/dom/htmlslotelement.rs b/components/script/dom/htmlslotelement.rs
index 2deb6b068e4..022cbbf388a 100644
--- a/components/script/dom/htmlslotelement.rs
+++ b/components/script/dom/htmlslotelement.rs
@@ -8,6 +8,7 @@ use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix, local_name, namespace_url, ns};
use js::gc::RootedVec;
use js::rust::HandleObject;
+use script_bindings::codegen::InheritTypes::{CharacterDataTypeId, NodeTypeId};
use crate::ScriptThread;
use crate::dom::attr::Attr;
@@ -19,7 +20,6 @@ use crate::dom::bindings::codegen::Bindings::ShadowRootBinding::ShadowRoot_Bindi
use crate::dom::bindings::codegen::Bindings::ShadowRootBinding::{
ShadowRootMode, SlotAssignmentMode,
};
-use crate::dom::bindings::codegen::InheritTypes::{CharacterDataTypeId, NodeTypeId};
use crate::dom::bindings::codegen::UnionTypes::ElementOrText;
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::root::{Dom, DomRoot};
@@ -35,7 +35,7 @@ use crate::script_runtime::CanGc;
/// <https://html.spec.whatwg.org/multipage/#the-slot-element>
#[dom_struct]
-pub struct HTMLSlotElement {
+pub(crate) struct HTMLSlotElement {
htmlelement: HTMLElement,
/// <https://dom.spec.whatwg.org/#slot-assigned-nodes>
diff --git a/components/script/dom/mediadevices.rs b/components/script/dom/mediadevices.rs
index f2f5a45d09c..78d145103a5 100644
--- a/components/script/dom/mediadevices.rs
+++ b/components/script/dom/mediadevices.rs
@@ -79,7 +79,7 @@ impl MediaDevicesMethods<crate::DomTypeHolder> for MediaDevices {
/// <https://w3c.github.io/mediacapture-main/#dom-mediadevices-enumeratedevices>
fn EnumerateDevices(&self, can_gc: CanGc) -> Rc<Promise> {
// Step 1.
- let in_realm_proof = AlreadyInRealm::assert();
+ let in_realm_proof = AlreadyInRealm::assert::<crate::DomTypeHolder>();
let p = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof), can_gc);
// Step 2.
diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs
index 717e5a1f5b9..a34e0b44221 100644
--- a/components/script/dom/mod.rs
+++ b/components/script/dom/mod.rs
@@ -205,6 +205,7 @@
#[macro_use]
pub(crate) mod macros;
+#[allow(unused_imports)]
pub(crate) mod types {
include!(concat!(env!("BINDINGS_OUT_DIR"), "/InterfaceTypes.rs"));
}
diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs
index 5cbcbb6f43c..d89263d2bf2 100644
--- a/components/script/dom/node.rs
+++ b/components/script/dom/node.rs
@@ -28,6 +28,7 @@ use js::rust::HandleObject;
use libc::{self, c_void, uintptr_t};
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
use pixels::{Image, ImageMetadata};
+use script_bindings::codegen::InheritTypes::DocumentFragmentTypeId;
use script_layout_interface::{
GenericLayoutData, HTMLCanvasData, HTMLMediaData, LayoutElementType, LayoutNodeType, QueryMsg,
SVGSVGData, StyleData, TrustedNodeAddress,
@@ -71,7 +72,6 @@ use crate::dom::bindings::codegen::Bindings::ShadowRootBinding::{
ShadowRootMode, SlotAssignmentMode,
};
use crate::dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
-use crate::dom::bindings::codegen::InheritTypes::DocumentFragmentTypeId;
use crate::dom::bindings::codegen::UnionTypes::NodeOrString;
use crate::dom::bindings::conversions::{self, DerivedFrom};
use crate::dom::bindings::error::{Error, ErrorResult, Fallible};
diff --git a/components/script/dom/permissions.rs b/components/script/dom/permissions.rs
index 0be136b8aff..ed611db79a8 100644
--- a/components/script/dom/permissions.rs
+++ b/components/script/dom/permissions.rs
@@ -95,7 +95,7 @@ impl Permissions {
let p = match promise {
Some(promise) => promise,
None => {
- let in_realm_proof = AlreadyInRealm::assert();
+ let in_realm_proof = AlreadyInRealm::assert::<crate::DomTypeHolder>();
Promise::new_in_current_realm(InRealm::Already(&in_realm_proof), can_gc)
},
};
diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs
index 0479f24fac8..4da445c20c6 100644
--- a/components/script/dom/window.rs
+++ b/components/script/dom/window.rs
@@ -57,6 +57,7 @@ use num_traits::ToPrimitive;
use profile_traits::ipc as ProfiledIpc;
use profile_traits::mem::ProfilerChan as MemProfilerChan;
use profile_traits::time::ProfilerChan as TimeProfilerChan;
+use script_bindings::interfaces::WindowHelpers;
use script_layout_interface::{
FragmentType, Layout, PendingImageState, QueryMsg, Reflow, ReflowGoal, ReflowRequest,
TrustedNodeAddress, combine_id_with_fragment_type,
@@ -3122,3 +3123,13 @@ unsafe extern "C" fn dump_js_stack(cx: *mut RawJSContext) {
DumpJSStack(cx, true, false, false);
}
}
+
+impl WindowHelpers for Window {
+ fn create_named_properties_object(
+ cx: JSContext,
+ proto: HandleObject,
+ object: MutableHandleObject,
+ ) {
+ Self::create_named_properties_object(cx, proto, object)
+ }
+}
diff --git a/components/script/realms.rs b/components/script/realms.rs
index 434aa93a0a2..1254b604b42 100644
--- a/components/script/realms.rs
+++ b/components/script/realms.rs
@@ -4,17 +4,18 @@
use js::jsapi::{GetCurrentRealmOrNull, JSAutoRealm};
+use crate::DomTypes;
use crate::dom::bindings::reflector::DomObject;
-use crate::dom::globalscope::GlobalScope;
+use crate::dom::globalscope::GlobalScopeHelpers;
use crate::script_runtime::JSContext;
pub(crate) struct AlreadyInRealm(());
impl AlreadyInRealm {
#![allow(unsafe_code)]
- pub(crate) fn assert() -> AlreadyInRealm {
+ pub(crate) fn assert<D: DomTypes>() -> AlreadyInRealm {
unsafe {
- assert!(!GetCurrentRealmOrNull(*GlobalScope::get_cx()).is_null());
+ assert!(!GetCurrentRealmOrNull(*D::GlobalScope::get_cx()).is_null());
}
AlreadyInRealm(())
}
@@ -55,9 +56,13 @@ impl InRealm<'_> {
}
}
-pub(crate) fn enter_realm(object: &impl DomObject) -> JSAutoRealm {
+pub(crate) fn enter_realm_generic<D: DomTypes>(object: &impl DomObject) -> JSAutoRealm {
JSAutoRealm::new(
- *GlobalScope::get_cx(),
+ *D::GlobalScope::get_cx(),
object.reflector().get_jsobject().get(),
)
}
+
+pub(crate) fn enter_realm(object: &impl DomObject) -> JSAutoRealm {
+ enter_realm_generic::<crate::DomTypeHolder>(object)
+}