diora-web/static/js/app/26-sidebar.js

99 lines
3.6 KiB
JavaScript
Raw Permalink Normal View History

'use strict';
// ---------------------------------------------------------------------------
// Sidebar
// ---------------------------------------------------------------------------
function openSidebar(title, htmlContent) {
$('sidebar-title').textContent = title;
$('sidebar-body').innerHTML = sanitizeSidebarHtml(htmlContent);
$('sidebar-overlay').style.display = '';
$('sidebar').classList.add('open');
}
function closeSidebar() {
$('sidebar').classList.remove('open');
$('sidebar-overlay').style.display = 'none';
}
document.addEventListener('keydown', e => {
const overlay = $('reader-overlay');
const readerOpen = overlay && overlay.style.display !== 'none';
if (e.key === 'Escape') {
if (readerOpen) {
closeReader();
} else {
closeSidebar();
}
}
if (readerOpen) {
if ((e.ctrlKey && e.key === 'f') || e.key === 'F3') {
e.preventDefault();
toggleReaderSearch();
}
if (readerSearchOpen) {
if (e.key === 'ArrowDown') { e.preventDefault(); readerSearchNext(); }
if (e.key === 'ArrowUp') { e.preventDefault(); readerSearchPrev(); }
}
if (readerSettings.pdfPaginated && currentPdfDoc) {
if (e.key === 'ArrowRight') { e.preventDefault(); pdfGoToPage(pdfCurrentPage + 1); }
if (e.key === 'ArrowLeft') { e.preventDefault(); pdfGoToPage(pdfCurrentPage - 1); }
}
// Vim-style scroll — ignore when typing in an input
const tag = document.activeElement?.tagName;
if (tag !== 'INPUT' && tag !== 'TEXTAREA') {
const contentEl = $('reader-content');
if (contentEl) {
const large = Math.round(contentEl.clientHeight * 0.85);
const continuousKeys = {'j': 1, 'k': -1};
if (continuousKeys[e.key] !== undefined && !e.repeat) {
e.preventDefault();
_readerScrollDir = continuousKeys[e.key];
if (!_readerScrollInterval) {
_readerScrollLastTs = performance.now();
_readerScrollInterval = setInterval(_readerScrollTick, READER_SCROLL_TICK_MS);
}
}
if (e.key === 'd') { e.preventDefault(); contentEl.scrollBy({top: large / 2, behavior: 'smooth'}); }
if (e.key === 'u') { e.preventDefault(); contentEl.scrollBy({top: -large / 2, behavior: 'smooth'}); }
if (e.key === 'f') { e.preventDefault(); contentEl.scrollBy({top: large, behavior: 'smooth'}); }
if (e.key === 'b') { e.preventDefault(); contentEl.scrollBy({top: -large, behavior: 'smooth'}); }
if (e.key === 'g') { e.preventDefault(); contentEl.scrollTop = 0; }
if (e.key === 'G') { e.preventDefault(); contentEl.scrollTop = contentEl.scrollHeight; }
if (currentPdfDoc && !readerSettings.pdfPaginated) {
if (e.key === 'n') { e.preventDefault(); pdfGoToPage(pdfCurrentPage + 1); }
if (e.key === 'p') { e.preventDefault(); pdfGoToPage(pdfCurrentPage - 1); }
}
}
}
}
});
document.addEventListener('keyup', e => {
if (e.key === 'j' || e.key === 'k') {
clearInterval(_readerScrollInterval);
_readerScrollInterval = null;
_readerScrollDir = 0;
}
});
function sanitizeSidebarHtml(html) {
if (!html) return '<p class="muted">Keine Shownotes vorhanden.</p>';
const div = document.createElement('div');
div.innerHTML = html;
div.querySelectorAll('script, iframe, object, embed, style').forEach(el => el.remove());
div.querySelectorAll('*').forEach(el => {
Array.from(el.attributes).forEach(attr => {
if (attr.name.startsWith('on')) el.removeAttribute(attr.name);
});
if (el.tagName === 'A') {
el.setAttribute('target', '_blank');
el.setAttribute('rel', 'noopener noreferrer');
}
});
return div.innerHTML;
}