Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
The 'domino' npm package is a server-side DOM implementation based on Mozilla's DOMParser. It allows you to create and manipulate DOM elements in a Node.js environment, similar to how you would in a browser. This is particularly useful for server-side rendering, web scraping, and testing.
Creating a DOM from HTML
This feature allows you to create a DOM structure from an HTML string. The code sample demonstrates creating a window and document object from an HTML string and then accessing an element by its ID.
const domino = require('domino');
const window = domino.createWindow('<div id="test">Hello World</div>');
const document = window.document;
console.log(document.getElementById('test').textContent); // Output: Hello World
Manipulating DOM elements
This feature allows you to manipulate DOM elements just like you would in a browser environment. The code sample shows how to change the text content of a DOM element.
const domino = require('domino');
const window = domino.createWindow('<div id="test">Hello World</div>');
const document = window.document;
const element = document.getElementById('test');
element.textContent = 'Hello Domino';
console.log(element.outerHTML); // Output: <div id="test">Hello Domino</div>
Parsing HTML
This feature allows you to parse an HTML string into a DOM document. The code sample demonstrates parsing an HTML string and querying an element using `querySelector`.
const domino = require('domino');
const document = domino.createDocument('<html><body><p>Hello World</p></body></html>');
console.log(document.querySelector('p').textContent); // Output: Hello World
jsdom is another popular library for creating and manipulating a DOM in a Node.js environment. It is more feature-rich and closely follows the WHATWG DOM and HTML standards. Compared to domino, jsdom offers more comprehensive support for modern web APIs and is generally more robust, but it can also be slower and more resource-intensive.
cheerio is a fast, flexible, and lean implementation of core jQuery designed specifically for the server. It parses HTML and XML documents and provides a jQuery-like API for traversing and manipulating the resulting data structure. While it is not a full DOM implementation like domino, it is very efficient for web scraping and simple DOM manipulation tasks.
As the name might suggest, domino's goal is to provide a DOM in Node.
In contrast to the original 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.
Domino currently doesn't use any harmony/ES6 features like proxies or WeakMaps and therefore also runs in older Node versions.
Domino is intended for building 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 to DOM 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 object
with a length
property and an item(n)
accessor method. See
github issue #27 for
further discussion. It does however implement direct indexed accessors
(element.attributes[i]
) and is live.
Domino provides support for querySelector()
, querySelectorAll()
, and matches()
backed by the Zest selector engine.
Domino represents the DOM tree structure in the same way Webkit and
other browser-based implementations do: as a linked list of children
which is converted to an array-based representation iff the
Node#childNodes
accessor is used. You will get the best performance
from tree modification code (inserting and removing children) if you
avoid the use of Node#childNodes
and traverse the tree using
Node#firstChild
/Node#nextSibling
(or
Node#lastChild
/Node#previousSibling
) or querySelector()
/etc.
Domino supports the DOM level 4 API, and thus API documentation can be found on standard reference sites. For example, you could start from MDN's documentation for Document and Node.
The only exception is the initial creation of a document:
var domino = require('domino');
var Element = domino.impl.Element; // etc
var window = domino.createWindow('<h1>Hello world</h1>', 'http://example.com');
var document = window.document;
// alternatively: document = domino.createDocument(htmlString, true)
var h1 = document.querySelector('h1');
console.log(h1.innerHTML);
console.log(h1 instanceof Element);
There is also an incremental parser available, if you need to interleave parsing with other processing:
var domino = require('domino');
var pauseAfter = function(ms) {
var start = Date.now();
return function() { return (Date.now() - start) >= ms; };
};
var incrParser = domino.createIncrementalHTMLParser();
incrParser.write('<p>hello<');
incrParser.write('b>&am');
incrParser.process(pauseAfter(1/*ms*/)); // can interleave processing
incrParser.write('p;');
// ...etc...
incrParser.end(); // when done writing the document
while (incrParser.process(pauseAfter(10/*ms*/))) {
// ...do other housekeeping...
}
console.log(incrParser.document().outerHTML);
If you want a more standards-compliant way to create a Document
, you can
also use DOMImplementation:
var domino = require('domino');
var domimpl = domino.createDOMImplementation();
var doc = domimpl.createHTMLDocument();
By default many domino methods will be stored in writable properties, to allow polyfills (as browsers do). You can lock down the implementation if desired as follows:
global.__domino_frozen__ = true; // Must precede any `require('domino')`
var domino = require('domino');
Domino includes test from the W3C DOM Conformance Suites as well as tests from HTML Working Group.
The tests can be run via npm test
or directly though the Mocha command line:
The majority of the code was originally written by Andreas Gal and David Flanagan as part of the dom.js project. Please refer to the included LICENSE file for the original copyright notice and disclaimer.
Felix Gnass extracted the code and turned it into a stand-alone npm package.
The code has been maintained since 2013 by C. Scott Ananian on behalf of the Wikimedia Foundation, which uses it in its Parsoid project. A large number of improvements have been made, mostly focusing on correctness, performance, and (to a lesser extent) completeness of the implementation.
domino 2.1.6 (16 Jul 2020)
mocha
dependency has been updated to 6.x. As a result, we are
no longer testing on node 4.FAQs
Server-side DOM implementation based on Mozilla's dom.js
The npm package domino receives a total of 444,257 weekly downloads. As such, domino popularity was classified as popular.
We found that domino demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.