add json validation to file inputs in UI and minify before upload (#5248)
* also updated edit.htm to do the same
This commit is contained in:
@@ -137,16 +137,26 @@ function showToast(text, error = false) {
|
||||
x.style.animation = 'none';
|
||||
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();
|
||||
req.addEventListener('load', function(){showToast(this.responseText,this.status >= 400)});
|
||||
req.addEventListener('error', function(e){showToast(e.stack,true);});
|
||||
req.addEventListener('load', function(){showToast(this.responseText,this.status >= 400); if(callback) callback(this.status < 400);});
|
||||
req.addEventListener('error', function(e){showToast("Upload failed",true); if(callback) callback(false);});
|
||||
req.open("POST", "/upload");
|
||||
var formData = new FormData();
|
||||
formData.append("data", fileObj.files[0], name);
|
||||
formData.append("data", file, name);
|
||||
req.send(formData);
|
||||
fileObj.value = '';
|
||||
return false;
|
||||
}
|
||||
// connect to WebSocket, use parent WS or open new, callback function gets passed the new WS object
|
||||
function connectWs(onOpen) {
|
||||
|
||||
@@ -134,6 +134,7 @@ loadFiles('common.js', -1, () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
var QueuedRequester = function(){ this.q=[]; this.r=false; this.x=null; }
|
||||
QueuedRequester.prototype = {
|
||||
_request: function(req){
|
||||
@@ -432,7 +433,7 @@ function createEditor(element,file){
|
||||
// Check filename from text field or current file
|
||||
var pathField = gId("filepath");
|
||||
var filename = (pathField && pathField.value) ? pathField.value : currentFile;
|
||||
aceEditor.session.setMode(filename && filename.toLowerCase().endsWith('.json') ? "ace/mode/json" : "ace/mode/text");
|
||||
aceEditor.session.setMode(filename && (/\.json$/i.test(filename)) ? "ace/mode/json" : "ace/mode/text"); // same as filename.toLowerCase().endsWith('.json')
|
||||
}
|
||||
|
||||
// Try to initialize Ace editor if available
|
||||
@@ -488,7 +489,7 @@ function createEditor(element,file){
|
||||
var filename = pathField ? pathField.value : currentFile;
|
||||
var border = "2px solid #333";
|
||||
|
||||
if (filename && filename.toLowerCase().endsWith('.json')) {
|
||||
if (filename && (/\.json$/i.test(filename))) { // same as filename.toLowerCase().endsWith('.json')
|
||||
try {
|
||||
JSON.parse(ta.value);
|
||||
} catch(e) {
|
||||
@@ -499,23 +500,19 @@ function createEditor(element,file){
|
||||
};
|
||||
|
||||
function saveFile(filename,data){
|
||||
var finalData = data;
|
||||
// Minify JSON files before upload
|
||||
if (filename.toLowerCase().endsWith('.json')) {
|
||||
var outdata = data;
|
||||
if (/\.json$/i.test(filename)) { // same as filename.toLowerCase().endsWith('.json')
|
||||
try {
|
||||
finalData = JSON.stringify(JSON.parse(data));
|
||||
outdata = JSON.stringify(JSON.parse(data)); // validate and minify
|
||||
} catch(e) {
|
||||
alert("Invalid JSON! Please fix syntax.");
|
||||
alert("Invalid JSON! Please fix.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
var fd=new FormData();
|
||||
fd.append("file",new Blob([finalData],{type:"text/plain"}),filename);
|
||||
req.add("POST","/upload",fd,function(st,resp){
|
||||
if (st!=200) alert("ERROR "+st+": "+resp);
|
||||
else {
|
||||
showToast("File saved");
|
||||
uploadFile({files: [new Blob([outdata], {type:"text/plain"})]}, filename, function(s) {
|
||||
if(s) {
|
||||
refreshTree();
|
||||
loadFile(filename); // (re)load if saved successfully to update formating or show file content
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -526,9 +523,9 @@ function createEditor(element,file){
|
||||
gId("preview").style.display="none";
|
||||
gId("editor").style.display="flex";
|
||||
if (st==200) {
|
||||
if (filename.toLowerCase().endsWith('.json')) {
|
||||
if ((/\.json$/i.test(filename))) { // same as filename.toLowerCase().endsWith('.json')
|
||||
try {
|
||||
setContent(filename.toLowerCase().includes('ledmap') ? prettyLedmap(resp) : JSON.stringify(JSON.parse(resp), null, 2));
|
||||
setContent(/ledmap/i.test(filename) ? prettyLedmap(resp) : JSON.stringify(JSON.parse(resp), null, 2)); // pretty-print ledmap files (i.e. if file name includes "ledmap" case-insensitive)
|
||||
} catch(e) {
|
||||
setContent(resp);
|
||||
}
|
||||
@@ -555,8 +552,7 @@ function createEditor(element,file){
|
||||
}
|
||||
if (!fn.startsWith("/")) fn = "/" + fn;
|
||||
currentFile = fn; // Update current file
|
||||
saveFile(fn, getContent());
|
||||
loadFile(fn);
|
||||
saveFile(fn, getContent())
|
||||
},
|
||||
loadText:function(fn){
|
||||
currentFile=fn;
|
||||
|
||||
Reference in New Issue
Block a user