Skip to main content

script_bindings/
interfaces.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use std::cell::RefCell;
6use std::ops::Deref;
7use std::thread::LocalKey;
8
9use js::context::JSContext;
10use js::conversions::{FromJSValConvertible, ToJSValConvertible};
11use js::gc::Traceable;
12use js::glue::JSPrincipalsCallbacks;
13use js::jsapi::{CallArgs, JSObject};
14use js::realm::CurrentRealm;
15use js::rust::{HandleObject, MutableHandleObject};
16use malloc_size_of::MallocSizeOf;
17use servo_base::id::PipelineId;
18use servo_constellation_traits::ScriptToConstellationChan;
19use servo_url::{MutableOrigin, ServoUrl};
20
21use crate::DomTypes;
22use crate::codegen::PrototypeList;
23use crate::conversions::DerivedFrom;
24use crate::error::Error;
25use crate::reflector::{DomObject, DomObjectWrap};
26use crate::root::DomRoot;
27use crate::settings_stack::StackEntry;
28use crate::utils::ProtoOrIfaceArray;
29
30/// Operations that can be invoked for a WebIDL interface against
31/// a global object.
32///
33/// <https://github.com/mozilla/gecko-dev/blob/3fd619f47/dom/bindings/WebIDLGlobalNameHash.h#L24>
34pub struct Interface {
35    /// Define the JS object for this interface on the given global.
36    pub define: fn(&mut JSContext, HandleObject),
37    /// Returns true if this interface's conditions are met for the given global.
38    pub enabled: fn(&mut JSContext, HandleObject) -> bool,
39}
40
41/// Operations that must be invoked from the generated bindings.
42pub trait DomHelpers<D: DomTypes> {
43    fn throw_dom_exception(cx: &mut JSContext, global: &D::GlobalScope, result: Error);
44
45    fn call_html_constructor<T: DerivedFrom<D::Element> + DomObject>(
46        cx: &mut JSContext,
47        args: &CallArgs,
48        global: &D::GlobalScope,
49        proto_id: PrototypeList::ID,
50        creator: unsafe fn(&mut JSContext, HandleObject, *mut ProtoOrIfaceArray),
51    ) -> bool;
52
53    fn settings_stack() -> &'static LocalKey<RefCell<Vec<StackEntry<D>>>>;
54
55    fn principals_callbacks() -> &'static JSPrincipalsCallbacks;
56
57    fn interface_map() -> &'static phf::Map<&'static [u8], Interface>;
58
59    fn push_new_element_queue();
60    fn pop_current_element_queue(cx: &mut JSContext);
61
62    fn reflect_dom_object_with_cx<T, U>(cx: &mut JSContext, obj: Box<T>, global: &U) -> DomRoot<T>
63    where
64        T: DomObject + DomObjectWrap<D>,
65        U: DerivedFrom<D::GlobalScope>;
66
67    fn report_pending_exception(cx: &mut CurrentRealm);
68}
69
70/// Operations that must be invoked from the generated bindings.
71#[expect(unsafe_code)]
72pub trait GlobalScopeHelpers<D: DomTypes>: DomObject + Sized {
73    fn from_current_realm(realm: &'_ mut CurrentRealm) -> DomRoot<D::GlobalScope>;
74
75    /// # Safety
76    /// `obj` must point to a valid, non-null JSObject.
77    unsafe fn from_object(obj: *mut JSObject) -> DomRoot<D::GlobalScope>;
78    fn from_reflector(reflector: &impl DomObject) -> DomRoot<D::GlobalScope>;
79
80    fn origin(&self) -> MutableOrigin;
81
82    fn incumbent() -> Option<DomRoot<D::GlobalScope>>;
83
84    fn perform_a_microtask_checkpoint(&self, cx: &mut JSContext);
85
86    fn get_url(&self) -> ServoUrl;
87
88    fn is_secure_context(&self) -> bool;
89
90    fn pipeline_id(&self) -> PipelineId;
91
92    fn script_to_constellation_chan(&self) -> ScriptToConstellationChan;
93    fn entry() -> DomRoot<Self>;
94}
95
96pub trait HeapTracedPromiseHelpers<D: DomTypes> {
97    type StackRoot;
98    fn root(&self, cx: &JSContext) -> Self::StackRoot;
99}
100
101pub trait StackRootPromiseHelpers<D: DomTypes> {
102    type HeapTraced;
103    fn to_traced(&self) -> Self::HeapTraced;
104}
105
106pub trait PromiseHelpers<D: DomTypes> {
107    type StackRoot: FromJSValConvertible<Config = ()>
108        + ToJSValConvertible
109        + Deref<Target = D::Promise>
110        + StackRootPromiseHelpers<D, HeapTraced = Self::HeapTraced>;
111    type HeapTraced: Traceable
112        + MallocSizeOf
113        + Deref<Target = D::Promise>
114        + HeapTracedPromiseHelpers<D, StackRoot = Self::StackRoot>;
115    fn new_in_realm(cx: &mut CurrentRealm) -> Self::StackRoot;
116    fn new(cx: &mut JSContext, global: &D::GlobalScope) -> Self::StackRoot;
117    fn reject_error(&self, cx: &mut JSContext, error: Error);
118    fn is_rejected(&self) -> bool;
119    fn is_pending(&self) -> bool;
120    fn is_fulfilled(&self) -> bool;
121    fn resolve_native<T: ToJSValConvertible>(&self, cx: &mut JSContext, val: &T);
122    fn reject_native<T: ToJSValConvertible>(&self, cx: &mut JSContext, val: &T);
123}
124
125pub trait DocumentHelpers {
126    fn ensure_safe_to_run_script_or_layout(&self);
127}
128
129pub trait ServoInternalsHelpers {
130    fn is_servo_internal(cx: &mut JSContext, global: HandleObject) -> bool;
131}
132
133pub trait TestBindingHelpers {
134    fn condition_satisfied(cx: &mut JSContext, global: HandleObject) -> bool;
135    fn condition_unsatisfied(cx: &mut JSContext, global: HandleObject) -> bool;
136}
137
138pub trait WebGL2RenderingContextHelpers {
139    fn is_webgl2_enabled(cx: &mut JSContext, global: HandleObject) -> bool;
140}
141
142pub trait WindowHelpers {
143    fn create_named_properties_object(
144        cx: &mut JSContext,
145        proto: HandleObject,
146        object: MutableHandleObject,
147    );
148}
149
150pub trait HasOrigin {
151    fn origin(&self) -> MutableOrigin;
152}