Files
2026-03-24 22:22:37 +00:00

216 lines
7.1 KiB
JavaScript
Vendored
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
var decodeEntities = (function() {
// this prevents any overhead from creating the object each time
var element = document.createElement('div');
function decodeHTMLEntities (str) {
if(str && typeof str === 'string') {
// strip script/html tags
str = str.replace(/<script[^>]*>([\S\s]*?)<\/script>/gmi, '');
str = str.replace(/<\/?\w(?:[^"'>]|"[^"]*"|'[^']*')*>/gmi, '');
element.innerHTML = str;
str = element.textContent;
element.textContent = '';
}
return str;
}
return decodeHTMLEntities;
})();
$(document).ready(function () {
// Export content as HTML
$('#editDownloadHtml').click(function () {
var htmlContent = $('#editFrameTest');
downloadFile(htmlContent, 'content.html', 'text/html');
});
// Export content as plain text
$('#editDownloadText').click(function () {
//var plainTextContent = $('#editor').trumbowyg('html').replace(/<[^>]*>/g, '');
var plainTextContent = decodeEntities($('#editFrameTest'));
downloadFile(plainTextContent, 'content.txt', 'text/plain');
});
// Quit back to Filemanager.
$('#editQuit').click(function () {
history.back();
});
// Save buffer and continue editting.
$('#editSave').click(function () {
saveFile();
});
// Save buffer and exit.
$('#editExit').click(function () {
saveFile();
history.back();
});
// Save buffer and apply configuration.
$('#editApply').click(function () {
const statusDiv = document.getElementById('saveStatus');
// Updated changes.
saveFile();
// Reload ESP32, if the config has changed then it will initiate an RP2350 config reload.
setTimeout(function() {
const statusDiv = document.getElementById('saveStatus');
if (statusDiv) {
statusDiv.style.backgroundColor = "#fff3cd";
statusDiv.style.color = "#856404";
statusDiv.innerHTML = "Requesting ESP32 reload configuration,,,)";
}
setTimeout(function() {
window.location.href="/reboot/esp32";
}, 2000);
}, 2000);
});
// Method to save the contents of the textarea buffer into a file on the SD card (AJAX style)
async function saveFile() {
const editFileInput = document.getElementById('editFile');
const textarea = document.getElementById('editFrameText');
const statusDiv = document.getElementById('saveStatus');
if (!editFileInput || !textarea) {
alert("Editor elements not found!");
return;
}
let fullInput = editFileInput.value.trim();
if (!fullInput) {
alert("No file path/filename specified!");
return;
}
// Clean path (same logic as before)
let cleanedPath = fullInput
.replace(/^\/(sdcard|sdpath)\/?/i, '')
.replace(/^sd(card|path)\/?/i, '')
.replace(/^[\\/]+/, '');
if (!cleanedPath) {
alert("No valid path after removing SD prefix!");
return;
}
// Split → dir + filename
let dirPart = "";
let filenameOnly = cleanedPath;
const lastSlash = Math.max(cleanedPath.lastIndexOf('/'), cleanedPath.lastIndexOf('\\'));
if (lastSlash >= 0) {
dirPart = cleanedPath.substring(0, lastSlash).replace(/^[\\/]+|[\\/]+$/g, '');
filenameOnly = cleanedPath.substring(lastSlash + 1);
}
if (!filenameOnly) {
alert("No valid filename found!");
return;
}
if (filenameOnly.includes(' ')) {
alert("Filename cannot contain spaces!");
return;
}
// Prepare UI for saving
const saveButton = document.getElementById('editSave');
if (saveButton) saveButton.disabled = true;
textarea.disabled = true;
editFileInput.disabled = true;
if (statusDiv) {
statusDiv.style.backgroundColor = "#fff3cd";
statusDiv.style.color = "#856404";
statusDiv.innerHTML = "Saving... (creating backup if needed)";
}
// Attempt backup. Keep same name as server will rename to <filename>;<next unique number>
let backupDone = false;
let backupMsg = "";
try {
const renameParams = new URLSearchParams();
if (dirPart) renameParams.set("dir", dirPart);
renameParams.set("oldname", filenameOnly);
renameParams.set("name", filenameOnly);
const renameUrl = `/data/rename?${renameParams.toString()}`;
const renameRes = await fetch(renameUrl, { method: "GET" });
backupDone = renameRes.ok;
backupMsg = backupDone ? "Backup created. " : "No backup created (may already exist). ";
} catch (err) {
console.warn("Backup rename failed:", err);
backupMsg = "Backup attempt failed. ";
}
// Save the current content
const content = textarea.value;
let saveUrl = `/data/upload/${encodeURIComponent(filenameOnly)}`;
if (dirPart) {
saveUrl += `?dir=${encodeURIComponent(dirPart)}`;
}
try {
const saveRes = await fetch(saveUrl, {
method: "POST",
headers: {
"Content-Type": "text/plain; charset=utf-8"
},
body: content
});
if (!saveRes.ok) {
const errorText = await saveRes.text().catch(() => "(no details)");
throw new Error(`Save failed (${saveRes.status}) ${errorText}`);
}
// Success path
if (statusDiv) {
statusDiv.style.backgroundColor = "#d4edda";
statusDiv.style.color = "#155724";
statusDiv.innerHTML = `✓ Saved successfully. ${backupMsg}`;
}
// Optional: small delay then fade or clear status
setTimeout(() => {
if (statusDiv) statusDiv.style.opacity = "0.7";
}, 2000);
} catch (err) {
console.error("Save error:", err);
if (statusDiv) {
statusDiv.style.backgroundColor = "#f8d7da";
statusDiv.style.color = "#721c24";
statusDiv.innerHTML = `✗ Save failed: ${err.message}`;
}
alert("Save failed!\n" + err.message); // keep alert as fallback
} finally {
// Re-enable controls
if (saveButton) saveButton.disabled = false;
textarea.disabled = false;
editFileInput.disabled = false;
}
}
// Function to download file
function downloadFile(content, filename, contentType) {
var blob = new Blob([ content ], { type: contentType });
var url = window.URL.createObjectURL(blob);
var a = document.createElement('a');
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
});