(function() { var __cfg = document.getElementById('partial-item-text-editor-cfg'); var ITEM_ID = __cfg ? __cfg.dataset.itemId : ''; function switchEditorTab(tab) { document.querySelectorAll('.editor-tab').forEach(t => t.classList.remove('is-selected')); document.querySelector('.editor-tab[data-tab="' + tab + '"]').classList.add('is-selected'); document.querySelectorAll('.editor-panel').forEach(p => p.classList.remove('active')); document.getElementById(tab + '-panel').classList.add('active'); if (tab === 'preview') { renderMarkdownPreview(); } } function renderMarkdownPreview() { const body = document.getElementById('text-body').value; const preview = document.getElementById('markdown-preview'); // Basic markdown rendering (paragraphs, bold, italic, headers) let html = body .split('\n\n').map(p => p.trim()).filter(p => p).map(p => { // Headers if (p.startsWith('### ')) return '
$1');
return '' + text + '
'; }).join('\n'); preview.innerHTML = html || 'Nothing to preview...
'; } function updateWordCount() { const body = document.getElementById('text-body').value; const words = body.trim().split(/\s+/).filter(w => w).length; const readingTime = Math.max(1, Math.ceil(words / 200)); document.getElementById('word-count').textContent = words + ' words'; document.querySelector('.reading-time').textContent = readingTime + ' min read'; } function saveTextContent() { const body = document.getElementById('text-body').value; const btn = document.getElementById('save-text-btn'); const status = document.getElementById('text-save-status'); const itemId = ITEM_ID; btn.disabled = true; status.innerHTML = ''; fetch('/api/items/' + itemId + '/text', { method: 'PUT', headers: { 'Content-Type': 'application/json', ...csrfHeaders() }, body: JSON.stringify({ body: body }) }) .then(res => res.json()) .then(data => { status.innerHTML = 'Saved'; if (data.word_count !== undefined) { document.getElementById('word-count').textContent = data.word_count + ' words'; } }) .catch(err => { status.innerHTML = 'Error saving'; }) .finally(() => { btn.disabled = false; }); } document.getElementById('text-body').addEventListener('input', updateWordCount); // Auto-save: debounce text body changes (30s after last keystroke) var autoSaveTimer = null; var autoSaveStatus = document.getElementById('text-save-status'); document.getElementById('text-body').addEventListener('input', function() { clearTimeout(autoSaveTimer); autoSaveTimer = setTimeout(function() { autoSaveStatus.innerHTML = 'Saving...'; var body = document.getElementById('text-body').value; fetch('/api/items/' + ITEM_ID + '/text', { method: 'PUT', headers: { 'Content-Type': 'application/json', ...csrfHeaders() }, body: JSON.stringify({ body: body }) }) .then(function(res) { return res.json(); }) .then(function(data) { autoSaveStatus.innerHTML = 'Auto-saved'; if (data.word_count !== undefined) { document.getElementById('word-count').textContent = data.word_count + ' words'; } setTimeout(function() { if (autoSaveStatus.textContent === 'Auto-saved') autoSaveStatus.innerHTML = ''; }, 3000); }) .catch(function() { autoSaveStatus.innerHTML = 'Auto-save failed'; }); }, 30000); }); window.switchEditorTab = switchEditorTab; window.renderMarkdownPreview = renderMarkdownPreview; window.escapeHtml = escapeHtml; window.updateWordCount = updateWordCount; window.saveTextContent = saveTextContent; })();