script/dom/
mod.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
5//! The implementation of the DOM.
6//!
7//! The DOM is comprised of interfaces (defined by specifications using
8//! [WebIDL](https://heycam.github.io/webidl/)) that are implemented as Rust
9//! structs in submodules of this module. Its implementation is documented
10//! below.
11//!
12//! A DOM object and its reflector
13//! ==============================
14//!
15//! The implementation of an interface `Foo` in Servo's DOM involves two
16//! related but distinct objects:
17//!
18//! * the **DOM object**: an instance of the Rust struct `dom::foo::Foo`
19//!   (marked with the `#[dom_struct]` attribute) on the Rust heap;
20//! * the **reflector**: a `JSObject` allocated by SpiderMonkey, that owns the
21//!   DOM object.
22//!
23//! Memory management
24//! =================
25//!
26//! Reflectors of DOM objects, and thus the DOM objects themselves, are managed
27//! by the SpiderMonkey Garbage Collector. Thus, keeping alive a DOM object
28//! is done through its reflector.
29//!
30//! For more information, see:
31//!
32//! * rooting pointers on the stack:
33//!   the [`Root`](bindings/root/struct.Root.html) smart pointer;
34//! * tracing pointers in member fields: the [`Dom`](bindings/root/struct.Dom.html),
35//!   [`MutNullableDom`](bindings/root/struct.MutNullableDom.html) and
36//!   [`MutDom`](bindings/root/struct.MutDom.html) smart pointers and
37//!   [the tracing implementation](bindings/trace/index.html);
38//! * rooting pointers from across thread boundaries or in channels: the
39//!   [`Trusted`](bindings/refcounted/struct.Trusted.html) smart pointer;
40//!
41//! Inheritance
42//! ===========
43//!
44//! Rust does not support struct inheritance, as would be used for the
45//! object-oriented DOM APIs. To work around this issue, Servo stores an
46//! instance of the superclass in the first field of its subclasses. (Note that
47//! it is stored by value, rather than in a smart pointer such as `Dom<T>`.)
48//!
49//! This implies that a pointer to an object can safely be cast to a pointer
50//! to all its classes.
51//!
52//! This invariant is enforced by the lint in
53//! `plugins::lints::inheritance_integrity`.
54//!
55//! Interfaces which either derive from or are derived by other interfaces
56//! implement the `Castable` trait, which provides three methods `is::<T>()`,
57//! `downcast::<T>()` and `upcast::<T>()` to cast across the type hierarchy
58//! and check whether a given instance is of a given type.
59//!
60//! ```ignore
61//! use dom::bindings::inheritance::Castable;
62//! use dom::element::Element;
63//! use dom::htmlelement::HTMLElement;
64//! use dom::htmlinputelement::HTMLInputElement;
65//!
66//! if let Some(elem) = node.downcast::<Element> {
67//!     if elem.is::<HTMLInputElement>() {
68//!         return elem.upcast::<HTMLElement>();
69//!     }
70//! }
71//! ```
72//!
73//! Furthermore, when discriminating a given instance against multiple
74//! interface types, code generation provides a convenient TypeId enum
75//! which can be used to write `match` expressions instead of multiple
76//! calls to `Castable::is::<T>`. The `type_id()` method of an instance is
77//! provided by the farthest interface it derives from, e.g. `EventTarget`
78//! for `HTMLMediaElement`. For convenience, that method is also provided
79//! on the `Node` interface to avoid unnecessary upcasts to `EventTarget`.
80//!
81//! ```ignore
82//! use dom::bindings::inheritance::{EventTargetTypeId, NodeTypeId};
83//!
84//! match *node.type_id() {
85//!     EventTargetTypeId::Node(NodeTypeId::CharacterData(_)) => ...,
86//!     EventTargetTypeId::Node(NodeTypeId::Element(_)) => ...,
87//!     ...,
88//! }
89//! ```
90//!
91//! Construction
92//! ============
93//!
94//! DOM objects of type `T` in Servo have two constructors:
95//!
96//! * a `T::new_inherited` static method that returns a plain `T`, and
97//! * a `T::new` static method that returns `DomRoot<T>`.
98//!
99//! (The result of either method can be wrapped in `Result`, if that is
100//! appropriate for the type in question.)
101//!
102//! The latter calls the former, boxes the result, and creates a reflector
103//! corresponding to it by calling `dom::bindings::utils::reflect_dom_object`
104//! (which yields ownership of the object to the SpiderMonkey Garbage Collector).
105//! This is the API to use when creating a DOM object.
106//!
107//! The former should only be called by the latter, and by subclasses'
108//! `new_inherited` methods.
109//!
110//! DOM object constructors in JavaScript correspond to a `T::Constructor`
111//! static method. This method is always fallible.
112//!
113//! Destruction
114//! ===========
115//!
116//! When the SpiderMonkey Garbage Collector discovers that the reflector of a
117//! DOM object is garbage, it calls the reflector's finalization hook. This
118//! function deletes the reflector's DOM object, calling its destructor in the
119//! process.
120//!
121//! Mutability and aliasing
122//! =======================
123//!
124//! Reflectors are JavaScript objects, and as such can be freely aliased. As
125//! Rust does not allow mutable aliasing, mutable borrows of DOM objects are
126//! not allowed. In particular, any mutable fields use `Cell` or `DomRefCell`
127//! to manage their mutability.
128//!
129//! `Reflector` and `DomObject`
130//! =============================
131//!
132//! Every DOM object has a `Reflector` as its first (transitive) member field.
133//! This contains a `*mut JSObject` that points to its reflector.
134//!
135//! The `FooBinding::Wrap` function creates the reflector, stores a pointer to
136//! the DOM object in the reflector, and initializes the pointer to the reflector
137//! in the `Reflector` field.
138//!
139//! The `DomObject` trait provides a `reflector()` method that returns the
140//! DOM object's `Reflector`. It is implemented automatically for DOM structs
141//! through the `#[dom_struct]` attribute.
142//!
143//! Implementing methods for a DOM object
144//! =====================================
145//!
146//! * `dom::bindings::codegen::Bindings::FooBinding::FooMethods` for methods
147//!   defined through IDL;
148//! * `&self` public methods for public helpers;
149//! * `&self` methods for private helpers.
150//!
151//! Accessing fields of a DOM object
152//! ================================
153//!
154//! All fields of DOM objects are private; accessing them from outside their
155//! module is done through explicit getter or setter methods.
156//!
157//! Inheritance and casting
158//! =======================
159//!
160//! All DOM interfaces part of an inheritance chain (i.e. interfaces
161//! that derive others or are derived from) implement the trait `Castable`
162//! which provides both downcast and upcasts.
163//!
164//! ```ignore
165//! # use script::dom::bindings::inheritance::Castable;
166//! # use script::dom::element::Element;
167//! # use script::dom::node::Node;
168//! # use script::dom::htmlelement::HTMLElement;
169//! fn f(element: &Element) {
170//!     let base = element.upcast::<Node>();
171//!     let derived = element.downcast::<HTMLElement>().unwrap();
172//! }
173//! ```
174//!
175//! Adding a new DOM interface
176//! ==========================
177//!
178//! Adding a new interface `Foo` requires at least the following:
179//!
180//! * adding the new IDL file at `components/script/dom/webidls/Foo.webidl`;
181//! * creating `components/script/dom/foo.rs`;
182//! * listing `foo.rs` in `components/script/dom/mod.rs`;
183//! * defining the DOM struct `Foo` with a `#[dom_struct]` attribute, a
184//!   superclass or `Reflector` member, and other members as appropriate;
185//! * implementing the
186//!   `dom::bindings::codegen::Bindings::FooBinding::FooMethods` trait for
187//!   `Foo`;
188//! * adding/updating the match arm in create_element in
189//!   `components/script/dom/create.rs` (only applicable to new types inheriting
190//!   from `HTMLElement`)
191//!
192//! More information is available in the [bindings module](bindings/index.html).
193//!
194//! Accessing DOM objects from layout
195//! =================================
196//!
197//! Layout code can access the DOM through the
198//! [`LayoutDom`](bindings/root/struct.LayoutDom.html) smart pointer. This does not
199//! keep the DOM object alive; we ensure that no DOM code (Garbage Collection
200//! in particular) runs while layout is accessing the DOM.
201//!
202//! Methods accessible to layout are implemented on `LayoutDom<Foo>` using
203//! `LayoutFooHelpers` traits.
204
205#[macro_use]
206pub(crate) mod macros;
207
208#[allow(unused_imports)]
209pub(crate) mod types {
210    include!(concat!(env!("OUT_DIR"), "/InterfaceTypes.rs"));
211}
212
213pub(crate) mod abortcontroller;
214pub(crate) mod abortsignal;
215#[allow(dead_code)]
216pub(crate) mod abstractrange;
217pub(crate) mod abstractworker;
218pub(crate) mod abstractworkerglobalscope;
219pub(crate) mod activation;
220pub(crate) mod animationevent;
221pub(crate) mod attr;
222pub(crate) mod audio;
223pub(crate) use self::audio::*;
224pub(crate) mod beforeunloadevent;
225pub(crate) mod bindings;
226pub(crate) mod blob;
227#[cfg(feature = "bluetooth")]
228pub(crate) mod bluetooth;
229#[cfg(feature = "bluetooth")]
230pub(crate) use self::bluetooth::*;
231pub(crate) mod broadcastchannel;
232pub(crate) mod bytelengthqueuingstrategy;
233mod canvas;
234pub(crate) use self::canvas::*;
235pub(crate) mod cdatasection;
236pub(crate) mod characterdata;
237pub(crate) mod client;
238pub(crate) mod clipboard;
239pub(crate) mod clipboardevent;
240pub(crate) mod clipboarditem;
241pub(crate) mod closeevent;
242pub(crate) mod comment;
243pub(crate) mod compositionevent;
244pub(crate) mod console;
245pub(crate) mod cookiestore;
246pub(crate) mod countqueuingstrategy;
247mod create;
248pub(crate) mod credentialmanagement;
249pub(crate) use self::credentialmanagement::*;
250pub(crate) mod crypto;
251pub(crate) mod cryptokey;
252pub(crate) mod csp;
253pub(crate) mod csppolicyviolationreport;
254pub(crate) mod css;
255pub(crate) mod cssconditionrule;
256pub(crate) mod cssfontfacerule;
257pub(crate) mod cssgroupingrule;
258pub(crate) mod cssimportrule;
259pub(crate) mod csskeyframerule;
260pub(crate) mod csskeyframesrule;
261pub(crate) mod csslayerblockrule;
262pub(crate) mod csslayerstatementrule;
263pub(crate) mod cssmediarule;
264pub(crate) mod cssnamespacerule;
265pub(crate) mod cssnesteddeclarations;
266pub(crate) mod cssrule;
267pub(crate) mod cssrulelist;
268pub(crate) mod cssstyledeclaration;
269pub(crate) mod cssstylerule;
270pub(crate) mod cssstylesheet;
271pub(crate) mod cssstylevalue;
272pub(crate) mod csssupportsrule;
273pub(crate) mod customelementregistry;
274pub(crate) mod customevent;
275pub(crate) mod customstateset;
276pub(crate) mod datatransfer;
277pub(crate) mod datatransferitem;
278pub(crate) mod datatransferitemlist;
279pub(crate) mod debuggeradddebuggeeevent;
280pub(crate) mod debuggergetpossiblebreakpointsevent;
281pub(crate) mod debuggerglobalscope;
282pub(crate) mod dedicatedworkerglobalscope;
283pub(crate) mod defaultteereadrequest;
284pub(crate) mod defaultteeunderlyingsource;
285pub(crate) mod dissimilaroriginlocation;
286pub(crate) mod dissimilaroriginwindow;
287#[allow(dead_code)]
288pub(crate) mod document;
289pub(crate) mod document_event_handler;
290pub(crate) mod documentfragment;
291pub(crate) mod documentorshadowroot;
292pub(crate) mod documenttype;
293pub(crate) mod domexception;
294pub(crate) mod domimplementation;
295pub(crate) mod dommatrix;
296pub(crate) mod dommatrixreadonly;
297pub(crate) mod domparser;
298pub(crate) mod dompoint;
299pub(crate) mod dompointreadonly;
300pub(crate) mod domquad;
301pub(crate) mod domrect;
302pub(crate) mod domrectlist;
303pub(crate) mod domrectreadonly;
304pub(crate) mod domstringlist;
305pub(crate) mod domstringmap;
306pub(crate) mod domtokenlist;
307pub(crate) mod dynamicmoduleowner;
308#[allow(dead_code)]
309pub(crate) mod element;
310pub(crate) mod elementinternals;
311pub(crate) mod errorevent;
312pub(crate) mod event;
313pub(crate) mod eventsource;
314pub(crate) mod eventtarget;
315pub(crate) mod extendableevent;
316pub(crate) mod extendablemessageevent;
317pub(crate) mod file;
318pub(crate) mod filelist;
319pub(crate) mod filereader;
320pub(crate) mod filereadersync;
321pub(crate) mod focusevent;
322pub(crate) mod fontface;
323pub(crate) mod fontfaceset;
324pub(crate) mod formdata;
325pub(crate) mod formdataevent;
326pub(crate) mod gamepad;
327pub(crate) use self::gamepad::*;
328#[allow(dead_code)]
329pub(crate) mod globalscope;
330pub(crate) mod hashchangeevent;
331pub(crate) mod headers;
332pub(crate) mod history;
333pub(crate) mod html;
334pub(crate) use self::html::*;
335pub(crate) mod idbcursor;
336pub(crate) mod idbcursorwithvalue;
337pub(crate) mod idbdatabase;
338pub(crate) mod idbfactory;
339pub(crate) mod idbindex;
340pub(crate) mod idbkeyrange;
341pub(crate) mod idbobjectstore;
342pub(crate) mod idbopendbrequest;
343pub(crate) mod idbrequest;
344pub(crate) mod idbtransaction;
345pub(crate) mod idbversionchangeevent;
346pub(crate) mod inputevent;
347pub(crate) mod intersectionobserver;
348pub(crate) mod intersectionobserverentry;
349pub(crate) mod keyboardevent;
350pub(crate) mod linkprocessingoptions;
351pub(crate) mod location;
352pub(crate) mod mediadeviceinfo;
353pub(crate) mod mediadevices;
354pub(crate) mod mediaerror;
355pub(crate) mod mediafragmentparser;
356pub(crate) mod medialist;
357pub(crate) mod mediametadata;
358pub(crate) mod mediaquerylist;
359pub(crate) mod mediaquerylistevent;
360pub(crate) mod mediasession;
361pub(crate) mod mediastream;
362pub(crate) mod mediastreamtrack;
363pub(crate) mod messagechannel;
364pub(crate) mod messageevent;
365#[allow(dead_code)]
366pub(crate) mod messageport;
367pub(crate) mod mimetype;
368pub(crate) mod mimetypearray;
369pub(crate) mod mouseevent;
370pub(crate) mod mutationobserver;
371pub(crate) mod mutationrecord;
372pub(crate) mod namednodemap;
373pub(crate) mod navigationpreloadmanager;
374pub(crate) mod navigator;
375pub(crate) mod navigatorinfo;
376#[allow(dead_code)]
377pub(crate) mod node;
378pub(crate) mod nodeiterator;
379#[allow(dead_code)]
380pub(crate) mod nodelist;
381pub(crate) mod notification;
382pub(crate) mod pagetransitionevent;
383pub(crate) mod paintsize;
384pub(crate) mod paintworkletglobalscope;
385pub(crate) mod performance;
386#[allow(dead_code)]
387pub(crate) mod performanceentry;
388pub(crate) mod performancemark;
389pub(crate) mod performancemeasure;
390pub(crate) mod performancenavigation;
391pub(crate) mod performancenavigationtiming;
392#[allow(dead_code)]
393pub(crate) mod performanceobserver;
394pub(crate) mod performanceobserverentrylist;
395pub(crate) mod performancepainttiming;
396pub(crate) mod performanceresourcetiming;
397pub(crate) mod permissions;
398pub(crate) mod permissionstatus;
399pub(crate) mod pipelineid;
400pub(crate) mod plugin;
401pub(crate) mod pluginarray;
402#[allow(dead_code)]
403pub(crate) mod pointerevent;
404pub(crate) mod popstateevent;
405pub(crate) mod processinginstruction;
406pub(crate) mod progressevent;
407#[allow(dead_code)]
408pub(crate) mod promise;
409pub(crate) mod promisenativehandler;
410pub(crate) mod promiserejectionevent;
411pub(crate) mod quotaexceedederror;
412pub(crate) mod radionodelist;
413pub(crate) mod range;
414pub(crate) mod raredata;
415#[allow(dead_code)]
416pub(crate) mod readablebytestreamcontroller;
417pub(crate) mod readablestream;
418pub(crate) mod readablestreambyobreader;
419pub(crate) mod readablestreambyobrequest;
420pub(crate) mod readablestreamdefaultcontroller;
421pub(crate) mod readablestreamdefaultreader;
422pub(crate) mod readablestreamgenericreader;
423pub(crate) mod reportingendpoint;
424pub(crate) mod reportingobserver;
425pub(crate) mod request;
426pub(crate) mod resizeobserver;
427pub(crate) mod resizeobserverentry;
428pub(crate) mod resizeobserversize;
429pub(crate) mod response;
430pub(crate) mod screen;
431pub(crate) mod securitypolicyviolationevent;
432pub(crate) mod selection;
433#[allow(dead_code)]
434pub(crate) mod serviceworker;
435pub(crate) mod serviceworkercontainer;
436pub(crate) mod serviceworkerglobalscope;
437#[allow(dead_code)]
438pub(crate) mod serviceworkerregistration;
439pub(crate) mod servointernals;
440#[allow(dead_code)]
441pub(crate) mod servoparser;
442pub(crate) mod shadowroot;
443pub(crate) mod staticrange;
444pub(crate) mod storage;
445pub(crate) mod storageevent;
446pub(crate) mod stylepropertymapreadonly;
447pub(crate) mod stylesheet;
448pub(crate) mod stylesheetcontentscache;
449pub(crate) mod stylesheetlist;
450pub(crate) mod submitevent;
451pub(crate) mod subtlecrypto;
452pub(crate) mod svgelement;
453pub(crate) mod svggraphicselement;
454pub(crate) mod svgimageelement;
455pub(crate) mod svgsvgelement;
456#[cfg(feature = "testbinding")]
457pub(crate) mod testbinding;
458#[cfg(feature = "testbinding")]
459pub(crate) mod testbindingiterable;
460#[cfg(feature = "testbinding")]
461pub(crate) mod testbindingmaplikewithinterface;
462#[cfg(feature = "testbinding")]
463pub(crate) mod testbindingmaplikewithprimitive;
464#[cfg(feature = "testbinding")]
465pub(crate) mod testbindingpairiterable;
466#[cfg(feature = "testbinding")]
467pub(crate) mod testbindingproxy;
468#[cfg(feature = "testbinding")]
469pub(crate) mod testbindingsetlikewithinterface;
470#[cfg(feature = "testbinding")]
471pub(crate) mod testbindingsetlikewithprimitive;
472#[cfg(feature = "testbinding")]
473pub(crate) mod testns;
474#[cfg(feature = "testbinding")]
475pub(crate) mod testutils;
476#[cfg(feature = "testbinding")]
477pub(crate) mod testworklet;
478#[cfg(feature = "testbinding")]
479pub(crate) mod testworkletglobalscope;
480pub(crate) mod text;
481pub(crate) mod textcontrol;
482pub(crate) mod textdecoder;
483pub(crate) mod textdecodercommon;
484pub(crate) mod textdecoderstream;
485pub(crate) mod textencoder;
486pub(crate) mod textencoderstream;
487pub(crate) mod texttrack;
488pub(crate) mod texttrackcue;
489pub(crate) mod texttrackcuelist;
490pub(crate) mod texttracklist;
491#[allow(dead_code)]
492pub(crate) mod timeranges;
493pub(crate) mod touch;
494pub(crate) mod touchevent;
495pub(crate) mod touchlist;
496pub(crate) mod trackevent;
497pub(crate) mod transitionevent;
498pub(crate) mod treewalker;
499pub(crate) mod trustedhtml;
500pub(crate) mod trustedscript;
501pub(crate) mod trustedscripturl;
502pub(crate) mod trustedtypepolicy;
503pub(crate) mod trustedtypepolicyfactory;
504pub(crate) mod uievent;
505pub(crate) mod underlyingsourcecontainer;
506pub(crate) mod url;
507pub(crate) mod urlhelper;
508pub(crate) mod urlpattern;
509pub(crate) mod urlsearchparams;
510pub(crate) mod userscripts;
511pub(crate) mod validation;
512pub(crate) mod validitystate;
513pub(crate) mod values;
514pub(crate) mod videotrack;
515pub(crate) mod videotracklist;
516pub(crate) mod virtualmethods;
517pub(crate) mod visibilitystateentry;
518pub(crate) mod vttcue;
519pub(crate) mod vttregion;
520pub(crate) mod webgl;
521pub(crate) use self::webgl::extensions::ext::*;
522pub(crate) use self::webgl::*;
523pub(crate) mod websocket;
524#[cfg(feature = "webxr")]
525mod webxr;
526#[cfg(feature = "webxr")]
527pub(crate) use self::webxr::*;
528#[cfg(feature = "webgpu")]
529pub(crate) mod webgpu;
530#[cfg(feature = "webgpu")]
531pub(crate) use self::webgpu::*;
532#[cfg(not(feature = "webgpu"))]
533pub(crate) mod gpucanvascontext;
534pub(crate) mod webrtc;
535pub(crate) use self::webrtc::*;
536pub(crate) mod transformstream;
537pub(crate) mod transformstreamdefaultcontroller;
538pub(crate) mod wheelevent;
539#[allow(dead_code)]
540pub(crate) mod window;
541#[allow(dead_code)]
542pub(crate) mod windowproxy;
543pub(crate) mod worker;
544#[allow(dead_code)]
545pub(crate) mod workerglobalscope;
546pub(crate) mod workerlocation;
547pub(crate) mod workernavigator;
548pub(crate) mod worklet;
549pub(crate) mod workletglobalscope;
550pub(crate) mod writablestream;
551pub(crate) mod writablestreamdefaultcontroller;
552pub(crate) mod writablestreamdefaultwriter;
553pub(crate) mod xmldocument;
554pub(crate) mod xmlhttprequest;
555pub(crate) mod xmlhttprequesteventtarget;
556pub(crate) mod xmlhttprequestupload;
557pub(crate) mod xmlserializer;
558pub(crate) mod xpathevaluator;
559pub(crate) mod xpathexpression;
560pub(crate) mod xpathresult;