function getAttributes (o) { const ignore = ['tag', 'innerText', 'children'] return Object.keys(o).reduce(function (r, k) { if (ignore.includes(k)) return r r += o[k] ? ` ${k}="${o[k] instanceof Array ? o[k].join(' ') : o[k]}"` : ` ${k}` return r }, '') } function getChildren (o) { return o.children.reduce(function (r, c) { r += toHtml(c) return r }, '') } const toHtml = (o) => `<${o.tag}${getAttributes(o)}>${o.innerText || getChildren(o)}` /* less performant function appendTo (node, content) { const range = document.createRange() range.selectNode(node) const documentFragment = range.createContextualFragment(content) document.body.appendChild(documentFragment) } */ const append = (node, content, position) => node.insertAdjacentHTML(position, content) const appendBefore = (node, content) => append(node, content, 'beforebegin') const appendAfter = (node, content) => append(node, content, 'afterend') const appendBeforeChildren = (node, content) => append(node, content, 'afterbegin') const appendTo = (node, content) => append(node, content, 'beforeend')