securite: #87 T5a supprime 16 handlers inline au profit de listeners (CSP inchangee)

This commit is contained in:
2026-09-26 22:32:01 -04:00
parent 330462e7a5
commit 36a4030c09
15 changed files with 91 additions and 59 deletions
+39 -3
View File
@@ -363,6 +363,27 @@ function initHelpModal() {
}
});
// Help TOC hamburger + search clear (#87, ex-onclick inline in index.html).
var helpHamburger = document.getElementById("help-hamburger");
if (helpHamburger) {
helpHamburger.addEventListener("click", function() {
var n = document.getElementById("help-nav");
if (n) {
var d = n.style.display;
n.style.display = d === "none" || d === "" ? "flex" : "none";
}
});
}
var helpSearch = document.getElementById("help-nav-search");
var helpSearchClear = document.getElementById("help-search-clear");
if (helpSearchClear && helpSearch) {
helpSearchClear.addEventListener("click", function() {
helpSearch.value = "";
helpSearch.dispatchEvent(new Event("input"));
helpSearch.focus();
});
}
document.addEventListener("keydown", (e) => {
if (e.key === "Escape" && modal.classList.contains("active")) {
closeHelpModal();
@@ -883,7 +904,7 @@ function initConfigModal() {
});
}
// Logout button — handled inline in index.html (onclick)
// Logout button — wired here with addEventListener (#87, no inline onclick)
// Config nav search
var cfgSearch = document.getElementById("config-nav-search");
@@ -901,6 +922,16 @@ function initConfigModal() {
});
}
// Config search clear button (#87, ex-onclick inline).
var cfgSearchClear = document.getElementById("config-search-clear");
if (cfgSearchClear && cfgSearch) {
cfgSearchClear.addEventListener("click", function() {
cfgSearch.value = "";
cfgSearch.dispatchEvent(new Event("input"));
cfgSearch.focus();
});
}
// BUG-071/#114: mobile table of contents. #config-nav shares the .help-nav
// rule that hides it below 768px, but — unlike the help modal — the config
// modal had no toggle to reveal it, leaving mobile users with no way to
@@ -1575,13 +1606,15 @@ export async function openShareDialog(vault, path) {
<p style="font-size:0.85rem;color:var(--text-muted);margin-bottom:4px">${escapeHtml(vault)}/${escapeHtml(path)}</p>
${expiresInfo}
<p style="font-size:0.75rem;color:var(--text-muted);margin-bottom:8px">${existingShare.access_count} vue(s)</p>
<input type="text" class="share-url-input" value="${url}" readonly onclick="this.select()">
<input type="text" class="share-url-input" value="${url}" readonly>
<div class="share-dialog-actions">
<button class="share-copy-btn">📋 Copier le lien</button>
<button class="share-revoke-btn">🗑 Révoquer</button>
<button class="share-close-btn">Fermer</button>
</div>
</div>`;
const shareUrlInput = div.querySelector(".share-url-input");
if (shareUrlInput) shareUrlInput.addEventListener("click", function() { shareUrlInput.select(); });
div.querySelector(".share-copy-btn").addEventListener("click", async () => {
try {
await navigator.clipboard.writeText(url);
@@ -2525,7 +2558,10 @@ function initProfile() {
} catch(e) {}
});
// Logout button — handled inline in index.html (onclick)
// Logout button (#87, ex-onclick inline in index.html).
if (logoutBtn && window.handleLogout) {
logoutBtn.addEventListener('click', function() { window.handleLogout(); });
}
// ── Avatar (#113) ────────────────────────────────────────────────
var avatarField = document.getElementById('profile-avatar-field');