@noseberry/nbd-editor 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +538 -0
- package/dist/nbd-editor.cjs.js +2 -0
- package/dist/nbd-editor.cjs.js.map +1 -0
- package/dist/nbd-editor.css +1 -0
- package/dist/nbd-editor.esm.js +2 -0
- package/dist/nbd-editor.esm.js.map +1 -0
- package/dist/nbd-editor.umd.js +2 -0
- package/dist/nbd-editor.umd.js.map +1 -0
- package/package.json +60 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nbd-editor.umd.js","sources":["../src/utils/EventEmitter.js","../src/utils/dom.js","../src/utils/icons.js","../src/core/BlockManager.js","../src/core/MediaUploader.js","../src/core/DragDrop.js","../src/blocks/registry.js","../src/blocks/BlockRenderer.js","../src/ui/Header.js","../src/ui/Toolbar.js","../src/ui/InserterPanel.js","../src/ui/SettingsPanel.js","../src/ui/SlashMenu.js","../src/ui/StatusBar.js","../src/NBDEditor.js","../src/react/ReactNBDEditor.js"],"sourcesContent":["/**\n * Lightweight event emitter for editor internals.\n */\nexport class EventEmitter {\n constructor() {\n this._listeners = {};\n }\n\n on(event, fn) {\n (this._listeners[event] ||= []).push(fn);\n return () => this.off(event, fn);\n }\n\n off(event, fn) {\n const list = this._listeners[event];\n if (!list) return;\n this._listeners[event] = list.filter((f) => f !== fn);\n }\n\n emit(event, ...args) {\n (this._listeners[event] || []).forEach((fn) => fn(...args));\n }\n\n once(event, fn) {\n const wrapper = (...args) => {\n this.off(event, wrapper);\n fn(...args);\n };\n this.on(event, wrapper);\n }\n}\n","/**\n * DOM helper utilities.\n */\n\nexport function el(tag, attrs = {}, children = []) {\n const node = document.createElement(tag);\n for (const [k, v] of Object.entries(attrs)) {\n if (k === 'className') node.className = v;\n else if (k === 'style' && typeof v === 'object') Object.assign(node.style, v);\n else if (k === 'dataset' && typeof v === 'object') {\n for (const [dk, dv] of Object.entries(v)) node.dataset[dk] = dv;\n } else if (k.startsWith('on') && typeof v === 'function') {\n node.addEventListener(k.slice(2).toLowerCase(), v);\n } else if (k === 'contentEditable') {\n node.contentEditable = v;\n } else if (k === 'innerHTML') {\n node.innerHTML = v;\n } else {\n node.setAttribute(k, v);\n }\n }\n for (const child of (Array.isArray(children) ? children : [children])) {\n if (typeof child === 'string') node.appendChild(document.createTextNode(child));\n else if (child instanceof Node) node.appendChild(child);\n }\n return node;\n}\n\nexport function qs(sel, root = document) {\n return root.querySelector(sel);\n}\n\nexport function qsa(sel, root = document) {\n return [...root.querySelectorAll(sel)];\n}\n\nexport function generateId() {\n return 'blk_' + Date.now().toString(36) + '_' + Math.random().toString(36).slice(2, 8);\n}\n\nexport function stripHTML(html) {\n const tmp = document.createElement('div');\n tmp.innerHTML = html;\n return tmp.textContent || '';\n}\n\nexport function getCaretRect() {\n const sel = window.getSelection();\n if (!sel || !sel.rangeCount) return null;\n const range = sel.getRangeAt(0);\n return range.getBoundingClientRect();\n}\n\nexport function placeCaretAtEnd(element) {\n element.focus();\n const range = document.createRange();\n range.selectNodeContents(element);\n range.collapse(false);\n const sel = window.getSelection();\n sel.removeAllRanges();\n sel.addRange(range);\n}\n\nexport function placeCaretAtStart(element) {\n element.focus();\n const range = document.createRange();\n range.selectNodeContents(element);\n range.collapse(true);\n const sel = window.getSelection();\n sel.removeAllRanges();\n sel.addRange(range);\n}\n","/**\n * SVG icons used throughout the editor.\n */\n\nconst svg = (inner, vb = '0 0 24 24') =>\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"${vb}\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">${inner}</svg>`;\n\nconst filled = (inner, vb = '0 0 24 24') =>\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"${vb}\" fill=\"currentColor\">${inner}</svg>`;\n\nexport const icons = {\n plus: svg('<line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/>'),\n undo: svg('<path d=\"M3 10h13a4 4 0 010 8H7\"/><path d=\"M3 10l4-4M3 10l4 4\"/>'),\n redo: svg('<path d=\"M21 10H8a4 4 0 000 8h9\"/><path d=\"M21 10l-4-4M21 10l-4 4\"/>'),\n listView: svg('<line x1=\"8\" y1=\"6\" x2=\"21\" y2=\"6\"/><line x1=\"8\" y1=\"12\" x2=\"21\" y2=\"12\"/><line x1=\"8\" y1=\"18\" x2=\"21\" y2=\"18\"/><line x1=\"3\" y1=\"6\" x2=\"3.01\" y2=\"6\"/><line x1=\"3\" y1=\"12\" x2=\"3.01\" y2=\"12\"/><line x1=\"3\" y1=\"18\" x2=\"3.01\" y2=\"18\"/>'),\n settings: svg('<circle cx=\"12\" cy=\"12\" r=\"3\"/><path d=\"M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 01-2.83 2.83l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-4 0v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83-2.83l.06-.06A1.65 1.65 0 004.68 15a1.65 1.65 0 00-1.51-1H3a2 2 0 010-4h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 012.83-2.83l.06.06A1.65 1.65 0 009 4.68a1.65 1.65 0 001-1.51V3a2 2 0 014 0v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 2.83l-.06.06A1.65 1.65 0 0019.4 9a1.65 1.65 0 001.51 1H21a2 2 0 010 4h-.09a1.65 1.65 0 00-1.51 1z\"/>'),\n moreVert: filled('<circle cx=\"12\" cy=\"5\" r=\"1.5\"/><circle cx=\"12\" cy=\"12\" r=\"1.5\"/><circle cx=\"12\" cy=\"19\" r=\"1.5\"/>'),\n bold: '<b>B</b>',\n italic: '<i>I</i>',\n underline: '<u>U</u>',\n strikethrough: '<s>S</s>',\n link: svg('<path d=\"M10 13a5 5 0 007.54.54l3-3a5 5 0 00-7.07-7.07l-1.72 1.71\"/><path d=\"M14 11a5 5 0 00-7.54-.54l-3 3a5 5 0 007.07 7.07l1.71-1.71\"/>'),\n code: svg('<polyline points=\"16 18 22 12 16 6\"/><polyline points=\"8 6 2 12 8 18\"/>'),\n alignLeft: svg('<line x1=\"17\" y1=\"10\" x2=\"3\" y2=\"10\"/><line x1=\"21\" y1=\"6\" x2=\"3\" y2=\"6\"/><line x1=\"21\" y1=\"14\" x2=\"3\" y2=\"14\"/><line x1=\"17\" y1=\"18\" x2=\"3\" y2=\"18\"/>'),\n alignCenter: svg('<line x1=\"18\" y1=\"10\" x2=\"6\" y2=\"10\"/><line x1=\"21\" y1=\"6\" x2=\"3\" y2=\"6\"/><line x1=\"21\" y1=\"14\" x2=\"3\" y2=\"14\"/><line x1=\"18\" y1=\"18\" x2=\"6\" y2=\"18\"/>'),\n alignRight: svg('<line x1=\"21\" y1=\"10\" x2=\"7\" y2=\"10\"/><line x1=\"21\" y1=\"6\" x2=\"3\" y2=\"6\"/><line x1=\"21\" y1=\"14\" x2=\"3\" y2=\"14\"/><line x1=\"21\" y1=\"18\" x2=\"7\" y2=\"18\"/>'),\n image: svg('<rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"/><circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\"/><polyline points=\"21 15 16 10 5 21\"/>'),\n heading: '<b>H</b>',\n paragraph: '<span style=\"font-size:16px\">¶</span>',\n quote: '<span style=\"font-size:18px\">❝</span>',\n list: svg('<line x1=\"8\" y1=\"6\" x2=\"21\" y2=\"6\"/><line x1=\"8\" y1=\"12\" x2=\"21\" y2=\"12\"/><line x1=\"8\" y1=\"18\" x2=\"21\" y2=\"18\"/><circle cx=\"4\" cy=\"6\" r=\"1\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"4\" cy=\"12\" r=\"1\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"4\" cy=\"18\" r=\"1\" fill=\"currentColor\" stroke=\"none\"/>'),\n orderedList: svg('<line x1=\"10\" y1=\"6\" x2=\"21\" y2=\"6\"/><line x1=\"10\" y1=\"12\" x2=\"21\" y2=\"12\"/><line x1=\"10\" y1=\"18\" x2=\"21\" y2=\"18\"/><text x=\"3\" y=\"8\" font-size=\"7\" fill=\"currentColor\" stroke=\"none\" font-family=\"sans-serif\">1</text><text x=\"3\" y=\"14\" font-size=\"7\" fill=\"currentColor\" stroke=\"none\" font-family=\"sans-serif\">2</text><text x=\"3\" y=\"20\" font-size=\"7\" fill=\"currentColor\" stroke=\"none\" font-family=\"sans-serif\">3</text>'),\n separator: svg('<line x1=\"3\" y1=\"12\" x2=\"21\" y2=\"12\"/>'),\n table: svg('<rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\"/><line x1=\"3\" y1=\"9\" x2=\"21\" y2=\"9\"/><line x1=\"3\" y1=\"15\" x2=\"21\" y2=\"15\"/><line x1=\"9\" y1=\"3\" x2=\"9\" y2=\"21\"/><line x1=\"15\" y1=\"3\" x2=\"15\" y2=\"21\"/>'),\n button: svg('<rect x=\"3\" y=\"7\" width=\"18\" height=\"10\" rx=\"3\"/>'),\n columns: svg('<rect x=\"3\" y=\"3\" width=\"7\" height=\"18\" rx=\"1\"/><rect x=\"14\" y=\"3\" width=\"7\" height=\"18\" rx=\"1\"/>'),\n spacer: svg('<path d=\"M12 5v14M5 12h14\"/>', '0 0 24 24'),\n embed: svg('<path d=\"M10 13a5 5 0 007.54.54l3-3a5 5 0 00-7.07-7.07l-1.72 1.71\"/><path d=\"M14 11a5 5 0 00-7.54-.54l-3 3a5 5 0 007.07 7.07l1.71-1.71\"/>'),\n gallery: svg('<rect x=\"2\" y=\"2\" width=\"8\" height=\"8\" rx=\"1\"/><rect x=\"14\" y=\"2\" width=\"8\" height=\"8\" rx=\"1\"/><rect x=\"2\" y=\"14\" width=\"8\" height=\"8\" rx=\"1\"/><rect x=\"14\" y=\"14\" width=\"8\" height=\"8\" rx=\"1\"/>'),\n video: svg('<polygon points=\"5 3 19 12 5 21 5 3\"/>'),\n audio: svg('<path d=\"M9 18V5l12-2v13\"/><circle cx=\"6\" cy=\"18\" r=\"3\"/><circle cx=\"18\" cy=\"16\" r=\"3\"/>'),\n file: svg('<path d=\"M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z\"/><polyline points=\"14 2 14 8 20 8\"/><line x1=\"16\" y1=\"13\" x2=\"8\" y2=\"13\"/><line x1=\"16\" y1=\"17\" x2=\"8\" y2=\"17\"/>'),\n dragHandle: filled('<circle cx=\"9\" cy=\"5\" r=\"1.2\"/><circle cx=\"15\" cy=\"5\" r=\"1.2\"/><circle cx=\"9\" cy=\"10\" r=\"1.2\"/><circle cx=\"15\" cy=\"10\" r=\"1.2\"/><circle cx=\"9\" cy=\"15\" r=\"1.2\"/><circle cx=\"15\" cy=\"15\" r=\"1.2\"/><circle cx=\"9\" cy=\"20\" r=\"1.2\"/><circle cx=\"15\" cy=\"20\" r=\"1.2\"/>'),\n arrowUp: svg('<polyline points=\"18 15 12 9 6 15\"/>'),\n arrowDown: svg('<polyline points=\"6 9 12 15 18 9\"/>'),\n trash: svg('<polyline points=\"3 6 5 6 21 6\"/><path d=\"M19 6l-1 14a2 2 0 01-2 2H8a2 2 0 01-2-2L5 6\"/><path d=\"M10 11v6M14 11v6\"/><path d=\"M9 6V4a1 1 0 011-1h4a1 1 0 011 1v2\"/>'),\n close: svg('<line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/>'),\n check: svg('<polyline points=\"20 6 9 17 4 12\"/>'),\n inlineCode: '<span style=\"font-family:monospace;font-size:13px\"></></span>',\n upload: svg('<path d=\"M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4\"/><polyline points=\"17 8 12 3 7 8\"/><line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"15\"/>'),\n externalLink: svg('<path d=\"M18 13v6a2 2 0 01-2 2H5a2 2 0 01-2-2V8a2 2 0 012-2h6\"/><polyline points=\"15 3 21 3 21 9\"/><line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\"/>'),\n html: '<span style=\"font-family:monospace;font-size:11px\"><HTML></span>',\n pullquote: svg('<path d=\"M3 21c3 0 7-1 7-8V5c0-1.25-.756-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V20c0 1 0 1 1 1z\"/><path d=\"M15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3c0 1 0 1 1 1z\"/>'),\n};\n","import { generateId } from '../utils/dom.js';\nimport { EventEmitter } from '../utils/EventEmitter.js';\n\n/**\n * Manages the block data model: add, remove, move, update, and undo/redo.\n */\nexport class BlockManager extends EventEmitter {\n constructor() {\n super();\n this.blocks = [];\n this._undoStack = [];\n this._redoStack = [];\n this._maxHistory = 100;\n this._undoStack.push(JSON.stringify(this.blocks));\n }\n\n /* ---- CRUD ---- */\n\n addBlock(type, data = {}, afterId = null) {\n const block = {\n id: generateId(),\n type,\n content: '',\n attrs: {},\n ...data,\n };\n\n if (afterId) {\n const idx = this.blocks.findIndex((b) => b.id === afterId);\n this.blocks.splice(idx + 1, 0, block);\n } else {\n this.blocks.push(block);\n }\n\n this._pushUndo();\n this.emit('block:added', block);\n this.emit('change', this.blocks);\n return block;\n }\n\n removeBlock(id) {\n const idx = this.blocks.findIndex((b) => b.id === id);\n if (idx === -1) return;\n if (this.blocks.length <= 1) return; // keep at least one block\n const [removed] = this.blocks.splice(idx, 1);\n this._pushUndo();\n this.emit('block:removed', removed, idx);\n this.emit('change', this.blocks);\n return removed;\n }\n\n updateBlock(id, patch) {\n const block = this.getBlock(id);\n if (!block) return;\n Object.assign(block, patch);\n this.emit('block:updated', block);\n this.emit('change', this.blocks);\n }\n\n changeBlockType(id, newType) {\n const block = this.getBlock(id);\n if (!block) return;\n block.type = newType;\n this._pushUndo();\n this.emit('block:typeChanged', block);\n this.emit('change', this.blocks);\n }\n\n moveBlock(id, direction) {\n const idx = this.blocks.findIndex((b) => b.id === id);\n const newIdx = idx + direction;\n if (newIdx < 0 || newIdx >= this.blocks.length) return;\n [this.blocks[idx], this.blocks[newIdx]] = [this.blocks[newIdx], this.blocks[idx]];\n this._pushUndo();\n this.emit('block:moved', this.blocks[newIdx], direction);\n this.emit('change', this.blocks);\n }\n\n duplicateBlock(id) {\n const block = this.getBlock(id);\n if (!block) return;\n const clone = { ...block, id: generateId(), content: block.content, attrs: { ...block.attrs } };\n const idx = this.blocks.findIndex((b) => b.id === id);\n this.blocks.splice(idx + 1, 0, clone);\n this._pushUndo();\n this.emit('block:added', clone);\n this.emit('change', this.blocks);\n return clone;\n }\n\n /* ---- Queries ---- */\n\n getBlock(id) {\n return this.blocks.find((b) => b.id === id) || null;\n }\n\n getIndex(id) {\n return this.blocks.findIndex((b) => b.id === id);\n }\n\n getPrevBlock(id) {\n const idx = this.getIndex(id);\n return idx > 0 ? this.blocks[idx - 1] : null;\n }\n\n getNextBlock(id) {\n const idx = this.getIndex(id);\n return idx < this.blocks.length - 1 ? this.blocks[idx + 1] : null;\n }\n\n /* ---- Serialization ---- */\n\n toJSON() {\n return this.blocks.map((b) => ({ ...b }));\n }\n\n fromJSON(data) {\n this.blocks = data.map((b) => ({ ...b }));\n this._undoStack = [JSON.stringify(this.blocks)];\n this._redoStack = [];\n this.emit('change', this.blocks);\n }\n\n toHTML() {\n return this.blocks.map((b) => this.blockToHTML(b)).join('\\n');\n }\n\n toHTMLBlocks() {\n return this.blocks.map((b) => ({\n ...b,\n html: this.blockToHTML(b),\n }));\n }\n\n blockToHTML(block) {\n return blockToHTML(block);\n }\n\n /* ---- Undo / Redo ---- */\n\n _pushUndo() {\n const next = JSON.stringify(this.blocks);\n const last = this._undoStack[this._undoStack.length - 1];\n if (next === last) return;\n this._undoStack.push(next);\n if (this._undoStack.length > this._maxHistory) this._undoStack.shift();\n this._redoStack = [];\n }\n\n saveSnapshot() {\n this._pushUndo();\n }\n\n undo() {\n if (this._undoStack.length < 2) return false;\n this._redoStack.push(this._undoStack.pop());\n this.blocks = JSON.parse(this._undoStack[this._undoStack.length - 1]);\n this.emit('change', this.blocks);\n return true;\n }\n\n redo() {\n if (this._redoStack.length === 0) return false;\n const state = this._redoStack.pop();\n this._undoStack.push(state);\n this.blocks = JSON.parse(state);\n this.emit('change', this.blocks);\n return true;\n }\n\n /* ---- Stats ---- */\n\n getWordCount() {\n let text = '';\n for (const b of this.blocks) {\n if (b.content) {\n const tmp = document.createElement('div');\n tmp.innerHTML = b.content;\n text += tmp.textContent + ' ';\n }\n }\n const words = text.trim().split(/\\s+/).filter((w) => w.length > 0);\n return words.length;\n }\n\n getCharCount() {\n let text = '';\n for (const b of this.blocks) {\n if (b.content) {\n const tmp = document.createElement('div');\n tmp.innerHTML = b.content;\n text += tmp.textContent;\n }\n }\n return text.replace(/\\s/g, '').length;\n }\n}\n\n/* ---- Helpers ---- */\n\n/**\n * Escape a string for safe use inside an HTML attribute value.\n * Prevents XSS via attribute injection (e.g. `\" onload=\"alert(1)`).\n */\nfunction _escAttr(str) {\n if (!str) return '';\n return String(str)\n .replace(/&/g, '&')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/</g, '<')\n .replace(/>/g, '>');\n}\n\n/**\n * Escape a string for safe use as HTML text content.\n */\nfunction _escText(str) {\n if (!str) return '';\n return String(str)\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>');\n}\n\nfunction blockToHTML(block) {\n const c = block.content || '';\n switch (block.type) {\n case 'paragraph':\n return _containsBlockMarkup(c) ? c : `<p>${c}</p>`;\n case 'heading':\n return `<h2>${c}</h2>`;\n case 'heading-3':\n return `<h3>${c}</h3>`;\n case 'heading-4':\n return `<h4>${c}</h4>`;\n case 'quote':\n return `<blockquote>${c}</blockquote>`;\n case 'code':\n return `<pre><code>${_escText(c)}</code></pre>`;\n case 'list':\n return `<ul>${c}</ul>`;\n case 'ordered-list':\n return `<ol>${c}</ol>`;\n case 'image': {\n if (!c) return '';\n const width = Number(block.attrs?.width);\n const style = Number.isFinite(width) ? ` style=\"width:${Math.max(10, Math.min(100, Math.round(width)))}%\"` : '';\n return `<figure><img src=\"${_escAttr(c)}\" alt=\"${_escAttr(block.attrs?.alt || '')}\"${style}/>${block.attrs?.caption ? `<figcaption>${block.attrs.caption}</figcaption>` : ''}</figure>`;\n }\n case 'separator':\n return '<hr/>';\n case 'spacer':\n return `<div style=\"height:${Number(block.attrs?.height) || 48}px\"></div>`;\n case 'table':\n return c || '<table></table>';\n case 'button':\n return `<div class=\"wp-block-button\"><a class=\"wp-block-button__link\" href=\"${_escAttr(block.attrs?.url || '#')}\">${c || 'Button'}</a></div>`;\n case 'columns':\n return `<div class=\"wp-block-columns\">${c}</div>`;\n case 'embed':\n return `<figure class=\"wp-block-embed\"><div class=\"wp-block-embed__wrapper\">${c}</div></figure>`;\n case 'gallery':\n return `<figure class=\"wp-block-gallery\">${c}</figure>`;\n case 'video':\n return c ? `<figure class=\"wp-block-video\"><video controls src=\"${_escAttr(c)}\"></video></figure>` : '';\n case 'audio':\n return c ? `<figure class=\"wp-block-audio\"><audio controls src=\"${_escAttr(c)}\"></audio></figure>` : '';\n case 'file':\n return c ? `<div class=\"wp-block-file\"><a href=\"${_escAttr(c)}\">${_escText(block.attrs?.filename || 'Download')}</a></div>` : '';\n case 'html':\n return c;\n case 'pullquote':\n return `<figure class=\"wp-block-pullquote\"><blockquote>${c}</blockquote></figure>`;\n default:\n return `<p>${c}</p>`;\n }\n}\n\nfunction _containsBlockMarkup(html) {\n if (!html || typeof html !== 'string') return false;\n return /<(h[1-6]|p|div|section|article|blockquote|ul|ol|li|table|thead|tbody|tr|td|th|figure|figcaption|img|pre|hr)\\b/i.test(html);\n}\n","import { EventEmitter } from '../utils/EventEmitter.js';\n\n/**\n * Handles media uploads: images, video, audio, files.\n * Supports custom upload handlers, drag-and-drop, clipboard paste, and local preview.\n */\nexport class MediaUploader extends EventEmitter {\n constructor(options = {}) {\n super();\n this.uploadHandler = options.uploadHandler || null; // async (file) => { url, id }\n this.maxFileSize = options.maxFileSize || 10 * 1024 * 1024; // 10MB\n this.allowedImageTypes = options.allowedImageTypes || ['image/jpeg', 'image/png', 'image/gif', 'image/webp', 'image/svg+xml'];\n this.allowedVideoTypes = options.allowedVideoTypes || ['video/mp4', 'video/webm', 'video/ogg'];\n this.allowedAudioTypes = options.allowedAudioTypes || ['audio/mpeg', 'audio/ogg', 'audio/wav', 'audio/webm'];\n this._fileInput = null;\n }\n\n /**\n * Create a hidden file input and trigger it.\n */\n openFilePicker(accept = 'image/*', multiple = false) {\n return new Promise((resolve) => {\n if (this._fileInput) this._fileInput.remove();\n const input = document.createElement('input');\n input.type = 'file';\n input.accept = accept;\n input.multiple = multiple;\n input.style.display = 'none';\n document.body.appendChild(input);\n this._fileInput = input;\n\n input.addEventListener('change', () => {\n const files = [...input.files];\n input.remove();\n this._fileInput = null;\n resolve(files);\n });\n\n input.addEventListener('cancel', () => {\n input.remove();\n this._fileInput = null;\n resolve([]);\n });\n\n input.click();\n });\n }\n\n /**\n * Process a file: validate, generate local preview, then optionally upload.\n * Returns { localUrl, remoteUrl?, file, error? }\n */\n async processFile(file) {\n // Validate size\n if (file.size > this.maxFileSize) {\n const err = `File \"${file.name}\" exceeds the ${(this.maxFileSize / 1024 / 1024).toFixed(0)}MB limit.`;\n this.emit('error', err);\n return { error: err, file };\n }\n\n // Generate local preview\n const localUrl = await this._readAsDataURL(file);\n this.emit('preview', { file, localUrl });\n\n // If a custom upload handler is provided, use it\n if (this.uploadHandler) {\n try {\n this.emit('upload:start', { file });\n const result = await this.uploadHandler(file);\n this.emit('upload:complete', { file, ...result });\n return { localUrl, remoteUrl: result.url, file, id: result.id };\n } catch (err) {\n this.emit('upload:error', { file, error: err });\n return { localUrl, file, error: err.message || 'Upload failed' };\n }\n }\n\n // No remote handler — just use local data URL\n return { localUrl, file };\n }\n\n /**\n * Process multiple files.\n */\n async processFiles(files) {\n return Promise.all(files.map((f) => this.processFile(f)));\n }\n\n /**\n * Handle a paste event for images.\n */\n async handlePaste(clipboardData) {\n const items = [...(clipboardData.items || [])];\n const imageItems = items.filter((item) => item.type.startsWith('image/'));\n if (imageItems.length === 0) return null;\n\n const files = imageItems.map((item) => item.getAsFile()).filter(Boolean);\n if (files.length === 0) return null;\n\n return this.processFiles(files);\n }\n\n /**\n * Handle drag-and-drop of files.\n */\n async handleDrop(dataTransfer) {\n const files = [...(dataTransfer.files || [])];\n if (files.length === 0) return null;\n return this.processFiles(files);\n }\n\n /**\n * Determine media type from file.\n */\n getMediaType(file) {\n if (file.type.startsWith('image/')) return 'image';\n if (file.type.startsWith('video/')) return 'video';\n if (file.type.startsWith('audio/')) return 'audio';\n return 'file';\n }\n\n /**\n * Read file as data URL.\n */\n _readAsDataURL(file) {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(reader.result);\n reader.onerror = () => reject(reader.error);\n reader.readAsDataURL(file);\n });\n }\n}\n","import { EventEmitter } from '../utils/EventEmitter.js';\n\n/**\n * Drag-and-drop reordering for blocks.\n */\nexport class DragDrop extends EventEmitter {\n constructor(container) {\n super();\n this.container = container;\n this._dragging = null;\n this._placeholder = null;\n this._offsetY = 0;\n this._bound = {};\n this._enabled = true;\n }\n\n enable() {\n this._enabled = true;\n }\n\n disable() {\n this._enabled = false;\n }\n\n /**\n * Initialise drag on a handle element within a block wrapper.\n */\n initDrag(handleEl, wrapperEl, blockId) {\n handleEl.setAttribute('draggable', 'true');\n handleEl.style.cursor = 'grab';\n\n handleEl.addEventListener('dragstart', (e) => {\n if (!this._enabled) return e.preventDefault();\n this._dragging = { el: wrapperEl, id: blockId };\n wrapperEl.style.opacity = '0.4';\n e.dataTransfer.effectAllowed = 'move';\n e.dataTransfer.setData('text/plain', blockId);\n this.emit('drag:start', blockId);\n });\n\n handleEl.addEventListener('dragend', () => {\n if (this._dragging) {\n this._dragging.el.style.opacity = '';\n this._dragging = null;\n }\n this._removePlaceholder();\n this.emit('drag:end');\n });\n\n wrapperEl.addEventListener('dragover', (e) => {\n if (!this._dragging || this._dragging.id === blockId) return;\n e.preventDefault();\n e.dataTransfer.dropEffect = 'move';\n\n const rect = wrapperEl.getBoundingClientRect();\n const midY = rect.top + rect.height / 2;\n const position = e.clientY < midY ? 'before' : 'after';\n\n this._showPlaceholder(wrapperEl, position);\n });\n\n wrapperEl.addEventListener('drop', (e) => {\n e.preventDefault();\n if (!this._dragging) return;\n const fromId = this._dragging.id;\n const toId = blockId;\n\n const rect = wrapperEl.getBoundingClientRect();\n const midY = rect.top + rect.height / 2;\n const position = e.clientY < midY ? 'before' : 'after';\n\n this._removePlaceholder();\n this._dragging.el.style.opacity = '';\n this._dragging = null;\n\n this.emit('drop', { fromId, toId, position });\n });\n }\n\n _showPlaceholder(referenceEl, position) {\n if (!this._placeholder) {\n this._placeholder = document.createElement('div');\n this._placeholder.className = 'fe-drag-placeholder';\n this._placeholder.style.cssText =\n 'height:4px;background:#2271b1;border-radius:2px;margin:4px 0;transition:all 0.15s;';\n }\n if (position === 'before') {\n referenceEl.parentNode.insertBefore(this._placeholder, referenceEl);\n } else {\n referenceEl.parentNode.insertBefore(this._placeholder, referenceEl.nextSibling);\n }\n }\n\n _removePlaceholder() {\n if (this._placeholder && this._placeholder.parentNode) {\n this._placeholder.parentNode.removeChild(this._placeholder);\n }\n }\n}\n","import { icons } from '../utils/icons.js';\n\n/**\n * Block type registry. Each entry describes a block type and how to render it.\n */\nexport const BLOCK_TYPES = {\n paragraph: {\n label: 'Paragraph',\n description: 'Start with the building block of all narrative.',\n icon: icons.paragraph,\n category: 'text',\n hasContent: true,\n contentTag: 'div',\n placeholder: 'Type / to choose a block',\n className: '',\n },\n heading: {\n label: 'Heading 2',\n description: 'Introduce new sections and organize content.',\n icon: icons.heading,\n category: 'text',\n hasContent: true,\n contentTag: 'h2',\n placeholder: 'Heading 2',\n className: 'fe-heading-2',\n },\n 'heading-3': {\n label: 'Heading 3',\n description: 'A smaller heading for subsections.',\n icon: icons.heading,\n category: 'text',\n hasContent: true,\n contentTag: 'h3',\n placeholder: 'Heading 3',\n className: 'fe-heading-3',\n },\n 'heading-4': {\n label: 'Heading 4',\n description: 'A small heading for nested subsections.',\n icon: icons.heading,\n category: 'text',\n hasContent: true,\n contentTag: 'h4',\n placeholder: 'Heading 4',\n className: 'fe-heading-4',\n },\n list: {\n label: 'List',\n description: 'Create a bulleted list.',\n icon: icons.list,\n category: 'text',\n hasContent: true,\n contentTag: 'div',\n placeholder: 'List',\n className: 'fe-list-block',\n },\n 'ordered-list': {\n label: 'Ordered List',\n description: 'Create a numbered list.',\n icon: icons.orderedList,\n category: 'text',\n hasContent: true,\n contentTag: 'div',\n placeholder: 'List',\n className: 'fe-ordered-list-block',\n },\n quote: {\n label: 'Quote',\n description: 'Give quoted text visual emphasis.',\n icon: icons.quote,\n category: 'text',\n hasContent: true,\n contentTag: 'div',\n placeholder: 'Write quote...',\n className: 'fe-quote',\n },\n pullquote: {\n label: 'Pullquote',\n description: 'Highlight a key quote from your content.',\n icon: icons.pullquote,\n category: 'text',\n hasContent: true,\n contentTag: 'div',\n placeholder: 'Write pullquote...',\n className: 'fe-pullquote',\n },\n code: {\n label: 'Code',\n description: 'Display code snippets that respect your spacing.',\n icon: icons.code,\n category: 'text',\n hasContent: true,\n contentTag: 'div',\n placeholder: 'Write code...',\n className: 'fe-code-block',\n },\n html: {\n label: 'Custom HTML',\n description: 'Add custom HTML code.',\n icon: icons.html,\n category: 'text',\n hasContent: true,\n contentTag: 'div',\n placeholder: 'Write HTML...',\n className: 'fe-html-block',\n },\n image: {\n label: 'Image',\n description: 'Insert an image to make a visual statement.',\n icon: icons.image,\n category: 'media',\n hasContent: false,\n isMedia: true,\n },\n gallery: {\n label: 'Gallery',\n description: 'Display multiple images in a gallery.',\n icon: icons.gallery,\n category: 'media',\n hasContent: false,\n isMedia: true,\n },\n video: {\n label: 'Video',\n description: 'Embed a video from your media library or URL.',\n icon: icons.video,\n category: 'media',\n hasContent: false,\n isMedia: true,\n },\n audio: {\n label: 'Audio',\n description: 'Embed an audio file.',\n icon: icons.audio,\n category: 'media',\n hasContent: false,\n isMedia: true,\n },\n file: {\n label: 'File',\n description: 'Add a link to a downloadable file.',\n icon: icons.file,\n category: 'media',\n hasContent: false,\n isMedia: true,\n },\n separator: {\n label: 'Separator',\n description: 'Create a break between ideas or sections.',\n icon: icons.separator,\n category: 'design',\n hasContent: false,\n },\n spacer: {\n label: 'Spacer',\n description: 'Add white space between blocks.',\n icon: icons.spacer,\n category: 'design',\n hasContent: false,\n },\n columns: {\n label: 'Columns',\n description: 'Display content in multiple columns.',\n icon: icons.columns,\n category: 'design',\n hasContent: false,\n },\n table: {\n label: 'Table',\n description: 'Insert a table for sharing data.',\n icon: icons.table,\n category: 'design',\n hasContent: false,\n },\n button: {\n label: 'Button',\n description: 'Prompt visitors to take action with a button.',\n icon: icons.button,\n category: 'design',\n hasContent: true,\n contentTag: 'div',\n placeholder: 'Add text...',\n className: 'fe-button-block',\n },\n embed: {\n label: 'Embed',\n description: 'Embed content from YouTube, Twitter, etc.',\n icon: icons.embed,\n category: 'media',\n hasContent: true,\n contentTag: 'div',\n placeholder: 'Enter URL to embed...',\n className: 'fe-embed-block',\n },\n};\n\nexport const CATEGORIES = [\n { id: 'text', label: 'Text' },\n { id: 'media', label: 'Media' },\n { id: 'design', label: 'Design' },\n];\n\n/**\n * Get blocks for a category.\n */\nexport function getBlocksByCategory(catId) {\n return Object.entries(BLOCK_TYPES)\n .filter(([, def]) => def.category === catId)\n .map(([type, def]) => ({ type, ...def }));\n}\n\n/**\n * Search blocks by query.\n */\nexport function searchBlocks(query) {\n const q = query.toLowerCase();\n return Object.entries(BLOCK_TYPES)\n .filter(([type, def]) => type.includes(q) || def.label.toLowerCase().includes(q) || def.description.toLowerCase().includes(q))\n .map(([type, def]) => ({ type, ...def }));\n}\n","import { el, placeCaretAtEnd } from '../utils/dom.js';\nimport { icons } from '../utils/icons.js';\nimport { BLOCK_TYPES } from './registry.js';\n\n/**\n * Creates the DOM for a single block based on its type and data.\n */\nexport class BlockRenderer {\n constructor(editor) {\n this.editor = editor;\n }\n\n render(block) {\n const def = BLOCK_TYPES[block.type];\n if (!def) return this._renderParagraph(block);\n\n if (def.isMedia) return this._renderMediaBlock(block, def);\n if (def.hasContent) return this._renderContentBlock(block, def);\n\n // Non-content blocks\n switch (block.type) {\n case 'separator': return this._renderSeparator(block);\n case 'spacer': return this._renderSpacer(block);\n case 'columns': return this._renderColumns(block);\n case 'table': return this._renderTable(block);\n default: return this._renderParagraph(block);\n }\n }\n\n /* ---- Content Blocks (editable) ---- */\n\n _renderContentBlock(block, def) {\n const isRawTextBlock = block.type === 'code' || block.type === 'html';\n const isEmpty = !block.content || block.content.trim() === '';\n const node = el(def.contentTag || 'div', {\n className: `fe-block-content ${def.className || ''}`.trim(),\n contentEditable: 'true',\n dataset: { \n placeholder: def.placeholder || '',\n empty: isEmpty ? 'true' : 'false'\n },\n innerHTML: isRawTextBlock ? '' : (block.content || '<br>'),\n });\n if (isRawTextBlock && block.content) {\n node.textContent = block.content;\n }\n\n this._bindContentEvents(node, block);\n return node;\n }\n\n _renderParagraph(block) {\n const isEmpty = !block.content || block.content.trim() === '';\n const node = el('div', {\n className: 'fe-block-content',\n contentEditable: 'true',\n dataset: { \n placeholder: 'Type / to choose a block',\n empty: isEmpty ? 'true' : 'false'\n },\n innerHTML: block.content || '<br>',\n });\n this._bindContentEvents(node, block);\n return node;\n }\n\n /* ---- Media Blocks ---- */\n\n _renderMediaBlock(block, def) {\n const container = el('div', { className: `fe-block-media fe-block-${block.type}` });\n\n switch (block.type) {\n case 'image':\n return this._renderImageBlock(block, container);\n case 'gallery':\n return this._renderGalleryBlock(block, container);\n case 'video':\n return this._renderVideoBlock(block, container);\n case 'audio':\n return this._renderAudioBlock(block, container);\n case 'file':\n return this._renderFileBlock(block, container);\n default:\n return this._renderMediaPlaceholder(block, container, def);\n }\n }\n\n _renderImageBlock(block, container) {\n if (block.content) {\n const width = _normalizeImageWidth(block.attrs?.width);\n const fig = el('figure', { className: 'fe-image-figure' });\n const img = el('img', { src: block.content, alt: block.attrs?.alt || '' });\n img.style.width = `${width}%`;\n img.style.maxWidth = '100%';\n img.style.borderRadius = '4px';\n img.style.display = 'block';\n fig.appendChild(img);\n\n // Caption\n const caption = el('figcaption', {\n className: 'fe-image-caption',\n contentEditable: 'true',\n dataset: { placeholder: 'Add caption...' },\n innerHTML: block.attrs?.caption || '',\n });\n caption.addEventListener('input', () => {\n block.attrs = block.attrs || {};\n block.attrs.caption = caption.innerHTML;\n });\n fig.appendChild(caption);\n\n // Toolbar overlay\n const overlay = el('div', { className: 'fe-image-overlay' });\n const replaceBtn = el('button', {\n className: 'fe-img-overlay-btn',\n innerHTML: 'Replace',\n onClick: () => this._triggerImageUpload(block),\n });\n const removeBtn = el('button', {\n className: 'fe-img-overlay-btn fe-img-overlay-btn-danger',\n innerHTML: 'Remove',\n onClick: () => {\n block.content = '';\n block.attrs = {};\n this.editor.render();\n },\n });\n overlay.appendChild(replaceBtn);\n overlay.appendChild(removeBtn);\n fig.appendChild(overlay);\n\n const resizeHandle = el('button', {\n type: 'button',\n className: 'fe-image-resize-handle',\n title: 'Drag to resize image',\n });\n resizeHandle.addEventListener('mousedown', (e) => {\n e.preventDefault();\n e.stopPropagation();\n this.editor.selectBlock(block.id);\n\n const startX = e.clientX;\n const startWidth = img.getBoundingClientRect().width;\n const parentWidth = container.getBoundingClientRect().width || startWidth || 1;\n\n const onMove = (ev) => {\n const delta = ev.clientX - startX;\n const nextWidthPx = Math.max(80, Math.min(parentWidth, startWidth + delta));\n const nextPercent = _normalizeImageWidth((nextWidthPx / parentWidth) * 100);\n block.attrs = block.attrs || {};\n block.attrs.width = nextPercent;\n img.style.width = `${nextPercent}%`;\n };\n\n const onUp = () => {\n document.removeEventListener('mousemove', onMove);\n document.removeEventListener('mouseup', onUp);\n this.editor.statusBar.update();\n };\n\n document.addEventListener('mousemove', onMove);\n document.addEventListener('mouseup', onUp);\n });\n fig.appendChild(resizeHandle);\n\n container.appendChild(fig);\n\n const sizeControls = el('div', { className: 'fe-image-size-controls' });\n [25, 50, 75, 100].forEach((pct) => {\n const btn = el('button', {\n type: 'button',\n className: `fe-img-size-btn ${width === pct ? 'is-active' : ''}`.trim(),\n innerHTML: `${pct}%`,\n onClick: () => {\n block.attrs = block.attrs || {};\n block.attrs.width = pct;\n this.editor.render();\n },\n });\n sizeControls.appendChild(btn);\n });\n container.appendChild(sizeControls);\n } else {\n this._renderMediaPlaceholder(block, container, BLOCK_TYPES.image);\n }\n\n return container;\n }\n\n _renderGalleryBlock(block, container) {\n const images = block.attrs?.images || [];\n if (images.length > 0) {\n const grid = el('div', { className: 'fe-gallery-grid' });\n images.forEach((src, i) => {\n const item = el('div', { className: 'fe-gallery-item' });\n item.appendChild(el('img', { src, alt: '' }));\n const removeBtn = el('button', {\n className: 'fe-gallery-remove',\n innerHTML: '×',\n onClick: () => {\n images.splice(i, 1);\n this.editor.render();\n },\n });\n item.appendChild(removeBtn);\n grid.appendChild(item);\n });\n container.appendChild(grid);\n\n const addMore = el('button', {\n className: 'fe-gallery-add',\n innerHTML: '+ Add Images',\n onClick: () => this._triggerGalleryUpload(block),\n });\n container.appendChild(addMore);\n } else {\n this._renderMediaPlaceholder(block, container, BLOCK_TYPES.gallery);\n }\n return container;\n }\n\n _renderVideoBlock(block, container) {\n if (block.content) {\n const video = el('video', { src: block.content });\n video.controls = true;\n video.style.maxWidth = '100%';\n video.style.borderRadius = '4px';\n container.appendChild(video);\n } else {\n this._renderMediaPlaceholder(block, container, BLOCK_TYPES.video);\n }\n return container;\n }\n\n _renderAudioBlock(block, container) {\n if (block.content) {\n const audio = el('audio', { src: block.content });\n audio.controls = true;\n audio.style.width = '100%';\n container.appendChild(audio);\n } else {\n this._renderMediaPlaceholder(block, container, BLOCK_TYPES.audio);\n }\n return container;\n }\n\n _renderFileBlock(block, container) {\n if (block.content) {\n const wrapper = el('div', { className: 'fe-file-wrapper' });\n\n const infoDiv = el('div', { className: 'fe-file-info' });\n infoDiv.appendChild(el('span', { className: 'fe-file-icon', innerHTML: icons.file }));\n infoDiv.appendChild(el('span', { className: 'fe-file-name' }, [block.attrs?.filename || 'File']));\n infoDiv.appendChild(el('span', { className: 'fe-file-size' }, [block.attrs?.filesize || '']));\n wrapper.appendChild(infoDiv);\n\n const downloadLink = el('a', { className: 'fe-file-download', href: block.content, download: '' }, ['Download']);\n wrapper.appendChild(downloadLink);\n\n container.appendChild(wrapper);\n } else {\n this._renderMediaPlaceholder(block, container, BLOCK_TYPES.file);\n }\n return container;\n }\n\n _renderMediaPlaceholder(block, container, def) {\n const placeholder = el('div', { className: 'fe-media-placeholder' });\n\n const iconEl = el('div', { className: 'fe-media-placeholder-icon', innerHTML: def.icon });\n const label = el('p', { className: 'fe-media-placeholder-label' }, [def.label]);\n const desc = el('p', { className: 'fe-media-placeholder-desc' }, ['Upload a file or pick one from your media library.']);\n\n const btnRow = el('div', { className: 'fe-media-placeholder-actions' });\n\n const uploadBtn = el('button', {\n className: 'fe-btn fe-btn-primary',\n innerHTML: `${icons.upload} Upload`,\n onClick: () => this._handleMediaUpload(block),\n });\n btnRow.appendChild(uploadBtn);\n\n // URL input for embeds, video, audio\n if (['embed', 'video', 'audio'].includes(block.type)) {\n const urlInput = el('input', {\n type: 'text',\n className: 'fe-media-url-input',\n placeholder: 'Or paste a URL...',\n });\n urlInput.addEventListener('keydown', (e) => {\n if (e.key === 'Enter') {\n block.content = urlInput.value;\n this.editor.render();\n }\n });\n btnRow.appendChild(urlInput);\n }\n\n placeholder.appendChild(iconEl);\n placeholder.appendChild(label);\n placeholder.appendChild(desc);\n placeholder.appendChild(btnRow);\n container.appendChild(placeholder);\n\n // Drop zone\n this._setupDropZone(placeholder, block);\n\n return container;\n }\n\n /* ---- Non-content Blocks ---- */\n\n _renderSeparator(block) {\n const node = el('div', { className: 'fe-block-separator' });\n node.appendChild(el('hr'));\n return node;\n }\n\n _renderSpacer(block) {\n const height = block.attrs?.height || 48;\n const node = el('div', {\n className: 'fe-block-spacer',\n style: { height: height + 'px' },\n });\n\n // Resize handle\n const handle = el('div', { className: 'fe-spacer-handle' });\n let startY, startH;\n handle.addEventListener('mousedown', (e) => {\n startY = e.clientY;\n startH = height;\n const onMove = (ev) => {\n const newH = Math.max(16, startH + ev.clientY - startY);\n node.style.height = newH + 'px';\n block.attrs = block.attrs || {};\n block.attrs.height = newH;\n };\n const onUp = () => {\n document.removeEventListener('mousemove', onMove);\n document.removeEventListener('mouseup', onUp);\n };\n document.addEventListener('mousemove', onMove);\n document.addEventListener('mouseup', onUp);\n });\n node.appendChild(handle);\n return node;\n }\n\n _renderColumns(block) {\n const numCols = block.attrs?.columns || 2;\n const node = el('div', { className: 'fe-block-columns' });\n for (let i = 0; i < numCols; i++) {\n const col = el('div', {\n className: 'fe-column',\n contentEditable: 'true',\n dataset: { placeholder: `Column ${i + 1}` },\n innerHTML: block.attrs?.[`col${i}`] || '',\n });\n col.addEventListener('input', () => {\n block.attrs = block.attrs || {};\n block.attrs[`col${i}`] = col.innerHTML;\n });\n node.appendChild(col);\n }\n\n const controls = el('div', { className: 'fe-columns-controls' });\n controls.appendChild(\n el('button', {\n className: 'fe-btn fe-btn-sm',\n type: 'button',\n innerHTML: '+ Column',\n onClick: () => {\n block.attrs = block.attrs || {};\n block.attrs.columns = Math.max(1, Number(block.attrs.columns || numCols) + 1);\n this.editor.render();\n },\n })\n );\n controls.appendChild(\n el('button', {\n className: 'fe-btn fe-btn-sm',\n type: 'button',\n innerHTML: '- Column',\n onClick: () => {\n block.attrs = block.attrs || {};\n const current = Math.max(1, Number(block.attrs.columns || numCols));\n if (current <= 1) return;\n delete block.attrs[`col${current - 1}`];\n block.attrs.columns = current - 1;\n this.editor.render();\n },\n })\n );\n node.appendChild(controls);\n return node;\n }\n\n _renderTable(block) {\n const rows = block.attrs?.rows || 3;\n const cols = block.attrs?.cols || 3;\n const node = el('div', { className: 'fe-block-table' });\n const table = el('table');\n const data = block.attrs?.data || [];\n\n for (let r = 0; r < rows; r++) {\n const tr = el('tr');\n for (let c = 0; c < cols; c++) {\n const cellTag = r === 0 ? 'th' : 'td';\n const cell = el(cellTag, {\n contentEditable: 'true',\n innerHTML: data[r]?.[c] || '',\n });\n cell.addEventListener('input', () => {\n if (!block.attrs) block.attrs = {};\n if (!block.attrs.data) block.attrs.data = [];\n if (!block.attrs.data[r]) block.attrs.data[r] = [];\n block.attrs.data[r][c] = cell.innerHTML;\n });\n tr.appendChild(cell);\n }\n table.appendChild(tr);\n }\n\n node.appendChild(table);\n\n // Add row/column buttons\n const controls = el('div', { className: 'fe-table-controls' });\n controls.appendChild(\n el('button', {\n className: 'fe-btn fe-btn-sm',\n innerHTML: '+ Row',\n onClick: () => {\n block.attrs = block.attrs || {};\n block.attrs.rows = (block.attrs.rows || 3) + 1;\n this.editor.render();\n },\n })\n );\n controls.appendChild(\n el('button', {\n className: 'fe-btn fe-btn-sm',\n innerHTML: '+ Column',\n onClick: () => {\n block.attrs = block.attrs || {};\n block.attrs.cols = (block.attrs.cols || 3) + 1;\n this.editor.render();\n },\n })\n );\n node.appendChild(controls);\n return node;\n }\n\n /* ---- Upload Helpers ---- */\n\n async _handleMediaUpload(block) {\n let accept = '*/*';\n if (block.type === 'image' || block.type === 'gallery') accept = 'image/*';\n else if (block.type === 'video') accept = 'video/*';\n else if (block.type === 'audio') accept = 'audio/*';\n\n const multiple = block.type === 'gallery';\n const files = await this.editor.mediaUploader.openFilePicker(accept, multiple);\n if (files.length === 0) return;\n\n if (block.type === 'gallery') {\n const results = await this.editor.mediaUploader.processFiles(files);\n block.attrs = block.attrs || {};\n block.attrs.images = block.attrs.images || [];\n for (const res of results) {\n if (!res.error) block.attrs.images.push(res.remoteUrl || res.localUrl);\n }\n } else {\n const result = await this.editor.mediaUploader.processFile(files[0]);\n if (!result.error) {\n block.content = result.remoteUrl || result.localUrl;\n if (block.type === 'file') {\n block.attrs = block.attrs || {};\n block.attrs.filename = files[0].name;\n block.attrs.filesize = _formatSize(files[0].size);\n }\n }\n }\n this.editor.render();\n }\n\n async _triggerImageUpload(block) {\n const files = await this.editor.mediaUploader.openFilePicker('image/*');\n if (files.length === 0) return;\n const result = await this.editor.mediaUploader.processFile(files[0]);\n if (!result.error) block.content = result.remoteUrl || result.localUrl;\n this.editor.render();\n }\n\n async _triggerGalleryUpload(block) {\n const files = await this.editor.mediaUploader.openFilePicker('image/*', true);\n if (files.length === 0) return;\n const results = await this.editor.mediaUploader.processFiles(files);\n block.attrs = block.attrs || {};\n block.attrs.images = block.attrs.images || [];\n for (const res of results) {\n if (!res.error) block.attrs.images.push(res.remoteUrl || res.localUrl);\n }\n this.editor.render();\n }\n\n _setupDropZone(element, block) {\n element.addEventListener('dragover', (e) => {\n e.preventDefault();\n element.classList.add('fe-drop-active');\n });\n element.addEventListener('dragleave', () => {\n element.classList.remove('fe-drop-active');\n });\n element.addEventListener('drop', async (e) => {\n e.preventDefault();\n element.classList.remove('fe-drop-active');\n const results = await this.editor.mediaUploader.handleDrop(e.dataTransfer);\n if (results && results.length > 0) {\n if (block.type === 'gallery') {\n block.attrs = block.attrs || {};\n block.attrs.images = block.attrs.images || [];\n for (const res of results) {\n if (!res.error) block.attrs.images.push(res.remoteUrl || res.localUrl);\n }\n } else {\n const res = results[0];\n if (!res.error) block.content = res.remoteUrl || res.localUrl;\n }\n this.editor.render();\n }\n });\n }\n\n /* ---- Content Events ---- */\n\n _bindContentEvents(node, block) {\n const isRawTextBlock = block.type === 'code' || block.type === 'html';\n\n // Helper to update empty state\n const updateEmptyState = () => {\n const text = node.textContent || '';\n const isEmpty = isRawTextBlock\n ? text.trim() === ''\n : text.trim() === '' && (node.innerHTML.trim() === '<br>' || node.innerHTML.trim() === '');\n node.dataset.empty = isEmpty ? 'true' : 'false';\n };\n\n // Update empty state initially\n updateEmptyState();\n\n // Ensure contenteditable gets focus when clicked\n node.addEventListener('mousedown', (e) => {\n // Let wrapper click handle first-time block selection to avoid losing focus on re-render\n if (this.editor._selectedBlockId !== block.id) return;\n // Stop propagation so wrapper click does not override caret placement on selected blocks\n e.stopPropagation();\n // Immediately focus on mousedown for better responsiveness\n if (document.activeElement !== node) {\n node.focus();\n // If empty (only has <br>), place caret correctly\n const text = node.textContent || '';\n if (text.trim() === '' && (node.innerHTML.trim() === '<br>' || node.innerHTML.trim() === '')) {\n // Ensure there's a <br> for cursor visibility\n if (node.innerHTML.trim() === '') {\n node.innerHTML = '<br>';\n }\n // Place caret after the <br>\n setTimeout(() => {\n const range = document.createRange();\n const sel = window.getSelection();\n range.selectNodeContents(node);\n range.collapse(false);\n sel.removeAllRanges();\n sel.addRange(range);\n }, 0);\n }\n }\n });\n\n node.addEventListener('input', () => {\n if (isRawTextBlock) {\n block.content = node.textContent || '';\n updateEmptyState();\n this.editor._onBlockInput(block, node);\n return;\n }\n\n // Clean up: if content is just <br> or empty, store as empty string\n let content = node.innerHTML.trim();\n if (content === '<br>' || content === '<br/>' || content === '') {\n content = '';\n // Keep the <br> in the DOM for cursor visibility, but don't save it\n if (!node.querySelector('br')) {\n node.innerHTML = '<br>';\n }\n }\n block.content = content;\n updateEmptyState();\n this.editor._onBlockInput(block, node);\n });\n\n node.addEventListener('keydown', (e) => {\n this.editor._onBlockKeydown(e, block, node);\n });\n\n node.addEventListener('focus', () => {\n this.editor.selectBlock(block.id);\n });\n\n node.addEventListener('paste', (e) => {\n // Code blocks: plain text only\n if (block.type === 'code' || block.type === 'html') {\n e.preventDefault();\n const text = e.clipboardData.getData('text/plain');\n document.execCommand('insertText', false, text);\n return;\n }\n\n // Image paste\n if (e.clipboardData.items) {\n const imageItems = [...e.clipboardData.items].filter((i) => i.type.startsWith('image/'));\n if (imageItems.length > 0) {\n e.preventDefault();\n this.editor.mediaUploader.handlePaste(e.clipboardData).then((results) => {\n if (results && results.length > 0) {\n const src = results[0].remoteUrl || results[0].localUrl;\n if (src) {\n document.execCommand('insertHTML', false, `<img src=\"${src}\" alt=\"\" />`);\n }\n }\n });\n return;\n }\n }\n });\n }\n}\n\nfunction _formatSize(bytes) {\n if (bytes < 1024) return bytes + ' B';\n if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';\n return (bytes / (1024 * 1024)).toFixed(1) + ' MB';\n}\n\nfunction _normalizeImageWidth(value) {\n const numeric = Number(value);\n if (!Number.isFinite(numeric)) return 100;\n return Math.max(10, Math.min(100, Math.round(numeric)));\n}\n","import { el } from '../utils/dom.js';\nimport { icons } from '../utils/icons.js';\n\n/**\n * Top editor header bar: inserter button, undo/redo, status, save/publish, settings toggle.\n */\nexport class Header {\n constructor(editor) {\n this.editor = editor;\n this.el = null;\n }\n\n create() {\n this.el = el('div', { className: 'fe-header' });\n\n // Left\n const left = el('div', { className: 'fe-header-left' });\n\n // Block inserter toggle\n const inserterBtn = el('button', {\n className: 'fe-inserter-toggle',\n innerHTML: icons.plus,\n title: 'Toggle block inserter',\n onClick: (e) => this.editor.inserterPanel.toggle(e.currentTarget),\n });\n left.appendChild(inserterBtn);\n left.appendChild(el('span', { className: 'fe-sep' }));\n\n // Undo / Redo\n left.appendChild(this._iconBtn(icons.undo, 'Undo (Ctrl+Z)', () => {\n const activeEl = document.activeElement;\n const inEditable =\n Boolean(activeEl && activeEl.isContentEditable && this.editor.rootEl.contains(activeEl)) ||\n Boolean(window.getSelection()?.anchorNode && this.editor.rootEl.contains(window.getSelection().anchorNode));\n this.editor.undo({ preferNative: inEditable });\n }));\n left.appendChild(this._iconBtn(icons.redo, 'Redo (Ctrl+Y)', () => {\n const activeEl = document.activeElement;\n const inEditable =\n Boolean(activeEl && activeEl.isContentEditable && this.editor.rootEl.contains(activeEl)) ||\n Boolean(window.getSelection()?.anchorNode && this.editor.rootEl.contains(window.getSelection().anchorNode));\n this.editor.redo({ preferNative: inEditable });\n }));\n left.appendChild(el('span', { className: 'fe-sep' }));\n\n // List view\n left.appendChild(this._iconBtn(icons.listView, 'Document overview', () => {\n this.editor.emit('listView:toggle');\n }));\n\n this.el.appendChild(left);\n\n // Center spacer\n const center = el('div', { className: 'fe-header-center' });\n this.el.appendChild(center);\n\n // Right\n const right = el('div', { className: 'fe-header-right' });\n\n if (this.editor.options.showHeaderActions) {\n const draftBtn = el('button', {\n className: 'fe-btn fe-btn-outline',\n innerHTML: 'Save draft',\n onClick: () => this.editor.save(),\n });\n right.appendChild(draftBtn);\n\n const publishBtn = el('button', {\n className: 'fe-btn fe-btn-primary',\n innerHTML: 'Publish',\n onClick: () => this.editor.publish(),\n });\n right.appendChild(publishBtn);\n }\n\n if (this.editor.options.showSettingsPanel) {\n if (right.childNodes.length > 0) {\n right.appendChild(el('span', { className: 'fe-sep' }));\n }\n right.appendChild(this._iconBtn(icons.settings, 'Settings', () => {\n this.editor.settingsPanel.toggle();\n this.editor._updateCanvasMargin();\n }));\n }\n\n this.el.appendChild(right);\n return this.el;\n }\n\n setStatus(text, color) {\n // no-op: status text removed from header UI\n }\n\n _iconBtn(iconHTML, title, onClick) {\n return el('button', {\n className: 'fe-icon-btn',\n innerHTML: iconHTML,\n title,\n onClick,\n });\n }\n}\n","import { el } from '../utils/dom.js';\nimport { icons } from '../utils/icons.js';\n\n/**\n * Floating block toolbar for formatting and block controls.\n */\nexport class Toolbar {\n constructor(editor) {\n this.editor = editor;\n this.el = null;\n this._linkPopover = null;\n this._fontSizeSelect = null;\n this._onSelectionChange = null;\n this._statefulButtons = [];\n this._savedLinkRange = null;\n this._tableToolsSep = null;\n this._tableRowBtn = null;\n this._tableColBtn = null;\n }\n\n create() {\n this.el = el('div', { className: 'fe-block-toolbar' });\n this._linkPopover = this._createLinkPopover();\n this._fontSizeSelect = null;\n this._onSelectionChange = null;\n return this.el;\n }\n\n show(blockId) {\n const block = this.editor.blockManager.getBlock(blockId);\n if (!block) return this.hide();\n const getActiveBlockId = () => this.editor._selectedBlockId || blockId;\n\n this.el.innerHTML = '';\n this.el.classList.add('fe-visible');\n this._statefulButtons = [];\n\n // Drag handle\n this._addBtn(icons.dragHandle, 'Drag', null, 'fe-tb-drag');\n\n this._addSep();\n\n // Move buttons\n this._addBtn(icons.arrowUp, 'Move up', () => this.editor.blockManager.moveBlock(blockId, -1));\n this._addBtn(icons.arrowDown, 'Move down', () => this.editor.blockManager.moveBlock(blockId, 1));\n\n this._addSep();\n\n // Type-specific tools\n const type = block.type;\n const textTypes = ['paragraph', 'heading', 'heading-3', 'heading-4', 'quote', 'pullquote', 'list', 'ordered-list'];\n const htmlEditableTypes = [...textTypes, 'code', 'html'];\n\n if (textTypes.includes(type)) {\n // Block type selector\n const select = el('select', { className: 'fe-tb-select' });\n const options = [\n { value: 'paragraph', label: 'Paragraph' },\n { value: 'heading', label: 'Heading 2' },\n { value: 'heading-3', label: 'Heading 3' },\n { value: 'heading-4', label: 'Heading 4' },\n { value: 'quote', label: 'Quote' },\n { value: 'list', label: 'Bullet List' },\n { value: 'ordered-list', label: 'Numbered List' },\n { value: 'code', label: 'Code' },\n ];\n options.forEach((opt) => {\n const o = el('option', { value: opt.value }, [opt.label]);\n if (opt.value === type) o.selected = true;\n select.appendChild(o);\n });\n select.addEventListener('change', () => {\n const value = select.value;\n const blockNow = this.editor.blockManager.getBlock(blockId);\n if (!blockNow) return;\n\n const ensureParagraphContext = () => {\n if (blockNow.type !== 'paragraph') {\n this.editor.blockManager.changeBlockType(blockId, 'paragraph');\n this.editor.render();\n }\n const contentEl = this.editor._getBlockContentEl(blockId);\n if (contentEl) contentEl.focus();\n return contentEl;\n };\n\n if (value === 'paragraph' || value === 'heading' || value === 'heading-3' || value === 'heading-4' || value === 'quote') {\n const contentEl = ensureParagraphContext();\n if (!contentEl) return;\n const tag = value === 'paragraph'\n ? 'P'\n : value === 'heading'\n ? 'H2'\n : value === 'heading-3'\n ? 'H3'\n : value === 'heading-4'\n ? 'H4'\n : 'BLOCKQUOTE';\n document.execCommand('formatBlock', false, tag);\n this.editor._syncCurrentBlockContent();\n return;\n }\n\n if (value === 'list' || value === 'ordered-list') {\n const contentEl = ensureParagraphContext();\n if (!contentEl) return;\n document.execCommand(value === 'list' ? 'insertUnorderedList' : 'insertOrderedList', false, null);\n this.editor._syncCurrentBlockContent();\n return;\n }\n\n this.editor.blockManager.changeBlockType(blockId, value);\n this.editor.render();\n this.editor.focusBlock(blockId);\n });\n this.el.appendChild(select);\n\n this._addSep();\n\n // Font size\n const fontSizeSelect = el('select', { className: 'fe-tb-select', title: 'Font size' });\n [\n { value: '', label: 'Size' },\n { value: '13', label: '13px' },\n { value: '16', label: '16px' },\n { value: '20', label: '20px' },\n { value: '28', label: '28px' },\n { value: '36', label: '36px' },\n ].forEach((opt) => {\n const o = el('option', { value: opt.value }, [opt.label]);\n fontSizeSelect.appendChild(o);\n });\n fontSizeSelect.addEventListener('change', () => {\n if (!fontSizeSelect.value) return;\n this._applyFontSize(fontSizeSelect.value);\n this._syncFontSizeSelect();\n });\n this.el.appendChild(fontSizeSelect);\n this._fontSizeSelect = fontSizeSelect;\n this._bindFontSizeTracking();\n this._syncFontSizeSelect();\n\n this._addSep();\n\n // Formatting\n this._addStatefulBtn('bold', icons.bold, 'Bold (Ctrl+B)', () => this._exec('bold'));\n this._addStatefulBtn('italic', icons.italic, 'Italic (Ctrl+I)', () => this._exec('italic'));\n this._addStatefulBtn('underline', icons.underline, 'Underline (Ctrl+U)', () => this._exec('underline'));\n this._addStatefulBtn('strikeThrough', icons.strikethrough, 'Strikethrough', () => this._exec('strikeThrough'));\n this._addBtn(icons.inlineCode, 'Inline Code', () => this._wrapInlineCode());\n this._addStatefulBtn('link', icons.link, 'Link (Ctrl+K)', () => this._showLinkPopover());\n\n this._addSep();\n\n // Alignment\n this._addBtn(icons.alignLeft, 'Align Left', () => this._exec('justifyLeft'));\n this._addBtn(icons.alignCenter, 'Align Center', () => this._exec('justifyCenter'));\n this._addBtn(icons.alignRight, 'Align Right', () => this._exec('justifyRight'));\n\n this._tableToolsSep = this._addSep();\n this._tableRowBtn = this._addTextBtn('+Row', 'Add table row', () => this._addTableRow());\n this._tableColBtn = this._addTextBtn('+Col', 'Add table column', () => this._addTableColumn());\n }\n\n if (htmlEditableTypes.includes(type)) {\n this._addSep();\n this._addBtn(\n icons.html,\n type === 'html' ? 'Switch to normal text mode' : 'Switch to HTML mode',\n () => this.editor.toggleBlockHtmlMode(getActiveBlockId()),\n type === 'html' ? 'active' : ''\n );\n }\n\n this._syncStatefulButtons();\n\n this._addSep();\n\n // Duplicate & Delete\n this._addBtn(icons.file, 'Duplicate', () => {\n const clone = this.editor.blockManager.duplicateBlock(getActiveBlockId());\n if (clone) this.editor.render();\n });\n this._addBtn(icons.trash, 'Delete', () => {\n const activeId = getActiveBlockId();\n const removed = this.editor.blockManager.removeBlock(activeId);\n if (removed) {\n this.editor.render();\n return;\n }\n\n // If only one block remains, make delete behave like \"clear block\".\n const blockToClear = this.editor.blockManager.getBlock(activeId);\n if (!blockToClear) return;\n blockToClear.type = 'paragraph';\n blockToClear.content = '';\n blockToClear.attrs = {};\n this.editor.render();\n this.editor.focusBlock(activeId);\n }, 'fe-tb-btn-danger');\n }\n\n hide() {\n if (this.el) this.el.classList.remove('fe-visible');\n this._hideLinkPopover();\n this._unbindFontSizeTracking();\n }\n\n /* ---- Private ---- */\n\n _addBtn(iconHTML, title, onClick, extraClass = '') {\n const btn = el('button', {\n className: `fe-tb-btn ${extraClass}`.trim(),\n type: 'button',\n innerHTML: iconHTML,\n title,\n });\n btn.addEventListener('mousedown', (e) => {\n // Preserve current editor selection for rich-text commands/popovers.\n e.preventDefault();\n e.stopPropagation();\n });\n if (onClick) btn.addEventListener('click', (e) => { e.preventDefault(); e.stopPropagation(); onClick(); });\n this.el.appendChild(btn);\n return btn;\n }\n\n _addStatefulBtn(command, iconHTML, title, onClick) {\n const btn = this._addBtn(iconHTML, title, onClick);\n this._statefulButtons.push({ command, btn });\n return btn;\n }\n\n _addSep() {\n const sep = el('span', { className: 'fe-tb-sep' });\n this.el.appendChild(sep);\n return sep;\n }\n\n _addTextBtn(label, title, onClick) {\n const btn = el('button', {\n className: 'fe-tb-text-btn',\n type: 'button',\n title,\n innerHTML: label,\n });\n btn.addEventListener('mousedown', (e) => {\n e.preventDefault();\n e.stopPropagation();\n });\n btn.addEventListener('click', (e) => {\n e.preventDefault();\n e.stopPropagation();\n onClick();\n });\n this.el.appendChild(btn);\n return btn;\n }\n\n _exec(cmd) {\n document.execCommand(cmd, false, null);\n this.editor._syncCurrentBlockContent();\n this._syncStatefulButtons();\n }\n\n _wrapInlineCode() {\n const sel = window.getSelection();\n if (!sel.rangeCount) return;\n const range = sel.getRangeAt(0);\n const code = document.createElement('code');\n code.className = 'fe-inline-code';\n range.surroundContents(code);\n this.editor._syncCurrentBlockContent();\n }\n\n _applyFontSize(px) {\n const size = Number(px);\n if (!Number.isFinite(size)) return;\n\n const sel = window.getSelection();\n if (!sel || !sel.rangeCount) return;\n const range = sel.getRangeAt(0);\n\n if (range.collapsed) {\n // Apply style for text typed from the current caret onward only.\n const marker = document.createElement('span');\n marker.style.fontSize = `${size}px`;\n marker.appendChild(document.createTextNode('\\u200B'));\n range.insertNode(marker);\n\n const nextRange = document.createRange();\n nextRange.setStart(marker.firstChild, 1);\n nextRange.collapse(true);\n sel.removeAllRanges();\n sel.addRange(nextRange);\n\n this.editor._syncCurrentBlockContent();\n return;\n }\n\n const span = document.createElement('span');\n span.style.fontSize = `${size}px`;\n span.appendChild(range.extractContents());\n range.insertNode(span);\n\n const nextRange = document.createRange();\n nextRange.selectNodeContents(span);\n sel.removeAllRanges();\n sel.addRange(nextRange);\n this.editor._syncCurrentBlockContent();\n }\n\n _bindFontSizeTracking() {\n if (!this._fontSizeSelect || this._onSelectionChange) return;\n this._onSelectionChange = () => {\n this._syncFontSizeSelect();\n this._syncStatefulButtons();\n };\n document.addEventListener('selectionchange', this._onSelectionChange);\n }\n\n _unbindFontSizeTracking() {\n if (!this._onSelectionChange) return;\n document.removeEventListener('selectionchange', this._onSelectionChange);\n this._onSelectionChange = null;\n }\n\n _syncFontSizeSelect() {\n if (!this._fontSizeSelect) return;\n const px = this._currentSelectionFontSizePx();\n if (!px) {\n this._fontSizeSelect.value = '';\n return;\n }\n const snapped = _closestFontSize(px, [13, 16, 20, 28, 36]);\n this._fontSizeSelect.value = String(snapped);\n }\n\n _currentSelectionFontSizePx() {\n const sel = window.getSelection();\n if (!sel || !sel.rangeCount) return null;\n const node = sel.focusNode;\n if (!node) return null;\n const elNode = node.nodeType === Node.ELEMENT_NODE ? node : node.parentElement;\n if (!elNode) return null;\n const wrapper = this.editor._getSelectedBlockEl();\n if (!wrapper || !wrapper.contains(elNode)) return null;\n const raw = window.getComputedStyle(elNode).fontSize;\n const px = Number.parseFloat(raw || '');\n return Number.isFinite(px) ? px : null;\n }\n\n _createLinkPopover() {\n const pop = el('div', { className: 'fe-link-popover' });\n const input = el('input', { type: 'text', placeholder: 'Paste URL or search...', className: 'fe-link-input' });\n const applyBtn = el('button', {\n className: 'fe-btn fe-btn-primary fe-btn-sm',\n innerHTML: 'Apply',\n });\n const removeBtn = el('button', {\n className: 'fe-btn fe-btn-sm',\n innerHTML: 'Remove',\n });\n\n applyBtn.addEventListener('click', () => {\n this._restoreSavedLinkRange();\n if (input.value) {\n document.execCommand('createLink', false, input.value);\n // Style links\n const wrapper = this.editor._getSelectedBlockEl();\n if (wrapper) {\n wrapper.querySelectorAll('a').forEach((a) => {\n a.classList.add('fe-link');\n a.target = '_blank';\n a.rel = 'noopener';\n });\n }\n }\n this._hideLinkPopover();\n this.editor._syncCurrentBlockContent();\n this._syncStatefulButtons();\n });\n\n removeBtn.addEventListener('click', () => {\n this._restoreSavedLinkRange();\n document.execCommand('unlink', false, null);\n this._hideLinkPopover();\n this.editor._syncCurrentBlockContent();\n this._syncStatefulButtons();\n });\n\n input.addEventListener('keydown', (e) => {\n if (e.key === 'Enter') { e.preventDefault(); applyBtn.click(); }\n if (e.key === 'Escape') this._hideLinkPopover();\n });\n\n pop.appendChild(input);\n pop.appendChild(applyBtn);\n pop.appendChild(removeBtn);\n return pop;\n }\n\n _showLinkPopover() {\n const sel = window.getSelection();\n if (!sel.rangeCount) return;\n const range = sel.getRangeAt(0);\n this._savedLinkRange = range.cloneRange();\n const rect = range.getBoundingClientRect();\n const wrapper = this.el.parentElement;\n if (!wrapper) return;\n\n if (!this._linkPopover.parentElement) {\n wrapper.appendChild(this._linkPopover);\n }\n\n this._linkPopover.style.top = (rect.bottom - wrapper.getBoundingClientRect().top + 6) + 'px';\n this._linkPopover.style.left = '0px';\n this._linkPopover.classList.add('fe-open');\n\n // Pre-fill if there's an existing link\n const anchor = sel.anchorNode?.parentElement?.closest('a');\n const input = this._linkPopover.querySelector('input');\n input.value = anchor ? anchor.href : '';\n setTimeout(() => input.focus(), 10);\n }\n\n _hideLinkPopover() {\n if (this._linkPopover) this._linkPopover.classList.remove('fe-open');\n }\n\n _getCurrentTableContext() {\n const wrapper = this.editor._getSelectedBlockEl();\n if (!wrapper) return null;\n const contentEl = wrapper.querySelector('.fe-block-content');\n if (!contentEl) return null;\n\n const sel = window.getSelection();\n let cell = null;\n if (sel && sel.rangeCount > 0) {\n let node = sel.anchorNode;\n if (node && node.nodeType === Node.TEXT_NODE) node = node.parentElement;\n if (node && typeof node.closest === 'function') {\n const maybeCell = node.closest('td,th');\n if (maybeCell && contentEl.contains(maybeCell)) cell = maybeCell;\n }\n }\n\n const table = cell ? cell.closest('table') : contentEl.querySelector('table');\n if (!table) return null;\n if (!cell) cell = table.querySelector('td,th');\n if (!cell) return null;\n return { table, cell };\n }\n\n _addTableRow() {\n const ctx = this._getCurrentTableContext();\n if (!ctx) return;\n const { table, cell } = ctx;\n const currentRow = cell.closest('tr');\n if (!currentRow) return;\n\n const rowCells = Array.from(currentRow.querySelectorAll('th,td'));\n const colCount = Math.max(1, rowCells.length);\n const newRow = document.createElement('tr');\n for (let i = 0; i < colCount; i++) {\n const td = document.createElement('td');\n td.innerHTML = '<br>';\n newRow.appendChild(td);\n }\n\n if (currentRow.nextSibling) currentRow.parentNode.insertBefore(newRow, currentRow.nextSibling);\n else currentRow.parentNode.appendChild(newRow);\n\n const range = document.createRange();\n range.selectNodeContents(newRow.querySelector('td'));\n range.collapse(true);\n const sel = window.getSelection();\n sel.removeAllRanges();\n sel.addRange(range);\n this.editor._syncCurrentBlockContent();\n }\n\n _addTableColumn() {\n const ctx = this._getCurrentTableContext();\n if (!ctx) return;\n const { table, cell } = ctx;\n const currentRow = cell.closest('tr');\n if (!currentRow) return;\n\n const idx = Array.from(currentRow.querySelectorAll('th,td')).indexOf(cell);\n if (idx < 0) return;\n\n const rows = Array.from(table.querySelectorAll('tr'));\n rows.forEach((row) => {\n const cells = Array.from(row.querySelectorAll('th,td'));\n const ref = cells[Math.min(idx, cells.length - 1)];\n const newCell = document.createElement(ref && ref.tagName.toLowerCase() === 'th' ? 'th' : 'td');\n newCell.innerHTML = '<br>';\n if (ref && ref.nextSibling) row.insertBefore(newCell, ref.nextSibling);\n else row.appendChild(newCell);\n });\n\n const targetRowCells = Array.from(currentRow.querySelectorAll('th,td'));\n const focusCell = targetRowCells[Math.min(idx + 1, targetRowCells.length - 1)];\n if (focusCell) {\n const range = document.createRange();\n range.selectNodeContents(focusCell);\n range.collapse(true);\n const sel = window.getSelection();\n sel.removeAllRanges();\n sel.addRange(range);\n }\n this.editor._syncCurrentBlockContent();\n }\n\n _restoreSavedLinkRange() {\n if (!this._savedLinkRange) return;\n const sel = window.getSelection();\n sel.removeAllRanges();\n sel.addRange(this._savedLinkRange);\n }\n\n _syncStatefulButtons() {\n const wrapper = this.editor._getSelectedBlockEl();\n const sel = window.getSelection();\n const anchor = sel?.anchorNode?.parentElement?.closest('a');\n const hasSelectionInEditor =\n wrapper &&\n sel &&\n sel.rangeCount > 0 &&\n wrapper.contains(sel.anchorNode);\n\n this._statefulButtons.forEach(({ command, btn }) => {\n let active = false;\n if (hasSelectionInEditor) {\n if (command === 'link') {\n active = Boolean(anchor && wrapper.contains(anchor));\n } else {\n try {\n active = document.queryCommandState(command);\n } catch {\n active = false;\n }\n }\n }\n btn.classList.toggle('active', Boolean(active));\n });\n\n const inTable = this._isSelectionInTable(wrapper);\n const tableDisplay = inTable ? '' : 'none';\n if (this._tableToolsSep) this._tableToolsSep.style.display = tableDisplay;\n if (this._tableRowBtn) this._tableRowBtn.style.display = tableDisplay;\n if (this._tableColBtn) this._tableColBtn.style.display = tableDisplay;\n }\n\n _isSelectionInTable(wrapper) {\n if (!wrapper) return false;\n const sel = window.getSelection();\n if (!sel || !sel.rangeCount) return false;\n let node = sel.anchorNode;\n if (!node) return false;\n if (node.nodeType === Node.TEXT_NODE) node = node.parentElement;\n if (!node || typeof node.closest !== 'function') return false;\n const table = node.closest('table');\n return Boolean(table && wrapper.contains(table));\n }\n}\n\nfunction _closestFontSize(value, sizes) {\n let best = sizes[0];\n let bestDelta = Math.abs(value - best);\n for (let i = 1; i < sizes.length; i++) {\n const delta = Math.abs(value - sizes[i]);\n if (delta < bestDelta) {\n best = sizes[i];\n bestDelta = delta;\n }\n }\n return best;\n}\n","import { el } from '../utils/dom.js';\nimport { icons } from '../utils/icons.js';\nimport { CATEGORIES, getBlocksByCategory, searchBlocks } from '../blocks/registry.js';\n\n/**\n * Side panel for browsing and inserting block types.\n */\nexport class InserterPanel {\n constructor(editor) {\n this.editor = editor;\n this.el = null;\n this._searchInput = null;\n this._listEl = null;\n this._anchorEl = null;\n this._onDocMouseDown = null;\n this._onDocKeyDown = null;\n this._savedRange = null;\n this._mediaModal = null;\n this._mediaModalCard = null;\n this._mediaModalTitle = null;\n this._mediaModalBody = null;\n this._mediaModalResolver = null;\n this._forceNewBlock = false;\n }\n\n create() {\n this.el = el('div', { className: 'fe-inserter-panel' });\n\n // Header\n const header = el('div', { className: 'fe-inserter-header' });\n header.appendChild(el('h3', {}, ['Blocks']));\n const closeBtn = el('button', {\n className: 'fe-icon-btn fe-icon-btn-sm',\n innerHTML: icons.close,\n onClick: () => this.close(),\n });\n header.appendChild(closeBtn);\n this.el.appendChild(header);\n\n // Search\n this._searchInput = el('input', {\n type: 'text',\n className: 'fe-inserter-search',\n placeholder: 'Search blocks...',\n });\n this._searchInput.addEventListener('input', () => this._renderList());\n this.el.appendChild(this._searchInput);\n\n // List\n this._listEl = el('div', { className: 'fe-inserter-list' });\n this.el.appendChild(this._listEl);\n\n this._renderList();\n this._createMediaModal();\n return this.el;\n }\n\n open(anchorEl = null, options = {}) {\n this._anchorEl = anchorEl || this._anchorEl;\n this._forceNewBlock = Boolean(options.forceNewBlock);\n this._savedRange = this._captureSelectionRange();\n this._positionNearAnchor();\n this.el.classList.add('fe-open');\n this._searchInput.value = '';\n this._renderList();\n this._bindGlobalCloseHandlers();\n setTimeout(() => this._searchInput.focus(), 20);\n }\n\n close() {\n this.el.classList.remove('fe-open');\n this._forceNewBlock = false;\n this._unbindGlobalCloseHandlers();\n }\n\n toggle(anchorEl = null, options = {}) {\n if (anchorEl) this._anchorEl = anchorEl;\n this.el.classList.contains('fe-open') ? this.close() : this.open(anchorEl, options);\n }\n\n isOpen() {\n return this.el.classList.contains('fe-open');\n }\n\n _renderList() {\n this._listEl.innerHTML = '';\n const query = this._searchInput?.value?.trim() || '';\n\n if (query) {\n const results = searchBlocks(query);\n if (results.length === 0) {\n this._listEl.appendChild(el('p', { className: 'fe-inserter-empty' }, ['No blocks found.']));\n return;\n }\n results.forEach((block) => this._listEl.appendChild(this._createBlockItem(block)));\n } else {\n for (const cat of CATEGORIES) {\n const blocks = getBlocksByCategory(cat.id);\n if (blocks.length === 0) continue;\n this._listEl.appendChild(el('div', { className: 'fe-inserter-category' }, [cat.label]));\n blocks.forEach((block) => this._listEl.appendChild(this._createBlockItem(block)));\n }\n }\n }\n\n _createBlockItem(blockDef) {\n const item = el('div', { className: 'fe-inserter-item' });\n item.appendChild(el('div', { className: 'fe-inserter-item-icon', innerHTML: blockDef.icon }));\n const info = el('div', { className: 'fe-inserter-item-info' });\n info.appendChild(el('h4', {}, [blockDef.label]));\n info.appendChild(el('p', {}, [blockDef.description]));\n item.appendChild(info);\n\n item.addEventListener('click', () => {\n this._insertFromPopover(blockDef.type);\n this.close();\n });\n\n return item;\n }\n\n _positionNearAnchor() {\n if (!this.el || !this._anchorEl) return;\n const rect = this._anchorEl.getBoundingClientRect();\n const gap = 8;\n const desiredLeft = Math.max(8, Math.min(window.innerWidth - 368, rect.left));\n const desiredTop = Math.max(8, Math.min(window.innerHeight - 520, rect.bottom + gap));\n this.el.style.left = `${desiredLeft}px`;\n this.el.style.top = `${desiredTop}px`;\n }\n\n _bindGlobalCloseHandlers() {\n this._onDocMouseDown = (e) => {\n if (!this.el?.classList.contains('fe-open')) return;\n if (this.el.contains(e.target)) return;\n if (this._anchorEl && this._anchorEl.contains(e.target)) return;\n this.close();\n };\n this._onDocKeyDown = (e) => {\n if (e.key === 'Escape') this.close();\n };\n document.addEventListener('mousedown', this._onDocMouseDown);\n document.addEventListener('keydown', this._onDocKeyDown);\n window.addEventListener('resize', () => this._positionNearAnchor(), { once: true });\n }\n\n _unbindGlobalCloseHandlers() {\n if (this._onDocMouseDown) {\n document.removeEventListener('mousedown', this._onDocMouseDown);\n this._onDocMouseDown = null;\n }\n if (this._onDocKeyDown) {\n document.removeEventListener('keydown', this._onDocKeyDown);\n this._onDocKeyDown = null;\n }\n }\n\n _captureSelectionRange() {\n const sel = window.getSelection();\n if (!sel || !sel.rangeCount) return null;\n const range = sel.getRangeAt(0);\n const container = range.commonAncestorContainer;\n if (!this.editor.rootEl.contains(container)) return null;\n return range.cloneRange();\n }\n\n _restoreSelectionRange() {\n if (!this._savedRange) return false;\n const sel = window.getSelection();\n sel.removeAllRanges();\n sel.addRange(this._savedRange);\n return true;\n }\n\n async _insertFromPopover(type) {\n if (this._forceNewBlock) {\n const selectedId = this.editor._selectedBlockId;\n const block = this.editor.blockManager.addBlock(type, {}, selectedId || null);\n this.editor.render();\n this.editor.focusBlock(block.id);\n return;\n }\n\n const selectedId = this.editor._selectedBlockId;\n const selectedBlock = selectedId ? this.editor.blockManager.getBlock(selectedId) : null;\n const canInline =\n selectedBlock &&\n selectedBlock.type !== 'code' &&\n selectedBlock.type !== 'html' &&\n selectedBlock.type !== 'image' &&\n selectedBlock.type !== 'gallery' &&\n selectedBlock.type !== 'video' &&\n selectedBlock.type !== 'audio' &&\n selectedBlock.type !== 'file';\n\n if (!canInline) {\n if (!this.editor.insertSingleBlockType(type)) {\n this.editor.insertBlockAtSelection(type);\n }\n return;\n }\n\n this._restoreSelectionRange();\n const contentEl = this.editor._getBlockContentEl(selectedId);\n if (contentEl) contentEl.focus();\n\n if (type === 'paragraph' || type === 'heading' || type === 'heading-3' || type === 'heading-4' || type === 'quote') {\n const tag = type === 'paragraph'\n ? 'P'\n : type === 'heading'\n ? 'H2'\n : type === 'heading-3'\n ? 'H3'\n : type === 'heading-4'\n ? 'H4'\n : 'BLOCKQUOTE';\n document.execCommand('formatBlock', false, tag);\n this.editor._syncCurrentBlockContent();\n return;\n }\n\n if (type === 'list' || type === 'ordered-list') {\n document.execCommand(type === 'list' ? 'insertUnorderedList' : 'insertOrderedList', false, null);\n this.editor._syncCurrentBlockContent();\n return;\n }\n\n if (type === 'image') {\n const files = await this.editor.mediaUploader.openFilePicker('image/*');\n if (!files.length) return;\n const result = await this.editor.mediaUploader.processFile(files[0]);\n if (!result.error) {\n const src = result.remoteUrl || result.localUrl;\n document.execCommand('insertHTML', false, `<img src=\"${src}\" alt=\"\" />`);\n this.editor._syncCurrentBlockContent();\n }\n return;\n }\n\n if (type === 'video' || type === 'audio') {\n const source = await this._chooseMediaSource(type);\n if (!source) return;\n\n if (source === 'url') {\n const url = await this._promptForMediaUrl(type);\n if (!url) return;\n const trimmed = url.trim();\n if (!trimmed) return;\n if (type === 'video') {\n document.execCommand('insertHTML', false, `<video controls style=\"width:100%;max-width:100%;\" src=\"${trimmed}\"></video><p><br></p>`);\n } else {\n document.execCommand('insertHTML', false, `<audio controls style=\"width:100%;\" src=\"${trimmed}\"></audio><p><br></p>`);\n }\n this.editor._syncCurrentBlockContent();\n return;\n }\n }\n\n if (type === 'video' || type === 'audio' || type === 'file') {\n const accept = type === 'video' ? 'video/*' : type === 'audio' ? 'audio/*' : '*/*';\n const files = await this.editor.mediaUploader.openFilePicker(accept);\n if (!files.length) return;\n const file = files[0];\n const result = await this.editor.mediaUploader.processFile(file);\n if (result.error) {\n if (typeof this.editor._showToast === 'function') this.editor._showToast(result.error);\n return;\n }\n const src = result.remoteUrl || result.localUrl;\n if (!src) return;\n\n if (type === 'video') {\n document.execCommand('insertHTML', false, `<video controls style=\"width:100%;max-width:100%;\" src=\"${src}\"></video><p><br></p>`);\n } else if (type === 'audio') {\n document.execCommand('insertHTML', false, `<audio controls style=\"width:100%;\" src=\"${src}\"></audio><p><br></p>`);\n } else {\n document.execCommand('insertHTML', false, `<p><a href=\"${src}\" target=\"_blank\" rel=\"noopener\">${file.name || 'Download file'}</a></p><p><br></p>`);\n }\n this.editor._syncCurrentBlockContent();\n return;\n }\n\n if (type === 'embed') {\n const url = window.prompt('Paste embed URL');\n if (!url) return;\n const trimmed = url.trim();\n if (!trimmed) return;\n document.execCommand('insertHTML', false, `<p><a href=\"${trimmed}\" target=\"_blank\" rel=\"noopener\">${trimmed}</a></p><p><br></p>`);\n this.editor._syncCurrentBlockContent();\n return;\n }\n\n if (!this.editor.insertSingleBlockType(type)) {\n this.editor.insertBlockAtSelection(type);\n }\n }\n\n async _chooseMediaSource(type) {\n if (typeof this.editor.options.onChooseMediaSource === 'function') {\n const selected = await this.editor.options.onChooseMediaSource(type);\n if (selected === 'url' || selected === 'upload') return selected;\n }\n return this._openMediaSourceModal(type);\n }\n\n _createMediaModal() {\n const overlay = el('div', { className: 'fe-media-modal-overlay' });\n const card = el('div', { className: 'fe-media-modal-card' });\n const title = el('h3', { className: 'fe-media-modal-title' }, ['Insert media']);\n const body = el('div', { className: 'fe-media-modal-body' });\n\n card.appendChild(title);\n card.appendChild(body);\n overlay.appendChild(card);\n\n overlay.addEventListener('click', (e) => {\n if (e.target === overlay) this._closeMediaModal(null);\n });\n\n this.editor.rootEl.appendChild(overlay);\n this._mediaModal = overlay;\n this._mediaModalCard = card;\n this._mediaModalTitle = title;\n this._mediaModalBody = body;\n }\n\n _openMediaSourceModal(type) {\n return new Promise((resolve) => {\n this._mediaModalResolver = resolve;\n this._mediaModalTitle.textContent = `Insert ${type}`;\n this._mediaModalBody.innerHTML = '';\n\n const desc = el('p', { className: 'fe-media-modal-desc' }, ['Choose how you want to add media']);\n const actions = el('div', { className: 'fe-media-modal-actions' });\n const uploadBtn = el('button', {\n className: 'fe-btn fe-btn-primary',\n type: 'button',\n innerHTML: 'Upload File',\n onClick: () => this._closeMediaModal('upload'),\n });\n const urlBtn = el('button', {\n className: 'fe-btn fe-btn-outline',\n type: 'button',\n innerHTML: 'Use URL',\n onClick: () => this._closeMediaModal('url'),\n });\n const cancelBtn = el('button', {\n className: 'fe-btn',\n type: 'button',\n innerHTML: 'Cancel',\n onClick: () => this._closeMediaModal(null),\n });\n actions.appendChild(uploadBtn);\n actions.appendChild(urlBtn);\n actions.appendChild(cancelBtn);\n this._mediaModalBody.appendChild(desc);\n this._mediaModalBody.appendChild(actions);\n\n this._mediaModal.classList.add('fe-open');\n });\n }\n\n _promptForMediaUrl(type) {\n return new Promise((resolve) => {\n this._mediaModalResolver = resolve;\n this._mediaModalTitle.textContent = `${type} URL`;\n this._mediaModalBody.innerHTML = '';\n\n const desc = el('p', { className: 'fe-media-modal-desc' }, ['Paste a direct media URL']);\n const input = el('input', {\n type: 'url',\n className: 'fe-media-modal-input',\n placeholder: `https://example.com/${type}.mp4`,\n });\n const actions = el('div', { className: 'fe-media-modal-actions' });\n const applyBtn = el('button', {\n className: 'fe-btn fe-btn-primary',\n type: 'button',\n innerHTML: 'Insert',\n onClick: () => this._closeMediaModal(input.value || null),\n });\n const cancelBtn = el('button', {\n className: 'fe-btn',\n type: 'button',\n innerHTML: 'Cancel',\n onClick: () => this._closeMediaModal(null),\n });\n\n input.addEventListener('keydown', (e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n this._closeMediaModal(input.value || null);\n }\n if (e.key === 'Escape') this._closeMediaModal(null);\n });\n\n actions.appendChild(applyBtn);\n actions.appendChild(cancelBtn);\n this._mediaModalBody.appendChild(desc);\n this._mediaModalBody.appendChild(input);\n this._mediaModalBody.appendChild(actions);\n this._mediaModal.classList.add('fe-open');\n setTimeout(() => input.focus(), 0);\n });\n }\n\n _closeMediaModal(value) {\n if (!this._mediaModal) return;\n this._mediaModal.classList.remove('fe-open');\n const resolver = this._mediaModalResolver;\n this._mediaModalResolver = null;\n if (resolver) resolver(value);\n }\n}\n","import { el } from '../utils/dom.js';\n\n/**\n * Right-hand settings panel with Post and Block tabs.\n */\nexport class SettingsPanel {\n constructor(editor) {\n this.editor = editor;\n this.el = null;\n this._activeTab = 'post';\n this._postTab = null;\n this._blockTab = null;\n this._tagInput = null;\n this._tags = [];\n this._categories = ['Uncategorized', 'Technology', 'Design', 'Business', 'Lifestyle'];\n this._featuredImage = null;\n }\n\n create() {\n this.el = el('div', { className: 'fe-settings-panel' });\n\n // Tabs\n const tabs = el('div', { className: 'fe-panel-tabs' });\n this._postTabBtn = el('button', { className: 'fe-panel-tab fe-active' }, ['Post']);\n this._blockTabBtn = el('button', { className: 'fe-panel-tab' }, ['Block']);\n this._postTabBtn.addEventListener('click', () => this._switchTab('post'));\n this._blockTabBtn.addEventListener('click', () => this._switchTab('block'));\n tabs.appendChild(this._postTabBtn);\n tabs.appendChild(this._blockTabBtn);\n this.el.appendChild(tabs);\n\n // Post tab content\n this._postTab = el('div', { className: 'fe-tab-content' });\n this._buildPostTab();\n this.el.appendChild(this._postTab);\n\n // Block tab content\n this._blockTab = el('div', { className: 'fe-tab-content', style: { display: 'none' } });\n this._buildBlockTab();\n this.el.appendChild(this._blockTab);\n\n return this.el;\n }\n\n open() { this.el.classList.add('fe-open'); }\n close() { this.el.classList.remove('fe-open'); }\n toggle() { this.el.classList.contains('fe-open') ? this.close() : this.open(); }\n isOpen() { return this.el.classList.contains('fe-open'); }\n\n updateBlockSettings(blockId) {\n this._blockSettingsContent.innerHTML = '';\n const block = this.editor.blockManager.getBlock(blockId);\n if (!block) {\n this._blockSettingsContent.innerHTML = '<p class=\"fe-muted fe-text-center\">Select a block to see its settings.</p>';\n return;\n }\n\n // Typography\n const section = el('div', { className: 'fe-panel-section' });\n section.appendChild(el('h3', { className: 'fe-section-title' }, ['Typography']));\n\n // Font size\n section.appendChild(el('label', {}, ['Font size']));\n const fontSelect = el('select', { className: 'fe-input' });\n [{ v: '', l: 'Default' }, { v: '13px', l: 'Small' }, { v: '16px', l: 'Medium' }, { v: '20px', l: 'Large' }, { v: '28px', l: 'Extra Large' }, { v: '36px', l: 'Huge' }]\n .forEach(({ v, l }) => fontSelect.appendChild(el('option', { value: v }, [l])));\n fontSelect.addEventListener('change', () => {\n const contentEl = this.editor._getBlockContentEl(blockId);\n if (contentEl) contentEl.style.fontSize = fontSelect.value;\n });\n section.appendChild(fontSelect);\n\n // Line height\n section.appendChild(el('label', {}, ['Line height']));\n const lhInput = el('input', { type: 'text', className: 'fe-input', placeholder: '1.7' });\n lhInput.addEventListener('change', () => {\n const contentEl = this.editor._getBlockContentEl(blockId);\n if (contentEl && lhInput.value) contentEl.style.lineHeight = lhInput.value;\n });\n section.appendChild(lhInput);\n\n this._blockSettingsContent.appendChild(section);\n\n // Color\n const colorSection = el('div', { className: 'fe-panel-section' });\n colorSection.appendChild(el('h3', { className: 'fe-section-title' }, ['Color']));\n\n // Text colors\n colorSection.appendChild(el('label', {}, ['Text color']));\n const textColors = el('div', { className: 'fe-color-grid' });\n ['#1e1e1e', '#cf2e2e', '#ff6900', '#fcb900', '#7bdcb5', '#00d084', '#0693e3', '#9b51e0'].forEach((c) => {\n const swatch = el('div', { className: 'fe-color-swatch', style: { background: c } });\n swatch.addEventListener('click', () => {\n const contentEl = this.editor._getBlockContentEl(blockId);\n if (contentEl) contentEl.style.color = c;\n });\n textColors.appendChild(swatch);\n });\n colorSection.appendChild(textColors);\n\n // BG colors\n colorSection.appendChild(el('label', {}, ['Background color']));\n const bgColors = el('div', { className: 'fe-color-grid' });\n ['transparent', '#fcf0f0', '#fef8ee', '#fefce8', '#edf7f2', '#eef6fc', '#f3eafa', '#f0f0f1'].forEach((c) => {\n const swatch = el('div', { className: 'fe-color-swatch', style: { background: c === 'transparent' ? '#fff' : c, border: c === 'transparent' ? '2px solid #ddd' : 'none' } });\n swatch.addEventListener('click', () => {\n const contentEl = this.editor._getBlockContentEl(blockId);\n if (contentEl) contentEl.style.background = c;\n });\n bgColors.appendChild(swatch);\n });\n colorSection.appendChild(bgColors);\n\n this._blockSettingsContent.appendChild(colorSection);\n }\n\n _switchTab(tab) {\n this._activeTab = tab;\n this._postTabBtn.classList.toggle('fe-active', tab === 'post');\n this._blockTabBtn.classList.toggle('fe-active', tab === 'block');\n this._postTab.style.display = tab === 'post' ? 'block' : 'none';\n this._blockTab.style.display = tab === 'block' ? 'block' : 'none';\n }\n\n _buildPostTab() {\n // Summary\n const summary = this._section('Summary');\n summary.appendChild(this._field('Visibility', 'select', ['Public', 'Private', 'Password Protected']));\n summary.appendChild(this._field('Publish', 'select', ['Immediately', 'Schedule']));\n summary.appendChild(this._field('URL Slug', 'text', null, 'fe-url-slug'));\n summary.appendChild(this._field('Author', 'select', ['Admin', 'Editor', 'Author']));\n this._postTab.appendChild(summary);\n\n // Categories\n const cats = this._section('Categories');\n const catList = el('div', { className: 'fe-category-list' });\n this._categories.forEach((cat) => {\n const label = el('label', { className: 'fe-checkbox-label' });\n label.appendChild(el('input', { type: 'checkbox' }));\n label.appendChild(document.createTextNode(' ' + cat));\n catList.appendChild(label);\n });\n cats.appendChild(catList);\n const addCat = el('a', { href: '#', className: 'fe-add-link' }, ['+ Add New Category']);\n addCat.addEventListener('click', (e) => {\n e.preventDefault();\n const name = prompt('Category name:');\n if (name) {\n this._categories.push(name);\n const label = el('label', { className: 'fe-checkbox-label' });\n label.appendChild(el('input', { type: 'checkbox', checked: true }));\n label.appendChild(document.createTextNode(' ' + name));\n catList.appendChild(label);\n }\n });\n cats.appendChild(addCat);\n this._postTab.appendChild(cats);\n\n // Tags\n const tags = this._section('Tags');\n const tagWrapper = el('div', { className: 'fe-tag-input-wrapper' });\n const tagInput = el('input', { type: 'text', placeholder: 'Add tag...' });\n tagInput.addEventListener('keydown', (e) => {\n if (e.key === 'Enter' || e.key === ',') {\n e.preventDefault();\n const val = tagInput.value.replace(',', '').trim();\n if (!val) return;\n this._tags.push(val);\n const tag = el('span', { className: 'fe-tag' });\n tag.appendChild(document.createTextNode(val + ' '));\n const remove = el('span', { className: 'fe-tag-remove', innerHTML: '×' });\n remove.addEventListener('click', () => {\n this._tags = this._tags.filter((t) => t !== val);\n tag.remove();\n });\n tag.appendChild(remove);\n tagWrapper.insertBefore(tag, tagInput);\n tagInput.value = '';\n }\n });\n tagWrapper.appendChild(tagInput);\n tagWrapper.addEventListener('click', () => tagInput.focus());\n tags.appendChild(tagWrapper);\n tags.appendChild(el('p', { className: 'fe-hint' }, ['Separate with commas or Enter key']));\n this._postTab.appendChild(tags);\n\n // Featured Image\n const fi = this._section('Featured Image');\n const fiArea = el('div', { className: 'fe-featured-image-area' });\n fiArea.appendChild(el('p', {}, ['Set featured image']));\n const fiInput = el('input', { type: 'file', accept: 'image/*', style: { display: 'none' } });\n fiInput.addEventListener('change', (e) => {\n const file = e.target.files[0];\n if (!file) return;\n const reader = new FileReader();\n reader.onload = (ev) => {\n fiArea.innerHTML = '';\n const img = el('img', { src: ev.target.result });\n img.style.maxWidth = '100%';\n img.style.borderRadius = '4px';\n fiArea.appendChild(img);\n this._featuredImage = ev.target.result;\n this.editor.emit('featuredImage:change', this._featuredImage);\n };\n reader.readAsDataURL(file);\n });\n fiArea.addEventListener('click', () => fiInput.click());\n fi.appendChild(fiArea);\n fi.appendChild(fiInput);\n this._postTab.appendChild(fi);\n\n // Excerpt\n const exc = this._section('Excerpt');\n exc.appendChild(el('textarea', { className: 'fe-input fe-textarea', placeholder: 'Write an excerpt (optional)' }));\n this._postTab.appendChild(exc);\n\n // Discussion\n const disc = this._section('Discussion');\n disc.appendChild(this._toggle('Allow comments', true));\n disc.appendChild(this._toggle('Allow pingbacks', false));\n this._postTab.appendChild(disc);\n }\n\n _buildBlockTab() {\n const section = el('div', { className: 'fe-panel-section' });\n section.appendChild(el('h3', { className: 'fe-section-title' }, ['Block Settings']));\n this._blockSettingsContent = el('div');\n this._blockSettingsContent.innerHTML = '<p class=\"fe-muted fe-text-center\">Select a block to see its settings.</p>';\n section.appendChild(this._blockSettingsContent);\n this._blockTab.appendChild(section);\n }\n\n _section(title) {\n const s = el('div', { className: 'fe-panel-section' });\n s.appendChild(el('h3', { className: 'fe-section-title' }, [title]));\n return s;\n }\n\n _field(label, type, options, id) {\n const frag = document.createDocumentFragment();\n frag.appendChild(el('label', {}, [label]));\n if (type === 'select') {\n const select = el('select', { className: 'fe-input' });\n if (id) select.id = id;\n (options || []).forEach((o) => select.appendChild(el('option', {}, [o])));\n frag.appendChild(select);\n } else {\n const input = el('input', { type, className: 'fe-input', placeholder: label.toLowerCase() });\n if (id) input.id = id;\n frag.appendChild(input);\n }\n return frag;\n }\n\n _toggle(label, defaultOn) {\n const row = el('div', { className: 'fe-toggle-row' });\n row.appendChild(el('label', {}, [label]));\n const btn = el('button', { className: `fe-toggle-switch ${defaultOn ? 'fe-on' : ''}` });\n btn.addEventListener('click', () => btn.classList.toggle('fe-on'));\n row.appendChild(btn);\n return row;\n }\n}\n","import { el } from '../utils/dom.js';\nimport { searchBlocks, BLOCK_TYPES } from '../blocks/registry.js';\n\n/**\n * Inline slash-command menu that appears when user types \"/\".\n */\nexport class SlashMenu {\n constructor(editor) {\n this.editor = editor;\n this.el = null;\n this._visible = false;\n this._highlightIndex = 0;\n this._items = [];\n this._targetBlock = null;\n }\n\n create() {\n this.el = el('div', { className: 'fe-slash-menu' });\n this._boundDocClick = (e) => {\n if (!e.target.closest('.fe-slash-menu')) this.close();\n };\n document.addEventListener('click', this._boundDocClick);\n return this.el;\n }\n\n /** Remove global listeners. Called by editor.destroy(). */\n destroy() {\n if (this._boundDocClick) {\n document.removeEventListener('click', this._boundDocClick);\n this._boundDocClick = null;\n }\n }\n\n open(block, rect) {\n this._targetBlock = block;\n this._visible = true;\n this._highlightIndex = 0;\n this.el.classList.add('fe-open');\n\n // Position near the caret\n const editorRect = this.editor.el.getBoundingClientRect();\n this.el.style.top = (rect.bottom - editorRect.top + 4) + 'px';\n this.el.style.left = (rect.left - editorRect.left) + 'px';\n\n this._filter('');\n }\n\n close() {\n this._visible = false;\n this._targetBlock = null;\n this.el.classList.remove('fe-open');\n }\n\n isOpen() {\n return this._visible;\n }\n\n filter(query) {\n this._filter(query);\n }\n\n handleKeydown(e) {\n if (!this._visible) return false;\n\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n this._navigate(1);\n return true;\n }\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n this._navigate(-1);\n return true;\n }\n if (e.key === 'Enter') {\n e.preventDefault();\n const visible = this._items.filter((i) => i.el.style.display !== 'none');\n if (visible[this._highlightIndex]) {\n this._selectItem(visible[this._highlightIndex].type);\n }\n return true;\n }\n if (e.key === 'Escape') {\n this.close();\n return true;\n }\n return false;\n }\n\n _filter(query) {\n this.el.innerHTML = '';\n this._items = [];\n\n const allBlocks = query ? searchBlocks(query) : Object.entries(BLOCK_TYPES).map(([type, def]) => ({ type, ...def }));\n\n allBlocks.forEach((blockDef, i) => {\n const item = el('div', { className: `fe-slash-item ${i === 0 ? 'fe-highlighted' : ''}` });\n item.appendChild(el('div', { className: 'fe-slash-icon', innerHTML: blockDef.icon }));\n const info = el('div', { className: 'fe-slash-info' });\n info.appendChild(el('div', { className: 'fe-slash-label' }, [blockDef.label]));\n info.appendChild(el('div', { className: 'fe-slash-desc' }, [blockDef.description]));\n item.appendChild(info);\n\n item.addEventListener('click', () => this._selectItem(blockDef.type));\n item.addEventListener('mouseenter', () => {\n this.el.querySelectorAll('.fe-slash-item').forEach((el) => el.classList.remove('fe-highlighted'));\n item.classList.add('fe-highlighted');\n });\n\n this.el.appendChild(item);\n this._items.push({ el: item, type: blockDef.type });\n });\n\n if (this._items.length === 0) {\n this.el.appendChild(el('div', { className: 'fe-slash-empty' }, ['No blocks found']));\n }\n\n this._highlightIndex = 0;\n }\n\n _navigate(dir) {\n const visible = this._items.filter((i) => i.el.style.display !== 'none');\n visible.forEach((i) => i.el.classList.remove('fe-highlighted'));\n this._highlightIndex = Math.max(0, Math.min(visible.length - 1, this._highlightIndex + dir));\n if (visible[this._highlightIndex]) {\n visible[this._highlightIndex].el.classList.add('fe-highlighted');\n visible[this._highlightIndex].el.scrollIntoView({ block: 'nearest' });\n }\n }\n\n _selectItem(type) {\n if (!this._targetBlock) return;\n const block = this._targetBlock;\n const inserted = this.editor.insertSingleBlockType(type);\n if (inserted) {\n this.close();\n this.editor.render();\n this.editor.focusBlock(block.id);\n return;\n }\n\n // Change the block type and clear content\n this.editor.blockManager.changeBlockType(block.id, type);\n block.content = '';\n this.close();\n this.editor.render();\n this.editor.focusBlock(block.id);\n }\n}\n","import { el } from '../utils/dom.js';\n\n/**\n * Bottom status bar showing word count, character count, block count.\n */\nexport class StatusBar {\n constructor(editor) {\n this.editor = editor;\n this.el = null;\n this._wordEl = null;\n this._charEl = null;\n this._blockEl = null;\n this._savedEl = null;\n }\n\n create() {\n this.el = el('div', { className: 'fe-status-bar' });\n this._wordEl = el('span', {}, ['Words: 0']);\n this._charEl = el('span', {}, ['Characters: 0']);\n this._blockEl = el('span', {}, ['Blocks: 0']);\n this._savedEl = el('span', { className: 'fe-status-right' });\n\n this.el.appendChild(this._wordEl);\n this.el.appendChild(this._charEl);\n this.el.appendChild(this._blockEl);\n this.el.appendChild(this._savedEl);\n\n return this.el;\n }\n\n update() {\n const bm = this.editor.blockManager;\n const titleText = this.editor._titleEl ? this.editor._titleEl.value : '';\n const titleWords = titleText.trim().split(/\\s+/).filter((w) => w.length).length;\n const words = bm.getWordCount() + titleWords;\n const chars = bm.getCharCount() + titleText.replace(/\\s/g, '').length;\n\n this._wordEl.textContent = `Words: ${words}`;\n this._charEl.textContent = `Characters: ${chars}`;\n this._blockEl.textContent = `Blocks: ${bm.blocks.length}`;\n }\n\n setSaved(text) {\n this._savedEl.textContent = text;\n }\n}\n","import { EventEmitter } from './utils/EventEmitter.js';\nimport { el, placeCaretAtEnd, placeCaretAtStart, getCaretRect } from './utils/dom.js';\nimport { icons } from './utils/icons.js';\nimport { BlockManager } from './core/BlockManager.js';\nimport { MediaUploader } from './core/MediaUploader.js';\nimport { DragDrop } from './core/DragDrop.js';\nimport { BlockRenderer } from './blocks/BlockRenderer.js';\nimport { Header } from './ui/Header.js';\nimport { Toolbar } from './ui/Toolbar.js';\nimport { InserterPanel } from './ui/InserterPanel.js';\nimport { SettingsPanel } from './ui/SettingsPanel.js';\nimport { SlashMenu } from './ui/SlashMenu.js';\nimport { StatusBar } from './ui/StatusBar.js';\n\n/**\n * NBDEditor — Gutenberg-style block editor.\n *\n * Usage:\n * const editor = new NBDEditor('#app', { ... });\n */\nexport class NBDEditor extends EventEmitter {\n constructor(selector, options = {}) {\n super();\n\n this.options = {\n siteName: 'My Site',\n authorName: 'Admin',\n showStatusBar: true,\n showSettingsPanel: false,\n showHeaderActions: false,\n placeholder: 'Start writing...',\n autoSaveInterval: 30000,\n uploadHandler: null, // async (file) => { url, id }\n maxFileSize: 10 * 1024 * 1024,\n onChooseMediaSource: null, // async/sync (type: 'video'|'audio') => 'url' | 'upload'\n content: null, // initial HTML content\n onChange: null,\n onSave: null,\n onPublish: null,\n ...options,\n };\n\n // Root element\n this.rootEl = typeof selector === 'string' ? document.querySelector(selector) : selector;\n if (!this.rootEl) throw new Error(`NBDEditor: element \"${selector}\" not found.`);\n\n // Core modules\n this.blockManager = new BlockManager();\n this.mediaUploader = new MediaUploader({\n uploadHandler: this.options.uploadHandler,\n maxFileSize: this.options.maxFileSize,\n });\n\n // UI modules\n this.blockRenderer = new BlockRenderer(this);\n this.header = new Header(this);\n this.toolbar = new Toolbar(this);\n this.inserterPanel = new InserterPanel(this);\n this.settingsPanel = new SettingsPanel(this);\n this.slashMenu = new SlashMenu(this);\n this.statusBar = new StatusBar(this);\n\n // State\n this._selectedBlockId = null;\n this._titleEl = null;\n this._blocksContainer = null;\n this._autoSaveTimer = null;\n this.el = null;\n this._htmlEditorModal = null;\n this._htmlEditorTextarea = null;\n this._htmlEditorTitle = null;\n this._htmlEditorBlockId = null;\n\n // Bound handlers for cleanup\n this._boundGlobalKeydown = (e) => this._handleGlobalKeydown(e);\n\n this._init();\n }\n\n /* ===== Initialization ===== */\n\n _init() {\n this.rootEl.innerHTML = '';\n this.rootEl.className = 'fe-root';\n\n // Header\n this.rootEl.appendChild(this.header.create());\n\n // Inserter panel\n this.rootEl.appendChild(this.inserterPanel.create());\n\n // Main wrapper\n this.el = el('div', { className: 'fe-editor-main' });\n\n // Canvas\n const canvas = el('div', { className: 'fe-editor-canvas', id: 'fe-canvas' });\n const content = el('div', { className: 'fe-editor-content' });\n\n // Blocks container\n this._blocksContainer = el('div', { className: 'fe-blocks-container' });\n content.appendChild(this._blocksContainer);\n\n canvas.appendChild(content);\n this.el.appendChild(canvas);\n\n // Settings panel\n if (this.options.showSettingsPanel) {\n this.el.appendChild(this.settingsPanel.create());\n }\n\n this.rootEl.appendChild(this.el);\n\n // Slash menu (appended to editor main for positioning)\n this.el.appendChild(this.slashMenu.create());\n\n // Status bar\n if (this.options.showStatusBar) {\n this.rootEl.appendChild(this.statusBar.create());\n }\n\n // Toast element\n this._toast = el('div', { className: 'fe-toast' });\n this.rootEl.appendChild(this._toast);\n this._createHtmlEditorModal();\n\n // Load initial content or create first block\n if (typeof this.options.content === 'string') {\n this.blockManager.fromJSON([{\n id: `blk_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`,\n type: 'paragraph',\n content: this.options.content,\n attrs: {},\n }]);\n } else if (this.options.content) {\n this.blockManager.fromJSON(this.options.content);\n } else {\n this.blockManager.addBlock('paragraph');\n }\n this._ensureAtLeastOneBlock();\n\n this.render();\n\n // Open settings panel by default\n if (this.options.showSettingsPanel) {\n this.settingsPanel.open();\n this._updateCanvasMargin();\n }\n\n // Keyboard shortcuts\n document.addEventListener('keydown', this._boundGlobalKeydown);\n\n // Auto-save\n if (this.options.autoSaveInterval > 0) {\n this._autoSaveTimer = setInterval(() => {\n this._syncAllBlockContent();\n this.statusBar.setSaved('Auto-saved: ' + new Date().toLocaleTimeString());\n this.emit('autosave', this.getData());\n }, this.options.autoSaveInterval);\n }\n\n // Listen for structural block changes (add, remove, move, type-change)\n this.blockManager.on('change', () => {\n const data = this.getData();\n if (this.options.onChange) this.options.onChange(data);\n this.emit('change', data);\n });\n\n // Drag & drop files onto the editor\n this._blocksContainer.addEventListener('dragover', (e) => e.preventDefault());\n this._blocksContainer.addEventListener('drop', async (e) => {\n if (e.dataTransfer.files.length > 0) {\n e.preventDefault();\n const results = await this.mediaUploader.handleDrop(e.dataTransfer);\n if (results) {\n const target =\n (this._selectedBlockId && this.blockManager.getBlock(this._selectedBlockId)) ||\n this.blockManager.blocks[0] ||\n this.blockManager.addBlock('paragraph');\n if (!target) return;\n const chunks = [];\n for (const res of results) {\n if (res.error) continue;\n const type = this.mediaUploader.getMediaType(res.file);\n const src = res.remoteUrl || res.localUrl;\n if (!src) continue;\n if (type === 'image') chunks.push(`<img src=\"${src}\" alt=\"\">`);\n else if (type === 'video') chunks.push(`<video controls src=\"${src}\"></video>`);\n else if (type === 'audio') chunks.push(`<audio controls src=\"${src}\"></audio>`);\n else if (type === 'file') chunks.push(`<a href=\"${src}\" target=\"_blank\" rel=\"noopener\">${res.file.name || 'Download file'}</a>`);\n }\n const toAppend = chunks.join('\\n');\n if (toAppend) target.content = `${target.content || ''}${target.content ? '\\n' : ''}${toAppend}`;\n this.render();\n this.focusBlock(target.id);\n }\n }\n });\n }\n\n /* ===== Rendering ===== */\n\n render() {\n this._ensureAtLeastOneBlock();\n this._blocksContainer.innerHTML = '';\n\n this.blockManager.blocks.forEach((block) => {\n const wrapper = el('section', {\n className: `fe-block-wrapper ${this._selectedBlockId === block.id ? 'fe-selected' : ''}`,\n dataset: { blockId: block.id },\n });\n\n // Toolbar (per-block, shown on selection)\n const tbContainer = el('div', { className: 'fe-block-toolbar-container' });\n if (this._selectedBlockId === block.id) {\n const tb = this.toolbar.create();\n this.toolbar.show(block.id);\n tb.scrollLeft = 0;\n tbContainer.appendChild(tb);\n requestAnimationFrame(() => this._positionBlockToolbar(tb, wrapper));\n }\n wrapper.appendChild(tbContainer);\n\n // Block content\n const rendered = this.blockRenderer.render(block);\n wrapper.appendChild(rendered);\n\n // Click to select\n wrapper.addEventListener('click', (e) => {\n const clickedContent = e.target.closest('.fe-block-content');\n const clickedEditable = e.target.closest('[contenteditable]');\n const clickedCell = e.target.closest('td,th');\n let clickedEditableIndex = -1;\n if (clickedEditable && wrapper.contains(clickedEditable)) {\n const editables = Array.from(wrapper.querySelectorAll('[contenteditable]'));\n clickedEditableIndex = editables.indexOf(clickedEditable);\n }\n let clickedCellPos = null;\n if (clickedCell) {\n const row = clickedCell.closest('tr');\n const table = clickedCell.closest('table');\n if (row && table) {\n const rows = Array.from(table.querySelectorAll('tr'));\n const rowIndex = rows.indexOf(row);\n const cols = Array.from(row.querySelectorAll('th,td'));\n const colIndex = cols.indexOf(clickedCell);\n if (rowIndex >= 0 && colIndex >= 0) clickedCellPos = { rowIndex, colIndex };\n }\n }\n if (!e.target.closest('.fe-block-toolbar') && !e.target.closest('.fe-link-popover')) {\n if (this._selectedBlockId === block.id && (clickedContent || clickedEditable || clickedCell)) {\n return;\n }\n const blockId = block.id;\n this.selectBlock(blockId);\n // selectBlock calls render() which destroys DOM; focus the NEW contenteditable\n setTimeout(() => {\n const contentEl = this._getBlockContentEl(blockId);\n if (contentEl) {\n contentEl.focus();\n if (clickedCellPos) {\n const rows = Array.from(contentEl.querySelectorAll('tr'));\n const row = rows[clickedCellPos.rowIndex];\n const cols = row ? Array.from(row.querySelectorAll('th,td')) : [];\n const nextCell = cols[clickedCellPos.colIndex] || cols[cols.length - 1] || null;\n if (nextCell) {\n const range = document.createRange();\n range.selectNodeContents(nextCell);\n range.collapse(false);\n const sel = window.getSelection();\n sel.removeAllRanges();\n sel.addRange(range);\n return;\n }\n }\n if (clickedEditableIndex >= 0) {\n const newWrapper = this._blocksContainer.querySelector(`[data-block-id=\"${blockId}\"]`);\n const editables = newWrapper ? Array.from(newWrapper.querySelectorAll('[contenteditable]')) : [];\n const targetEditable = editables[clickedEditableIndex] || editables[0] || null;\n if (targetEditable) {\n targetEditable.focus();\n placeCaretAtEnd(targetEditable);\n return;\n }\n }\n if (!clickedContent) placeCaretAtEnd(contentEl);\n }\n }, 0);\n }\n });\n\n // Drag handle setup\n const dragHandle = wrapper.querySelector('.fe-tb-drag');\n if (dragHandle) {\n const dd = new DragDrop(this._blocksContainer);\n dd.initDrag(dragHandle, wrapper, block.id);\n dd.on('drop', ({ fromId, toId, position }) => {\n const fromIdx = this.blockManager.getIndex(fromId);\n let toIdx = this.blockManager.getIndex(toId);\n if (position === 'after') toIdx++;\n if (fromIdx < toIdx) toIdx--;\n const [moved] = this.blockManager.blocks.splice(fromIdx, 1);\n this.blockManager.blocks.splice(toIdx, 0, moved);\n this.blockManager.saveSnapshot();\n this.render();\n });\n }\n\n this._blocksContainer.appendChild(wrapper);\n });\n\n // Single global appender (outside blocks) to match WP-like flow.\n const appender = el('button', {\n type: 'button',\n className: 'fe-block-appender',\n 'aria-label': 'Add block',\n });\n const plusIcon = el('span', { className: 'fe-plus-icon', innerHTML: icons.plus });\n const label = el('span', {}, ['Add block']);\n appender.appendChild(plusIcon);\n appender.appendChild(label);\n appender.addEventListener('click', (e) => {\n e.preventDefault();\n e.stopPropagation();\n const targetId = this._selectedBlockId || this.blockManager.blocks[this.blockManager.blocks.length - 1]?.id;\n if (targetId) this.selectBlock(targetId);\n this.inserterPanel.open(appender, { forceNewBlock: true });\n });\n this._blocksContainer.appendChild(appender);\n\n this.statusBar.update();\n }\n\n /* ===== Block Operations ===== */\n\n selectBlock(id) {\n if (this._selectedBlockId === id) {\n if (this.options.showSettingsPanel) {\n this.settingsPanel.updateBlockSettings(id);\n }\n return;\n }\n this._selectedBlockId = id;\n this.render();\n if (this.options.showSettingsPanel) {\n this.settingsPanel.updateBlockSettings(id);\n }\n this.emit('block:select', id);\n }\n\n focusBlock(id) {\n this.selectBlock(id);\n setTimeout(() => {\n const contentEl = this._getBlockContentEl(id);\n if (contentEl) {\n contentEl.focus();\n placeCaretAtEnd(contentEl);\n }\n }, 0);\n }\n\n insertBlockAtSelection(type, data = {}) {\n if (this.insertSingleBlockType(type, data)) {\n const block = this._getInsertionTargetBlock();\n this.render();\n this.focusBlock(block.id);\n return block;\n }\n const selectedId = this._selectedBlockId;\n const block = this.blockManager.addBlock(type, data, selectedId || null);\n this.render();\n this.focusBlock(block.id);\n return block;\n }\n\n insertBlockAtEnd(type, data = {}) {\n if (this.insertSingleBlockType(type, data)) {\n const block = this._getInsertionTargetBlock();\n this.render();\n this.focusBlock(block.id);\n return block;\n }\n const block = this.blockManager.addBlock(type, data);\n this.render();\n this.focusBlock(block.id);\n return block;\n }\n\n /* ===== Block Input Handling ===== */\n\n _onBlockInput(block, node) {\n block.content = (block.type === 'code' || block.type === 'html')\n ? (node.textContent || '')\n : node.innerHTML;\n this.statusBar.update();\n\n // Slash command detection\n const text = node.textContent;\n if (text === '/') {\n const rect = getCaretRect() || node.getBoundingClientRect();\n this.slashMenu.open(block, rect);\n } else if (text.startsWith('/') && text.length > 1) {\n if (this.slashMenu.isOpen()) {\n this.slashMenu.filter(text.slice(1).toLowerCase());\n }\n } else {\n if (this.slashMenu.isOpen()) this.slashMenu.close();\n }\n\n const data = this.getData();\n if (this.options.onChange) this.options.onChange(data);\n this.emit('change', data);\n this.emit('input', block);\n }\n\n _onBlockKeydown(e, block, node) {\n // Slash menu takes priority\n if (this.slashMenu.isOpen() && this.slashMenu.handleKeydown(e)) return;\n // Keep Enter behavior inside the same block.\n // New blocks are created explicitly via inserter/add controls.\n\n // Table navigation + row creation with Tab\n if (e.key === 'Tab') {\n const cell = this._getSelectionTableCell();\n if (cell) {\n e.preventDefault();\n this._handleTableTab(cell, e.shiftKey);\n this._syncCurrentBlockContent();\n return;\n }\n }\n\n // Arrow Up at start: focus previous block\n if (e.key === 'ArrowUp') {\n const sel = window.getSelection();\n if (sel.rangeCount) {\n const range = sel.getRangeAt(0);\n const rect = range.getBoundingClientRect();\n const nodeRect = node.getBoundingClientRect();\n if (rect.top <= nodeRect.top + 2) {\n const prev = this.blockManager.getPrevBlock(block.id);\n if (prev) {\n e.preventDefault();\n this.focusBlock(prev.id);\n }\n }\n }\n }\n\n // Arrow Down at end: focus next block\n if (e.key === 'ArrowDown') {\n const sel = window.getSelection();\n if (sel.rangeCount) {\n const range = sel.getRangeAt(0);\n const rect = range.getBoundingClientRect();\n const nodeRect = node.getBoundingClientRect();\n if (rect.bottom >= nodeRect.bottom - 2) {\n const next = this.blockManager.getNextBlock(block.id);\n if (next) {\n e.preventDefault();\n const contentEl = this._getBlockContentEl(next.id);\n if (contentEl) {\n contentEl.focus();\n placeCaretAtStart(contentEl);\n this.selectBlock(next.id);\n }\n }\n }\n }\n }\n\n // Tab in code block\n if (e.key === 'Tab' && (block.type === 'code' || block.type === 'html')) {\n e.preventDefault();\n document.execCommand('insertText', false, ' ');\n }\n }\n\n /* ===== Helpers ===== */\n\n _getBlockContentEl(blockId) {\n const wrapper = this._blocksContainer.querySelector(`[data-block-id=\"${blockId}\"]`);\n return wrapper?.querySelector('.fe-block-content') || wrapper?.querySelector('[contenteditable]');\n }\n\n _getSelectedBlockEl() {\n if (!this._selectedBlockId) return null;\n return this._blocksContainer.querySelector(`[data-block-id=\"${this._selectedBlockId}\"]`);\n }\n\n _syncCurrentBlockContent() {\n if (!this._selectedBlockId) return;\n const block = this.blockManager.getBlock(this._selectedBlockId);\n const contentEl = this._getBlockContentEl(this._selectedBlockId);\n if (block && contentEl) {\n block.content = (block.type === 'code' || block.type === 'html')\n ? (contentEl.textContent || '')\n : contentEl.innerHTML;\n }\n }\n\n _syncAllBlockContent() {\n this.blockManager.blocks.forEach((block) => {\n const contentEl = this._getBlockContentEl(block.id);\n if (contentEl) {\n block.content = (block.type === 'code' || block.type === 'html')\n ? (contentEl.textContent || '')\n : contentEl.innerHTML;\n }\n });\n }\n\n _generateSlug() {\n const slug = (this._titleEl?.value || '')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-|-$/g, '');\n const slugEl = document.getElementById('fe-url-slug');\n if (slugEl) slugEl.value = slug;\n }\n\n _updateCanvasMargin() {\n if (!this.options.showSettingsPanel) return;\n const canvas = this.el.querySelector('.fe-editor-canvas');\n if (canvas) {\n canvas.classList.toggle('fe-panel-open', this.settingsPanel.isOpen());\n }\n }\n\n _createHtmlEditorModal() {\n const overlay = el('div', { className: 'fe-html-modal-overlay' });\n const modal = el('div', { className: 'fe-html-modal' });\n const header = el('div', { className: 'fe-html-modal-header' });\n const title = el('h3', { className: 'fe-html-modal-title' }, ['Edit as HTML']);\n const closeBtn = el('button', {\n type: 'button',\n className: 'fe-icon-btn fe-icon-btn-sm',\n innerHTML: icons.close,\n onClick: () => this._closeBlockHtmlEditor(),\n });\n header.appendChild(title);\n header.appendChild(closeBtn);\n\n const textarea = el('textarea', {\n className: 'fe-html-modal-textarea',\n spellcheck: 'false',\n placeholder: 'Edit block HTML...',\n });\n\n const actions = el('div', { className: 'fe-html-modal-actions' });\n const cancelBtn = el('button', {\n type: 'button',\n className: 'fe-btn fe-btn-outline',\n innerHTML: 'Cancel',\n onClick: () => this._closeBlockHtmlEditor(),\n });\n const applyBtn = el('button', {\n type: 'button',\n className: 'fe-btn fe-btn-primary',\n innerHTML: 'Apply HTML',\n onClick: () => this._applyBlockHtmlEditor(),\n });\n actions.appendChild(cancelBtn);\n actions.appendChild(applyBtn);\n\n modal.appendChild(header);\n modal.appendChild(textarea);\n modal.appendChild(actions);\n overlay.appendChild(modal);\n\n overlay.addEventListener('click', (e) => {\n if (e.target === overlay) this._closeBlockHtmlEditor();\n });\n textarea.addEventListener('keydown', (e) => {\n if (e.key === 'Escape') this._closeBlockHtmlEditor();\n if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') this._applyBlockHtmlEditor();\n });\n\n this.rootEl.appendChild(overlay);\n this._htmlEditorModal = overlay;\n this._htmlEditorTextarea = textarea;\n this._htmlEditorTitle = title;\n }\n\n _parseBlockFromHTML(html, fallbackType = 'paragraph') {\n const raw = (html || '').trim();\n if (!raw) return { type: fallbackType, content: '', attrs: {} };\n if (typeof document === 'undefined') return { type: 'html', content: raw, attrs: {} };\n\n const wrap = document.createElement('div');\n wrap.innerHTML = raw;\n const first = wrap.firstElementChild;\n const onlyOneElement =\n wrap.childElementCount === 1 &&\n Array.from(wrap.childNodes).every((n) => n.nodeType === Node.ELEMENT_NODE || n.textContent.trim() === '');\n\n if (!first || !onlyOneElement) {\n return { type: 'html', content: raw, attrs: {} };\n }\n\n const tag = first.tagName.toLowerCase();\n if (tag === 'p') return { type: 'paragraph', content: first.innerHTML, attrs: {} };\n if (tag === 'h2') return { type: 'heading', content: first.innerHTML, attrs: {} };\n if (tag === 'h3') return { type: 'heading-3', content: first.innerHTML, attrs: {} };\n if (tag === 'h4') return { type: 'heading-4', content: first.innerHTML, attrs: {} };\n if (tag === 'blockquote') return { type: 'quote', content: first.innerHTML, attrs: {} };\n if (tag === 'ul') return { type: 'list', content: first.innerHTML, attrs: {} };\n if (tag === 'ol') return { type: 'ordered-list', content: first.innerHTML, attrs: {} };\n if (tag === 'hr') return { type: 'separator', content: '', attrs: {} };\n if (tag === 'img') {\n const styleWidth = _readPercentWidth(first.getAttribute('style') || '');\n return {\n type: 'image',\n content: first.getAttribute('src') || '',\n attrs: {\n alt: first.getAttribute('alt') || '',\n ...(styleWidth ? { width: styleWidth } : {}),\n },\n };\n }\n if (tag === 'figure') {\n const img = first.querySelector('img');\n if (img) {\n const caption = first.querySelector('figcaption');\n const styleWidth = _readPercentWidth(img.getAttribute('style') || '');\n return {\n type: 'image',\n content: img.getAttribute('src') || '',\n attrs: {\n alt: img.getAttribute('alt') || '',\n caption: caption ? caption.innerHTML : '',\n ...(styleWidth ? { width: styleWidth } : {}),\n },\n };\n }\n }\n if (tag === 'pre') {\n const code = first.querySelector('code');\n return {\n type: 'code',\n content: code ? (code.textContent || '') : (first.textContent || ''),\n attrs: {},\n };\n }\n\n return { type: 'html', content: raw, attrs: {} };\n }\n\n /* ===== Global Keyboard Shortcuts ===== */\n\n _handleGlobalKeydown(e) {\n const mod = e.ctrlKey || e.metaKey;\n const activeEl = document.activeElement;\n const inEditable =\n Boolean(activeEl && activeEl.isContentEditable && this.rootEl.contains(activeEl)) ||\n Boolean(window.getSelection()?.anchorNode && this.rootEl.contains(window.getSelection().anchorNode));\n\n if (mod && e.key === 'z' && !e.shiftKey) {\n e.preventDefault();\n this.undo({ preferNative: inEditable });\n }\n if (mod && (e.key === 'y' || (e.key === 'z' && e.shiftKey))) {\n e.preventDefault();\n this.redo({ preferNative: inEditable });\n }\n if (mod && e.key === 's') {\n e.preventDefault();\n this.save();\n }\n if (mod && e.key === 'b') {\n e.preventDefault();\n document.execCommand('bold', false, null);\n this._syncCurrentBlockContent();\n }\n if (mod && e.key === 'i') {\n e.preventDefault();\n document.execCommand('italic', false, null);\n this._syncCurrentBlockContent();\n }\n if (mod && e.key === 'u') {\n e.preventDefault();\n document.execCommand('underline', false, null);\n this._syncCurrentBlockContent();\n }\n if (mod && e.key === 'k') {\n e.preventDefault();\n this.toolbar._showLinkPopover();\n }\n if (mod && e.key === 'a') {\n const contentEl = this._getBlockContentEl(this._selectedBlockId);\n if (contentEl && this.rootEl.contains(document.activeElement)) {\n e.preventDefault();\n const range = document.createRange();\n range.selectNodeContents(contentEl);\n const sel = window.getSelection();\n sel.removeAllRanges();\n sel.addRange(range);\n }\n }\n }\n\n /* ===== Public API ===== */\n\n /** Get all editor data as a JSON object. */\n getData() {\n this._syncAllBlockContent();\n const mergedHtml = this.blockManager.toHTML();\n return { content: mergedHtml };\n }\n\n /** Set editor content from a content string or { content } object. */\n setData(data) {\n const content = typeof data === 'string'\n ? data\n : (typeof data?.content === 'string' ? data.content : '');\n\n this.blockManager.fromJSON([\n {\n id: `blk_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`,\n type: 'paragraph',\n content,\n attrs: {},\n },\n ]);\n this.render();\n }\n\n /** Export blocks as HTML string. */\n toHTML() {\n this._syncAllBlockContent();\n return this.blockManager.toHTML();\n }\n\n toggleBlockHtmlMode(blockId = this._selectedBlockId) {\n if (!blockId) return;\n this._syncCurrentBlockContent();\n const block = this.blockManager.getBlock(blockId);\n if (!block) return;\n\n if (block.type === 'html') {\n const fallbackType = block.attrs?.__sourceType || 'paragraph';\n const parsed = this._parseBlockFromHTML(block.content || '', fallbackType);\n block.type = parsed.type === 'html' ? fallbackType : parsed.type;\n block.content = parsed.content;\n block.attrs = parsed.attrs || {};\n this.render();\n this.focusBlock(blockId);\n return;\n }\n\n const html = this.blockManager.blockToHTML(block);\n block.attrs = { ...(block.attrs || {}), __sourceType: block.type };\n block.type = 'html';\n block.content = html;\n this.render();\n this.focusBlock(blockId);\n }\n\n openBlockHtmlEditor(blockId = this._selectedBlockId) {\n if (!blockId || !this._htmlEditorModal || !this._htmlEditorTextarea) return;\n this._syncCurrentBlockContent();\n const block = this.blockManager.getBlock(blockId);\n if (!block) return;\n\n this._htmlEditorBlockId = blockId;\n this._htmlEditorTitle.textContent = `Edit as HTML: ${block.type}`;\n this._htmlEditorTextarea.value = this.blockManager.blockToHTML(block);\n this._htmlEditorModal.classList.add('fe-open');\n setTimeout(() => {\n this._htmlEditorTextarea.focus();\n this._htmlEditorTextarea.select();\n }, 0);\n }\n\n _closeBlockHtmlEditor() {\n if (!this._htmlEditorModal) return;\n this._htmlEditorModal.classList.remove('fe-open');\n this._htmlEditorBlockId = null;\n }\n\n _applyBlockHtmlEditor() {\n if (!this._htmlEditorBlockId || !this._htmlEditorTextarea) return;\n const block = this.blockManager.getBlock(this._htmlEditorBlockId);\n if (!block) return this._closeBlockHtmlEditor();\n\n const parsed = this._parseBlockFromHTML(this._htmlEditorTextarea.value, block.type);\n block.type = parsed.type;\n block.content = parsed.content;\n block.attrs = parsed.attrs || {};\n this._closeBlockHtmlEditor();\n this.render();\n this.focusBlock(block.id);\n }\n\n /** Save draft (emits save event). */\n save() {\n const data = this.getData();\n this.header.setStatus('Draft saved');\n this.statusBar.setSaved('Last saved: ' + new Date().toLocaleTimeString());\n this._showToast('Draft saved');\n if (this.options.onSave) this.options.onSave(data);\n this.emit('save', data);\n }\n\n /** Publish (emits publish event). */\n publish() {\n const data = this.getData();\n this.header.setStatus('Published', '#00a32a');\n this._showToast('Post published!');\n if (this.options.onPublish) this.options.onPublish(data);\n this.emit('publish', data);\n }\n\n /** Get / set the title. */\n getTitle() { return this._titleEl?.value || ''; }\n setTitle(title) { if (this._titleEl) this._titleEl.value = title; }\n\n undo({ preferNative = false } = {}) {\n if (preferNative) {\n const didNative = document.execCommand('undo', false, null);\n if (didNative) {\n this._syncCurrentBlockContent();\n return true;\n }\n }\n\n const didBlockUndo = this.blockManager.undo();\n if (didBlockUndo) this.render();\n return didBlockUndo;\n }\n\n redo({ preferNative = false } = {}) {\n if (preferNative) {\n const didNative = document.execCommand('redo', false, null);\n if (didNative) {\n this._syncCurrentBlockContent();\n return true;\n }\n }\n\n const didBlockRedo = this.blockManager.redo();\n if (didBlockRedo) this.render();\n return didBlockRedo;\n }\n\n /** Destroy editor instance. */\n destroy() {\n if (this._autoSaveTimer) clearInterval(this._autoSaveTimer);\n document.removeEventListener('keydown', this._boundGlobalKeydown);\n this.slashMenu.destroy();\n this.toolbar.hide();\n this.rootEl.innerHTML = '';\n this._listeners = {};\n }\n\n _showToast(msg) {\n this._toast.textContent = msg;\n this._toast.classList.add('fe-show');\n setTimeout(() => this._toast.classList.remove('fe-show'), 2500);\n }\n\n _positionBlockToolbar(toolbarEl, wrapperEl) {\n if (!toolbarEl || !wrapperEl) return;\n const viewportPadding = 8;\n\n toolbarEl.classList.remove('fe-toolbar-below');\n toolbarEl.style.top = '-44px';\n toolbarEl.style.left = '0px';\n\n const toolbarRect = toolbarEl.getBoundingClientRect();\n const wrapperRect = wrapperEl.getBoundingClientRect();\n\n let shiftX = 0;\n if (toolbarRect.right > window.innerWidth - viewportPadding) {\n shiftX -= toolbarRect.right - (window.innerWidth - viewportPadding);\n }\n if (toolbarRect.left + shiftX < viewportPadding) {\n shiftX += viewportPadding - (toolbarRect.left + shiftX);\n }\n toolbarEl.style.left = `${Math.round(shiftX)}px`;\n\n const topIfAbove = wrapperRect.top - toolbarRect.height - 6;\n const shouldPlaceBelow = topIfAbove < viewportPadding;\n if (shouldPlaceBelow) {\n toolbarEl.classList.add('fe-toolbar-below');\n toolbarEl.style.top = '6px';\n }\n wrapperEl.classList.toggle('fe-toolbar-inset', shouldPlaceBelow);\n }\n\n _getSelectionTableCell() {\n const sel = window.getSelection();\n if (!sel || !sel.rangeCount) return null;\n let node = sel.anchorNode;\n if (!node) return null;\n if (node.nodeType === Node.TEXT_NODE) node = node.parentElement;\n if (!node || typeof node.closest !== 'function') return null;\n const cell = node.closest('td,th');\n if (!cell) return null;\n const contentEl = this._getBlockContentEl(this._selectedBlockId);\n if (!contentEl || !contentEl.contains(cell)) return null;\n return cell;\n }\n\n _handleTableTab(currentCell, reverse = false) {\n const row = currentCell.closest('tr');\n const table = currentCell.closest('table');\n if (!row || !table) return;\n\n const rowCells = Array.from(row.querySelectorAll('th,td'));\n const cellIndex = rowCells.indexOf(currentCell);\n const rows = Array.from(table.querySelectorAll('tr'));\n const rowIndex = rows.indexOf(row);\n\n if (reverse) {\n if (cellIndex > 0) {\n this._placeCaretInCell(rowCells[cellIndex - 1]);\n return;\n }\n if (rowIndex > 0) {\n const prevRowCells = Array.from(rows[rowIndex - 1].querySelectorAll('th,td'));\n this._placeCaretInCell(prevRowCells[prevRowCells.length - 1]);\n }\n return;\n }\n\n if (cellIndex < rowCells.length - 1) {\n this._placeCaretInCell(rowCells[cellIndex + 1]);\n return;\n }\n\n if (rowIndex < rows.length - 1) {\n const nextRowCells = Array.from(rows[rowIndex + 1].querySelectorAll('th,td'));\n this._placeCaretInCell(nextRowCells[0]);\n return;\n }\n\n const colCount = Math.max(1, rowCells.length);\n const newRow = document.createElement('tr');\n for (let i = 0; i < colCount; i++) {\n const td = document.createElement('td');\n td.innerHTML = '<br>';\n newRow.appendChild(td);\n }\n\n const tbody = table.querySelector('tbody');\n if (tbody) tbody.appendChild(newRow);\n else table.appendChild(newRow);\n this._placeCaretInCell(newRow.querySelector('td'));\n }\n\n _placeCaretInCell(cell) {\n if (!cell) return;\n if ((cell.innerHTML || '').trim() === '') cell.innerHTML = '<br>';\n const range = document.createRange();\n range.selectNodeContents(cell);\n range.collapse(true);\n const sel = window.getSelection();\n sel.removeAllRanges();\n sel.addRange(range);\n }\n\n insertSingleBlockType(type, data = {}) {\n const block = this._getInsertionTargetBlock();\n if (!block) return false;\n\n const snippet = this._snippetForType(type, data);\n if (!snippet) return false;\n\n if (typeof document.execCommand === 'function') {\n const contentEl = this._getBlockContentEl(block.id);\n if (contentEl) {\n contentEl.focus();\n const ok = document.execCommand('insertHTML', false, snippet);\n if (ok) {\n this._focusEditableTail(contentEl);\n this._syncCurrentBlockContent();\n return true;\n }\n }\n }\n\n block.content = `${block.content || ''}${block.content ? '\\n' : ''}${snippet}`;\n return true;\n }\n\n _snippetForType(type, data = {}) {\n if (type === 'separator') return '<hr><p><br></p>';\n if (type === 'spacer') return `<div style=\"height:${Number(data?.height) || 48}px\"></div><p><br></p>`;\n if (type === 'table') {\n return [\n '<table border=\"1\" style=\"width:100%;border-collapse:collapse;\">',\n '<tbody>',\n '<tr><td>Cell 1</td><td>Cell 2</td></tr>',\n '<tr><td>Cell 3</td><td>Cell 4</td></tr>',\n '</tbody>',\n '</table>',\n '<p><br></p>',\n ].join('');\n }\n if (type === 'columns') {\n return [\n '<div class=\"fe-inline-columns\">',\n '<div class=\"fe-inline-column\"><p>Column 1</p></div>',\n '<div class=\"fe-inline-column\"><p>Column 2</p></div>',\n '</div>',\n '<p><br></p>',\n ].join('');\n }\n\n if (type === 'button') {\n return '<p><a href=\"#\" style=\"display:inline-block;background:#2271b1;color:#fff;padding:10px 24px;border-radius:4px;text-decoration:none;\" contenteditable=\"false\">Button</a></p><p><br></p>';\n }\n if (type === 'video') {\n const src = String(data?.url || '').trim();\n return src\n ? `<video controls style=\"width:100%;max-width:100%;\" src=\"${src}\"></video><p><br></p>`\n : '<video controls style=\"width:100%;max-width:100%;\"></video><p><br></p>';\n }\n if (type === 'audio') {\n const src = String(data?.url || '').trim();\n return src\n ? `<audio controls style=\"width:100%;\" src=\"${src}\"></audio><p><br></p>`\n : '<audio controls style=\"width:100%;\"></audio><p><br></p>';\n }\n if (type === 'file') {\n const url = String(data?.url || '').trim();\n const name = String(data?.name || 'Download file').trim();\n return url ? `<p><a href=\"${url}\" target=\"_blank\" rel=\"noopener\">${name}</a></p><p><br></p>` : null;\n }\n if (type === 'embed') {\n const url = String(data?.url || '').trim();\n return url\n ? `<p><a href=\"${url}\" target=\"_blank\" rel=\"noopener\">${url}</a></p><p><br></p>`\n : '<p>Paste embed URL here</p><p><br></p>';\n }\n return null;\n }\n\n _focusEditableTail(contentEl) {\n if (!contentEl) return;\n let tail = contentEl.lastElementChild;\n const needsTail = !tail || tail.tagName !== 'P';\n if (needsTail) {\n tail = document.createElement('p');\n tail.innerHTML = '<br>';\n contentEl.appendChild(tail);\n } else if ((tail.innerHTML || '').trim() === '') {\n tail.innerHTML = '<br>';\n }\n\n const range = document.createRange();\n range.selectNodeContents(tail);\n range.collapse(false);\n const sel = window.getSelection();\n sel.removeAllRanges();\n sel.addRange(range);\n }\n\n _ensureAtLeastOneBlock() {\n if (!Array.isArray(this.blockManager.blocks) || this.blockManager.blocks.length === 0) {\n return this.blockManager.addBlock('paragraph');\n }\n return this.blockManager.blocks[0];\n }\n\n _getInsertionTargetBlock() {\n const selected =\n this._selectedBlockId\n ? this.blockManager.getBlock(this._selectedBlockId)\n : null;\n if (selected) return selected;\n\n const last = this.blockManager.blocks[this.blockManager.blocks.length - 1];\n if (last) return last;\n\n return this.blockManager.addBlock('paragraph');\n }\n}\n\nfunction _readPercentWidth(style) {\n const match = /width\\s*:\\s*([0-9.]+)%/i.exec(style || '');\n if (!match) return null;\n const value = Number(match[1]);\n if (!Number.isFinite(value)) return null;\n return Math.max(10, Math.min(100, Math.round(value)));\n}\n","/**\n * React wrapper for NBDEditor.\n *\n * Guarded so the module can be safely imported in environments where React\n * is not available (e.g. vanilla-JS UMD usage). When React is missing,\n * `ReactNBDEditor` will be `null`.\n */\nimport * as React from 'react';\nimport { NBDEditor } from '../NBDEditor.js';\n\n// Guard: React may be undefined in vanilla-JS / UMD without React loaded.\nconst _hasReact = typeof React !== 'undefined' && React !== null && typeof React.forwardRef === 'function';\n\nfunction ReactNBDEditorComponent(props, ref) {\n const {\n className,\n style,\n content,\n onChange,\n onReady,\n ...editorOptions\n } = props || {};\n\n const hostRef = React.useRef(null);\n const editorRef = React.useRef(null);\n const lastContentRef = React.useRef(undefined);\n\n React.useEffect(() => {\n if (!hostRef.current) return undefined;\n\n const initialOptions = {\n ...editorOptions,\n onChange: (data) => {\n const nextContent = typeof data?.content === 'string' ? data.content : '';\n lastContentRef.current = nextContent;\n if (typeof onChange === 'function') onChange(data);\n },\n ...(typeof content === 'string' ? { content } : {}),\n };\n\n const editor = new NBDEditor(hostRef.current, initialOptions);\n editorRef.current = editor;\n lastContentRef.current = typeof content === 'string' ? content : undefined;\n if (typeof onReady === 'function') onReady(editor);\n\n return () => {\n if (editorRef.current) {\n editorRef.current.destroy();\n editorRef.current = null;\n }\n };\n // Intentionally one-time init; options should be stable at mount.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n React.useEffect(() => {\n if (!editorRef.current) return;\n if (typeof content !== 'string') return;\n if (content === lastContentRef.current) return;\n if (content === editorRef.current.toHTML()) {\n lastContentRef.current = content;\n return;\n }\n editorRef.current.setData({ content });\n lastContentRef.current = content;\n }, [content]);\n\n React.useImperativeHandle(ref, () => ({\n getInstance: () => editorRef.current,\n getData: () => editorRef.current?.getData(),\n setData: (data) => editorRef.current?.setData(data),\n toHTML: () => editorRef.current?.toHTML(),\n save: () => editorRef.current?.save(),\n publish: () => editorRef.current?.publish(),\n undo: (opts) => editorRef.current?.undo(opts),\n redo: (opts) => editorRef.current?.redo(opts),\n destroy: () => editorRef.current?.destroy(),\n }), []);\n\n return React.createElement('div', {\n ref: hostRef,\n className,\n style,\n });\n}\n\nexport const ReactNBDEditor = _hasReact ? React.forwardRef(ReactNBDEditorComponent) : null;\n"],"names":["EventEmitter","constructor","this","_listeners","on","event","fn","push","off","list","filter","f","emit","args","forEach","once","wrapper","el","tag","attrs","children","node","document","createElement","k","v","Object","entries","className","assign","style","dk","dv","dataset","startsWith","addEventListener","slice","toLowerCase","contentEditable","innerHTML","setAttribute","child","Array","isArray","appendChild","createTextNode","Node","generateId","Date","now","toString","Math","random","placeCaretAtEnd","element","focus","range","createRange","selectNodeContents","collapse","sel","window","getSelection","removeAllRanges","addRange","svg","inner","vb","icons","plus","undo","redo","listView","settings","bold","italic","underline","strikethrough","link","code","alignLeft","alignCenter","alignRight","image","heading","paragraph","quote","orderedList","separator","table","button","columns","spacer","embed","gallery","video","audio","file","dragHandle","filled","arrowUp","arrowDown","trash","close","inlineCode","upload","html","pullquote","BlockManager","super","blocks","_undoStack","_redoStack","_maxHistory","JSON","stringify","addBlock","type","data","afterId","block","id","content","idx","findIndex","b","splice","_pushUndo","removeBlock","length","removed","updateBlock","patch","getBlock","changeBlockType","newType","moveBlock","direction","newIdx","duplicateBlock","clone","find","getIndex","getPrevBlock","getNextBlock","toJSON","map","fromJSON","toHTML","blockToHTML","join","toHTMLBlocks","c","test","_escText","width","Number","isFinite","max","min","round","_escAttr","alt","caption","height","url","filename","next","shift","saveSnapshot","pop","parse","state","getWordCount","text","tmp","textContent","trim","split","w","getCharCount","replace","str","String","MediaUploader","options","uploadHandler","maxFileSize","allowedImageTypes","allowedVideoTypes","allowedAudioTypes","_fileInput","openFilePicker","accept","multiple","Promise","resolve","remove","input","display","body","files","click","processFile","size","err","name","toFixed","error","localUrl","_readAsDataURL","result","remoteUrl","message","processFiles","all","handlePaste","clipboardData","imageItems","items","item","getAsFile","Boolean","handleDrop","dataTransfer","getMediaType","reject","reader","FileReader","onload","onerror","readAsDataURL","DragDrop","container","_dragging","_placeholder","_offsetY","_bound","_enabled","enable","disable","initDrag","handleEl","wrapperEl","blockId","cursor","e","preventDefault","opacity","effectAllowed","setData","_removePlaceholder","dropEffect","rect","getBoundingClientRect","midY","top","position","clientY","_showPlaceholder","fromId","toId","referenceEl","cssText","parentNode","insertBefore","nextSibling","removeChild","BLOCK_TYPES","label","description","icon","category","hasContent","contentTag","placeholder","isMedia","CATEGORIES","getBlocksByCategory","catId","def","searchBlocks","query","q","includes","BlockRenderer","editor","render","_renderParagraph","_renderMediaBlock","_renderContentBlock","_renderSeparator","_renderSpacer","_renderColumns","_renderTable","isRawTextBlock","isEmpty","empty","_bindContentEvents","_renderImageBlock","_renderGalleryBlock","_renderVideoBlock","_renderAudioBlock","_renderFileBlock","_renderMediaPlaceholder","_normalizeImageWidth","fig","img","src","maxWidth","borderRadius","overlay","replaceBtn","onClick","_triggerImageUpload","removeBtn","resizeHandle","title","stopPropagation","selectBlock","startX","clientX","startWidth","parentWidth","onMove","ev","delta","nextPercent","onUp","removeEventListener","statusBar","update","sizeControls","pct","btn","images","grid","i","addMore","_triggerGalleryUpload","controls","infoDiv","filesize","downloadLink","href","download","iconEl","desc","btnRow","uploadBtn","_handleMediaUpload","urlInput","key","value","_setupDropZone","handle","startY","startH","newH","numCols","col","current","rows","cols","r","tr","cell","mediaUploader","results","res","bytes","classList","add","async","updateEmptyState","_selectedBlockId","activeElement","setTimeout","_onBlockInput","querySelector","_onBlockKeydown","getData","execCommand","then","numeric","Header","create","left","inserterBtn","inserterPanel","toggle","currentTarget","_iconBtn","activeEl","inEditable","isContentEditable","rootEl","contains","anchorNode","preferNative","center","right","showHeaderActions","draftBtn","save","publishBtn","publish","showSettingsPanel","childNodes","settingsPanel","_updateCanvasMargin","setStatus","color","iconHTML","Toolbar","_linkPopover","_fontSizeSelect","_onSelectionChange","_statefulButtons","_savedLinkRange","_tableToolsSep","_tableRowBtn","_tableColBtn","_createLinkPopover","show","blockManager","hide","getActiveBlockId","_addBtn","_addSep","textTypes","htmlEditableTypes","select","opt","o","selected","blockNow","ensureParagraphContext","contentEl","_getBlockContentEl","_syncCurrentBlockContent","focusBlock","fontSizeSelect","_applyFontSize","_syncFontSizeSelect","_bindFontSizeTracking","_addStatefulBtn","_exec","_wrapInlineCode","_showLinkPopover","_addTextBtn","_addTableRow","_addTableColumn","toggleBlockHtmlMode","_syncStatefulButtons","activeId","blockToClear","_hideLinkPopover","_unbindFontSizeTracking","extraClass","command","sep","cmd","rangeCount","getRangeAt","surroundContents","px","collapsed","marker","fontSize","insertNode","nextRange","setStart","firstChild","span","extractContents","_currentSelectionFontSizePx","snapped","sizes","best","bestDelta","abs","_closestFontSize","focusNode","elNode","nodeType","ELEMENT_NODE","parentElement","_getSelectedBlockEl","raw","getComputedStyle","parseFloat","applyBtn","_restoreSavedLinkRange","querySelectorAll","a","target","rel","cloneRange","bottom","anchor","closest","_getCurrentTableContext","TEXT_NODE","maybeCell","ctx","currentRow","rowCells","from","colCount","newRow","td","indexOf","row","cells","ref","newCell","tagName","targetRowCells","focusCell","hasSelectionInEditor","active","queryCommandState","tableDisplay","_isSelectionInTable","InserterPanel","_searchInput","_listEl","_anchorEl","_onDocMouseDown","_onDocKeyDown","_savedRange","_mediaModal","_mediaModalCard","_mediaModalTitle","_mediaModalBody","_mediaModalResolver","_forceNewBlock","header","closeBtn","_renderList","_createMediaModal","open","anchorEl","forceNewBlock","_captureSelectionRange","_positionNearAnchor","_bindGlobalCloseHandlers","_unbindGlobalCloseHandlers","isOpen","_createBlockItem","cat","blockDef","info","_insertFromPopover","desiredLeft","innerWidth","desiredTop","innerHeight","commonAncestorContainer","_restoreSelectionRange","selectedId","selectedBlock","insertSingleBlockType","insertBlockAtSelection","source","_chooseMediaSource","_promptForMediaUrl","trimmed","_showToast","prompt","onChooseMediaSource","_openMediaSourceModal","card","_closeMediaModal","actions","urlBtn","cancelBtn","resolver","SettingsPanel","_activeTab","_postTab","_blockTab","_tagInput","_tags","_categories","_featuredImage","tabs","_postTabBtn","_blockTabBtn","_switchTab","_buildPostTab","_buildBlockTab","updateBlockSettings","_blockSettingsContent","section","fontSelect","l","lhInput","lineHeight","colorSection","textColors","swatch","background","bgColors","border","tab","summary","_section","_field","cats","catList","addCat","checked","tags","tagWrapper","tagInput","val","t","fi","fiArea","fiInput","exc","disc","_toggle","s","frag","createDocumentFragment","defaultOn","SlashMenu","_visible","_highlightIndex","_items","_targetBlock","_boundDocClick","destroy","editorRect","_filter","handleKeydown","_navigate","visible","_selectItem","dir","scrollIntoView","StatusBar","_wordEl","_charEl","_blockEl","_savedEl","bm","titleText","_titleEl","titleWords","words","chars","setSaved","NBDEditor","selector","siteName","authorName","showStatusBar","autoSaveInterval","onChange","onSave","onPublish","Error","blockRenderer","toolbar","slashMenu","_blocksContainer","_autoSaveTimer","_htmlEditorModal","_htmlEditorTextarea","_htmlEditorTitle","_htmlEditorBlockId","_boundGlobalKeydown","_handleGlobalKeydown","_init","canvas","_toast","_createHtmlEditorModal","_ensureAtLeastOneBlock","setInterval","_syncAllBlockContent","toLocaleTimeString","chunks","toAppend","tbContainer","tb","scrollLeft","requestAnimationFrame","_positionBlockToolbar","rendered","clickedContent","clickedEditable","clickedCell","clickedEditableIndex","editables","clickedCellPos","rowIndex","colIndex","nextCell","newWrapper","targetEditable","dd","fromIdx","toIdx","moved","appender","plusIcon","targetId","_getInsertionTargetBlock","insertBlockAtEnd","getCaretRect","_getSelectionTableCell","_handleTableTab","shiftKey","nodeRect","prev","placeCaretAtStart","_generateSlug","slug","slugEl","getElementById","modal","_closeBlockHtmlEditor","textarea","spellcheck","_applyBlockHtmlEditor","ctrlKey","metaKey","_parseBlockFromHTML","fallbackType","wrap","first","firstElementChild","onlyOneElement","childElementCount","every","n","styleWidth","_readPercentWidth","getAttribute","mod","__sourceType","parsed","openBlockHtmlEditor","getTitle","setTitle","didBlockUndo","didBlockRedo","clearInterval","msg","toolbarEl","toolbarRect","wrapperRect","shiftX","shouldPlaceBelow","currentCell","reverse","cellIndex","_placeCaretInCell","prevRowCells","nextRowCells","tbody","snippet","_snippetForType","_focusEditableTail","tail","lastElementChild","last","match","exec","ReactNBDEditor","React","forwardRef","props","onReady","editorOptions","hostRef","useRef","editorRef","lastContentRef","undefined","useEffect","initialOptions","nextContent","useImperativeHandle","getInstance","opts"],"mappings":"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"}
|