const $e = function(info, attrs, child, created) { info = info || {}; if(typeof info === 'string') { info = {tag: info}; if(attrs) info.attrs = attrs; if(child) info.child = child; if(created) info.created = created; } const elem = document.createElement(info.tag || 'div'); if(info.attrs) { const attrs = info.attrs; for(let key in attrs) { const attr = attrs[key]; if(attr === undefined || attr === null) continue; switch(typeof attr) { case 'function': if(key.substring(0, 2) === 'on') key = key.substring(2).toLowerCase(); elem.addEventListener(key, attr); break; case 'object': if(attr instanceof Array) { if(key === 'class') key = 'classList'; const prop = elem[key]; let addFunc = null; if(prop instanceof Array) addFunc = prop.push.bind(prop); else if(prop instanceof DOMTokenList) addFunc = prop.add.bind(prop); if(addFunc !== null) { for(let j = 0; j < attr.length; ++j) addFunc(attr[j]); } else { if(key === 'classList') key = 'class'; elem.setAttribute(key, attr.toString()); } } else { for(const attrKey in attr) elem[key][attrKey] = attr[attrKey]; } break; case 'boolean': if(attr) elem.setAttribute(key, ''); break; default: if(key === 'className') key = 'class'; elem.setAttribute(key, attr.toString()); break; } } } if(info.child) { let children = info.child; if(!Array.isArray(children)) children = [children]; for(const child of children) { switch(typeof child) { case 'string': elem.appendChild(document.createTextNode(child)); break; case 'object': if(child instanceof Element) { elem.appendChild(child); } else if('element' in child) { const childElem = child.element; if(childElem instanceof Element) elem.appendChild(childElem); else elem.appendChild($e(child)); } else if('getElement' in child) { const childElem = child.getElement(); if(childElem instanceof Element) elem.appendChild(childElem); else elem.appendChild($e(child)); } else { elem.appendChild($e(child)); } break; default: elem.appendChild(document.createTextNode(child.toString())); break; } } } if(info.created) info.created(elem); return elem; }; const $er = (type, props, ...children) => $e({ tag: type, attrs: props, child: children });