1[![Latest Stable Version]](https://packagist.org/packages/wikimedia/idle-dom) [![License]](https://packagist.org/packages/wikimedia/idle-dom) 2 3[![Run on Repl.it](https://repl.it/badge/github/wikimedia/mediawiki-libs-idledom)](https://repl.it/github/wikimedia/mediawiki-libs-idledom) 4 5IDLeDOM 6===================== 7 8IDLeDOM is a set of PHP interfaces for the [WHATWG DOM spec](https://dom.spec.whatwg.org/) 9automatically generated from the [WebIDL](https://heycam.github.io/webidl/) sources in the spec, 10using a [PHP binding for WebIDL](./WebIDL.md). 11 12The PHP binding is described in [WebIDL.md](./WebIDL.md). It is 13intended to be largely compatible with the ad hoc binding used for the 14PHP built-in [DOM 15extension](https://www.php.net/manual/en/book.dom.php). Explicit 16getter and setter functions are used for attributes, but PHP [magic 17methods](https://www.php.net/manual/en/language.oop5.magic.php) are 18used to allow property-style access. The best performance will be 19obtained by using the explicit getters and setters, however. 20 21IDLeDOM is *not* a DOM implementation, it is only a set of interfaces. 22An actual DOM implementation, like 23[`mediawiki/dodo`](https://packagist.org/packages/wikimedia/dodo) will 24implement the interfaces defined by IDLeDOM. Client code can be 25written to work with any DOM implementation which follows the IDLeDOM 26PHP binding for WebIDL. 27 28IDLeDOM does contain stubs and helper traits which can greatly aid a 29DOM implementation. Including stub traits in your DOM implementation 30will ensure that new methods added to IDLeDOM will be stubbed out by 31default (throwing a user-defined exception), instead of breaking your 32implementation due to new unimplemented interface methods. Including 33the helper traits in your DOM implementation will provide 34implementations of certain PHP magic methods and IDL "attribute 35reflection" attributes. 36 37Additional documentation about the library can be found on 38[MediaWiki.org](https://www.mediawiki.org/wiki/IDLeDOM). 39 40Install 41------- 42 43This package is [available on Packagist](https://packagist.org/packages/wikimedia/idle-dom): 44 45```bash 46$ composer require wikimedia/idle-dom 47``` 48 49Usage 50----- 51 52Use the interface types in `Wikimedia\IDLeDOM\` when you wish to be 53compatible with any PHP DOM implementation. For example, assuming 54your DOM implementation gives you an object implementing 55`Wikimedia\IDLeDOM\DOMImplementation`, called `$domImpl`: 56 57```php 58$doc = $domImpl->createHTMLDocument( 'My HTML Document ); 59$doc->getBody()->setInnerHTML( '<p>Whee!!</p> ); 60// This is equivalent, but slightly slower: 61$doc->body->innerHTML = '<p>Whee!!</p>'; 62 63// Use the interface type in type hints for max compatibility 64$f = function( \Wikimedia\IDLeDOM\Document $doc ): string { 65 return $doc->getTitle(); // or $doc->title 66}; 67``` 68 69Writing a new DOM implementation 70-------------------------------- 71 72To write a new DOM implementation you will be implementing the 73interface types in `Wikimedia\IDLeDOM`. This library provides 74two traits for most interfaces in order to ease the task: 75 761. The helper trait in `Wikimedia\IDLeDOM\Helper` will implement the 77magic `__get` and `__set` methods for interfaces and dictionaries, 78`ArrayAccess` methods for dictionaries, the magic `__invoke` method 79for callback classes, and `cast` methods for callbacks and 80dictionaries to turn a `callable` and associative-array, respectively, 81into the proper callback or dictionary type. The helper will 82implement `Countable` and `IteratorAggregate` where appropriate. For 83IDL interfaces which reflect Element attributes, the helper class will 84also implement these reflected interface attributes in terms of 85`Element::getAttribute()`, `Element::hasAttribute()`, and 86`Element::setAttribute()` calls. 87 882. The stub trait in `Wikimedia\IDLeDOM\Stub` will stub out all 89methods of the interface by implementing them to throw the 90exception returned by `::_unimplemented()` (which can be your 91own subclass of `DOMException` or whatever you like). This 92helps bootstrap a DOM implementation and ensures that new 93methods can be added to the DOM spec, and by extension to the 94`IDLeDOM` interfaces, without breaking code which implements 95these interfaces. 96 97Putting these together, the first few lines of a typical 98DOM implementation will look something like this: 99 100```php 101// Your implementations of DOM mixins are traits, like this: 102trait NonElementParentNode /* implements \Wikimedia\IDLeDOM\NonElementParentNode */ { 103 use \Wikimedia\IDLeDOM\Stub\NonElementParentNode; 104 105 // Your code here... 106} 107 108// DOM interfaces are classes: 109class Document extends Node implements \Wikimedia\IDLeDOM\Document { 110 // DOM mixins: these are your code, but they include 111 // the appropriate IDLeDOM stubs 112 use DocumentOrShadowRoot; 113 use NonElementParentNode; 114 use ParentNode; 115 use XPathEvaluatorBase; 116 117 // Stub out methods not yet implemented. 118 use \Wikimedia\IDLeDOM\Stub\Document; 119 120 // Helper functions from IDLeDOM 121 // (Note that the Document helper will also include reflected 122 // attribute accessors for the mixin classes; you don't need 123 // to include helper traits in your implementations of DOM mixins) 124 use \Wikimedia\IDLeDOM\Helper\Document; 125 126 protected function _unimplemented() : \Exception { 127 return new UnimplementedException(); // your own exception type 128 } 129 130 // Your code here... 131} 132``` 133 134Hacking on IDLeDOM 135------------------ 136 137To regenerate the interfaces in `src/` from the WebIDL sources in `spec/`: 138 139 composer build 140 141To run tests: 142 143 composer test 144 145## License and Credits 146 147The initial version of this code was written by C. Scott Ananian and is 148Copyright (c) 2021 Wikimedia Foundation. 149 150This code is distributed under the MIT license; see 151[LICENSE](./LICENSE) for more info. 152 153--- 154[Latest Stable Version]: https://poser.pugx.org/wikimedia/idle-dom/v/stable.svg 155[License]: https://poser.pugx.org/wikimedia/idle-dom/license.svg 156 157