107 lines
3.1 KiB
JavaScript
107 lines
3.1 KiB
JavaScript
/*
|
|
* This file is part of NoccyLabs JavaScript Standard Library (JSL)
|
|
* Copyright (c) 2025, NoccyLabs. Licensed under GNU GPL v2 or later
|
|
*
|
|
*
|
|
*/
|
|
|
|
/**
|
|
* A helper class to create (and manipulate) elements in the DOM.
|
|
*
|
|
*/
|
|
class DomHelper {
|
|
|
|
/**
|
|
* Create a new element without all the fuzz.
|
|
*
|
|
* @param {string} tag The name of the HTML tag
|
|
* @param {object} attr Map of attributes to apply to the element
|
|
* @param {array|Element|string} children Children or single child/text to apply
|
|
* @returns Element
|
|
*/
|
|
createEl(tag, attr = {}, children = []) {
|
|
//console.debug(`create: ${tag}`, attr, children);
|
|
let el = document.createElement(tag);
|
|
this.apply(el, attr);
|
|
this.append(el, children);
|
|
return el;
|
|
};
|
|
|
|
/**
|
|
* Apply attributes from an object to an element
|
|
*
|
|
* @param {Element} tag The element to modify
|
|
* @param {object} attr Key-value pairs of attributes to apply, or if null remove
|
|
*/
|
|
apply(tag, attr) {
|
|
Object.keys(attr).forEach(key => {
|
|
if (key.match(/^on:/)) {
|
|
const ev = key.substring(3);
|
|
tag.addEventListener(ev, attr[key]);
|
|
return;
|
|
}
|
|
if (attr[key] === null) {
|
|
tag.removeAttribute(key);
|
|
} else {
|
|
tag.setAttribute(key, attr[key]);
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Append one or more children or text nodes to an element.
|
|
*
|
|
* @param {Element} tag The element to modify
|
|
* @param {array|Element|string} children List of elements or single element to append to the element
|
|
* @returns
|
|
*/
|
|
append(tag, children) {
|
|
//console.debug(`append: ${tag.nodeName}`, children);
|
|
if (typeof children == 'object' && children instanceof Element) {
|
|
//console.debug(`-> appended element`);
|
|
tag.appendChild(children);
|
|
return;
|
|
}
|
|
if (typeof children == 'string') {
|
|
//console.debug(`-> appended string`);
|
|
let n = document.createTextNode(children);
|
|
tag.appendChild(n);
|
|
return;
|
|
}
|
|
if (Array.isArray(children)) {
|
|
children.forEach(child => {
|
|
this.append(tag, child);
|
|
});
|
|
//console.debug(`-> appended nested`);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Apply templated values to a string
|
|
*
|
|
* @param {string} str The string to perform interpolation on
|
|
* @param {object} tpl A string of key-value pair to replace between percent signs
|
|
* @returns string
|
|
*/
|
|
interpolate(str, tpl) {
|
|
Object.keys(tpl).forEach(key => {
|
|
str = str.replace(`%${key}%`, tpl[key]);
|
|
});
|
|
return str;
|
|
}
|
|
};
|
|
|
|
// The DOM helper
|
|
const dom = new DomHelper();
|
|
|
|
// Proxy for creating any supported HTML element via el.TAG
|
|
const el = new Proxy(dom, {
|
|
get(target,name) {
|
|
return name in target
|
|
? target[name]
|
|
: (attr = {}, children = []) => target.createEl(name, attr, children);
|
|
}
|
|
});
|
|
|
|
export { dom, el };
|