1 | # Server-side DOM implementation based on Mozilla's dom.js
|
2 |
|
3 | [![Build Status][1]][2] [![dependency status][3]][4] [![dev dependency status][5]][6]
|
4 |
|
5 | As the name might suggest, domino's goal is to provide a <b>DOM in No</b>de.
|
6 |
|
7 | In contrast to the original [dom.js](https://github.com/andreasgal/dom.js) project, domino was not designed to run untrusted code. Hence it doesn't have to hide its internals behind a proxy facade which makes the code not only simpler, but also [more performant](https://github.com/fgnass/dombench).
|
8 |
|
9 | Domino currently doesn't use any harmony features like proxies or WeakMaps and therefore also runs in older Node versions.
|
10 |
|
11 | ## Speed over Compliance
|
12 |
|
13 | Domino is intended for _building_ pages rather than scraping them. Hence Domino doesn't execute scripts nor does it download external resources.
|
14 |
|
15 | Also Domino doesn't implement any properties which have been deprecated in HTML5.
|
16 |
|
17 | Domino sticks to the [DOM level 4](http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#interface-attr) working draft, which means that Attributes do not inherit the Node interface. Also [Element.attributes](http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-element-attributes) returns a read-only array instead of a NamedNodeMap.
|
18 |
|
19 | <b>Note that</b> because domino does not use proxies,
|
20 | `Element.attributes` is not a true JavaScript array; it is an object
|
21 | with a `length` property and an `item(n)` accessor method. See
|
22 | [github issue #27](https://github.com/fgnass/domino/issues/27) for
|
23 | further discussion.
|
24 |
|
25 | ## CSS Selector Support
|
26 |
|
27 | Domino provides support for `querySelector()`, `querySelectorAll()`, and `matches()` backed by the [Zest](https://github.com/chjj/zest) selector engine.
|
28 |
|
29 | ## Optimization
|
30 |
|
31 | Domino represents the DOM tree structure in the same way Webkit and
|
32 | other browser-based implementations do: as a linked list of children
|
33 | which is converted to an array-based representation iff the
|
34 | `Node#childNodes` accessor is used. You will get the best performance
|
35 | from tree modification code (inserting and removing children) if you
|
36 | avoid the use of `Node#childNodes` and traverse the tree using
|
37 | `Node#firstChild`/`Node#nextSibling` (or
|
38 | `Node#lastChild`/`Node#previousSibling`) or `querySelector()`/etc.
|
39 |
|
40 | ## Usage
|
41 |
|
42 | Domino supports the DOM level 4 API, and thus API documentation can be
|
43 | found on standard reference sites. For example, you could start from
|
44 | MDN's documentation for
|
45 | [Document](https://developer.mozilla.org/en-US/docs/Web/API/Document) and
|
46 | [Node](https://developer.mozilla.org/en-US/docs/Web/API/Node).
|
47 |
|
48 | The only exception is the initial creation of a document:
|
49 | ```javascript
|
50 | var domino = require('domino');
|
51 | var Element = domino.impl.Element; // etc
|
52 |
|
53 | var window = domino.createWindow('<h1>Hello world</h1>', 'http://example.com');
|
54 | var document = window.document;
|
55 |
|
56 | // alternatively: document = domino.createDocument(htmlString, true)
|
57 |
|
58 | var h1 = document.querySelector('h1');
|
59 | console.log(h1.innerHTML);
|
60 | console.log(h1 instanceof Element);
|
61 | ```
|
62 |
|
63 | If you want a more standards-compliant way to create a `Document`, you can
|
64 | also use [DOMImplementation](https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation):
|
65 | ```javascript
|
66 | var domino = require('domino');
|
67 | var domimpl = domino.createDOMImplementation();
|
68 | var doc = domimpl.createHTMLDocument();
|
69 | ```
|
70 |
|
71 | By default many domino methods will be stored in writable properties, to
|
72 | allow polyfills (as browsers do). You can lock down the implementation
|
73 | if desired as follows:
|
74 | ```javascript
|
75 | global.__domino_frozen__ = true; // Must precede any `require('domino')`
|
76 | var domino = require('domino');
|
77 | ```
|
78 |
|
79 | ## Tests
|
80 |
|
81 | Domino includes test from the [W3C DOM Conformance Suites](http://www.w3.org/DOM/Test/)
|
82 | as well as tests from [HTML Working Group](http://www.w3.org/html/wg/wiki/Testing).
|
83 |
|
84 | The tests can be run via `npm test` or directly though the [Mocha](http://mochajs.org/) command line:
|
85 |
|
86 | ![Screenshot](http://fgnass.github.com/images/domino.png)
|
87 |
|
88 | ## License and Credits
|
89 |
|
90 | The majority of the code was originally written by [Andreas Gal](https://github.com/andreasgal/) and [David Flanagan](https://github.com/davidflanagan) as part of the [dom.js](https://github.com/andreasgal/dom.js) project. Please refer to the included LICENSE file for the original copyright notice and disclaimer.
|
91 |
|
92 | [Felix Gnass](https://github.com/fgnass/) extracted the code and turned
|
93 | it into a stand-alone npm package.
|
94 |
|
95 | The code has been maintained since 2013 by [C. Scott Ananian](https://github.com/cscott/) on behalf of the Wikimedia Foundation, which uses it in its
|
96 | [Parsoid](https://www.mediawiki.org/wiki/Parsoid) project. A large number
|
97 | of improvements have been made, mostly focusing on correctness,
|
98 | performance, and (to a lesser extent) completeness of the implementation.
|
99 |
|
100 | [1]: https://travis-ci.org/fgnass/domino.svg
|
101 | [2]: https://travis-ci.org/fgnass/domino
|
102 | [3]: https://david-dm.org/fgnass/domino.svg
|
103 | [4]: https://david-dm.org/fgnass/domino
|
104 | [5]: https://david-dm.org/fgnass/domino/dev-status.svg
|
105 | [6]: https://david-dm.org/fgnass/domino#info=devDependencies
|