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 http://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::FooBindings::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::FooBindings::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 the layout thread is accessing the DOM.
201 //!
202 //! Methods accessible to layout are implemented on `LayoutDom<Foo>` using
203 //! `LayoutFooHelpers` traits.
204 
205 #[macro_use]
206 pub mod macros;
207 
208 pub mod types {
209     #[cfg(not(target_env = "msvc"))]
210     include!(concat!(env!("OUT_DIR"), "/InterfaceTypes.rs"));
211     #[cfg(target_env = "msvc")]
212     include!(concat!(env!("OUT_DIR"), "/build/InterfaceTypes.rs"));
213 }
214 
215 pub mod abstractworker;
216 pub mod abstractworkerglobalscope;
217 pub mod activation;
218 pub mod attr;
219 pub mod beforeunloadevent;
220 pub mod bindings;
221 pub mod blob;
222 pub mod bluetooth;
223 pub mod bluetoothadvertisingevent;
224 pub mod bluetoothcharacteristicproperties;
225 pub mod bluetoothdevice;
226 pub mod bluetoothpermissionresult;
227 pub mod bluetoothremotegattcharacteristic;
228 pub mod bluetoothremotegattdescriptor;
229 pub mod bluetoothremotegattserver;
230 pub mod bluetoothremotegattservice;
231 pub mod bluetoothuuid;
232 pub mod canvasgradient;
233 pub mod canvaspattern;
234 pub mod canvasrenderingcontext2d;
235 pub mod characterdata;
236 pub mod client;
237 pub mod closeevent;
238 pub mod comment;
239 pub mod compositionevent;
240 pub mod console;
241 mod create;
242 pub mod crypto;
243 pub mod css;
244 pub mod cssconditionrule;
245 pub mod cssfontfacerule;
246 pub mod cssgroupingrule;
247 pub mod cssimportrule;
248 pub mod csskeyframerule;
249 pub mod csskeyframesrule;
250 pub mod cssmediarule;
251 pub mod cssnamespacerule;
252 pub mod cssrule;
253 pub mod cssrulelist;
254 pub mod cssstyledeclaration;
255 pub mod cssstylerule;
256 pub mod cssstylesheet;
257 pub mod cssstylevalue;
258 pub mod csssupportsrule;
259 pub mod cssviewportrule;
260 pub mod customelementregistry;
261 pub mod customevent;
262 pub mod dedicatedworkerglobalscope;
263 pub mod dissimilaroriginlocation;
264 pub mod dissimilaroriginwindow;
265 pub mod document;
266 pub mod documentfragment;
267 pub mod documenttype;
268 pub mod domexception;
269 pub mod domimplementation;
270 pub mod dommatrix;
271 pub mod dommatrixreadonly;
272 pub mod domparser;
273 pub mod dompoint;
274 pub mod dompointreadonly;
275 pub mod domquad;
276 pub mod domrect;
277 pub mod domrectreadonly;
278 pub mod domstringmap;
279 pub mod domtokenlist;
280 pub mod element;
281 pub mod errorevent;
282 pub mod event;
283 pub mod eventsource;
284 pub mod eventtarget;
285 pub mod extendableevent;
286 pub mod extendablemessageevent;
287 pub mod file;
288 pub mod filelist;
289 pub mod filereader;
290 pub mod filereadersync;
291 pub mod focusevent;
292 pub mod formdata;
293 pub mod gamepad;
294 pub mod gamepadbutton;
295 pub mod gamepadbuttonlist;
296 pub mod gamepadevent;
297 pub mod gamepadlist;
298 pub mod globalscope;
299 pub mod hashchangeevent;
300 pub mod headers;
301 pub mod history;
302 pub mod htmlanchorelement;
303 pub mod htmlareaelement;
304 pub mod htmlaudioelement;
305 pub mod htmlbaseelement;
306 pub mod htmlbodyelement;
307 pub mod htmlbrelement;
308 pub mod htmlbuttonelement;
309 pub mod htmlcanvaselement;
310 pub mod htmlcollection;
311 pub mod htmldataelement;
312 pub mod htmldatalistelement;
313 pub mod htmldetailselement;
314 pub mod htmldialogelement;
315 pub mod htmldirectoryelement;
316 pub mod htmldivelement;
317 pub mod htmldlistelement;
318 pub mod htmlelement;
319 pub mod htmlembedelement;
320 pub mod htmlfieldsetelement;
321 pub mod htmlfontelement;
322 pub mod htmlformcontrolscollection;
323 pub mod htmlformelement;
324 pub mod htmlframeelement;
325 pub mod htmlframesetelement;
326 pub mod htmlheadelement;
327 pub mod htmlheadingelement;
328 pub mod htmlhrelement;
329 pub mod htmlhtmlelement;
330 pub mod htmliframeelement;
331 pub mod htmlimageelement;
332 pub mod htmlinputelement;
333 pub mod htmllabelelement;
334 pub mod htmllegendelement;
335 pub mod htmllielement;
336 pub mod htmllinkelement;
337 pub mod htmlmapelement;
338 pub mod htmlmediaelement;
339 pub mod htmlmetaelement;
340 pub mod htmlmeterelement;
341 pub mod htmlmodelement;
342 pub mod htmlobjectelement;
343 pub mod htmlolistelement;
344 pub mod htmloptgroupelement;
345 pub mod htmloptionelement;
346 pub mod htmloptionscollection;
347 pub mod htmloutputelement;
348 pub mod htmlparagraphelement;
349 pub mod htmlparamelement;
350 pub mod htmlpictureelement;
351 pub mod htmlpreelement;
352 pub mod htmlprogresselement;
353 pub mod htmlquoteelement;
354 pub mod htmlscriptelement;
355 pub mod htmlselectelement;
356 pub mod htmlsourceelement;
357 pub mod htmlspanelement;
358 pub mod htmlstyleelement;
359 pub mod htmltablecaptionelement;
360 pub mod htmltablecellelement;
361 pub mod htmltablecolelement;
362 pub mod htmltabledatacellelement;
363 pub mod htmltableelement;
364 pub mod htmltableheadercellelement;
365 pub mod htmltablerowelement;
366 pub mod htmltablesectionelement;
367 pub mod htmltemplateelement;
368 pub mod htmltextareaelement;
369 pub mod htmltimeelement;
370 pub mod htmltitleelement;
371 pub mod htmltrackelement;
372 pub mod htmlulistelement;
373 pub mod htmlunknownelement;
374 pub mod htmlvideoelement;
375 pub mod imagedata;
376 pub mod inputevent;
377 pub mod keyboardevent;
378 pub mod location;
379 pub mod mediaerror;
380 pub mod medialist;
381 pub mod mediaquerylist;
382 pub mod mediaquerylistevent;
383 pub mod messageevent;
384 pub mod mimetype;
385 pub mod mimetypearray;
386 pub mod mouseevent;
387 pub mod mutationobserver;
388 pub mod mutationrecord;
389 pub mod namednodemap;
390 pub mod navigator;
391 pub mod navigatorinfo;
392 pub mod node;
393 pub mod nodeiterator;
394 pub mod nodelist;
395 pub mod pagetransitionevent;
396 pub mod paintrenderingcontext2d;
397 pub mod paintsize;
398 pub mod paintworkletglobalscope;
399 pub mod performance;
400 pub mod performanceentry;
401 pub mod performancemark;
402 pub mod performancemeasure;
403 pub mod performanceobserver;
404 pub mod performanceobserverentrylist;
405 pub mod performancepainttiming;
406 pub mod performancetiming;
407 pub mod permissions;
408 pub mod permissionstatus;
409 pub mod plugin;
410 pub mod pluginarray;
411 pub mod popstateevent;
412 pub mod processinginstruction;
413 pub mod progressevent;
414 pub mod promise;
415 pub mod promisenativehandler;
416 pub mod radionodelist;
417 pub mod range;
418 pub mod request;
419 pub mod response;
420 pub mod screen;
421 pub mod serviceworker;
422 pub mod serviceworkercontainer;
423 pub mod serviceworkerglobalscope;
424 pub mod serviceworkerregistration;
425 pub mod servoparser;
426 pub mod storage;
427 pub mod storageevent;
428 pub mod stylepropertymapreadonly;
429 pub mod stylesheet;
430 pub mod stylesheetlist;
431 pub mod svgelement;
432 pub mod svggraphicselement;
433 pub mod svgsvgelement;
434 pub mod testbinding;
435 pub mod testbindingiterable;
436 pub mod testbindingpairiterable;
437 pub mod testbindingproxy;
438 pub mod testrunner;
439 pub mod testworklet;
440 pub mod testworkletglobalscope;
441 pub mod text;
442 pub mod textcontrol;
443 pub mod textdecoder;
444 pub mod textencoder;
445 pub mod touch;
446 pub mod touchevent;
447 pub mod touchlist;
448 pub mod transitionevent;
449 pub mod treewalker;
450 pub mod uievent;
451 pub mod url;
452 pub mod urlhelper;
453 pub mod urlsearchparams;
454 pub mod userscripts;
455 pub mod validation;
456 pub mod validitystate;
457 pub mod values;
458 pub mod virtualmethods;
459 pub mod vr;
460 pub mod vrdisplay;
461 pub mod vrdisplaycapabilities;
462 pub mod vrdisplayevent;
463 pub mod vreyeparameters;
464 pub mod vrfieldofview;
465 pub mod vrframedata;
466 pub mod vrpose;
467 pub mod vrstageparameters;
468 pub mod webgl_extensions;
469 pub use self::webgl_extensions::ext::*;
470 pub mod webgl2renderingcontext;
471 pub mod webgl_validations;
472 pub mod webglactiveinfo;
473 pub mod webglbuffer;
474 pub mod webglcontextevent;
475 pub mod webglframebuffer;
476 pub mod webglobject;
477 pub mod webglprogram;
478 pub mod webglrenderbuffer;
479 pub mod webglrenderingcontext;
480 pub mod webglshader;
481 pub mod webglshaderprecisionformat;
482 pub mod webgltexture;
483 pub mod webgluniformlocation;
484 pub mod websocket;
485 pub mod window;
486 pub mod windowproxy;
487 pub mod worker;
488 pub mod workerglobalscope;
489 pub mod workerlocation;
490 pub mod workernavigator;
491 pub mod worklet;
492 pub mod workletglobalscope;
493 pub mod xmldocument;
494 pub mod xmlhttprequest;
495 pub mod xmlhttprequesteventtarget;
496 pub mod xmlhttprequestupload;
497