developit / undom

🍩 1kb minimally viable DOM Document implementation
https://npm.im/undom
MIT License
662 stars 25 forks source link

Instantiable env #25

Closed developit closed 5 years ago

developit commented 5 years ago

This PR builds on #24. In #24, DOM classes/prototypes became shared across all Documents created via undom():

import undom from 'undom';

const doc1 = undom();
const doc2 = undom();
doc1.defaultView.Node === doc1.defaultView.Node  // true

With this PR, undom() continues to return shared constructors. However, a new undom.env() method returns a new factory function (akin to undom()) that can be called to create documents with a new set of constructors:

import undom from 'undom';

// as with #24, documents default to the shared environment:
const doc1 = undom();
const doc2 = undom();
doc1.defaultView.Node === doc1.defaultView.Node;

// but now we have an escape hatch:
const env = undom.env();
const doc3 = env();
doc3.defaultView.Node === doc1.defaultView.Node;  // FALSE!

This means we still encourage using the shared globals, but allow creating a new set of them if necessary.

It also opens up an interesting option for plugins, which were proposed a while ago, but would have been difficult to implement.

import undom from 'undom';
import serialization from 'undom/serialization';
import shadow from 'undom/shadow';

function applyPlugin(dom, plugin) {
  plugin(typeof dom==='function' ? dom() : dom);
}

// create a clean environment
const env = undom.env();
applyPlugin(env, serialization);
applyPlugin(env, shadow);

// now all documents created for the environment have those plugins:
const doc1 = env();
const doc2 = env();

// fun part - this works with the default environment too:
applyPlugin(undom, serialization);
const doc3 = undom(); // has the plugin