/**
* @param {HTMLElement}
* @return {object} object literal presentation
*/
function virtualize(element) {
if (element.nodeType === 3)
return element.textContent;
const ret = {
type: element.tagName.toLowerCase(),
props: {
children: []
}
};
element.childNodes.forEach(child => ret.props.children.push(virtualize(child)));
if (ret.props.children.length === 1)
ret.props.children = ret.props.children[0];
for (const {
name,
value
} of element.attributes)
ret.props[name === 'class' ? 'className' : name] = value;
return ret;
}
/**
* @param {object} valid object literal presentation
* @return {HTMLElement}
*/
function render(obj) {
if (typeof obj === 'string') return document.createTextNode(obj);
const {
type,
props: {
children,
...attributes
}
} = obj;
const ret = document.createElement(type);
const childNodes = typeof children === 'string' ? [children] : children;
childNodes.forEach(childNode => ret.append(render(childNode)));
for (const [key, val] of Object.entries(attributes)) {
ret.setAttribute(key === 'className' ? 'class' : key, val)
}
return ret;
}
Categories