mirror of
https://github.com/infinition/Bjorn.git
synced 2026-03-15 08:52:00 +00:00
Add RLUtils class for managing RL/AI dashboard endpoints
- Implemented methods for fetching AI stats, training history, and recent experiences. - Added functionality to set operation mode (MANUAL, AUTO, AI) with appropriate handling. - Included helper methods for querying the database and sending JSON responses. - Integrated model metadata extraction for visualization purposes.
This commit is contained in:
97
web/js/core/dom.js
Normal file
97
web/js/core/dom.js
Normal file
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* Safe DOM utilities — avoids innerHTML with untrusted content.
|
||||
*/
|
||||
import { trLoose } from './i18n.js';
|
||||
|
||||
/**
|
||||
* Create an element with attributes and children (safe, no innerHTML).
|
||||
* @param {string} tag
|
||||
* @param {object} attrs - className, style, data-*, event handlers (onclick, etc.)
|
||||
* @param {Array} children - strings or HTMLElements
|
||||
* @returns {HTMLElement}
|
||||
*/
|
||||
export function el(tag, attrs = {}, children = []) {
|
||||
const node = document.createElement(tag);
|
||||
for (const [k, v] of Object.entries(attrs)) {
|
||||
if (v == null || v === false) continue;
|
||||
if (k === 'class' || k === 'className') node.className = v;
|
||||
else if (k === 'style' && typeof v === 'string') node.style.cssText = v;
|
||||
else if (k === 'style' && typeof v === 'object') Object.assign(node.style, v);
|
||||
else if (k.startsWith('on') && typeof v === 'function') {
|
||||
node.addEventListener(k.slice(2).toLowerCase(), v);
|
||||
}
|
||||
else node.setAttribute(k, String(v));
|
||||
}
|
||||
for (const child of (Array.isArray(children) ? children : [children])) {
|
||||
if (child == null || child === false) continue;
|
||||
if (typeof child === 'string' || typeof child === 'number') {
|
||||
node.appendChild(document.createTextNode(String(child)));
|
||||
} else if (child instanceof Node) {
|
||||
node.appendChild(child);
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shorthand selectors.
|
||||
*/
|
||||
export const $ = (s, root = document) => root.querySelector(s);
|
||||
export const $$ = (s, root = document) => Array.from(root.querySelectorAll(s));
|
||||
|
||||
/**
|
||||
* Escape HTML entities to prevent XSS when rendering untrusted text.
|
||||
* @param {string} str
|
||||
* @returns {string}
|
||||
*/
|
||||
export function escapeHtml(str) {
|
||||
const div = document.createElement('div');
|
||||
div.appendChild(document.createTextNode(str));
|
||||
return div.innerHTML;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set text content safely (never innerHTML with untrusted data).
|
||||
* @param {HTMLElement} el
|
||||
* @param {string} text
|
||||
*/
|
||||
export function setText(el, text) {
|
||||
if (el) el.textContent = text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a toast notification.
|
||||
* @param {string} message - plain text (safe)
|
||||
* @param {number} duration - ms
|
||||
* @param {string} type - 'info' | 'success' | 'error' | 'warning'
|
||||
*/
|
||||
export function toast(message, duration = 2600, type = 'info') {
|
||||
const container = document.getElementById('toasts');
|
||||
if (!container) return;
|
||||
|
||||
const t = el('div', { class: `toast toast-${type}` }, [trLoose(String(message))]);
|
||||
container.appendChild(t);
|
||||
|
||||
setTimeout(() => {
|
||||
t.style.transition = 'transform .2s ease, opacity .2s';
|
||||
t.style.transform = 'translateY(10px)';
|
||||
t.style.opacity = '0';
|
||||
setTimeout(() => t.remove(), 220);
|
||||
}, duration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty a container safely.
|
||||
* @param {HTMLElement} container
|
||||
*/
|
||||
export function empty(container) {
|
||||
while (container.firstChild) container.removeChild(container.firstChild);
|
||||
}
|
||||
|
||||
export function confirmT(message) {
|
||||
return window.confirm(trLoose(String(message)));
|
||||
}
|
||||
|
||||
export function promptT(message, defaultValue = '') {
|
||||
return window.prompt(trLoose(String(message)), defaultValue);
|
||||
}
|
||||
Reference in New Issue
Block a user