script_bindings/
reflector.rs1use js::jsapi::{Heap, JSObject};
6use js::rust::HandleObject;
7use malloc_size_of_derive::MallocSizeOf;
8
9use crate::interfaces::GlobalScopeHelpers;
10use crate::iterable::{Iterable, IterableIterator};
11use crate::realms::InRealm;
12use crate::root::{Dom, DomRoot, Root};
13use crate::script_runtime::{CanGc, JSContext};
14use crate::{DomTypes, JSTraceable};
15
16#[cfg_attr(crown, allow(crown::unrooted_must_root))]
18#[derive(MallocSizeOf)]
19#[cfg_attr(crown, crown::unrooted_must_root_lint::must_root)]
20pub struct Reflector {
22 #[ignore_malloc_size_of = "defined and measured in rust-mozjs"]
23 object: Heap<*mut JSObject>,
24}
25
26unsafe impl js::gc::Traceable for Reflector {
27 unsafe fn trace(&self, _: *mut js::jsapi::JSTracer) {}
28}
29
30#[cfg_attr(crown, allow(crown::unrooted_must_root))]
31impl PartialEq for Reflector {
32 fn eq(&self, other: &Reflector) -> bool {
33 self.object.get() == other.object.get()
34 }
35}
36
37impl Reflector {
38 #[inline]
40 pub fn get_jsobject(&self) -> HandleObject<'_> {
41 unsafe { HandleObject::from_raw(self.object.handle()) }
43 }
44
45 pub unsafe fn set_jsobject(&self, object: *mut JSObject) {
51 assert!(self.object.get().is_null());
52 assert!(!object.is_null());
53 self.object.set(object);
54 }
55
56 pub fn rootable(&self) -> &Heap<*mut JSObject> {
60 &self.object
61 }
62
63 #[allow(clippy::new_without_default)]
66 pub fn new() -> Reflector {
67 Reflector {
68 object: Heap::default(),
69 }
70 }
71}
72
73pub trait DomObject: js::gc::Traceable + 'static {
75 fn reflector(&self) -> &Reflector;
77}
78
79impl DomObject for Reflector {
80 fn reflector(&self) -> &Self {
81 self
82 }
83}
84
85pub trait MutDomObject: DomObject {
87 unsafe fn init_reflector(&self, obj: *mut JSObject);
93}
94
95impl MutDomObject for Reflector {
96 unsafe fn init_reflector(&self, obj: *mut JSObject) {
97 self.set_jsobject(obj)
98 }
99}
100
101pub trait DomGlobalGeneric<D: DomTypes>: DomObject {
102 fn global_(&self, realm: InRealm) -> DomRoot<D::GlobalScope>
106 where
107 Self: Sized,
108 {
109 D::GlobalScope::from_reflector(self, realm)
110 }
111}
112
113impl<D: DomTypes, T: DomObject> DomGlobalGeneric<D> for T {}
114
115pub trait DomObjectWrap<D: DomTypes>: Sized + DomObject + DomGlobalGeneric<D> {
117 #[allow(clippy::type_complexity)]
119 const WRAP: unsafe fn(
120 JSContext,
121 &D::GlobalScope,
122 Option<HandleObject>,
123 Box<Self>,
124 CanGc,
125 ) -> Root<Dom<Self>>;
126}
127
128pub trait DomObjectIteratorWrap<D: DomTypes>: DomObjectWrap<D> + JSTraceable + Iterable {
131 #[allow(clippy::type_complexity)]
133 const ITER_WRAP: unsafe fn(
134 JSContext,
135 &D::GlobalScope,
136 Option<HandleObject>,
137 Box<IterableIterator<D, Self>>,
138 CanGc,
139 ) -> Root<Dom<IterableIterator<D, Self>>>;
140}