116 lines
3.7 KiB
JavaScript
116 lines
3.7 KiB
JavaScript
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 });
|