Open jfsiii opened 8 years ago
I think querySelector()
/ querySelectorAll()
would be nice to have, but it seems like the kind of thing that could just be bolted on as part of setup (or in a wrapper module?). I have a couple different implementations of selector engines lying around, but nothing I am able to properly open-source, given the added maintenance overhead.
For the other features - namespaceURI
is an easy one for sure, it's already there just using the wrong name (my bad!). Style should be fairly easy, though I'm curious if there is a way to get around implementing the entire interface considering most stuff just uses property access. Generation of style.cssText
/ the style
attribute based on style.*
should be pretty minimal, I think Preact's version of that was around 100 bytes. The inverse can probably be done similarly lightweight by using a simplified parser that may not account for 100% of the various ill-formatted value normalizations & edge cases.
The other complex item on that list would be get*ClientRect()
and the other layout calculations. These could be an add-on, or perhaps included in the repo as separate modules to be imported.
It might be nice to establish an extension mechanism, even it it's as simple as an Express-style .use()
that just invokes plugins on a created document:
import undom from 'undom';
import mutationObserver from 'undom/mutation-observer';
import querySelector from 'undom/query-selector';
import layout from 'undom/layout';
import serialization from 'undom/serialization';
let document = undom()
.use(mutationObserver)
.use(querySelector)
.use(layout)
.use(serialization);
// or even just:
let document = undom([
mutationObserver,
querySelector,
layout,
serialization
]);
For those using ES Module bundlers with tree-shaking, we could have the ES Modules source provide re-exports of the various plugins/middleware:
import undom, { mutations, selectors, layout, serialization } from 'undom';
let document = undom([
mutations,
selectors,
layout,
serialization
]);
// ^ this could also be provided as a convenience loader:
import undom from 'undom/all';
let document = undom();
I was thinking of a very similar API for opting-in to various features. You got so much done in so little code it'd be a shame to lose the simple & small option (which satisfied your original use case) as more features are added. At the same time, it'd be a shame to have to pull in all of jsdom
if you don't need the full BOM.
I like the idea of a undom-d3
project which build on the small core of undom
. That way, any branches required for d3 patterns or bugs can be limited to that project.
Great point about mixing in querySelector{,All}
. The one react-faux-dom uses, query-selector
is the smallest (22KB/8KB) I've seen and has solid tests, IMO.
FWIW, I think getComputedStyle & getBoundingClientRect are "we fixed the glitch"-level code.
Ah yeah, I figured those layout methods were basically faked. The recursive nature of layout computation seems like overkill for anything aiming to be lightweight.
I pulled MutationObserver from core in order to keep things light, so I'll probably submit a PR with the architecture we came to here and add MutationObserver as the first bundled plugin.
Any thoughts as to whether we should go with separate NPM packages (undom-mutationobserver
, undom-selectors
) versus a meta-package like above? I'm sort-of leaning towards the metapackage in order to keep versioning sane.
metapackage sounds good to me
Just stumbled across udom. While it's a complete nightmare to maintain I prefer individual packages over metapackages. Why, it encourages others to help maintain, keeps bugs with their owner, means I only have to download/install the parts I need, and it seems to be "way" most of the Node world is working now.
The hard decision is what is part of the udom core, and what belongs in an extension. Of course you can also have metapackage's and support for external packages gaining the best of both worlds as long as udom doesn't bloat :D
One option there would be to have a monorepo (perhaps set up via lerna), but publish the packages separately (undom-foo
, etc). That would centralize development and versioning for whatever list of "core" modules we end up with, but keep the installs light (1 file).
TBH, monorepo + Lerna was my first reaction, but I wanted to prevent a tangent/bikeshed.
I'm ok with it if you are. It's my preferred approach but I haven't used Learna in any of my existing monorepi.
Same. I can take a stab at the initial setup if that seems like a good approach.
Part of the reason I created #1 was I wondered about using this to render
d3
.I was reading the https://github.com/Olical/react-faux-dom/ source when I saw your Tweet about this project.
I'm not sure exactly what changes are required. I believe some will be small (like
ownerDocument
) ornamespaceURI
while others (likestyle
andquerySelector
) will require more time and bytes.FWIW, here's their DOM support and their d3 tests. A key first step would be to get
d3.select(document.createElement('div')).append('p').node()
to return to newly created<p></p>
.It seems like we can either a) add support for this use case into this document b) create another project which imports
undom
. Do you have a preference? Does this use case (with limitations) seem like a fit for undom "core" or should it be an separate lib?