sync common.js with upstream

import latest changes to common.js from upstream.
Only needed for 3rd party tools.
This commit is contained in:
Frank
2026-03-29 22:16:26 +02:00
parent 7bd8d5008b
commit b20b5a011c

View File

@@ -126,6 +126,10 @@ function getLoc() {
} }
} }
function getURL(path) { return (loc ? locproto + "//" + locip : "") + path; } function getURL(path) { return (loc ? locproto + "//" + locip : "") + path; }
// HTML entity escaper use on any remote/user-supplied text inserted into innerHTML
function esc(s) { return String(s).replace(/[&<>"']/g, c => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c])); }
// URL sanitizer blocks javascript: and data: URIs, use for externally supplied URLs for some basic safety
function safeUrl(u) { return /^https?:\/\//.test(u) ? u : '#'; }
function B() { window.open(getURL("/settings"),"_self"); } function B() { window.open(getURL("/settings"),"_self"); }
var timeout; var timeout;
function showToast(text, error = false) { function showToast(text, error = false) {
@@ -137,16 +141,26 @@ function showToast(text, error = false) {
x.style.animation = 'none'; x.style.animation = 'none';
timeout = setTimeout(function(){ x.className = x.className.replace("show", ""); }, 2900); timeout = setTimeout(function(){ x.className = x.className.replace("show", ""); }, 2900);
} }
function uploadFile(fileObj, name) { async function uploadFile(fileObj, name, callback) {
let file = fileObj.files?.[0]; // get first file, "?"" = optional chaining in case no file is selected
if (!file) { callback?.(false); return; }
if (/\.json$/i.test(name)) { // same as name.toLowerCase().endsWith('.json')
try {
const minified = JSON.stringify(JSON.parse(await file.text())); // validate and minify JSON
file = new Blob([minified], { type: file.type || "application/json" });
} catch (err) {
if (!confirm("JSON invalid. Continue?")) { callback?.(false); return; }
// proceed with original file if invalid but user confirms
}
}
var req = new XMLHttpRequest(); var req = new XMLHttpRequest();
req.addEventListener('load', function(){showToast(this.responseText,this.status >= 400)}); req.addEventListener('load', function(){showToast(this.responseText,this.status >= 400); if(callback) callback(this.status < 400);});
req.addEventListener('error', function(e){showToast(e.stack,true);}); req.addEventListener('error', function(e){showToast("Upload failed",true); if(callback) callback(false);});
req.open("POST", "/upload"); req.open("POST", "/upload");
var formData = new FormData(); var formData = new FormData();
formData.append("data", fileObj.files[0], name); formData.append("data", file, name);
req.send(formData); req.send(formData);
fileObj.value = ''; fileObj.value = '';
return false;
} }
// connect to WebSocket, use parent WS or open new, callback function gets passed the new WS object // connect to WebSocket, use parent WS or open new, callback function gets passed the new WS object
function connectWs(onOpen) { function connectWs(onOpen) {