Harden settings UI: robust parentDir, escape browse paths, surface load error
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -346,6 +346,12 @@ function openSettings() {
|
|||||||
document.getElementById('setSave').onclick = saveSettings;
|
document.getElementById('setSave').onclick = saveSettings;
|
||||||
document.getElementById('setBrowse').onclick = () =>
|
document.getElementById('setBrowse').onclick = () =>
|
||||||
loadBrowse(parentDir(document.getElementById('setKnow').value));
|
loadBrowse(parentDir(document.getElementById('setKnow').value));
|
||||||
|
}).catch(() => {
|
||||||
|
const ov = document.getElementById('settingsOverlay');
|
||||||
|
ov.innerHTML = '<div class="modal"><div class="set-error">Could not load settings.</div>' +
|
||||||
|
'<div class="modal-actions"><button type="button" class="btn btn-ghost" id="setClose">Close</button></div></div>';
|
||||||
|
ov.hidden = false;
|
||||||
|
document.getElementById('setClose').onclick = closeSettings;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -371,7 +377,13 @@ function saveSettings() {
|
|||||||
|
|
||||||
function parentDir(path) {
|
function parentDir(path) {
|
||||||
if (!path) return '';
|
if (!path) return '';
|
||||||
return path.replace(/\/[^/]*$/, '');
|
const i = path.lastIndexOf('/');
|
||||||
|
if (i <= 0) return '/';
|
||||||
|
return path.slice(0, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
function esc(s) {
|
||||||
|
return String(s).replace(/&/g, '&').replace(/</g, '<').replace(/"/g, '"');
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadBrowse(dir) {
|
function loadBrowse(dir) {
|
||||||
@@ -383,16 +395,16 @@ function loadBrowse(dir) {
|
|||||||
}).then(d => {
|
}).then(d => {
|
||||||
const items = [];
|
const items = [];
|
||||||
if (d.parent && d.parent !== d.dir) {
|
if (d.parent && d.parent !== d.dir) {
|
||||||
items.push(`<li><button type="button" data-dir="${d.parent}">../</button></li>`);
|
items.push(`<li><button type="button" data-dir="${esc(d.parent)}">../</button></li>`);
|
||||||
}
|
}
|
||||||
for (const e of d.entries) {
|
for (const e of d.entries) {
|
||||||
if (e.is_dir) {
|
if (e.is_dir) {
|
||||||
items.push(`<li><button type="button" data-dir="${e.path}">${e.name}/</button></li>`);
|
items.push(`<li><button type="button" data-dir="${esc(e.path)}">${esc(e.name)}/</button></li>`);
|
||||||
} else {
|
} else {
|
||||||
items.push(`<li><button type="button" data-file="${e.path}">${e.name}</button></li>`);
|
items.push(`<li><button type="button" data-file="${esc(e.path)}">${esc(e.name)}</button></li>`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pane.innerHTML = `<div class="browse-dir">${d.dir}</div><ul class="browse-list">${items.join('')}</ul>`;
|
pane.innerHTML = `<div class="browse-dir">${esc(d.dir)}</div><ul class="browse-list">${items.join('')}</ul>`;
|
||||||
pane.querySelectorAll('button[data-dir]').forEach(b =>
|
pane.querySelectorAll('button[data-dir]').forEach(b =>
|
||||||
b.onclick = () => loadBrowse(b.getAttribute('data-dir')));
|
b.onclick = () => loadBrowse(b.getAttribute('data-dir')));
|
||||||
pane.querySelectorAll('button[data-file]').forEach(b =>
|
pane.querySelectorAll('button[data-file]').forEach(b =>
|
||||||
|
|||||||
Reference in New Issue
Block a user