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