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