import { esc, stripTags } from './utils.js'; export function createNotesEditor(options) { options = options || {}; var editor = null; function mount(container, initialHtml) { var T = window.Tiptap || {}; if (!T.Editor) { container.innerHTML = ''; editor = null; var fb = container.querySelector('.notes-body-fallback'); if (fb) fb.addEventListener('input', function() { markDirty(); }); return; } container.innerHTML = toolbarHTML() + '
'; editor = new T.Editor({ element: container.querySelector('.tp-content'), extensions: [ T.StarterKit, T.Link.configure({ openOnClick: false, autolink: true }), T.Underline ], content: initialHtml || '', autofocus: false, onUpdate: function() { markDirty(); updateToolbarState(container); }, onSelectionUpdate: function() { updateToolbarState(container); } }); wireToolbar(container, editor); } function destroy() { if (!editor) return; editor.destroy(); editor = null; } function getBody() { if (!editor) { var fb = document.querySelector('.notes-body-fallback'); return fb ? fb.value : ''; } var html = editor.getHTML(); return (html === '

' || html === '') ? '' : html; } function applyGenerated(container, body) { if (editor && typeof editor.commands === 'object') { try { editor.commands.setContent(body || '

', { emitUpdate: true }); if (typeof options.onDirty === 'function') options.onDirty(); return; } catch (err) { console.warn('[notes] Tiptap setContent failed, rebuilding:', err && err.message); } } destroy(); mount(container, body || '

'); if (typeof options.onDirty === 'function') options.onDirty(); } function markDirty() { if (typeof options.onDirty === 'function') options.onDirty(); if (typeof options.onStatus === 'function') options.onStatus('Saving...', 'saving'); if (typeof options.onAutosave === 'function') options.onAutosave(); } function toolbarHTML() { var btns = '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + ''; return '' + '
' + btns + '
' + ''; } function wireToolbar(wrap, ed) { var toolbar = wrap.querySelector('.tp-toolbar'); var linkBar = wrap.querySelector('.tp-link-bar'); var linkInput = wrap.querySelector('.tp-link-input'); toolbar.addEventListener('mousedown', function(e) { var btn = e.target.closest('.tp-btn[data-cmd]'); if (!btn) return; e.preventDefault(); var cmd = btn.dataset.cmd; switch (cmd) { case 'bold': ed.chain().focus().toggleBold().run(); break; case 'italic': ed.chain().focus().toggleItalic().run(); break; case 'underline': ed.chain().focus().toggleUnderline().run(); break; case 'strike': ed.chain().focus().toggleStrike().run(); break; case 'h2': ed.chain().focus().toggleHeading({ level: 2 }).run(); break; case 'h3': ed.chain().focus().toggleHeading({ level: 3 }).run(); break; case 'bulletList': ed.chain().focus().toggleBulletList().run(); break; case 'orderedList': ed.chain().focus().toggleOrderedList().run(); break; case 'blockquote': ed.chain().focus().toggleBlockquote().run(); break; case 'codeBlock': ed.chain().focus().toggleCodeBlock().run(); break; case 'clear': ed.chain().focus().unsetAllMarks().clearNodes().run(); break; case 'link': if (linkBar.style.display === 'none') { linkInput.value = ed.getAttributes('link').href || ''; linkBar.style.display = 'flex'; setTimeout(function() { linkInput.focus(); }, 0); } else { linkBar.style.display = 'none'; } break; } updateToolbarState(wrap); }); wrap.querySelector('.tp-link-apply').addEventListener('mousedown', function(e) { e.preventDefault(); var url = linkInput.value.trim(); if (url) ed.chain().focus().extendMarkRange('link').setLink({ href: url }).run(); linkBar.style.display = 'none'; }); wrap.querySelector('.tp-link-remove').addEventListener('mousedown', function(e) { e.preventDefault(); ed.chain().focus().unsetLink().run(); linkBar.style.display = 'none'; }); wrap.querySelector('.tp-link-cancel').addEventListener('mousedown', function(e) { e.preventDefault(); linkBar.style.display = 'none'; }); linkInput.addEventListener('keydown', function(e) { if (e.key === 'Enter') { e.preventDefault(); wrap.querySelector('.tp-link-apply').dispatchEvent(new MouseEvent('mousedown')); } if (e.key === 'Escape') { linkBar.style.display = 'none'; } }); } function updateToolbarState(wrap) { if (!editor) return; wrap.querySelectorAll('.tp-btn[data-cmd]').forEach(function(btn) { var cmd = btn.dataset.cmd; var active = false; if (cmd === 'bold') active = editor.isActive('bold'); else if (cmd === 'italic') active = editor.isActive('italic'); else if (cmd === 'underline') active = editor.isActive('underline'); else if (cmd === 'strike') active = editor.isActive('strike'); else if (cmd === 'h2') active = editor.isActive('heading', { level: 2 }); else if (cmd === 'h3') active = editor.isActive('heading', { level: 3 }); else if (cmd === 'bulletList') active = editor.isActive('bulletList'); else if (cmd === 'orderedList') active = editor.isActive('orderedList'); else if (cmd === 'blockquote') active = editor.isActive('blockquote'); else if (cmd === 'codeBlock') active = editor.isActive('codeBlock'); else if (cmd === 'link') active = editor.isActive('link'); btn.classList.toggle('active', active); }); } return { mount: mount, destroy: destroy, getBody: getBody, applyGenerated: applyGenerated }; }