- Notifications
You must be signed in to change notification settings - Fork121
Server-side DOM implementation based on Mozilla's dom.js
License
fgnass/domino
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
As the name might suggest, domino's goal is to provide aDOM in Node.
In contrast to the originaldom.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 alsomore performant.
Domino currently doesn't use any harmony/ES6 features like proxies or WeakMaps and therefore also runs in older Node versions.
Domino is intended forbuilding pages rather than scraping them. Hence Domino doesn't execute scripts nor does it download external resources.
Also Domino doesn't generally implement properties which have been deprecated in HTML5.
Domino sticks toDOM level 4, which means that Attributes do not inherit the Node interface.
Note that because domino does not use proxies,Element.attributes
is not a true JavaScript array; it is an objectwith alength
property and anitem(n)
accessor method. Seegithub issue #27 forfurther discussion. It does however implement direct indexed accessors(element.attributes[i]
) and is live.
Domino provides support forquerySelector()
,querySelectorAll()
, andmatches()
backed by theZest selector engine.
Domino represents the DOM tree structure in the same way Webkit andother browser-based implementations do: as a linked list of childrenwhich is converted to an array-based representation iff theNode#childNodes
accessor is used. You will get the best performancefrom tree modification code (inserting and removing children) if youavoid the use ofNode#childNodes
and traverse the tree usingNode#firstChild
/Node#nextSibling
(orNode#lastChild
/Node#previousSibling
) orquerySelector()
/etc.
Domino supports the DOM level 4 API, and thus API documentation can befound on standard reference sites. For example, you could start fromMDN's documentation forDocument andNode.
The only exception is the initial creation of a document:
vardomino=require('domino');varElement=domino.impl.Element;// etcvarwindow=domino.createWindow('<h1>Hello world</h1>','http://example.com');vardocument=window.document;// alternatively: document = domino.createDocument(htmlString, true)varh1=document.querySelector('h1');console.log(h1.innerHTML);console.log(h1instanceofElement);
There is also an incremental parser available, if you need to interleaveparsing with other processing:
vardomino=require('domino');varpauseAfter=function(ms){varstart=Date.now();returnfunction(){return(Date.now()-start)>=ms;};};varincrParser=domino.createIncrementalHTMLParser();incrParser.write('<p>hello<');incrParser.write('b>&am');incrParser.process(pauseAfter(1/*ms*/));// can interleave processingincrParser.write('p;');// ...etc...incrParser.end();// when done writing the documentwhile(incrParser.process(pauseAfter(10/*ms*/))){// ...do other housekeeping...}console.log(incrParser.document().outerHTML);
If you want a more standards-compliant way to create aDocument
, you canalso useDOMImplementation:
vardomino=require('domino');vardomimpl=domino.createDOMImplementation();vardoc=domimpl.createHTMLDocument();
By default many domino methods will be stored in writable properties, toallow polyfills (as browsers do). You can lock down the implementationif desired as follows:
global.__domino_frozen__=true;// Must precede any `require('domino')`vardomino=require('domino');
Domino includes test from theW3C DOM Conformance Suitesas well as tests fromHTML Working Group.
The tests can be run vianpm test
or directly though theMocha command line:
The majority of the code was originally written byAndreas Gal andDavid Flanagan as part of thedom.js project. Please refer to the included LICENSE file for the original copyright notice and disclaimer.
Felix Gnass extracted the code and turnedit into a stand-alone npm package.
The code has been maintained since 2013 byC. Scott Ananian on behalf of the Wikimedia Foundation, which uses it in itsParsoid project. A large numberof improvements have been made, mostly focusing on correctness,performance, and (to a lesser extent) completeness of the implementation.
About
Server-side DOM implementation based on Mozilla's dom.js