@shgysk8zer0/node-dom
A basic DOM implementation for node.
[!WARNING] This project is under development and IS NOT intended for parsing HTML. Expect missing attributes and methods,
document.createElement()
resulting inHTMLUnknownElement
s, etc.
This project aims to help in creating elements and documents using familiar methods while being rather minimal.
Installation
npm i @shgysk8zer0/node-dom --save
Example
import { HTMLDocument } from '@shgysk8zer0/node-dom';
import { FORM_MULTIPART } from '@shgysk8zer0/consts/mimes';
const document = new HTMLDocument();
const base = document.createElement('base');
const main = document.createElement('main');
const frag = document.createDocumentFragment();
const a = document.createElement('a');
const div = document.createElement('div');
const img = document.createElement('img');
const script = document.createElement('script');
const link = document.createElement('link');
const iframe = document.createElement('iframe');
const meta = document.createElement('meta');
const form = document.createElement('form');
const input = document.createElement('input');
const label = document.createElement('label');
const time = document.createElement('time');
const footer = document.createElement('footer');
document.title = 'Node Test';
base.href = 'https://example.com';
img.src = 'https://example.com/img.png';
img.id = 'logo';
img.alt = 'Logo';
img.loading = 'lazy';
img.crossOrigin = 'anonymous';
img.referrerPolicy = 'no-referrer';
img.height = 64;
img.width = 64;
img.dataset.fooBar = '42';
img.classList.add('block', 'card');
script.src = '/js/index.js';
script.defer = true;
script.type = 'module';
script.crossOrigin = 'anonymous';
script.referrerPolicy = 'no-referrer';
script.fetchPriority = 'high';
a.href = img.src;
a.download = img.src.split('/').at(-1);
a.title = 'A "d&ngerous" <filename>';
a.relList.add('noreferrer', 'noopener');
a.target = '_blank';
a.append(img);
div.classList.add('container');
div.append(a);
link.href = '/css/styles.css';
link.relList.add('stylesheet');
link.media = 'all';
iframe.src = 'https://events.kernvalley.us/embed/';
iframe.sandbox.add('allow-script');
iframe.part.add('content');
document.head.append(base, link, script);
meta.charset = 'utf-8';
frag.append(div, '&<<<<dangerous "content">', iframe);
main.append(frag, document.createElement('hr'));
form.name = 'test';
form.action = '/api';
form.method = 'POST';
form.encoding = FORM_MULTIPART;
input.name = 'foo';
input.id = 'input';
input.value = 'bar';
input.required = true;
label.htmlFor = input.id;
label.textContent = 'Some Text';
form.append(label, input);
main.prepend(form);
const date = new Date();
time.dateTime = date.toISOString();
time.textContent = date.toLocaleString();
footer.append(time);
console.log(document.toString());
Limitations
This DOM implementation is intentionally limited and mostly useful for constructing, not parsing or manipulating. It only aims to be able to create Elements & Documents that end up being saved or sent as strings.
Implementation Differences
- All elements can be created using
new SomeElement()
- All elements return their
outerHTML
viatoString()
-
Document
has additional staticcreateElement()
®isterElement()
methods -
Attr.ownerElement
is not read-only - There is no global
document
unless you create it (globalThis.document = new HTMLDocument()
) - The element classes are not attached to the global object either (e.g. no
HTMLScriptElement
) - Some property getters associated with attributes may return the wrong types when not set (e.g.
''
instead ofnull
orundefined
)
Not Yet Implemented / Incorrect Implementations
- Namespaces for attributes and elements (
element.setAttributeNS()
) - Doctype will always be
<!DOCTYPE html>
-
elememt.after()
,element.before()
,node.insertBefore()
,node.insertAfter()
-
node.cloneNode()
,node.isSameNode()
,node.isEqualNode()
-
element.style
not supported except aselement.setAttribute('style', styleString)
-
aria*
properties - Tables and many form/input properties and methods
- Various properties, methods, and classes
Not Planned
-
DOMParser()
,set innerHTML
, or anything that requires parsing HTML -
querySelector()
,querySelectorAll()
,element.matches()
,element.closest()
, etc.
Things that Do Not Make Sense Here
- Various
<canvas>
methods - Animations
- Form Validation
- Dispatching events such as
load
,click
, etc - Any properties or methods that depend on how a document is rendered (
DOMRect
,offset*
, etc) - Scroll properties and methods
- Custom Elements / Web Components / ShadowRoot