dom
dom copied to clipboard
Update the "convert nodes into a node" to accept arrays of nodes.
The natural container for nodes is the DocumentFragment, but since it loses its children on insertion, it can't be used to hold onto them.
It would be nice if .append(), .before and friends could accept (nested) JS Arrays of nodes and domstrings as well The "convert nodes" algo can be updated to:
// TODO: translate to standardese :-)
function convert(...nodes) {
const accumulator = document.createDocumentFragment()
const circularCheck = new Set()
const depth = 0
nodes.forEach(node => _convert(node, accumulator, circularCheck, depth))
return accumulator
}
function _convert(node, acc, circularCheck, depth) {
if (depth > MAX_RECURSION_DEPTH) throw new Error("Max recursion depth exceeded")
if (Array.isArray(node) {
if circularCheck.has(node) throw new Error("Circular reference in Array<Node>")
circularCheck.add(node)
node.forEach(n => _convert(n, acc, circular, depth + 1))
else {
// convert strings to TextNode if needed, and insert
}
}
depth and circularCheck may seem redundant, but they serve distinct purposes:
The circular ref check being there to help with accidental misuse, providing more accurate feedback to authors.
The depth check is there to prevent stack overflows triggered by passing an array that misuses getters:
function misuse(a) {
a[0] = null
Object.defineProperty(a, '0', {get() {return misuse([])}})
return a
}
node.append(misuse([])) // boom
As a side note, I see that the spec graduated without #433 being implemented, and I suppose that it may be too late now to change it, for Web compat reasons (re. mutation records)...
If it isn't can we revisit it? It is regrettable that the new, ergonomic API is slower than the clunkier one. Especially because it could be faster, since it lend itself to fewer JS/native round-trips.
The spec for the DOM4 methods would become more complex though.
Another way to tackle this would be to make a new kind of mindful fragments (by contrast to the current amnesiac ones).
const frag = document.createDocumentFragment()
frag.mindful = true
frag.append('a', 'b')
document.body.append(frag)
frag.estranged // true
frag.childNodes.length // 0 ... or maybe 2? keeping the parent => child link,
// but not the other way around? That would be more useful.
frag.append('c') // throws
frag.reclaimChildren()
frag.estranged // false
frag.childNodes.length // 2
frag.append('c') // works
Reclaiming a fragment with nested fragments would work recursively.
Can you point to precedent in libraries? Are they widely adopted/used?
This is related to moving keyed lists of fragments, but it may actually be an X/Y question, as I'm still processing the DOM 4 methods. I probably posted too soon, sorry for the noise.
Is #433 set in stone?
I don't think anything has really changed since I wrote the comments I wrote there, so probably?
Edit: there's also no DOM4 anymore.