sync common.js with upstream
import latest changes to common.js from upstream. Only needed for 3rd party tools.
This commit is contained in:
@@ -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 => ({'&':'&','<':'<','>':'>','"':'"',"'":'''}[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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user