Improve security, accessibility, and performance

- Add Content Security Policy meta tag for XSS protection
- Add width/height to image for CLS prevention
- Add aria-hidden to decorative SVG icons (7 locations)
- Refactor inline onclick to addEventListener for CSP compliance
- Add visibility-aware setInterval for ping updates
- Add keyboard navigation (Arrow keys) for tab panels

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
kappa
2026-01-20 23:35:46 +09:00
parent 4c3bb09913
commit b1468b48a2
2 changed files with 73 additions and 12 deletions

62
app.js
View File

@@ -323,5 +323,63 @@ function updatePing() {
});
}
// Ping 업데이트 시작
setInterval(updatePing, 2000);
// Ping 업데이트 시작 (visibility-aware)
let pingInterval;
function startPingUpdates() {
if (!pingInterval) {
pingInterval = setInterval(updatePing, 2000);
}
}
function stopPingUpdates() {
if (pingInterval) {
clearInterval(pingInterval);
pingInterval = null;
}
}
// Visibility change handler
document.addEventListener('visibilitychange', () => {
if (document.hidden) {
stopPingUpdates();
} else {
startPingUpdates();
}
});
// Initial start
startPingUpdates();
// Tab switching with event listeners and keyboard navigation
document.addEventListener('DOMContentLoaded', () => {
const btnN8n = document.getElementById('btn-n8n');
const btnTf = document.getElementById('btn-tf');
if (btnN8n && btnTf) {
// Click event listeners
btnN8n.addEventListener('click', () => switchTab('n8n'));
btnTf.addEventListener('click', () => switchTab('tf'));
// Keyboard navigation (Arrow keys)
[btnN8n, btnTf].forEach(btn => {
btn.addEventListener('keydown', (e) => {
const currentTab = btn.getAttribute('data-tab');
if (e.key === 'ArrowRight') {
e.preventDefault();
if (currentTab === 'n8n') {
btnTf.focus();
switchTab('tf');
}
} else if (e.key === 'ArrowLeft') {
e.preventDefault();
if (currentTab === 'tf') {
btnN8n.focus();
switchTab('n8n');
}
}
});
});
}
});