/** * Blocknotes Application Main JavaScript (Vanilla JS) */ document.addEventListener("DOMContentLoaded", function() { // --- 1. MODALS OPEN & CLOSE HANDLERS --- document.querySelectorAll('[data-modal-target]').forEach(function(trigger) { trigger.addEventListener('click', function(e) { e.preventDefault(); const modalId = this.getAttribute('data-modal-target'); const modal = document.getElementById(modalId); if (modal) { modal.classList.add('active'); } }); }); document.querySelectorAll('.modal-close-btn, .modal-close-trigger').forEach(function(closeBtn) { closeBtn.addEventListener('click', function() { const modal = this.closest('.modal-backdrop'); if (modal) { modal.classList.remove('active'); } }); }); // Close modal when clicking on backdrop outside modal-card document.querySelectorAll('.modal-backdrop').forEach(function(backdrop) { backdrop.addEventListener('click', function(e) { if (e.target === this) { this.classList.remove('active'); } }); }); // --- 2. LIVE HSL THEME COLOR PREVIEW (PROFILE PAGE) --- const priInput = document.getElementById('theme_pri'); const secInput = document.getElementById('theme_sec'); const thiInput = document.getElementById('theme_thi'); if (priInput && secInput && thiInput) { function updateLiveTheme() { const priVal = priInput.value; const secVal = secInput.value; const thiVal = thiInput.value; document.documentElement.style.setProperty('--pri', priVal); document.documentElement.style.setProperty('--sec', secVal); document.documentElement.style.setProperty('--thi', thiVal); const priValDisp = document.getElementById('pri_val'); const secValDisp = document.getElementById('sec_val'); const thiValDisp = document.getElementById('thi_val'); if (priValDisp) priValDisp.textContent = priVal + '°'; if (secValDisp) secValDisp.textContent = secVal + '°'; if (thiValDisp) thiValDisp.textContent = thiVal + '°'; } priInput.addEventListener('input', updateLiveTheme); secInput.addEventListener('input', updateLiveTheme); thiInput.addEventListener('input', updateLiveTheme); } }); /** * Copy text to clipboard with fallback and localized feedback */ function copyToClipboard(btnElement, textToCopy) { if (navigator.clipboard && window.isSecureContext) { navigator.clipboard.writeText(textToCopy).then(() => { handleCopySuccess(btnElement); }).catch(() => { fallbackCopyText(btnElement, textToCopy); }); } else { fallbackCopyText(btnElement, textToCopy); } } function fallbackCopyText(btnElement, textToCopy) { let textArea = document.createElement("textarea"); textArea.value = textToCopy; textArea.style.position = "fixed"; textArea.style.left = "-999999px"; document.body.appendChild(textArea); textArea.focus(); textArea.select(); try { document.execCommand('copy'); handleCopySuccess(btnElement); } catch (err) { console.error('Fallback copy failed', err); } document.body.removeChild(textArea); } function handleCopySuccess(btnElement) { if (!btnElement) return; const originalHTML = btnElement.innerHTML; const copiedLabel = btnElement.getAttribute('data-copied-text') || '✓ Copiato!'; btnElement.innerHTML = copiedLabel; btnElement.classList.add('copied'); setTimeout(() => { btnElement.innerHTML = originalHTML; btnElement.classList.remove('copied'); }, 2000); } /** * Toggle collapse state for a specific note block */ function toggleNoteCollapse(noteId) { const noteBlock = document.getElementById('note-block-' + noteId); if (noteBlock) { noteBlock.classList.toggle('collapsed'); } } /** * Expand all note blocks on page */ function expandAllNotes() { document.querySelectorAll('.note-block').forEach(function(nb) { nb.classList.remove('collapsed'); }); } /** * Collapse all note blocks on page */ function collapseAllNotes() { document.querySelectorAll('.note-block').forEach(function(nb) { nb.classList.add('collapsed'); }); } /** * Filter notes and subnotes within the current blocknote in real-time */ function filterCurrentBlocknoteNotes(query) { const term = query.toLowerCase().trim(); const clearBtn = document.getElementById('clear-search-btn'); const noResults = document.getElementById('no-search-results'); const noteBlocks = document.querySelectorAll('.note-block'); if (clearBtn) { clearBtn.style.display = term ? 'inline-flex' : 'none'; } let totalMatches = 0; noteBlocks.forEach(function(noteBlock) { if (!term) { // Reset search noteBlock.style.display = ''; noteBlock.classList.add('collapsed'); noteBlock.querySelectorAll('.subnote-card').forEach(function(sub) { sub.style.display = ''; }); totalMatches++; return; } const noteTitle = (noteBlock.querySelector('.note-title-wrapper h3')?.innerText || '').toLowerCase(); const noteDesc = (noteBlock.querySelector('.note-description-box p')?.innerText || '').toLowerCase(); const noteTitleMatch = noteTitle.includes(term) || noteDesc.includes(term); let subnoteMatchCount = 0; const subnoteCards = noteBlock.querySelectorAll('.subnote-card'); subnoteCards.forEach(function(subCard) { const subTitle = (subCard.querySelector('.subnote-title')?.innerText || '').toLowerCase(); const subContent = (subCard.querySelector('.subnote-content-text, .command-code')?.innerText || '').toLowerCase(); if (noteTitleMatch || subTitle.includes(term) || subContent.includes(term)) { subCard.style.display = ''; subnoteMatchCount++; } else { subCard.style.display = 'none'; } }); if (noteTitleMatch || subnoteMatchCount > 0) { noteBlock.style.display = ''; noteBlock.classList.remove('collapsed'); // Auto expand on match totalMatches++; } else { noteBlock.style.display = 'none'; } }); if (noResults) { if (term && totalMatches === 0) { noResults.style.display = 'block'; } else { noResults.style.display = 'none'; } } } /** * Clear search input and restore view */ function clearNoteSearch() { const input = document.getElementById('note-search-input'); if (input) { input.value = ''; filterCurrentBlocknoteNotes(''); } }