2025-02-02 21:27:31 +00:00
|
|
|
const $id = document.getElementById.bind(document);
|
|
|
|
const $query = document.querySelector.bind(document);
|
|
|
|
const $queryAll = document.querySelectorAll.bind(document);
|
|
|
|
const $text = document.createTextNode.bind(document);
|
2025-02-02 02:09:56 +00:00
|
|
|
|
2025-02-20 02:19:32 +00:00
|
|
|
const $insertBefore = function(target, element) {
|
|
|
|
target.parentNode.insertBefore(element, target);
|
|
|
|
};
|
|
|
|
|
|
|
|
const $appendChild = function(element, child) {
|
|
|
|
switch(typeof child) {
|
|
|
|
case 'undefined':
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'string':
|
|
|
|
element.appendChild($text(child));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'function':
|
|
|
|
$appendChild(element, child());
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'object':
|
|
|
|
if(child === null)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if(child instanceof Node)
|
|
|
|
element.appendChild(child);
|
|
|
|
else if(child?.element instanceof Node)
|
|
|
|
element.appendChild(child.element);
|
|
|
|
else if(typeof child?.toString === 'function')
|
|
|
|
element.appendChild($text(child.toString()));
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
element.appendChild($text(child.toString()));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const $appendChildren = function(element, ...children) {
|
|
|
|
for(const child of children)
|
|
|
|
$appendChild(element, child);
|
2025-02-02 02:09:56 +00:00
|
|
|
};
|
|
|
|
|
2025-02-02 21:27:31 +00:00
|
|
|
const $removeChildren = function(element) {
|
|
|
|
while(element.firstChild)
|
|
|
|
element.firstChild.remove();
|
2025-02-02 02:09:56 +00:00
|
|
|
};
|
|
|
|
|
2025-02-20 02:19:32 +00:00
|
|
|
const $fragment = function(props, ...children) {
|
|
|
|
const fragment = new DocumentFragment(props);
|
|
|
|
$appendChildren(fragment, ...children);
|
|
|
|
return fragment;
|
|
|
|
};
|
2025-02-02 02:09:56 +00:00
|
|
|
|
2025-02-20 02:19:32 +00:00
|
|
|
const $element = function(type, props, ...children) {
|
|
|
|
if(typeof type === 'function')
|
|
|
|
return new type(props ?? {}, ...children);
|
2025-02-02 02:09:56 +00:00
|
|
|
|
2025-02-20 02:19:32 +00:00
|
|
|
const element = document.createElement(type ?? 'div');
|
2025-02-02 02:09:56 +00:00
|
|
|
|
2025-02-20 02:19:32 +00:00
|
|
|
if(props)
|
|
|
|
for(let key in props) {
|
|
|
|
const prop = props[key];
|
|
|
|
if(prop === undefined || prop === null)
|
2025-02-02 02:09:56 +00:00
|
|
|
continue;
|
|
|
|
|
2025-02-20 02:19:32 +00:00
|
|
|
switch(typeof prop) {
|
2025-02-02 02:09:56 +00:00
|
|
|
case 'function':
|
|
|
|
if(key.substring(0, 2) === 'on')
|
|
|
|
key = key.substring(2).toLowerCase();
|
2025-02-20 02:19:32 +00:00
|
|
|
element.addEventListener(key, prop);
|
2025-02-02 02:09:56 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 'object':
|
2025-02-20 02:19:32 +00:00
|
|
|
if(prop instanceof Array) {
|
2025-02-02 02:09:56 +00:00
|
|
|
if(key === 'class')
|
|
|
|
key = 'classList';
|
|
|
|
|
2025-02-20 02:19:32 +00:00
|
|
|
const attr = element[key];
|
2025-02-02 02:09:56 +00:00
|
|
|
let addFunc = null;
|
|
|
|
|
2025-02-20 02:19:32 +00:00
|
|
|
if(attr instanceof Array)
|
|
|
|
addFunc = attr.push.bind(attr);
|
|
|
|
else if(attr instanceof DOMTokenList)
|
|
|
|
addFunc = attr.add.bind(attr);
|
2025-02-02 02:09:56 +00:00
|
|
|
|
|
|
|
if(addFunc !== null) {
|
2025-02-20 02:19:32 +00:00
|
|
|
for(let j = 0; j < prop.length; ++j)
|
|
|
|
addFunc(prop[j]);
|
2025-02-02 02:09:56 +00:00
|
|
|
} else {
|
|
|
|
if(key === 'classList')
|
|
|
|
key = 'class';
|
2025-02-20 02:19:32 +00:00
|
|
|
element.setAttribute(key, prop.toString());
|
2025-02-02 02:09:56 +00:00
|
|
|
}
|
|
|
|
} else {
|
2025-02-20 02:19:32 +00:00
|
|
|
if(key === 'class' || key === 'className')
|
|
|
|
key = 'classList';
|
|
|
|
|
|
|
|
let setFunc = null;
|
|
|
|
if(element[key] instanceof DOMTokenList)
|
|
|
|
setFunc = (ak, av) => { if(av) element[key].add(ak); };
|
|
|
|
else if(element[key] instanceof CSSStyleDeclaration)
|
|
|
|
setFunc = (ak, av) => { element[key].setProperty(ak, av); }
|
|
|
|
else
|
|
|
|
setFunc = (ak, av) => { element[key][ak] = av; };
|
|
|
|
|
|
|
|
for(const attrKey in prop) {
|
|
|
|
const attrValue = prop[attrKey];
|
|
|
|
if(attrValue)
|
|
|
|
setFunc(attrKey, attrValue);
|
|
|
|
}
|
2025-02-02 02:09:56 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'boolean':
|
2025-02-20 02:19:32 +00:00
|
|
|
if(prop)
|
|
|
|
element.setAttribute(key, '');
|
2025-02-02 02:09:56 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
if(key === 'className')
|
|
|
|
key = 'class';
|
|
|
|
|
2025-02-20 02:19:32 +00:00
|
|
|
element.setAttribute(key, prop.toString());
|
2025-02-02 02:09:56 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-02-20 02:19:32 +00:00
|
|
|
$appendChildren(element, ...children);
|
2025-02-02 02:09:56 +00:00
|
|
|
|
2025-02-20 02:19:32 +00:00
|
|
|
return element;
|
2025-02-02 02:09:56 +00:00
|
|
|
};
|