@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,2 @@
|
|
|
1
|
+
"use strict";function e(e){var t=Object.create(null);return e&&Object.keys(e).forEach(function(n){if("default"!==n){var i=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,i.get?i:{enumerable:!0,get:function(){return e[n]}})}}),t.default=e,Object.freeze(t)}var t=e(require("react"));class n{constructor(){this._listeners={}}on(e,t){return(this._listeners[e]||=[]).push(t),()=>this.off(e,t)}off(e,t){const n=this._listeners[e];n&&(this._listeners[e]=n.filter(e=>e!==t))}emit(e,...t){(this._listeners[e]||[]).forEach(e=>e(...t))}once(e,t){const n=(...i)=>{this.off(e,n),t(...i)};this.on(e,n)}}function i(e,t={},n=[]){const i=document.createElement(e);for(const[e,n]of Object.entries(t))if("className"===e)i.className=n;else if("style"===e&&"object"==typeof n)Object.assign(i.style,n);else if("dataset"===e&&"object"==typeof n)for(const[e,t]of Object.entries(n))i.dataset[e]=t;else e.startsWith("on")&&"function"==typeof n?i.addEventListener(e.slice(2).toLowerCase(),n):"contentEditable"===e?i.contentEditable=n:"innerHTML"===e?i.innerHTML=n:i.setAttribute(e,n);for(const e of Array.isArray(n)?n:[n])"string"==typeof e?i.appendChild(document.createTextNode(e)):e instanceof Node&&i.appendChild(e);return i}function o(){return"blk_"+Date.now().toString(36)+"_"+Math.random().toString(36).slice(2,8)}function s(e){e.focus();const t=document.createRange();t.selectNodeContents(e),t.collapse(!1);const n=window.getSelection();n.removeAllRanges(),n.addRange(t)}const l=(e,t="0 0 24 24")=>`<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="${t}" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">${e}</svg>`,a={plus:l('<line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/>'),undo:l('<path d="M3 10h13a4 4 0 010 8H7"/><path d="M3 10l4-4M3 10l4 4"/>'),redo:l('<path d="M21 10H8a4 4 0 000 8h9"/><path d="M21 10l-4-4M21 10l-4 4"/>'),listView:l('<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"/>'),settings:l('<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"/>'),bold:"<b>B</b>",italic:"<i>I</i>",underline:"<u>U</u>",strikethrough:"<s>S</s>",link:l('<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"/>'),code:l('<polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/>'),alignLeft:l('<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"/>'),alignCenter:l('<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"/>'),alignRight:l('<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"/>'),image:l('<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"/>'),heading:"<b>H</b>",paragraph:'<span style="font-size:16px">¶</span>',quote:'<span style="font-size:18px">❝</span>',list:l('<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"/>'),orderedList:l('<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>'),separator:l('<line x1="3" y1="12" x2="21" y2="12"/>'),table:l('<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"/>'),button:l('<rect x="3" y="7" width="18" height="10" rx="3"/>'),columns:l('<rect x="3" y="3" width="7" height="18" rx="1"/><rect x="14" y="3" width="7" height="18" rx="1"/>'),spacer:l('<path d="M12 5v14M5 12h14"/>',"0 0 24 24"),embed:l('<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"/>'),gallery:l('<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"/>'),video:l('<polygon points="5 3 19 12 5 21 5 3"/>'),audio:l('<path d="M9 18V5l12-2v13"/><circle cx="6" cy="18" r="3"/><circle cx="18" cy="16" r="3"/>'),file:l('<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"/>'),dragHandle:((e,t="0 0 24 24")=>`<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="${t}" fill="currentColor">${e}</svg>`)('<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"/>'),arrowUp:l('<polyline points="18 15 12 9 6 15"/>'),arrowDown:l('<polyline points="6 9 12 15 18 9"/>'),trash:l('<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"/>'),close:l('<line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/>'),inlineCode:'<span style="font-family:monospace;font-size:13px"></></span>',upload:l('<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"/>'),html:'<span style="font-family:monospace;font-size:11px"><HTML></span>',pullquote:l('<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"/>')};class r extends n{constructor(){super(),this.blocks=[],this._undoStack=[],this._redoStack=[],this._maxHistory=100,this._undoStack.push(JSON.stringify(this.blocks))}addBlock(e,t={},n=null){const i={id:o(),type:e,content:"",attrs:{},...t};if(n){const e=this.blocks.findIndex(e=>e.id===n);this.blocks.splice(e+1,0,i)}else this.blocks.push(i);return this._pushUndo(),this.emit("block:added",i),this.emit("change",this.blocks),i}removeBlock(e){const t=this.blocks.findIndex(t=>t.id===e);if(-1===t)return;if(this.blocks.length<=1)return;const[n]=this.blocks.splice(t,1);return this._pushUndo(),this.emit("block:removed",n,t),this.emit("change",this.blocks),n}updateBlock(e,t){const n=this.getBlock(e);n&&(Object.assign(n,t),this.emit("block:updated",n),this.emit("change",this.blocks))}changeBlockType(e,t){const n=this.getBlock(e);n&&(n.type=t,this._pushUndo(),this.emit("block:typeChanged",n),this.emit("change",this.blocks))}moveBlock(e,t){const n=this.blocks.findIndex(t=>t.id===e),i=n+t;i<0||i>=this.blocks.length||([this.blocks[n],this.blocks[i]]=[this.blocks[i],this.blocks[n]],this._pushUndo(),this.emit("block:moved",this.blocks[i],t),this.emit("change",this.blocks))}duplicateBlock(e){const t=this.getBlock(e);if(!t)return;const n={...t,id:o(),content:t.content,attrs:{...t.attrs}},i=this.blocks.findIndex(t=>t.id===e);return this.blocks.splice(i+1,0,n),this._pushUndo(),this.emit("block:added",n),this.emit("change",this.blocks),n}getBlock(e){return this.blocks.find(t=>t.id===e)||null}getIndex(e){return this.blocks.findIndex(t=>t.id===e)}getPrevBlock(e){const t=this.getIndex(e);return t>0?this.blocks[t-1]:null}getNextBlock(e){const t=this.getIndex(e);return t<this.blocks.length-1?this.blocks[t+1]:null}toJSON(){return this.blocks.map(e=>({...e}))}fromJSON(e){this.blocks=e.map(e=>({...e})),this._undoStack=[JSON.stringify(this.blocks)],this._redoStack=[],this.emit("change",this.blocks)}toHTML(){return this.blocks.map(e=>this.blockToHTML(e)).join("\n")}toHTMLBlocks(){return this.blocks.map(e=>({...e,html:this.blockToHTML(e)}))}blockToHTML(e){return function(e){const t=e.content||"";switch(e.type){case"paragraph":return(n=t)&&"string"==typeof n&&/<(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(n)?t:`<p>${t}</p>`;case"heading":return`<h2>${t}</h2>`;case"heading-3":return`<h3>${t}</h3>`;case"heading-4":return`<h4>${t}</h4>`;case"quote":return`<blockquote>${t}</blockquote>`;case"code":return`<pre><code>${d(t)}</code></pre>`;case"list":return`<ul>${t}</ul>`;case"ordered-list":return`<ol>${t}</ol>`;case"image":{if(!t)return"";const n=Number(e.attrs?.width),i=Number.isFinite(n)?` style="width:${Math.max(10,Math.min(100,Math.round(n)))}%"`:"";return`<figure><img src="${c(t)}" alt="${c(e.attrs?.alt||"")}"${i}/>${e.attrs?.caption?`<figcaption>${e.attrs.caption}</figcaption>`:""}</figure>`}case"separator":return"<hr/>";case"spacer":return`<div style="height:${Number(e.attrs?.height)||48}px"></div>`;case"table":return t||"<table></table>";case"button":return`<div class="wp-block-button"><a class="wp-block-button__link" href="${c(e.attrs?.url||"#")}">${t||"Button"}</a></div>`;case"columns":return`<div class="wp-block-columns">${t}</div>`;case"embed":return`<figure class="wp-block-embed"><div class="wp-block-embed__wrapper">${t}</div></figure>`;case"gallery":return`<figure class="wp-block-gallery">${t}</figure>`;case"video":return t?`<figure class="wp-block-video"><video controls src="${c(t)}"></video></figure>`:"";case"audio":return t?`<figure class="wp-block-audio"><audio controls src="${c(t)}"></audio></figure>`:"";case"file":return t?`<div class="wp-block-file"><a href="${c(t)}">${d(e.attrs?.filename||"Download")}</a></div>`:"";case"html":return t;case"pullquote":return`<figure class="wp-block-pullquote"><blockquote>${t}</blockquote></figure>`;default:return`<p>${t}</p>`}var n}(e)}_pushUndo(){const e=JSON.stringify(this.blocks);e!==this._undoStack[this._undoStack.length-1]&&(this._undoStack.push(e),this._undoStack.length>this._maxHistory&&this._undoStack.shift(),this._redoStack=[])}saveSnapshot(){this._pushUndo()}undo(){return!(this._undoStack.length<2)&&(this._redoStack.push(this._undoStack.pop()),this.blocks=JSON.parse(this._undoStack[this._undoStack.length-1]),this.emit("change",this.blocks),!0)}redo(){if(0===this._redoStack.length)return!1;const e=this._redoStack.pop();return this._undoStack.push(e),this.blocks=JSON.parse(e),this.emit("change",this.blocks),!0}getWordCount(){let e="";for(const t of this.blocks)if(t.content){const n=document.createElement("div");n.innerHTML=t.content,e+=n.textContent+" "}return e.trim().split(/\s+/).filter(e=>e.length>0).length}getCharCount(){let e="";for(const t of this.blocks)if(t.content){const n=document.createElement("div");n.innerHTML=t.content,e+=n.textContent}return e.replace(/\s/g,"").length}}function c(e){return e?String(e).replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">"):""}function d(e){return e?String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"):""}class h extends n{constructor(e={}){super(),this.uploadHandler=e.uploadHandler||null,this.maxFileSize=e.maxFileSize||10485760,this.allowedImageTypes=e.allowedImageTypes||["image/jpeg","image/png","image/gif","image/webp","image/svg+xml"],this.allowedVideoTypes=e.allowedVideoTypes||["video/mp4","video/webm","video/ogg"],this.allowedAudioTypes=e.allowedAudioTypes||["audio/mpeg","audio/ogg","audio/wav","audio/webm"],this._fileInput=null}openFilePicker(e="image/*",t=!1){return new Promise(n=>{this._fileInput&&this._fileInput.remove();const i=document.createElement("input");i.type="file",i.accept=e,i.multiple=t,i.style.display="none",document.body.appendChild(i),this._fileInput=i,i.addEventListener("change",()=>{const e=[...i.files];i.remove(),this._fileInput=null,n(e)}),i.addEventListener("cancel",()=>{i.remove(),this._fileInput=null,n([])}),i.click()})}async processFile(e){if(e.size>this.maxFileSize){const t=`File "${e.name}" exceeds the ${(this.maxFileSize/1024/1024).toFixed(0)}MB limit.`;return this.emit("error",t),{error:t,file:e}}const t=await this._readAsDataURL(e);if(this.emit("preview",{file:e,localUrl:t}),this.uploadHandler)try{this.emit("upload:start",{file:e});const n=await this.uploadHandler(e);return this.emit("upload:complete",{file:e,...n}),{localUrl:t,remoteUrl:n.url,file:e,id:n.id}}catch(n){return this.emit("upload:error",{file:e,error:n}),{localUrl:t,file:e,error:n.message||"Upload failed"}}return{localUrl:t,file:e}}async processFiles(e){return Promise.all(e.map(e=>this.processFile(e)))}async handlePaste(e){const t=[...e.items||[]].filter(e=>e.type.startsWith("image/"));if(0===t.length)return null;const n=t.map(e=>e.getAsFile()).filter(Boolean);return 0===n.length?null:this.processFiles(n)}async handleDrop(e){const t=[...e.files||[]];return 0===t.length?null:this.processFiles(t)}getMediaType(e){return e.type.startsWith("image/")?"image":e.type.startsWith("video/")?"video":e.type.startsWith("audio/")?"audio":"file"}_readAsDataURL(e){return new Promise((t,n)=>{const i=new FileReader;i.onload=()=>t(i.result),i.onerror=()=>n(i.error),i.readAsDataURL(e)})}}class p extends n{constructor(e){super(),this.container=e,this._dragging=null,this._placeholder=null,this._offsetY=0,this._bound={},this._enabled=!0}enable(){this._enabled=!0}disable(){this._enabled=!1}initDrag(e,t,n){e.setAttribute("draggable","true"),e.style.cursor="grab",e.addEventListener("dragstart",e=>{if(!this._enabled)return e.preventDefault();this._dragging={el:t,id:n},t.style.opacity="0.4",e.dataTransfer.effectAllowed="move",e.dataTransfer.setData("text/plain",n),this.emit("drag:start",n)}),e.addEventListener("dragend",()=>{this._dragging&&(this._dragging.el.style.opacity="",this._dragging=null),this._removePlaceholder(),this.emit("drag:end")}),t.addEventListener("dragover",e=>{if(!this._dragging||this._dragging.id===n)return;e.preventDefault(),e.dataTransfer.dropEffect="move";const i=t.getBoundingClientRect(),o=i.top+i.height/2,s=e.clientY<o?"before":"after";this._showPlaceholder(t,s)}),t.addEventListener("drop",e=>{if(e.preventDefault(),!this._dragging)return;const i=this._dragging.id,o=n,s=t.getBoundingClientRect(),l=s.top+s.height/2,a=e.clientY<l?"before":"after";this._removePlaceholder(),this._dragging.el.style.opacity="",this._dragging=null,this.emit("drop",{fromId:i,toId:o,position:a})})}_showPlaceholder(e,t){this._placeholder||(this._placeholder=document.createElement("div"),this._placeholder.className="fe-drag-placeholder",this._placeholder.style.cssText="height:4px;background:#2271b1;border-radius:2px;margin:4px 0;transition:all 0.15s;"),"before"===t?e.parentNode.insertBefore(this._placeholder,e):e.parentNode.insertBefore(this._placeholder,e.nextSibling)}_removePlaceholder(){this._placeholder&&this._placeholder.parentNode&&this._placeholder.parentNode.removeChild(this._placeholder)}}const u={paragraph:{label:"Paragraph",description:"Start with the building block of all narrative.",icon:a.paragraph,category:"text",hasContent:!0,contentTag:"div",placeholder:"Type / to choose a block",className:""},heading:{label:"Heading 2",description:"Introduce new sections and organize content.",icon:a.heading,category:"text",hasContent:!0,contentTag:"h2",placeholder:"Heading 2",className:"fe-heading-2"},"heading-3":{label:"Heading 3",description:"A smaller heading for subsections.",icon:a.heading,category:"text",hasContent:!0,contentTag:"h3",placeholder:"Heading 3",className:"fe-heading-3"},"heading-4":{label:"Heading 4",description:"A small heading for nested subsections.",icon:a.heading,category:"text",hasContent:!0,contentTag:"h4",placeholder:"Heading 4",className:"fe-heading-4"},list:{label:"List",description:"Create a bulleted list.",icon:a.list,category:"text",hasContent:!0,contentTag:"div",placeholder:"List",className:"fe-list-block"},"ordered-list":{label:"Ordered List",description:"Create a numbered list.",icon:a.orderedList,category:"text",hasContent:!0,contentTag:"div",placeholder:"List",className:"fe-ordered-list-block"},quote:{label:"Quote",description:"Give quoted text visual emphasis.",icon:a.quote,category:"text",hasContent:!0,contentTag:"div",placeholder:"Write quote...",className:"fe-quote"},pullquote:{label:"Pullquote",description:"Highlight a key quote from your content.",icon:a.pullquote,category:"text",hasContent:!0,contentTag:"div",placeholder:"Write pullquote...",className:"fe-pullquote"},code:{label:"Code",description:"Display code snippets that respect your spacing.",icon:a.code,category:"text",hasContent:!0,contentTag:"div",placeholder:"Write code...",className:"fe-code-block"},html:{label:"Custom HTML",description:"Add custom HTML code.",icon:a.html,category:"text",hasContent:!0,contentTag:"div",placeholder:"Write HTML...",className:"fe-html-block"},image:{label:"Image",description:"Insert an image to make a visual statement.",icon:a.image,category:"media",hasContent:!1,isMedia:!0},gallery:{label:"Gallery",description:"Display multiple images in a gallery.",icon:a.gallery,category:"media",hasContent:!1,isMedia:!0},video:{label:"Video",description:"Embed a video from your media library or URL.",icon:a.video,category:"media",hasContent:!1,isMedia:!0},audio:{label:"Audio",description:"Embed an audio file.",icon:a.audio,category:"media",hasContent:!1,isMedia:!0},file:{label:"File",description:"Add a link to a downloadable file.",icon:a.file,category:"media",hasContent:!1,isMedia:!0},separator:{label:"Separator",description:"Create a break between ideas or sections.",icon:a.separator,category:"design",hasContent:!1},spacer:{label:"Spacer",description:"Add white space between blocks.",icon:a.spacer,category:"design",hasContent:!1},columns:{label:"Columns",description:"Display content in multiple columns.",icon:a.columns,category:"design",hasContent:!1},table:{label:"Table",description:"Insert a table for sharing data.",icon:a.table,category:"design",hasContent:!1},button:{label:"Button",description:"Prompt visitors to take action with a button.",icon:a.button,category:"design",hasContent:!0,contentTag:"div",placeholder:"Add text...",className:"fe-button-block"},embed:{label:"Embed",description:"Embed content from YouTube, Twitter, etc.",icon:a.embed,category:"media",hasContent:!0,contentTag:"div",placeholder:"Enter URL to embed...",className:"fe-embed-block"}},m=[{id:"text",label:"Text"},{id:"media",label:"Media"},{id:"design",label:"Design"}];function g(e){return Object.entries(u).filter(([,t])=>t.category===e).map(([e,t])=>({type:e,...t}))}function f(e){const t=e.toLowerCase();return Object.entries(u).filter(([e,n])=>e.includes(t)||n.label.toLowerCase().includes(t)||n.description.toLowerCase().includes(t)).map(([e,t])=>({type:e,...t}))}class b{constructor(e){this.editor=e}render(e){const t=u[e.type];if(!t)return this._renderParagraph(e);if(t.isMedia)return this._renderMediaBlock(e,t);if(t.hasContent)return this._renderContentBlock(e,t);switch(e.type){case"separator":return this._renderSeparator(e);case"spacer":return this._renderSpacer(e);case"columns":return this._renderColumns(e);case"table":return this._renderTable(e);default:return this._renderParagraph(e)}}_renderContentBlock(e,t){const n="code"===e.type||"html"===e.type,o=!e.content||""===e.content.trim(),s=i(t.contentTag||"div",{className:`fe-block-content ${t.className||""}`.trim(),contentEditable:"true",dataset:{placeholder:t.placeholder||"",empty:o?"true":"false"},innerHTML:n?"":e.content||"<br>"});return n&&e.content&&(s.textContent=e.content),this._bindContentEvents(s,e),s}_renderParagraph(e){const t=i("div",{className:"fe-block-content",contentEditable:"true",dataset:{placeholder:"Type / to choose a block",empty:!e.content||""===e.content.trim()?"true":"false"},innerHTML:e.content||"<br>"});return this._bindContentEvents(t,e),t}_renderMediaBlock(e,t){const n=i("div",{className:`fe-block-media fe-block-${e.type}`});switch(e.type){case"image":return this._renderImageBlock(e,n);case"gallery":return this._renderGalleryBlock(e,n);case"video":return this._renderVideoBlock(e,n);case"audio":return this._renderAudioBlock(e,n);case"file":return this._renderFileBlock(e,n);default:return this._renderMediaPlaceholder(e,n,t)}}_renderImageBlock(e,t){if(e.content){const n=_(e.attrs?.width),o=i("figure",{className:"fe-image-figure"}),s=i("img",{src:e.content,alt:e.attrs?.alt||""});s.style.width=`${n}%`,s.style.maxWidth="100%",s.style.borderRadius="4px",s.style.display="block",o.appendChild(s);const l=i("figcaption",{className:"fe-image-caption",contentEditable:"true",dataset:{placeholder:"Add caption..."},innerHTML:e.attrs?.caption||""});l.addEventListener("input",()=>{e.attrs=e.attrs||{},e.attrs.caption=l.innerHTML}),o.appendChild(l);const a=i("div",{className:"fe-image-overlay"}),r=i("button",{className:"fe-img-overlay-btn",innerHTML:"Replace",onClick:()=>this._triggerImageUpload(e)}),c=i("button",{className:"fe-img-overlay-btn fe-img-overlay-btn-danger",innerHTML:"Remove",onClick:()=>{e.content="",e.attrs={},this.editor.render()}});a.appendChild(r),a.appendChild(c),o.appendChild(a);const d=i("button",{type:"button",className:"fe-image-resize-handle",title:"Drag to resize image"});d.addEventListener("mousedown",n=>{n.preventDefault(),n.stopPropagation(),this.editor.selectBlock(e.id);const i=n.clientX,o=s.getBoundingClientRect().width,l=t.getBoundingClientRect().width||o||1,a=t=>{const n=t.clientX-i,a=_(Math.max(80,Math.min(l,o+n))/l*100);e.attrs=e.attrs||{},e.attrs.width=a,s.style.width=`${a}%`},r=()=>{document.removeEventListener("mousemove",a),document.removeEventListener("mouseup",r),this.editor.statusBar.update()};document.addEventListener("mousemove",a),document.addEventListener("mouseup",r)}),o.appendChild(d),t.appendChild(o);const h=i("div",{className:"fe-image-size-controls"});[25,50,75,100].forEach(t=>{const o=i("button",{type:"button",className:("fe-img-size-btn "+(n===t?"is-active":"")).trim(),innerHTML:`${t}%`,onClick:()=>{e.attrs=e.attrs||{},e.attrs.width=t,this.editor.render()}});h.appendChild(o)}),t.appendChild(h)}else this._renderMediaPlaceholder(e,t,u.image);return t}_renderGalleryBlock(e,t){const n=e.attrs?.images||[];if(n.length>0){const o=i("div",{className:"fe-gallery-grid"});n.forEach((e,t)=>{const s=i("div",{className:"fe-gallery-item"});s.appendChild(i("img",{src:e,alt:""}));const l=i("button",{className:"fe-gallery-remove",innerHTML:"×",onClick:()=>{n.splice(t,1),this.editor.render()}});s.appendChild(l),o.appendChild(s)}),t.appendChild(o);const s=i("button",{className:"fe-gallery-add",innerHTML:"+ Add Images",onClick:()=>this._triggerGalleryUpload(e)});t.appendChild(s)}else this._renderMediaPlaceholder(e,t,u.gallery);return t}_renderVideoBlock(e,t){if(e.content){const n=i("video",{src:e.content});n.controls=!0,n.style.maxWidth="100%",n.style.borderRadius="4px",t.appendChild(n)}else this._renderMediaPlaceholder(e,t,u.video);return t}_renderAudioBlock(e,t){if(e.content){const n=i("audio",{src:e.content});n.controls=!0,n.style.width="100%",t.appendChild(n)}else this._renderMediaPlaceholder(e,t,u.audio);return t}_renderFileBlock(e,t){if(e.content){const n=i("div",{className:"fe-file-wrapper"}),o=i("div",{className:"fe-file-info"});o.appendChild(i("span",{className:"fe-file-icon",innerHTML:a.file})),o.appendChild(i("span",{className:"fe-file-name"},[e.attrs?.filename||"File"])),o.appendChild(i("span",{className:"fe-file-size"},[e.attrs?.filesize||""])),n.appendChild(o);const s=i("a",{className:"fe-file-download",href:e.content,download:""},["Download"]);n.appendChild(s),t.appendChild(n)}else this._renderMediaPlaceholder(e,t,u.file);return t}_renderMediaPlaceholder(e,t,n){const o=i("div",{className:"fe-media-placeholder"}),s=i("div",{className:"fe-media-placeholder-icon",innerHTML:n.icon}),l=i("p",{className:"fe-media-placeholder-label"},[n.label]),r=i("p",{className:"fe-media-placeholder-desc"},["Upload a file or pick one from your media library."]),c=i("div",{className:"fe-media-placeholder-actions"}),d=i("button",{className:"fe-btn fe-btn-primary",innerHTML:`${a.upload} Upload`,onClick:()=>this._handleMediaUpload(e)});if(c.appendChild(d),["embed","video","audio"].includes(e.type)){const t=i("input",{type:"text",className:"fe-media-url-input",placeholder:"Or paste a URL..."});t.addEventListener("keydown",n=>{"Enter"===n.key&&(e.content=t.value,this.editor.render())}),c.appendChild(t)}return o.appendChild(s),o.appendChild(l),o.appendChild(r),o.appendChild(c),t.appendChild(o),this._setupDropZone(o,e),t}_renderSeparator(e){const t=i("div",{className:"fe-block-separator"});return t.appendChild(i("hr")),t}_renderSpacer(e){const t=e.attrs?.height||48,n=i("div",{className:"fe-block-spacer",style:{height:t+"px"}}),o=i("div",{className:"fe-spacer-handle"});let s,l;return o.addEventListener("mousedown",i=>{s=i.clientY,l=t;const o=t=>{const i=Math.max(16,l+t.clientY-s);n.style.height=i+"px",e.attrs=e.attrs||{},e.attrs.height=i},a=()=>{document.removeEventListener("mousemove",o),document.removeEventListener("mouseup",a)};document.addEventListener("mousemove",o),document.addEventListener("mouseup",a)}),n.appendChild(o),n}_renderColumns(e){const t=e.attrs?.columns||2,n=i("div",{className:"fe-block-columns"});for(let o=0;o<t;o++){const t=i("div",{className:"fe-column",contentEditable:"true",dataset:{placeholder:`Column ${o+1}`},innerHTML:e.attrs?.[`col${o}`]||""});t.addEventListener("input",()=>{e.attrs=e.attrs||{},e.attrs[`col${o}`]=t.innerHTML}),n.appendChild(t)}const o=i("div",{className:"fe-columns-controls"});return o.appendChild(i("button",{className:"fe-btn fe-btn-sm",type:"button",innerHTML:"+ Column",onClick:()=>{e.attrs=e.attrs||{},e.attrs.columns=Math.max(1,Number(e.attrs.columns||t)+1),this.editor.render()}})),o.appendChild(i("button",{className:"fe-btn fe-btn-sm",type:"button",innerHTML:"- Column",onClick:()=>{e.attrs=e.attrs||{};const n=Math.max(1,Number(e.attrs.columns||t));n<=1||(delete e.attrs["col"+(n-1)],e.attrs.columns=n-1,this.editor.render())}})),n.appendChild(o),n}_renderTable(e){const t=e.attrs?.rows||3,n=e.attrs?.cols||3,o=i("div",{className:"fe-block-table"}),s=i("table"),l=e.attrs?.data||[];for(let o=0;o<t;o++){const t=i("tr");for(let s=0;s<n;s++){const n=i(0===o?"th":"td",{contentEditable:"true",innerHTML:l[o]?.[s]||""});n.addEventListener("input",()=>{e.attrs||(e.attrs={}),e.attrs.data||(e.attrs.data=[]),e.attrs.data[o]||(e.attrs.data[o]=[]),e.attrs.data[o][s]=n.innerHTML}),t.appendChild(n)}s.appendChild(t)}o.appendChild(s);const a=i("div",{className:"fe-table-controls"});return a.appendChild(i("button",{className:"fe-btn fe-btn-sm",innerHTML:"+ Row",onClick:()=>{e.attrs=e.attrs||{},e.attrs.rows=(e.attrs.rows||3)+1,this.editor.render()}})),a.appendChild(i("button",{className:"fe-btn fe-btn-sm",innerHTML:"+ Column",onClick:()=>{e.attrs=e.attrs||{},e.attrs.cols=(e.attrs.cols||3)+1,this.editor.render()}})),o.appendChild(a),o}async _handleMediaUpload(e){let t="*/*";"image"===e.type||"gallery"===e.type?t="image/*":"video"===e.type?t="video/*":"audio"===e.type&&(t="audio/*");const n="gallery"===e.type,i=await this.editor.mediaUploader.openFilePicker(t,n);if(0!==i.length){if("gallery"===e.type){const t=await this.editor.mediaUploader.processFiles(i);e.attrs=e.attrs||{},e.attrs.images=e.attrs.images||[];for(const n of t)n.error||e.attrs.images.push(n.remoteUrl||n.localUrl)}else{const t=await this.editor.mediaUploader.processFile(i[0]);t.error||(e.content=t.remoteUrl||t.localUrl,"file"===e.type&&(e.attrs=e.attrs||{},e.attrs.filename=i[0].name,e.attrs.filesize=(o=i[0].size)<1024?o+" B":o<1048576?(o/1024).toFixed(1)+" KB":(o/1048576).toFixed(1)+" MB"))}var o;this.editor.render()}}async _triggerImageUpload(e){const t=await this.editor.mediaUploader.openFilePicker("image/*");if(0===t.length)return;const n=await this.editor.mediaUploader.processFile(t[0]);n.error||(e.content=n.remoteUrl||n.localUrl),this.editor.render()}async _triggerGalleryUpload(e){const t=await this.editor.mediaUploader.openFilePicker("image/*",!0);if(0===t.length)return;const n=await this.editor.mediaUploader.processFiles(t);e.attrs=e.attrs||{},e.attrs.images=e.attrs.images||[];for(const t of n)t.error||e.attrs.images.push(t.remoteUrl||t.localUrl);this.editor.render()}_setupDropZone(e,t){e.addEventListener("dragover",t=>{t.preventDefault(),e.classList.add("fe-drop-active")}),e.addEventListener("dragleave",()=>{e.classList.remove("fe-drop-active")}),e.addEventListener("drop",async n=>{n.preventDefault(),e.classList.remove("fe-drop-active");const i=await this.editor.mediaUploader.handleDrop(n.dataTransfer);if(i&&i.length>0){if("gallery"===t.type){t.attrs=t.attrs||{},t.attrs.images=t.attrs.images||[];for(const e of i)e.error||t.attrs.images.push(e.remoteUrl||e.localUrl)}else{const e=i[0];e.error||(t.content=e.remoteUrl||e.localUrl)}this.editor.render()}})}_bindContentEvents(e,t){const n="code"===t.type||"html"===t.type,i=()=>{const t=e.textContent||"",i=n?""===t.trim():""===t.trim()&&("<br>"===e.innerHTML.trim()||""===e.innerHTML.trim());e.dataset.empty=i?"true":"false"};i(),e.addEventListener("mousedown",n=>{if(this.editor._selectedBlockId===t.id&&(n.stopPropagation(),document.activeElement!==e)){e.focus();""!==(e.textContent||"").trim()||"<br>"!==e.innerHTML.trim()&&""!==e.innerHTML.trim()||(""===e.innerHTML.trim()&&(e.innerHTML="<br>"),setTimeout(()=>{const t=document.createRange(),n=window.getSelection();t.selectNodeContents(e),t.collapse(!1),n.removeAllRanges(),n.addRange(t)},0))}}),e.addEventListener("input",()=>{if(n)return t.content=e.textContent||"",i(),void this.editor._onBlockInput(t,e);let o=e.innerHTML.trim();"<br>"!==o&&"<br/>"!==o&&""!==o||(o="",e.querySelector("br")||(e.innerHTML="<br>")),t.content=o,i(),this.editor._onBlockInput(t,e)}),e.addEventListener("keydown",n=>{this.editor._onBlockKeydown(n,t,e)}),e.addEventListener("focus",()=>{this.editor.selectBlock(t.id)}),e.addEventListener("paste",e=>{if("code"===t.type||"html"===t.type){e.preventDefault();const t=e.clipboardData.getData("text/plain");return void document.execCommand("insertText",!1,t)}if(e.clipboardData.items){if([...e.clipboardData.items].filter(e=>e.type.startsWith("image/")).length>0)return e.preventDefault(),void this.editor.mediaUploader.handlePaste(e.clipboardData).then(e=>{if(e&&e.length>0){const t=e[0].remoteUrl||e[0].localUrl;t&&document.execCommand("insertHTML",!1,`<img src="${t}" alt="" />`)}})}})}}function _(e){const t=Number(e);return Number.isFinite(t)?Math.max(10,Math.min(100,Math.round(t))):100}class y{constructor(e){this.editor=e,this.el=null}create(){this.el=i("div",{className:"fe-header"});const e=i("div",{className:"fe-header-left"}),t=i("button",{className:"fe-inserter-toggle",innerHTML:a.plus,title:"Toggle block inserter",onClick:e=>this.editor.inserterPanel.toggle(e.currentTarget)});e.appendChild(t),e.appendChild(i("span",{className:"fe-sep"})),e.appendChild(this._iconBtn(a.undo,"Undo (Ctrl+Z)",()=>{const e=document.activeElement,t=Boolean(e&&e.isContentEditable&&this.editor.rootEl.contains(e))||Boolean(window.getSelection()?.anchorNode&&this.editor.rootEl.contains(window.getSelection().anchorNode));this.editor.undo({preferNative:t})})),e.appendChild(this._iconBtn(a.redo,"Redo (Ctrl+Y)",()=>{const e=document.activeElement,t=Boolean(e&&e.isContentEditable&&this.editor.rootEl.contains(e))||Boolean(window.getSelection()?.anchorNode&&this.editor.rootEl.contains(window.getSelection().anchorNode));this.editor.redo({preferNative:t})})),e.appendChild(i("span",{className:"fe-sep"})),e.appendChild(this._iconBtn(a.listView,"Document overview",()=>{this.editor.emit("listView:toggle")})),this.el.appendChild(e);const n=i("div",{className:"fe-header-center"});this.el.appendChild(n);const o=i("div",{className:"fe-header-right"});if(this.editor.options.showHeaderActions){const e=i("button",{className:"fe-btn fe-btn-outline",innerHTML:"Save draft",onClick:()=>this.editor.save()});o.appendChild(e);const t=i("button",{className:"fe-btn fe-btn-primary",innerHTML:"Publish",onClick:()=>this.editor.publish()});o.appendChild(t)}return this.editor.options.showSettingsPanel&&(o.childNodes.length>0&&o.appendChild(i("span",{className:"fe-sep"})),o.appendChild(this._iconBtn(a.settings,"Settings",()=>{this.editor.settingsPanel.toggle(),this.editor._updateCanvasMargin()}))),this.el.appendChild(o),this.el}setStatus(e,t){}_iconBtn(e,t,n){return i("button",{className:"fe-icon-btn",innerHTML:e,title:t,onClick:n})}}class k{constructor(e){this.editor=e,this.el=null,this._linkPopover=null,this._fontSizeSelect=null,this._onSelectionChange=null,this._statefulButtons=[],this._savedLinkRange=null,this._tableToolsSep=null,this._tableRowBtn=null,this._tableColBtn=null}create(){return this.el=i("div",{className:"fe-block-toolbar"}),this._linkPopover=this._createLinkPopover(),this._fontSizeSelect=null,this._onSelectionChange=null,this.el}show(e){const t=this.editor.blockManager.getBlock(e);if(!t)return this.hide();const n=()=>this.editor._selectedBlockId||e;this.el.innerHTML="",this.el.classList.add("fe-visible"),this._statefulButtons=[],this._addBtn(a.dragHandle,"Drag",null,"fe-tb-drag"),this._addSep(),this._addBtn(a.arrowUp,"Move up",()=>this.editor.blockManager.moveBlock(e,-1)),this._addBtn(a.arrowDown,"Move down",()=>this.editor.blockManager.moveBlock(e,1)),this._addSep();const o=t.type,s=["paragraph","heading","heading-3","heading-4","quote","pullquote","list","ordered-list"],l=[...s,"code","html"];if(s.includes(o)){const t=i("select",{className:"fe-tb-select"});[{value:"paragraph",label:"Paragraph"},{value:"heading",label:"Heading 2"},{value:"heading-3",label:"Heading 3"},{value:"heading-4",label:"Heading 4"},{value:"quote",label:"Quote"},{value:"list",label:"Bullet List"},{value:"ordered-list",label:"Numbered List"},{value:"code",label:"Code"}].forEach(e=>{const n=i("option",{value:e.value},[e.label]);e.value===o&&(n.selected=!0),t.appendChild(n)}),t.addEventListener("change",()=>{const n=t.value,i=this.editor.blockManager.getBlock(e);if(!i)return;const o=()=>{"paragraph"!==i.type&&(this.editor.blockManager.changeBlockType(e,"paragraph"),this.editor.render());const t=this.editor._getBlockContentEl(e);return t&&t.focus(),t};if("paragraph"===n||"heading"===n||"heading-3"===n||"heading-4"===n||"quote"===n){if(!o())return;const e="paragraph"===n?"P":"heading"===n?"H2":"heading-3"===n?"H3":"heading-4"===n?"H4":"BLOCKQUOTE";return document.execCommand("formatBlock",!1,e),void this.editor._syncCurrentBlockContent()}if("list"===n||"ordered-list"===n){if(!o())return;return document.execCommand("list"===n?"insertUnorderedList":"insertOrderedList",!1,null),void this.editor._syncCurrentBlockContent()}this.editor.blockManager.changeBlockType(e,n),this.editor.render(),this.editor.focusBlock(e)}),this.el.appendChild(t),this._addSep();const n=i("select",{className:"fe-tb-select",title:"Font size"});[{value:"",label:"Size"},{value:"13",label:"13px"},{value:"16",label:"16px"},{value:"20",label:"20px"},{value:"28",label:"28px"},{value:"36",label:"36px"}].forEach(e=>{const t=i("option",{value:e.value},[e.label]);n.appendChild(t)}),n.addEventListener("change",()=>{n.value&&(this._applyFontSize(n.value),this._syncFontSizeSelect())}),this.el.appendChild(n),this._fontSizeSelect=n,this._bindFontSizeTracking(),this._syncFontSizeSelect(),this._addSep(),this._addStatefulBtn("bold",a.bold,"Bold (Ctrl+B)",()=>this._exec("bold")),this._addStatefulBtn("italic",a.italic,"Italic (Ctrl+I)",()=>this._exec("italic")),this._addStatefulBtn("underline",a.underline,"Underline (Ctrl+U)",()=>this._exec("underline")),this._addStatefulBtn("strikeThrough",a.strikethrough,"Strikethrough",()=>this._exec("strikeThrough")),this._addBtn(a.inlineCode,"Inline Code",()=>this._wrapInlineCode()),this._addStatefulBtn("link",a.link,"Link (Ctrl+K)",()=>this._showLinkPopover()),this._addSep(),this._addBtn(a.alignLeft,"Align Left",()=>this._exec("justifyLeft")),this._addBtn(a.alignCenter,"Align Center",()=>this._exec("justifyCenter")),this._addBtn(a.alignRight,"Align Right",()=>this._exec("justifyRight")),this._tableToolsSep=this._addSep(),this._tableRowBtn=this._addTextBtn("+Row","Add table row",()=>this._addTableRow()),this._tableColBtn=this._addTextBtn("+Col","Add table column",()=>this._addTableColumn())}l.includes(o)&&(this._addSep(),this._addBtn(a.html,"html"===o?"Switch to normal text mode":"Switch to HTML mode",()=>this.editor.toggleBlockHtmlMode(n()),"html"===o?"active":"")),this._syncStatefulButtons(),this._addSep(),this._addBtn(a.file,"Duplicate",()=>{this.editor.blockManager.duplicateBlock(n())&&this.editor.render()}),this._addBtn(a.trash,"Delete",()=>{const e=n();if(this.editor.blockManager.removeBlock(e))return void this.editor.render();const t=this.editor.blockManager.getBlock(e);t&&(t.type="paragraph",t.content="",t.attrs={},this.editor.render(),this.editor.focusBlock(e))},"fe-tb-btn-danger")}hide(){this.el&&this.el.classList.remove("fe-visible"),this._hideLinkPopover(),this._unbindFontSizeTracking()}_addBtn(e,t,n,o=""){const s=i("button",{className:`fe-tb-btn ${o}`.trim(),type:"button",innerHTML:e,title:t});return s.addEventListener("mousedown",e=>{e.preventDefault(),e.stopPropagation()}),n&&s.addEventListener("click",e=>{e.preventDefault(),e.stopPropagation(),n()}),this.el.appendChild(s),s}_addStatefulBtn(e,t,n,i){const o=this._addBtn(t,n,i);return this._statefulButtons.push({command:e,btn:o}),o}_addSep(){const e=i("span",{className:"fe-tb-sep"});return this.el.appendChild(e),e}_addTextBtn(e,t,n){const o=i("button",{className:"fe-tb-text-btn",type:"button",title:t,innerHTML:e});return o.addEventListener("mousedown",e=>{e.preventDefault(),e.stopPropagation()}),o.addEventListener("click",e=>{e.preventDefault(),e.stopPropagation(),n()}),this.el.appendChild(o),o}_exec(e){document.execCommand(e,!1,null),this.editor._syncCurrentBlockContent(),this._syncStatefulButtons()}_wrapInlineCode(){const e=window.getSelection();if(!e.rangeCount)return;const t=e.getRangeAt(0),n=document.createElement("code");n.className="fe-inline-code",t.surroundContents(n),this.editor._syncCurrentBlockContent()}_applyFontSize(e){const t=Number(e);if(!Number.isFinite(t))return;const n=window.getSelection();if(!n||!n.rangeCount)return;const i=n.getRangeAt(0);if(i.collapsed){const e=document.createElement("span");e.style.fontSize=`${t}px`,e.appendChild(document.createTextNode("")),i.insertNode(e);const o=document.createRange();return o.setStart(e.firstChild,1),o.collapse(!0),n.removeAllRanges(),n.addRange(o),void this.editor._syncCurrentBlockContent()}const o=document.createElement("span");o.style.fontSize=`${t}px`,o.appendChild(i.extractContents()),i.insertNode(o);const s=document.createRange();s.selectNodeContents(o),n.removeAllRanges(),n.addRange(s),this.editor._syncCurrentBlockContent()}_bindFontSizeTracking(){this._fontSizeSelect&&!this._onSelectionChange&&(this._onSelectionChange=()=>{this._syncFontSizeSelect(),this._syncStatefulButtons()},document.addEventListener("selectionchange",this._onSelectionChange))}_unbindFontSizeTracking(){this._onSelectionChange&&(document.removeEventListener("selectionchange",this._onSelectionChange),this._onSelectionChange=null)}_syncFontSizeSelect(){if(!this._fontSizeSelect)return;const e=this._currentSelectionFontSizePx();if(!e)return void(this._fontSizeSelect.value="");const t=function(e,t){let n=t[0],i=Math.abs(e-n);for(let o=1;o<t.length;o++){const s=Math.abs(e-t[o]);s<i&&(n=t[o],i=s)}return n}(e,[13,16,20,28,36]);this._fontSizeSelect.value=String(t)}_currentSelectionFontSizePx(){const e=window.getSelection();if(!e||!e.rangeCount)return null;const t=e.focusNode;if(!t)return null;const n=t.nodeType===Node.ELEMENT_NODE?t:t.parentElement;if(!n)return null;const i=this.editor._getSelectedBlockEl();if(!i||!i.contains(n))return null;const o=window.getComputedStyle(n).fontSize,s=Number.parseFloat(o||"");return Number.isFinite(s)?s:null}_createLinkPopover(){const e=i("div",{className:"fe-link-popover"}),t=i("input",{type:"text",placeholder:"Paste URL or search...",className:"fe-link-input"}),n=i("button",{className:"fe-btn fe-btn-primary fe-btn-sm",innerHTML:"Apply"}),o=i("button",{className:"fe-btn fe-btn-sm",innerHTML:"Remove"});return n.addEventListener("click",()=>{if(this._restoreSavedLinkRange(),t.value){document.execCommand("createLink",!1,t.value);const e=this.editor._getSelectedBlockEl();e&&e.querySelectorAll("a").forEach(e=>{e.classList.add("fe-link"),e.target="_blank",e.rel="noopener"})}this._hideLinkPopover(),this.editor._syncCurrentBlockContent(),this._syncStatefulButtons()}),o.addEventListener("click",()=>{this._restoreSavedLinkRange(),document.execCommand("unlink",!1,null),this._hideLinkPopover(),this.editor._syncCurrentBlockContent(),this._syncStatefulButtons()}),t.addEventListener("keydown",e=>{"Enter"===e.key&&(e.preventDefault(),n.click()),"Escape"===e.key&&this._hideLinkPopover()}),e.appendChild(t),e.appendChild(n),e.appendChild(o),e}_showLinkPopover(){const e=window.getSelection();if(!e.rangeCount)return;const t=e.getRangeAt(0);this._savedLinkRange=t.cloneRange();const n=t.getBoundingClientRect(),i=this.el.parentElement;if(!i)return;this._linkPopover.parentElement||i.appendChild(this._linkPopover),this._linkPopover.style.top=n.bottom-i.getBoundingClientRect().top+6+"px",this._linkPopover.style.left="0px",this._linkPopover.classList.add("fe-open");const o=e.anchorNode?.parentElement?.closest("a"),s=this._linkPopover.querySelector("input");s.value=o?o.href:"",setTimeout(()=>s.focus(),10)}_hideLinkPopover(){this._linkPopover&&this._linkPopover.classList.remove("fe-open")}_getCurrentTableContext(){const e=this.editor._getSelectedBlockEl();if(!e)return null;const t=e.querySelector(".fe-block-content");if(!t)return null;const n=window.getSelection();let i=null;if(n&&n.rangeCount>0){let e=n.anchorNode;if(e&&e.nodeType===Node.TEXT_NODE&&(e=e.parentElement),e&&"function"==typeof e.closest){const n=e.closest("td,th");n&&t.contains(n)&&(i=n)}}const o=i?i.closest("table"):t.querySelector("table");return o?(i||(i=o.querySelector("td,th")),i?{table:o,cell:i}:null):null}_addTableRow(){const e=this._getCurrentTableContext();if(!e)return;const{table:t,cell:n}=e,i=n.closest("tr");if(!i)return;const o=Array.from(i.querySelectorAll("th,td")),s=Math.max(1,o.length),l=document.createElement("tr");for(let e=0;e<s;e++){const e=document.createElement("td");e.innerHTML="<br>",l.appendChild(e)}i.nextSibling?i.parentNode.insertBefore(l,i.nextSibling):i.parentNode.appendChild(l);const a=document.createRange();a.selectNodeContents(l.querySelector("td")),a.collapse(!0);const r=window.getSelection();r.removeAllRanges(),r.addRange(a),this.editor._syncCurrentBlockContent()}_addTableColumn(){const e=this._getCurrentTableContext();if(!e)return;const{table:t,cell:n}=e,i=n.closest("tr");if(!i)return;const o=Array.from(i.querySelectorAll("th,td")).indexOf(n);if(o<0)return;Array.from(t.querySelectorAll("tr")).forEach(e=>{const t=Array.from(e.querySelectorAll("th,td")),n=t[Math.min(o,t.length-1)],i=document.createElement(n&&"th"===n.tagName.toLowerCase()?"th":"td");i.innerHTML="<br>",n&&n.nextSibling?e.insertBefore(i,n.nextSibling):e.appendChild(i)});const s=Array.from(i.querySelectorAll("th,td")),l=s[Math.min(o+1,s.length-1)];if(l){const e=document.createRange();e.selectNodeContents(l),e.collapse(!0);const t=window.getSelection();t.removeAllRanges(),t.addRange(e)}this.editor._syncCurrentBlockContent()}_restoreSavedLinkRange(){if(!this._savedLinkRange)return;const e=window.getSelection();e.removeAllRanges(),e.addRange(this._savedLinkRange)}_syncStatefulButtons(){const e=this.editor._getSelectedBlockEl(),t=window.getSelection(),n=t?.anchorNode?.parentElement?.closest("a"),i=e&&t&&t.rangeCount>0&&e.contains(t.anchorNode);this._statefulButtons.forEach(({command:t,btn:o})=>{let s=!1;if(i)if("link"===t)s=Boolean(n&&e.contains(n));else try{s=document.queryCommandState(t)}catch{s=!1}o.classList.toggle("active",Boolean(s))});const o=this._isSelectionInTable(e)?"":"none";this._tableToolsSep&&(this._tableToolsSep.style.display=o),this._tableRowBtn&&(this._tableRowBtn.style.display=o),this._tableColBtn&&(this._tableColBtn.style.display=o)}_isSelectionInTable(e){if(!e)return!1;const t=window.getSelection();if(!t||!t.rangeCount)return!1;let n=t.anchorNode;if(!n)return!1;if(n.nodeType===Node.TEXT_NODE&&(n=n.parentElement),!n||"function"!=typeof n.closest)return!1;const i=n.closest("table");return Boolean(i&&e.contains(i))}}class C{constructor(e){this.editor=e,this.el=null,this._searchInput=null,this._listEl=null,this._anchorEl=null,this._onDocMouseDown=null,this._onDocKeyDown=null,this._savedRange=null,this._mediaModal=null,this._mediaModalCard=null,this._mediaModalTitle=null,this._mediaModalBody=null,this._mediaModalResolver=null,this._forceNewBlock=!1}create(){this.el=i("div",{className:"fe-inserter-panel"});const e=i("div",{className:"fe-inserter-header"});e.appendChild(i("h3",{},["Blocks"]));const t=i("button",{className:"fe-icon-btn fe-icon-btn-sm",innerHTML:a.close,onClick:()=>this.close()});return e.appendChild(t),this.el.appendChild(e),this._searchInput=i("input",{type:"text",className:"fe-inserter-search",placeholder:"Search blocks..."}),this._searchInput.addEventListener("input",()=>this._renderList()),this.el.appendChild(this._searchInput),this._listEl=i("div",{className:"fe-inserter-list"}),this.el.appendChild(this._listEl),this._renderList(),this._createMediaModal(),this.el}open(e=null,t={}){this._anchorEl=e||this._anchorEl,this._forceNewBlock=Boolean(t.forceNewBlock),this._savedRange=this._captureSelectionRange(),this._positionNearAnchor(),this.el.classList.add("fe-open"),this._searchInput.value="",this._renderList(),this._bindGlobalCloseHandlers(),setTimeout(()=>this._searchInput.focus(),20)}close(){this.el.classList.remove("fe-open"),this._forceNewBlock=!1,this._unbindGlobalCloseHandlers()}toggle(e=null,t={}){e&&(this._anchorEl=e),this.el.classList.contains("fe-open")?this.close():this.open(e,t)}isOpen(){return this.el.classList.contains("fe-open")}_renderList(){this._listEl.innerHTML="";const e=this._searchInput?.value?.trim()||"";if(e){const t=f(e);if(0===t.length)return void this._listEl.appendChild(i("p",{className:"fe-inserter-empty"},["No blocks found."]));t.forEach(e=>this._listEl.appendChild(this._createBlockItem(e)))}else for(const e of m){const t=g(e.id);0!==t.length&&(this._listEl.appendChild(i("div",{className:"fe-inserter-category"},[e.label])),t.forEach(e=>this._listEl.appendChild(this._createBlockItem(e))))}}_createBlockItem(e){const t=i("div",{className:"fe-inserter-item"});t.appendChild(i("div",{className:"fe-inserter-item-icon",innerHTML:e.icon}));const n=i("div",{className:"fe-inserter-item-info"});return n.appendChild(i("h4",{},[e.label])),n.appendChild(i("p",{},[e.description])),t.appendChild(n),t.addEventListener("click",()=>{this._insertFromPopover(e.type),this.close()}),t}_positionNearAnchor(){if(!this.el||!this._anchorEl)return;const e=this._anchorEl.getBoundingClientRect(),t=Math.max(8,Math.min(window.innerWidth-368,e.left)),n=Math.max(8,Math.min(window.innerHeight-520,e.bottom+8));this.el.style.left=`${t}px`,this.el.style.top=`${n}px`}_bindGlobalCloseHandlers(){this._onDocMouseDown=e=>{this.el?.classList.contains("fe-open")&&(this.el.contains(e.target)||this._anchorEl&&this._anchorEl.contains(e.target)||this.close())},this._onDocKeyDown=e=>{"Escape"===e.key&&this.close()},document.addEventListener("mousedown",this._onDocMouseDown),document.addEventListener("keydown",this._onDocKeyDown),window.addEventListener("resize",()=>this._positionNearAnchor(),{once:!0})}_unbindGlobalCloseHandlers(){this._onDocMouseDown&&(document.removeEventListener("mousedown",this._onDocMouseDown),this._onDocMouseDown=null),this._onDocKeyDown&&(document.removeEventListener("keydown",this._onDocKeyDown),this._onDocKeyDown=null)}_captureSelectionRange(){const e=window.getSelection();if(!e||!e.rangeCount)return null;const t=e.getRangeAt(0),n=t.commonAncestorContainer;return this.editor.rootEl.contains(n)?t.cloneRange():null}_restoreSelectionRange(){if(!this._savedRange)return!1;const e=window.getSelection();return e.removeAllRanges(),e.addRange(this._savedRange),!0}async _insertFromPopover(e){if(this._forceNewBlock){const t=this.editor._selectedBlockId,n=this.editor.blockManager.addBlock(e,{},t||null);return this.editor.render(),void this.editor.focusBlock(n.id)}const t=this.editor._selectedBlockId,n=t?this.editor.blockManager.getBlock(t):null;if(!(n&&"code"!==n.type&&"html"!==n.type&&"image"!==n.type&&"gallery"!==n.type&&"video"!==n.type&&"audio"!==n.type&&"file"!==n.type))return void(this.editor.insertSingleBlockType(e)||this.editor.insertBlockAtSelection(e));this._restoreSelectionRange();const i=this.editor._getBlockContentEl(t);if(i&&i.focus(),"paragraph"===e||"heading"===e||"heading-3"===e||"heading-4"===e||"quote"===e){const t="paragraph"===e?"P":"heading"===e?"H2":"heading-3"===e?"H3":"heading-4"===e?"H4":"BLOCKQUOTE";return document.execCommand("formatBlock",!1,t),void this.editor._syncCurrentBlockContent()}if("list"===e||"ordered-list"===e)return document.execCommand("list"===e?"insertUnorderedList":"insertOrderedList",!1,null),void this.editor._syncCurrentBlockContent();if("image"===e){const e=await this.editor.mediaUploader.openFilePicker("image/*");if(!e.length)return;const t=await this.editor.mediaUploader.processFile(e[0]);if(!t.error){const e=t.remoteUrl||t.localUrl;document.execCommand("insertHTML",!1,`<img src="${e}" alt="" />`),this.editor._syncCurrentBlockContent()}return}if("video"===e||"audio"===e){const t=await this._chooseMediaSource(e);if(!t)return;if("url"===t){const t=await this._promptForMediaUrl(e);if(!t)return;const n=t.trim();if(!n)return;return"video"===e?document.execCommand("insertHTML",!1,`<video controls style="width:100%;max-width:100%;" src="${n}"></video><p><br></p>`):document.execCommand("insertHTML",!1,`<audio controls style="width:100%;" src="${n}"></audio><p><br></p>`),void this.editor._syncCurrentBlockContent()}}if("video"===e||"audio"===e||"file"===e){const t="video"===e?"video/*":"audio"===e?"audio/*":"*/*",n=await this.editor.mediaUploader.openFilePicker(t);if(!n.length)return;const i=n[0],o=await this.editor.mediaUploader.processFile(i);if(o.error)return void("function"==typeof this.editor._showToast&&this.editor._showToast(o.error));const s=o.remoteUrl||o.localUrl;if(!s)return;return"video"===e?document.execCommand("insertHTML",!1,`<video controls style="width:100%;max-width:100%;" src="${s}"></video><p><br></p>`):"audio"===e?document.execCommand("insertHTML",!1,`<audio controls style="width:100%;" src="${s}"></audio><p><br></p>`):document.execCommand("insertHTML",!1,`<p><a href="${s}" target="_blank" rel="noopener">${i.name||"Download file"}</a></p><p><br></p>`),void this.editor._syncCurrentBlockContent()}if("embed"===e){const e=window.prompt("Paste embed URL");if(!e)return;const t=e.trim();if(!t)return;return document.execCommand("insertHTML",!1,`<p><a href="${t}" target="_blank" rel="noopener">${t}</a></p><p><br></p>`),void this.editor._syncCurrentBlockContent()}this.editor.insertSingleBlockType(e)||this.editor.insertBlockAtSelection(e)}async _chooseMediaSource(e){if("function"==typeof this.editor.options.onChooseMediaSource){const t=await this.editor.options.onChooseMediaSource(e);if("url"===t||"upload"===t)return t}return this._openMediaSourceModal(e)}_createMediaModal(){const e=i("div",{className:"fe-media-modal-overlay"}),t=i("div",{className:"fe-media-modal-card"}),n=i("h3",{className:"fe-media-modal-title"},["Insert media"]),o=i("div",{className:"fe-media-modal-body"});t.appendChild(n),t.appendChild(o),e.appendChild(t),e.addEventListener("click",t=>{t.target===e&&this._closeMediaModal(null)}),this.editor.rootEl.appendChild(e),this._mediaModal=e,this._mediaModalCard=t,this._mediaModalTitle=n,this._mediaModalBody=o}_openMediaSourceModal(e){return new Promise(t=>{this._mediaModalResolver=t,this._mediaModalTitle.textContent=`Insert ${e}`,this._mediaModalBody.innerHTML="";const n=i("p",{className:"fe-media-modal-desc"},["Choose how you want to add media"]),o=i("div",{className:"fe-media-modal-actions"}),s=i("button",{className:"fe-btn fe-btn-primary",type:"button",innerHTML:"Upload File",onClick:()=>this._closeMediaModal("upload")}),l=i("button",{className:"fe-btn fe-btn-outline",type:"button",innerHTML:"Use URL",onClick:()=>this._closeMediaModal("url")}),a=i("button",{className:"fe-btn",type:"button",innerHTML:"Cancel",onClick:()=>this._closeMediaModal(null)});o.appendChild(s),o.appendChild(l),o.appendChild(a),this._mediaModalBody.appendChild(n),this._mediaModalBody.appendChild(o),this._mediaModal.classList.add("fe-open")})}_promptForMediaUrl(e){return new Promise(t=>{this._mediaModalResolver=t,this._mediaModalTitle.textContent=`${e} URL`,this._mediaModalBody.innerHTML="";const n=i("p",{className:"fe-media-modal-desc"},["Paste a direct media URL"]),o=i("input",{type:"url",className:"fe-media-modal-input",placeholder:`https://example.com/${e}.mp4`}),s=i("div",{className:"fe-media-modal-actions"}),l=i("button",{className:"fe-btn fe-btn-primary",type:"button",innerHTML:"Insert",onClick:()=>this._closeMediaModal(o.value||null)}),a=i("button",{className:"fe-btn",type:"button",innerHTML:"Cancel",onClick:()=>this._closeMediaModal(null)});o.addEventListener("keydown",e=>{"Enter"===e.key&&(e.preventDefault(),this._closeMediaModal(o.value||null)),"Escape"===e.key&&this._closeMediaModal(null)}),s.appendChild(l),s.appendChild(a),this._mediaModalBody.appendChild(n),this._mediaModalBody.appendChild(o),this._mediaModalBody.appendChild(s),this._mediaModal.classList.add("fe-open"),setTimeout(()=>o.focus(),0)})}_closeMediaModal(e){if(!this._mediaModal)return;this._mediaModal.classList.remove("fe-open");const t=this._mediaModalResolver;this._mediaModalResolver=null,t&&t(e)}}class v{constructor(e){this.editor=e,this.el=null,this._activeTab="post",this._postTab=null,this._blockTab=null,this._tagInput=null,this._tags=[],this._categories=["Uncategorized","Technology","Design","Business","Lifestyle"],this._featuredImage=null}create(){this.el=i("div",{className:"fe-settings-panel"});const e=i("div",{className:"fe-panel-tabs"});return this._postTabBtn=i("button",{className:"fe-panel-tab fe-active"},["Post"]),this._blockTabBtn=i("button",{className:"fe-panel-tab"},["Block"]),this._postTabBtn.addEventListener("click",()=>this._switchTab("post")),this._blockTabBtn.addEventListener("click",()=>this._switchTab("block")),e.appendChild(this._postTabBtn),e.appendChild(this._blockTabBtn),this.el.appendChild(e),this._postTab=i("div",{className:"fe-tab-content"}),this._buildPostTab(),this.el.appendChild(this._postTab),this._blockTab=i("div",{className:"fe-tab-content",style:{display:"none"}}),this._buildBlockTab(),this.el.appendChild(this._blockTab),this.el}open(){this.el.classList.add("fe-open")}close(){this.el.classList.remove("fe-open")}toggle(){this.el.classList.contains("fe-open")?this.close():this.open()}isOpen(){return this.el.classList.contains("fe-open")}updateBlockSettings(e){this._blockSettingsContent.innerHTML="";if(!this.editor.blockManager.getBlock(e))return void(this._blockSettingsContent.innerHTML='<p class="fe-muted fe-text-center">Select a block to see its settings.</p>');const t=i("div",{className:"fe-panel-section"});t.appendChild(i("h3",{className:"fe-section-title"},["Typography"])),t.appendChild(i("label",{},["Font size"]));const n=i("select",{className:"fe-input"});[{v:"",l:"Default"},{v:"13px",l:"Small"},{v:"16px",l:"Medium"},{v:"20px",l:"Large"},{v:"28px",l:"Extra Large"},{v:"36px",l:"Huge"}].forEach(({v:e,l:t})=>n.appendChild(i("option",{value:e},[t]))),n.addEventListener("change",()=>{const t=this.editor._getBlockContentEl(e);t&&(t.style.fontSize=n.value)}),t.appendChild(n),t.appendChild(i("label",{},["Line height"]));const o=i("input",{type:"text",className:"fe-input",placeholder:"1.7"});o.addEventListener("change",()=>{const t=this.editor._getBlockContentEl(e);t&&o.value&&(t.style.lineHeight=o.value)}),t.appendChild(o),this._blockSettingsContent.appendChild(t);const s=i("div",{className:"fe-panel-section"});s.appendChild(i("h3",{className:"fe-section-title"},["Color"])),s.appendChild(i("label",{},["Text color"]));const l=i("div",{className:"fe-color-grid"});["#1e1e1e","#cf2e2e","#ff6900","#fcb900","#7bdcb5","#00d084","#0693e3","#9b51e0"].forEach(t=>{const n=i("div",{className:"fe-color-swatch",style:{background:t}});n.addEventListener("click",()=>{const n=this.editor._getBlockContentEl(e);n&&(n.style.color=t)}),l.appendChild(n)}),s.appendChild(l),s.appendChild(i("label",{},["Background color"]));const a=i("div",{className:"fe-color-grid"});["transparent","#fcf0f0","#fef8ee","#fefce8","#edf7f2","#eef6fc","#f3eafa","#f0f0f1"].forEach(t=>{const n=i("div",{className:"fe-color-swatch",style:{background:"transparent"===t?"#fff":t,border:"transparent"===t?"2px solid #ddd":"none"}});n.addEventListener("click",()=>{const n=this.editor._getBlockContentEl(e);n&&(n.style.background=t)}),a.appendChild(n)}),s.appendChild(a),this._blockSettingsContent.appendChild(s)}_switchTab(e){this._activeTab=e,this._postTabBtn.classList.toggle("fe-active","post"===e),this._blockTabBtn.classList.toggle("fe-active","block"===e),this._postTab.style.display="post"===e?"block":"none",this._blockTab.style.display="block"===e?"block":"none"}_buildPostTab(){const e=this._section("Summary");e.appendChild(this._field("Visibility","select",["Public","Private","Password Protected"])),e.appendChild(this._field("Publish","select",["Immediately","Schedule"])),e.appendChild(this._field("URL Slug","text",null,"fe-url-slug")),e.appendChild(this._field("Author","select",["Admin","Editor","Author"])),this._postTab.appendChild(e);const t=this._section("Categories"),n=i("div",{className:"fe-category-list"});this._categories.forEach(e=>{const t=i("label",{className:"fe-checkbox-label"});t.appendChild(i("input",{type:"checkbox"})),t.appendChild(document.createTextNode(" "+e)),n.appendChild(t)}),t.appendChild(n);const o=i("a",{href:"#",className:"fe-add-link"},["+ Add New Category"]);o.addEventListener("click",e=>{e.preventDefault();const t=prompt("Category name:");if(t){this._categories.push(t);const e=i("label",{className:"fe-checkbox-label"});e.appendChild(i("input",{type:"checkbox",checked:!0})),e.appendChild(document.createTextNode(" "+t)),n.appendChild(e)}}),t.appendChild(o),this._postTab.appendChild(t);const s=this._section("Tags"),l=i("div",{className:"fe-tag-input-wrapper"}),a=i("input",{type:"text",placeholder:"Add tag..."});a.addEventListener("keydown",e=>{if("Enter"===e.key||","===e.key){e.preventDefault();const t=a.value.replace(",","").trim();if(!t)return;this._tags.push(t);const n=i("span",{className:"fe-tag"});n.appendChild(document.createTextNode(t+" "));const o=i("span",{className:"fe-tag-remove",innerHTML:"×"});o.addEventListener("click",()=>{this._tags=this._tags.filter(e=>e!==t),n.remove()}),n.appendChild(o),l.insertBefore(n,a),a.value=""}}),l.appendChild(a),l.addEventListener("click",()=>a.focus()),s.appendChild(l),s.appendChild(i("p",{className:"fe-hint"},["Separate with commas or Enter key"])),this._postTab.appendChild(s);const r=this._section("Featured Image"),c=i("div",{className:"fe-featured-image-area"});c.appendChild(i("p",{},["Set featured image"]));const d=i("input",{type:"file",accept:"image/*",style:{display:"none"}});d.addEventListener("change",e=>{const t=e.target.files[0];if(!t)return;const n=new FileReader;n.onload=e=>{c.innerHTML="";const t=i("img",{src:e.target.result});t.style.maxWidth="100%",t.style.borderRadius="4px",c.appendChild(t),this._featuredImage=e.target.result,this.editor.emit("featuredImage:change",this._featuredImage)},n.readAsDataURL(t)}),c.addEventListener("click",()=>d.click()),r.appendChild(c),r.appendChild(d),this._postTab.appendChild(r);const h=this._section("Excerpt");h.appendChild(i("textarea",{className:"fe-input fe-textarea",placeholder:"Write an excerpt (optional)"})),this._postTab.appendChild(h);const p=this._section("Discussion");p.appendChild(this._toggle("Allow comments",!0)),p.appendChild(this._toggle("Allow pingbacks",!1)),this._postTab.appendChild(p)}_buildBlockTab(){const e=i("div",{className:"fe-panel-section"});e.appendChild(i("h3",{className:"fe-section-title"},["Block Settings"])),this._blockSettingsContent=i("div"),this._blockSettingsContent.innerHTML='<p class="fe-muted fe-text-center">Select a block to see its settings.</p>',e.appendChild(this._blockSettingsContent),this._blockTab.appendChild(e)}_section(e){const t=i("div",{className:"fe-panel-section"});return t.appendChild(i("h3",{className:"fe-section-title"},[e])),t}_field(e,t,n,o){const s=document.createDocumentFragment();if(s.appendChild(i("label",{},[e])),"select"===t){const e=i("select",{className:"fe-input"});o&&(e.id=o),(n||[]).forEach(t=>e.appendChild(i("option",{},[t]))),s.appendChild(e)}else{const n=i("input",{type:t,className:"fe-input",placeholder:e.toLowerCase()});o&&(n.id=o),s.appendChild(n)}return s}_toggle(e,t){const n=i("div",{className:"fe-toggle-row"});n.appendChild(i("label",{},[e]));const o=i("button",{className:"fe-toggle-switch "+(t?"fe-on":"")});return o.addEventListener("click",()=>o.classList.toggle("fe-on")),n.appendChild(o),n}}class x{constructor(e){this.editor=e,this.el=null,this._visible=!1,this._highlightIndex=0,this._items=[],this._targetBlock=null}create(){return this.el=i("div",{className:"fe-slash-menu"}),this._boundDocClick=e=>{e.target.closest(".fe-slash-menu")||this.close()},document.addEventListener("click",this._boundDocClick),this.el}destroy(){this._boundDocClick&&(document.removeEventListener("click",this._boundDocClick),this._boundDocClick=null)}open(e,t){this._targetBlock=e,this._visible=!0,this._highlightIndex=0,this.el.classList.add("fe-open");const n=this.editor.el.getBoundingClientRect();this.el.style.top=t.bottom-n.top+4+"px",this.el.style.left=t.left-n.left+"px",this._filter("")}close(){this._visible=!1,this._targetBlock=null,this.el.classList.remove("fe-open")}isOpen(){return this._visible}filter(e){this._filter(e)}handleKeydown(e){if(!this._visible)return!1;if("ArrowDown"===e.key)return e.preventDefault(),this._navigate(1),!0;if("ArrowUp"===e.key)return e.preventDefault(),this._navigate(-1),!0;if("Enter"===e.key){e.preventDefault();const t=this._items.filter(e=>"none"!==e.el.style.display);return t[this._highlightIndex]&&this._selectItem(t[this._highlightIndex].type),!0}return"Escape"===e.key&&(this.close(),!0)}_filter(e){this.el.innerHTML="",this._items=[];(e?f(e):Object.entries(u).map(([e,t])=>({type:e,...t}))).forEach((e,t)=>{const n=i("div",{className:"fe-slash-item "+(0===t?"fe-highlighted":"")});n.appendChild(i("div",{className:"fe-slash-icon",innerHTML:e.icon}));const o=i("div",{className:"fe-slash-info"});o.appendChild(i("div",{className:"fe-slash-label"},[e.label])),o.appendChild(i("div",{className:"fe-slash-desc"},[e.description])),n.appendChild(o),n.addEventListener("click",()=>this._selectItem(e.type)),n.addEventListener("mouseenter",()=>{this.el.querySelectorAll(".fe-slash-item").forEach(e=>e.classList.remove("fe-highlighted")),n.classList.add("fe-highlighted")}),this.el.appendChild(n),this._items.push({el:n,type:e.type})}),0===this._items.length&&this.el.appendChild(i("div",{className:"fe-slash-empty"},["No blocks found"])),this._highlightIndex=0}_navigate(e){const t=this._items.filter(e=>"none"!==e.el.style.display);t.forEach(e=>e.el.classList.remove("fe-highlighted")),this._highlightIndex=Math.max(0,Math.min(t.length-1,this._highlightIndex+e)),t[this._highlightIndex]&&(t[this._highlightIndex].el.classList.add("fe-highlighted"),t[this._highlightIndex].el.scrollIntoView({block:"nearest"}))}_selectItem(e){if(!this._targetBlock)return;const t=this._targetBlock;if(this.editor.insertSingleBlockType(e))return this.close(),this.editor.render(),void this.editor.focusBlock(t.id);this.editor.blockManager.changeBlockType(t.id,e),t.content="",this.close(),this.editor.render(),this.editor.focusBlock(t.id)}}class B{constructor(e){this.editor=e,this.el=null,this._wordEl=null,this._charEl=null,this._blockEl=null,this._savedEl=null}create(){return this.el=i("div",{className:"fe-status-bar"}),this._wordEl=i("span",{},["Words: 0"]),this._charEl=i("span",{},["Characters: 0"]),this._blockEl=i("span",{},["Blocks: 0"]),this._savedEl=i("span",{className:"fe-status-right"}),this.el.appendChild(this._wordEl),this.el.appendChild(this._charEl),this.el.appendChild(this._blockEl),this.el.appendChild(this._savedEl),this.el}update(){const e=this.editor.blockManager,t=this.editor._titleEl?this.editor._titleEl.value:"",n=t.trim().split(/\s+/).filter(e=>e.length).length,i=e.getWordCount()+n,o=e.getCharCount()+t.replace(/\s/g,"").length;this._wordEl.textContent=`Words: ${i}`,this._charEl.textContent=`Characters: ${o}`,this._blockEl.textContent=`Blocks: ${e.blocks.length}`}setSaved(e){this._savedEl.textContent=e}}class w extends n{constructor(e,t={}){if(super(),this.options={siteName:"My Site",authorName:"Admin",showStatusBar:!0,showSettingsPanel:!1,showHeaderActions:!1,placeholder:"Start writing...",autoSaveInterval:3e4,uploadHandler:null,maxFileSize:10485760,onChooseMediaSource:null,content:null,onChange:null,onSave:null,onPublish:null,...t},this.rootEl="string"==typeof e?document.querySelector(e):e,!this.rootEl)throw new Error(`NBDEditor: element "${e}" not found.`);this.blockManager=new r,this.mediaUploader=new h({uploadHandler:this.options.uploadHandler,maxFileSize:this.options.maxFileSize}),this.blockRenderer=new b(this),this.header=new y(this),this.toolbar=new k(this),this.inserterPanel=new C(this),this.settingsPanel=new v(this),this.slashMenu=new x(this),this.statusBar=new B(this),this._selectedBlockId=null,this._titleEl=null,this._blocksContainer=null,this._autoSaveTimer=null,this.el=null,this._htmlEditorModal=null,this._htmlEditorTextarea=null,this._htmlEditorTitle=null,this._htmlEditorBlockId=null,this._boundGlobalKeydown=e=>this._handleGlobalKeydown(e),this._init()}_init(){this.rootEl.innerHTML="",this.rootEl.className="fe-root",this.rootEl.appendChild(this.header.create()),this.rootEl.appendChild(this.inserterPanel.create()),this.el=i("div",{className:"fe-editor-main"});const e=i("div",{className:"fe-editor-canvas",id:"fe-canvas"}),t=i("div",{className:"fe-editor-content"});this._blocksContainer=i("div",{className:"fe-blocks-container"}),t.appendChild(this._blocksContainer),e.appendChild(t),this.el.appendChild(e),this.options.showSettingsPanel&&this.el.appendChild(this.settingsPanel.create()),this.rootEl.appendChild(this.el),this.el.appendChild(this.slashMenu.create()),this.options.showStatusBar&&this.rootEl.appendChild(this.statusBar.create()),this._toast=i("div",{className:"fe-toast"}),this.rootEl.appendChild(this._toast),this._createHtmlEditorModal(),"string"==typeof this.options.content?this.blockManager.fromJSON([{id:`blk_${Date.now().toString(36)}_${Math.random().toString(36).slice(2,8)}`,type:"paragraph",content:this.options.content,attrs:{}}]):this.options.content?this.blockManager.fromJSON(this.options.content):this.blockManager.addBlock("paragraph"),this._ensureAtLeastOneBlock(),this.render(),this.options.showSettingsPanel&&(this.settingsPanel.open(),this._updateCanvasMargin()),document.addEventListener("keydown",this._boundGlobalKeydown),this.options.autoSaveInterval>0&&(this._autoSaveTimer=setInterval(()=>{this._syncAllBlockContent(),this.statusBar.setSaved("Auto-saved: "+(new Date).toLocaleTimeString()),this.emit("autosave",this.getData())},this.options.autoSaveInterval)),this.blockManager.on("change",()=>{const e=this.getData();this.options.onChange&&this.options.onChange(e),this.emit("change",e)}),this._blocksContainer.addEventListener("dragover",e=>e.preventDefault()),this._blocksContainer.addEventListener("drop",async e=>{if(e.dataTransfer.files.length>0){e.preventDefault();const t=await this.mediaUploader.handleDrop(e.dataTransfer);if(t){const e=this._selectedBlockId&&this.blockManager.getBlock(this._selectedBlockId)||this.blockManager.blocks[0]||this.blockManager.addBlock("paragraph");if(!e)return;const n=[];for(const e of t){if(e.error)continue;const t=this.mediaUploader.getMediaType(e.file),i=e.remoteUrl||e.localUrl;i&&("image"===t?n.push(`<img src="${i}" alt="">`):"video"===t?n.push(`<video controls src="${i}"></video>`):"audio"===t?n.push(`<audio controls src="${i}"></audio>`):"file"===t&&n.push(`<a href="${i}" target="_blank" rel="noopener">${e.file.name||"Download file"}</a>`))}const i=n.join("\n");i&&(e.content=`${e.content||""}${e.content?"\n":""}${i}`),this.render(),this.focusBlock(e.id)}}})}render(){this._ensureAtLeastOneBlock(),this._blocksContainer.innerHTML="",this.blockManager.blocks.forEach(e=>{const t=i("section",{className:"fe-block-wrapper "+(this._selectedBlockId===e.id?"fe-selected":""),dataset:{blockId:e.id}}),n=i("div",{className:"fe-block-toolbar-container"});if(this._selectedBlockId===e.id){const i=this.toolbar.create();this.toolbar.show(e.id),i.scrollLeft=0,n.appendChild(i),requestAnimationFrame(()=>this._positionBlockToolbar(i,t))}t.appendChild(n);const o=this.blockRenderer.render(e);t.appendChild(o),t.addEventListener("click",n=>{const i=n.target.closest(".fe-block-content"),o=n.target.closest("[contenteditable]"),l=n.target.closest("td,th");let a=-1;if(o&&t.contains(o)){const e=Array.from(t.querySelectorAll("[contenteditable]"));a=e.indexOf(o)}let r=null;if(l){const e=l.closest("tr"),t=l.closest("table");if(e&&t){const n=Array.from(t.querySelectorAll("tr")).indexOf(e),i=Array.from(e.querySelectorAll("th,td")).indexOf(l);n>=0&&i>=0&&(r={rowIndex:n,colIndex:i})}}if(!n.target.closest(".fe-block-toolbar")&&!n.target.closest(".fe-link-popover")){if(this._selectedBlockId===e.id&&(i||o||l))return;const t=e.id;this.selectBlock(t),setTimeout(()=>{const e=this._getBlockContentEl(t);if(e){if(e.focus(),r){const t=Array.from(e.querySelectorAll("tr"))[r.rowIndex],n=t?Array.from(t.querySelectorAll("th,td")):[],i=n[r.colIndex]||n[n.length-1]||null;if(i){const e=document.createRange();e.selectNodeContents(i),e.collapse(!1);const t=window.getSelection();return t.removeAllRanges(),void t.addRange(e)}}if(a>=0){const e=this._blocksContainer.querySelector(`[data-block-id="${t}"]`),n=e?Array.from(e.querySelectorAll("[contenteditable]")):[],i=n[a]||n[0]||null;if(i)return i.focus(),void s(i)}i||s(e)}},0)}});const l=t.querySelector(".fe-tb-drag");if(l){const n=new p(this._blocksContainer);n.initDrag(l,t,e.id),n.on("drop",({fromId:e,toId:t,position:n})=>{const i=this.blockManager.getIndex(e);let o=this.blockManager.getIndex(t);"after"===n&&o++,i<o&&o--;const[s]=this.blockManager.blocks.splice(i,1);this.blockManager.blocks.splice(o,0,s),this.blockManager.saveSnapshot(),this.render()})}this._blocksContainer.appendChild(t)});const e=i("button",{type:"button",className:"fe-block-appender","aria-label":"Add block"}),t=i("span",{className:"fe-plus-icon",innerHTML:a.plus}),n=i("span",{},["Add block"]);e.appendChild(t),e.appendChild(n),e.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation();const n=this._selectedBlockId||this.blockManager.blocks[this.blockManager.blocks.length-1]?.id;n&&this.selectBlock(n),this.inserterPanel.open(e,{forceNewBlock:!0})}),this._blocksContainer.appendChild(e),this.statusBar.update()}selectBlock(e){this._selectedBlockId!==e?(this._selectedBlockId=e,this.render(),this.options.showSettingsPanel&&this.settingsPanel.updateBlockSettings(e),this.emit("block:select",e)):this.options.showSettingsPanel&&this.settingsPanel.updateBlockSettings(e)}focusBlock(e){this.selectBlock(e),setTimeout(()=>{const t=this._getBlockContentEl(e);t&&(t.focus(),s(t))},0)}insertBlockAtSelection(e,t={}){if(this.insertSingleBlockType(e,t)){const e=this._getInsertionTargetBlock();return this.render(),this.focusBlock(e.id),e}const n=this._selectedBlockId,i=this.blockManager.addBlock(e,t,n||null);return this.render(),this.focusBlock(i.id),i}insertBlockAtEnd(e,t={}){if(this.insertSingleBlockType(e,t)){const e=this._getInsertionTargetBlock();return this.render(),this.focusBlock(e.id),e}const n=this.blockManager.addBlock(e,t);return this.render(),this.focusBlock(n.id),n}_onBlockInput(e,t){e.content="code"===e.type||"html"===e.type?t.textContent||"":t.innerHTML,this.statusBar.update();const n=t.textContent;if("/"===n){const n=function(){const e=window.getSelection();return e&&e.rangeCount?e.getRangeAt(0).getBoundingClientRect():null}()||t.getBoundingClientRect();this.slashMenu.open(e,n)}else n.startsWith("/")&&n.length>1?this.slashMenu.isOpen()&&this.slashMenu.filter(n.slice(1).toLowerCase()):this.slashMenu.isOpen()&&this.slashMenu.close();const i=this.getData();this.options.onChange&&this.options.onChange(i),this.emit("change",i),this.emit("input",e)}_onBlockKeydown(e,t,n){if(!this.slashMenu.isOpen()||!this.slashMenu.handleKeydown(e)){if("Tab"===e.key){const t=this._getSelectionTableCell();if(t)return e.preventDefault(),this._handleTableTab(t,e.shiftKey),void this._syncCurrentBlockContent()}if("ArrowUp"===e.key){const i=window.getSelection();if(i.rangeCount){const o=i.getRangeAt(0).getBoundingClientRect(),s=n.getBoundingClientRect();if(o.top<=s.top+2){const n=this.blockManager.getPrevBlock(t.id);n&&(e.preventDefault(),this.focusBlock(n.id))}}}if("ArrowDown"===e.key){const i=window.getSelection();if(i.rangeCount){const o=i.getRangeAt(0).getBoundingClientRect(),s=n.getBoundingClientRect();if(o.bottom>=s.bottom-2){const n=this.blockManager.getNextBlock(t.id);if(n){e.preventDefault();const t=this._getBlockContentEl(n.id);t&&(t.focus(),function(e){e.focus();const t=document.createRange();t.selectNodeContents(e),t.collapse(!0);const n=window.getSelection();n.removeAllRanges(),n.addRange(t)}(t),this.selectBlock(n.id))}}}}"Tab"!==e.key||"code"!==t.type&&"html"!==t.type||(e.preventDefault(),document.execCommand("insertText",!1," "))}}_getBlockContentEl(e){const t=this._blocksContainer.querySelector(`[data-block-id="${e}"]`);return t?.querySelector(".fe-block-content")||t?.querySelector("[contenteditable]")}_getSelectedBlockEl(){return this._selectedBlockId?this._blocksContainer.querySelector(`[data-block-id="${this._selectedBlockId}"]`):null}_syncCurrentBlockContent(){if(!this._selectedBlockId)return;const e=this.blockManager.getBlock(this._selectedBlockId),t=this._getBlockContentEl(this._selectedBlockId);e&&t&&(e.content="code"===e.type||"html"===e.type?t.textContent||"":t.innerHTML)}_syncAllBlockContent(){this.blockManager.blocks.forEach(e=>{const t=this._getBlockContentEl(e.id);t&&(e.content="code"===e.type||"html"===e.type?t.textContent||"":t.innerHTML)})}_generateSlug(){const e=(this._titleEl?.value||"").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,""),t=document.getElementById("fe-url-slug");t&&(t.value=e)}_updateCanvasMargin(){if(!this.options.showSettingsPanel)return;const e=this.el.querySelector(".fe-editor-canvas");e&&e.classList.toggle("fe-panel-open",this.settingsPanel.isOpen())}_createHtmlEditorModal(){const e=i("div",{className:"fe-html-modal-overlay"}),t=i("div",{className:"fe-html-modal"}),n=i("div",{className:"fe-html-modal-header"}),o=i("h3",{className:"fe-html-modal-title"},["Edit as HTML"]),s=i("button",{type:"button",className:"fe-icon-btn fe-icon-btn-sm",innerHTML:a.close,onClick:()=>this._closeBlockHtmlEditor()});n.appendChild(o),n.appendChild(s);const l=i("textarea",{className:"fe-html-modal-textarea",spellcheck:"false",placeholder:"Edit block HTML..."}),r=i("div",{className:"fe-html-modal-actions"}),c=i("button",{type:"button",className:"fe-btn fe-btn-outline",innerHTML:"Cancel",onClick:()=>this._closeBlockHtmlEditor()}),d=i("button",{type:"button",className:"fe-btn fe-btn-primary",innerHTML:"Apply HTML",onClick:()=>this._applyBlockHtmlEditor()});r.appendChild(c),r.appendChild(d),t.appendChild(n),t.appendChild(l),t.appendChild(r),e.appendChild(t),e.addEventListener("click",t=>{t.target===e&&this._closeBlockHtmlEditor()}),l.addEventListener("keydown",e=>{"Escape"===e.key&&this._closeBlockHtmlEditor(),(e.ctrlKey||e.metaKey)&&"Enter"===e.key&&this._applyBlockHtmlEditor()}),this.rootEl.appendChild(e),this._htmlEditorModal=e,this._htmlEditorTextarea=l,this._htmlEditorTitle=o}_parseBlockFromHTML(e,t="paragraph"){const n=(e||"").trim();if(!n)return{type:t,content:"",attrs:{}};if("undefined"==typeof document)return{type:"html",content:n,attrs:{}};const i=document.createElement("div");i.innerHTML=n;const o=i.firstElementChild,s=1===i.childElementCount&&Array.from(i.childNodes).every(e=>e.nodeType===Node.ELEMENT_NODE||""===e.textContent.trim());if(!o||!s)return{type:"html",content:n,attrs:{}};const l=o.tagName.toLowerCase();if("p"===l)return{type:"paragraph",content:o.innerHTML,attrs:{}};if("h2"===l)return{type:"heading",content:o.innerHTML,attrs:{}};if("h3"===l)return{type:"heading-3",content:o.innerHTML,attrs:{}};if("h4"===l)return{type:"heading-4",content:o.innerHTML,attrs:{}};if("blockquote"===l)return{type:"quote",content:o.innerHTML,attrs:{}};if("ul"===l)return{type:"list",content:o.innerHTML,attrs:{}};if("ol"===l)return{type:"ordered-list",content:o.innerHTML,attrs:{}};if("hr"===l)return{type:"separator",content:"",attrs:{}};if("img"===l){const e=M(o.getAttribute("style")||"");return{type:"image",content:o.getAttribute("src")||"",attrs:{alt:o.getAttribute("alt")||"",...e?{width:e}:{}}}}if("figure"===l){const e=o.querySelector("img");if(e){const t=o.querySelector("figcaption"),n=M(e.getAttribute("style")||"");return{type:"image",content:e.getAttribute("src")||"",attrs:{alt:e.getAttribute("alt")||"",caption:t?t.innerHTML:"",...n?{width:n}:{}}}}}if("pre"===l){const e=o.querySelector("code");return{type:"code",content:e?e.textContent||"":o.textContent||"",attrs:{}}}return{type:"html",content:n,attrs:{}}}_handleGlobalKeydown(e){const t=e.ctrlKey||e.metaKey,n=document.activeElement,i=Boolean(n&&n.isContentEditable&&this.rootEl.contains(n))||Boolean(window.getSelection()?.anchorNode&&this.rootEl.contains(window.getSelection().anchorNode));if(t&&"z"===e.key&&!e.shiftKey&&(e.preventDefault(),this.undo({preferNative:i})),t&&("y"===e.key||"z"===e.key&&e.shiftKey)&&(e.preventDefault(),this.redo({preferNative:i})),t&&"s"===e.key&&(e.preventDefault(),this.save()),t&&"b"===e.key&&(e.preventDefault(),document.execCommand("bold",!1,null),this._syncCurrentBlockContent()),t&&"i"===e.key&&(e.preventDefault(),document.execCommand("italic",!1,null),this._syncCurrentBlockContent()),t&&"u"===e.key&&(e.preventDefault(),document.execCommand("underline",!1,null),this._syncCurrentBlockContent()),t&&"k"===e.key&&(e.preventDefault(),this.toolbar._showLinkPopover()),t&&"a"===e.key){const t=this._getBlockContentEl(this._selectedBlockId);if(t&&this.rootEl.contains(document.activeElement)){e.preventDefault();const n=document.createRange();n.selectNodeContents(t);const i=window.getSelection();i.removeAllRanges(),i.addRange(n)}}}getData(){this._syncAllBlockContent();return{content:this.blockManager.toHTML()}}setData(e){const t="string"==typeof e?e:"string"==typeof e?.content?e.content:"";this.blockManager.fromJSON([{id:`blk_${Date.now().toString(36)}_${Math.random().toString(36).slice(2,8)}`,type:"paragraph",content:t,attrs:{}}]),this.render()}toHTML(){return this._syncAllBlockContent(),this.blockManager.toHTML()}toggleBlockHtmlMode(e=this._selectedBlockId){if(!e)return;this._syncCurrentBlockContent();const t=this.blockManager.getBlock(e);if(!t)return;if("html"===t.type){const n=t.attrs?.__sourceType||"paragraph",i=this._parseBlockFromHTML(t.content||"",n);return t.type="html"===i.type?n:i.type,t.content=i.content,t.attrs=i.attrs||{},this.render(),void this.focusBlock(e)}const n=this.blockManager.blockToHTML(t);t.attrs={...t.attrs||{},__sourceType:t.type},t.type="html",t.content=n,this.render(),this.focusBlock(e)}openBlockHtmlEditor(e=this._selectedBlockId){if(!e||!this._htmlEditorModal||!this._htmlEditorTextarea)return;this._syncCurrentBlockContent();const t=this.blockManager.getBlock(e);t&&(this._htmlEditorBlockId=e,this._htmlEditorTitle.textContent=`Edit as HTML: ${t.type}`,this._htmlEditorTextarea.value=this.blockManager.blockToHTML(t),this._htmlEditorModal.classList.add("fe-open"),setTimeout(()=>{this._htmlEditorTextarea.focus(),this._htmlEditorTextarea.select()},0))}_closeBlockHtmlEditor(){this._htmlEditorModal&&(this._htmlEditorModal.classList.remove("fe-open"),this._htmlEditorBlockId=null)}_applyBlockHtmlEditor(){if(!this._htmlEditorBlockId||!this._htmlEditorTextarea)return;const e=this.blockManager.getBlock(this._htmlEditorBlockId);if(!e)return this._closeBlockHtmlEditor();const t=this._parseBlockFromHTML(this._htmlEditorTextarea.value,e.type);e.type=t.type,e.content=t.content,e.attrs=t.attrs||{},this._closeBlockHtmlEditor(),this.render(),this.focusBlock(e.id)}save(){const e=this.getData();this.header.setStatus("Draft saved"),this.statusBar.setSaved("Last saved: "+(new Date).toLocaleTimeString()),this._showToast("Draft saved"),this.options.onSave&&this.options.onSave(e),this.emit("save",e)}publish(){const e=this.getData();this.header.setStatus("Published","#00a32a"),this._showToast("Post published!"),this.options.onPublish&&this.options.onPublish(e),this.emit("publish",e)}getTitle(){return this._titleEl?.value||""}setTitle(e){this._titleEl&&(this._titleEl.value=e)}undo({preferNative:e=!1}={}){if(e){if(document.execCommand("undo",!1,null))return this._syncCurrentBlockContent(),!0}const t=this.blockManager.undo();return t&&this.render(),t}redo({preferNative:e=!1}={}){if(e){if(document.execCommand("redo",!1,null))return this._syncCurrentBlockContent(),!0}const t=this.blockManager.redo();return t&&this.render(),t}destroy(){this._autoSaveTimer&&clearInterval(this._autoSaveTimer),document.removeEventListener("keydown",this._boundGlobalKeydown),this.slashMenu.destroy(),this.toolbar.hide(),this.rootEl.innerHTML="",this._listeners={}}_showToast(e){this._toast.textContent=e,this._toast.classList.add("fe-show"),setTimeout(()=>this._toast.classList.remove("fe-show"),2500)}_positionBlockToolbar(e,t){if(!e||!t)return;e.classList.remove("fe-toolbar-below"),e.style.top="-44px",e.style.left="0px";const n=e.getBoundingClientRect(),i=t.getBoundingClientRect();let o=0;n.right>window.innerWidth-8&&(o-=n.right-(window.innerWidth-8)),n.left+o<8&&(o+=8-(n.left+o)),e.style.left=`${Math.round(o)}px`;const s=i.top-n.height-6<8;s&&(e.classList.add("fe-toolbar-below"),e.style.top="6px"),t.classList.toggle("fe-toolbar-inset",s)}_getSelectionTableCell(){const e=window.getSelection();if(!e||!e.rangeCount)return null;let t=e.anchorNode;if(!t)return null;if(t.nodeType===Node.TEXT_NODE&&(t=t.parentElement),!t||"function"!=typeof t.closest)return null;const n=t.closest("td,th");if(!n)return null;const i=this._getBlockContentEl(this._selectedBlockId);return i&&i.contains(n)?n:null}_handleTableTab(e,t=!1){const n=e.closest("tr"),i=e.closest("table");if(!n||!i)return;const o=Array.from(n.querySelectorAll("th,td")),s=o.indexOf(e),l=Array.from(i.querySelectorAll("tr")),a=l.indexOf(n);if(t){if(s>0)return void this._placeCaretInCell(o[s-1]);if(a>0){const e=Array.from(l[a-1].querySelectorAll("th,td"));this._placeCaretInCell(e[e.length-1])}return}if(s<o.length-1)return void this._placeCaretInCell(o[s+1]);if(a<l.length-1){const e=Array.from(l[a+1].querySelectorAll("th,td"));return void this._placeCaretInCell(e[0])}const r=Math.max(1,o.length),c=document.createElement("tr");for(let e=0;e<r;e++){const e=document.createElement("td");e.innerHTML="<br>",c.appendChild(e)}const d=i.querySelector("tbody");d?d.appendChild(c):i.appendChild(c),this._placeCaretInCell(c.querySelector("td"))}_placeCaretInCell(e){if(!e)return;""===(e.innerHTML||"").trim()&&(e.innerHTML="<br>");const t=document.createRange();t.selectNodeContents(e),t.collapse(!0);const n=window.getSelection();n.removeAllRanges(),n.addRange(t)}insertSingleBlockType(e,t={}){const n=this._getInsertionTargetBlock();if(!n)return!1;const i=this._snippetForType(e,t);if(!i)return!1;if("function"==typeof document.execCommand){const e=this._getBlockContentEl(n.id);if(e){e.focus();if(document.execCommand("insertHTML",!1,i))return this._focusEditableTail(e),this._syncCurrentBlockContent(),!0}}return n.content=`${n.content||""}${n.content?"\n":""}${i}`,!0}_snippetForType(e,t={}){if("separator"===e)return"<hr><p><br></p>";if("spacer"===e)return`<div style="height:${Number(t?.height)||48}px"></div><p><br></p>`;if("table"===e)return['<table border="1" style="width:100%;border-collapse:collapse;">',"<tbody>","<tr><td>Cell 1</td><td>Cell 2</td></tr>","<tr><td>Cell 3</td><td>Cell 4</td></tr>","</tbody>","</table>","<p><br></p>"].join("");if("columns"===e)return['<div class="fe-inline-columns">','<div class="fe-inline-column"><p>Column 1</p></div>','<div class="fe-inline-column"><p>Column 2</p></div>',"</div>","<p><br></p>"].join("");if("button"===e)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>';if("video"===e){const e=String(t?.url||"").trim();return e?`<video controls style="width:100%;max-width:100%;" src="${e}"></video><p><br></p>`:'<video controls style="width:100%;max-width:100%;"></video><p><br></p>'}if("audio"===e){const e=String(t?.url||"").trim();return e?`<audio controls style="width:100%;" src="${e}"></audio><p><br></p>`:'<audio controls style="width:100%;"></audio><p><br></p>'}if("file"===e){const e=String(t?.url||"").trim(),n=String(t?.name||"Download file").trim();return e?`<p><a href="${e}" target="_blank" rel="noopener">${n}</a></p><p><br></p>`:null}if("embed"===e){const e=String(t?.url||"").trim();return e?`<p><a href="${e}" target="_blank" rel="noopener">${e}</a></p><p><br></p>`:"<p>Paste embed URL here</p><p><br></p>"}return null}_focusEditableTail(e){if(!e)return;let t=e.lastElementChild;!t||"P"!==t.tagName?(t=document.createElement("p"),t.innerHTML="<br>",e.appendChild(t)):""===(t.innerHTML||"").trim()&&(t.innerHTML="<br>");const n=document.createRange();n.selectNodeContents(t),n.collapse(!1);const i=window.getSelection();i.removeAllRanges(),i.addRange(n)}_ensureAtLeastOneBlock(){return Array.isArray(this.blockManager.blocks)&&0!==this.blockManager.blocks.length?this.blockManager.blocks[0]:this.blockManager.addBlock("paragraph")}_getInsertionTargetBlock(){const e=this._selectedBlockId?this.blockManager.getBlock(this._selectedBlockId):null;if(e)return e;const t=this.blockManager.blocks[this.blockManager.blocks.length-1];return t||this.blockManager.addBlock("paragraph")}}function M(e){const t=/width\s*:\s*([0-9.]+)%/i.exec(e||"");if(!t)return null;const n=Number(t[1]);return Number.isFinite(n)?Math.max(10,Math.min(100,Math.round(n))):null}const L=null!=t&&"function"==typeof t.forwardRef?t.forwardRef(function(e,n){const{className:i,style:o,content:s,onChange:l,onReady:a,...r}=e||{},c=t.useRef(null),d=t.useRef(null),h=t.useRef(void 0);return t.useEffect(()=>{if(!c.current)return;const e={...r,onChange:e=>{const t="string"==typeof e?.content?e.content:"";h.current=t,"function"==typeof l&&l(e)},..."string"==typeof s?{content:s}:{}},t=new w(c.current,e);return d.current=t,h.current="string"==typeof s?s:void 0,"function"==typeof a&&a(t),()=>{d.current&&(d.current.destroy(),d.current=null)}},[]),t.useEffect(()=>{d.current&&"string"==typeof s&&s!==h.current&&(s!==d.current.toHTML()?(d.current.setData({content:s}),h.current=s):h.current=s)},[s]),t.useImperativeHandle(n,()=>({getInstance:()=>d.current,getData:()=>d.current?.getData(),setData:e=>d.current?.setData(e),toHTML:()=>d.current?.toHTML(),save:()=>d.current?.save(),publish:()=>d.current?.publish(),undo:e=>d.current?.undo(e),redo:e=>d.current?.redo(e),destroy:()=>d.current?.destroy()}),[]),t.createElement("div",{ref:c,className:i,style:o})}):null;exports.BLOCK_TYPES=u,exports.BlockManager=r,exports.CATEGORIES=m,exports.DragDrop=p,exports.EventEmitter=n,exports.MediaUploader=h,exports.NBDEditor=w,exports.ReactNBDEditor=L,exports.getBlocksByCategory=g,exports.searchBlocks=f;
|
|
2
|
+
//# sourceMappingURL=nbd-editor.cjs.js.map
|