@editora/core 1.0.0 → 1.0.1

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.
@@ -1,7 +1,520 @@
1
- var Editora=(function(s){"use strict";class l{constructor(e,t,i){this.doc=e,this.selection=t,this.schema=i}static create(e,t){const i=t||e.node("doc",{},[e.node("paragraph")]);return new l(i,{anchor:0,head:0},e)}apply(e,t){return new l(e,t||this.selection,this.schema)}}class f{constructor(e){this.listeners=[],this.pluginManager=e;const t=e.buildSchema();this.state=l.create(t),this.commands=e.getCommands()}setState(e){this.state=e,this.listeners.forEach(t=>t(e))}onChange(e){return this.listeners.push(e),()=>{this.listeners=this.listeners.filter(t=>t!==e)}}execCommand(e){const t=this.commands[e];if(!t)return!1;const i=t(this.state);return i?(this.setState(i),!0):!1}setContent(e){this.setState(this.state.apply(e))}getContent(){return this.state.doc}}class g{constructor(e,t){this.nodes=new Map(Object.entries(e)),this.marks=new Map(Object.entries(t))}node(e,t,i){return{type:e,attrs:t,content:i}}text(e,t){return{type:"text",text:e,marks:t}}}class y{constructor(){this.plugins=[]}register(e){this.plugins.push(e)}buildSchema(){const e={},t={};return this.plugins.forEach(i=>{i.nodes&&Object.assign(e,i.nodes),i.marks&&Object.assign(t,i.marks)}),new g(e,t)}getCommands(){const e={};return this.plugins.forEach(t=>{t.commands&&Object.assign(e,t.commands)}),e}getToolbarItems(){return this.plugins.flatMap(e=>e.toolbar||[])}}class p{constructor(e){this.initialized=!1,this.plugin=e}initialize(e){if(this.initialized)return console.warn(`Plugin "${this.plugin.name}" already initialized`),!1;try{return this.context=e,this.plugin.context?.initialize&&this.plugin.context.initialize(),this.plugin.context?.onEditorReady&&e.provider&&this.plugin.context.onEditorReady(e),this.initialized=!0,!0}catch(t){return console.error(`Failed to initialize plugin "${this.plugin.name}":`,t),!1}}destroy(){if(!this.initialized)return!1;try{return this.plugin.context?.destroy&&this.plugin.context.destroy(),this.initialized=!1,this.context=void 0,!0}catch(e){return console.error(`Failed to destroy plugin "${this.plugin.name}":`,e),!1}}executeCommand(e,...t){if(!this.initialized)return console.warn(`Plugin "${this.plugin.name}" not initialized, cannot execute command "${e}"`),null;try{const i=this.plugin.commands?.[e];return i?i(...t):(console.warn(`Command "${e}" not found in plugin "${this.plugin.name}"`),null)}catch(i){return console.error(`Error executing command "${e}" in plugin "${this.plugin.name}":`,i),null}}getName(){return this.plugin.name}isInitialized(){return this.initialized}getPlugin(){return this.plugin}getContext(){return this.context}}function S(a){return new p(a)}class k{constructor(e){this.shortcuts=new Map,this.enabled=!0,this.isMac=typeof navigator<"u"&&navigator.platform.toUpperCase().indexOf("MAC")>=0,e?.enabled===!1&&(this.enabled=!1),this.registerDefaultShortcuts(),e?.shortcuts&&e.shortcuts.forEach(t=>this.registerShortcut(t)),e?.customShortcuts&&Object.values(e.customShortcuts).forEach(t=>{this.registerShortcut(t)})}registerDefaultShortcuts(){this.registerShortcut({key:"b",ctrl:!this.isMac,meta:this.isMac,command:"toggleBold",description:"Bold",preventDefault:!0}),this.registerShortcut({key:"i",ctrl:!this.isMac,meta:this.isMac,command:"toggleItalic",description:"Italic",preventDefault:!0}),this.registerShortcut({key:"u",ctrl:!this.isMac,meta:this.isMac,command:"toggleUnderline",description:"Underline",preventDefault:!0}),this.registerShortcut({key:"d",ctrl:!this.isMac,meta:this.isMac,command:"toggleStrikethrough",description:"Strikethrough",preventDefault:!0}),this.registerShortcut({key:"z",ctrl:!this.isMac,meta:this.isMac,command:"undo",description:"Undo",preventDefault:!0}),this.registerShortcut({key:"z",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"redo",description:"Redo",preventDefault:!0}),this.registerShortcut({key:"y",ctrl:!this.isMac,meta:this.isMac,command:"redo",description:"Redo",preventDefault:!0});for(let e=1;e<=6;e++)this.registerShortcut({key:String(e),ctrl:!this.isMac,meta:this.isMac,alt:!0,command:"setBlockType",params:`h${e}`,description:`Heading ${e}`,preventDefault:!0});this.registerShortcut({key:"7",ctrl:!this.isMac,meta:this.isMac,alt:!0,command:"setBlockType",params:"p",description:"Paragraph",preventDefault:!0}),this.registerShortcut({key:"7",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"toggleOrderedList",description:"Numbered List",preventDefault:!0}),this.registerShortcut({key:"8",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"toggleBulletList",description:"Bullet List",preventDefault:!0}),this.registerShortcut({key:"k",ctrl:!this.isMac,meta:this.isMac,command:"openLinkDialog",description:"Insert/Edit Link",preventDefault:!0}),this.registerShortcut({key:"e",ctrl:!this.isMac,meta:this.isMac,alt:!0,command:"insertCodeBlock",description:"Code Block",preventDefault:!0}),this.registerShortcut({key:"q",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"toggleBlockquote",description:"Blockquote",preventDefault:!0}),this.registerShortcut({key:"l",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"setTextAlignment",params:"left",description:"Align Left",preventDefault:!0}),this.registerShortcut({key:"e",ctrl:!this.isMac,meta:this.isMac,shift:!0,alt:!0,command:"setTextAlignment",params:"center",description:"Align Center",preventDefault:!0}),this.registerShortcut({key:"r",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"setTextAlignment",params:"right",description:"Align Right",preventDefault:!0}),this.registerShortcut({key:"j",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"setTextAlignment",params:"justify",description:"Justify",preventDefault:!0}),this.registerShortcut({key:"\\",ctrl:!this.isMac,meta:this.isMac,command:"clearFormatting",description:"Clear Formatting",preventDefault:!0}),this.registerShortcut({key:"]",ctrl:!this.isMac,meta:this.isMac,command:"increaseIndent",description:"Indent",preventDefault:!0}),this.registerShortcut({key:"[",ctrl:!this.isMac,meta:this.isMac,command:"decreaseIndent",description:"Outdent",preventDefault:!0}),this.registerShortcut({key:"g",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"insertImage",description:"Insert Image",preventDefault:!0}),this.registerShortcut({key:"t",ctrl:!this.isMac,meta:this.isMac,shift:!0,alt:!0,command:"insertTable",description:"Insert Table",preventDefault:!0}),this.registerShortcut({key:"f11",command:"toggleFullscreen",description:"Toggle Fullscreen",preventDefault:!0}),this.registerShortcut({key:"p",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"togglePreview",description:"Preview",preventDefault:!0}),this.registerShortcut({key:"p",ctrl:!this.isMac,meta:this.isMac,command:"print",description:"Print",preventDefault:!0}),this.registerShortcut({key:"s",ctrl:!this.isMac,meta:this.isMac,shift:!0,alt:!0,command:"insertSpecialCharacter",description:"Insert Special Character",preventDefault:!0}),this.registerShortcut({key:"m",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"insertEmoji",description:"Insert Emoji",preventDefault:!0}),this.registerShortcut({key:"9",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"toggleChecklist",description:"Checklist",preventDefault:!0}),this.registerShortcut({key:"a",ctrl:!this.isMac,meta:this.isMac,shift:!0,alt:!0,command:"toggleA11yChecker",description:"Accessibility Checker",preventDefault:!0}),this.registerShortcut({key:"F7",command:"toggleSpellCheck",description:"Spell Check",preventDefault:!0}),this.registerShortcut({key:"m",ctrl:!this.isMac,meta:this.isMac,alt:!0,command:"insertMath",description:"Insert Math",preventDefault:!0}),this.registerShortcut({key:"f",ctrl:!this.isMac,meta:this.isMac,alt:!0,command:"insertFootnote",description:"Insert Footnote",preventDefault:!0})}registerShortcut(e){const t=this.getShortcutKey(e);this.shortcuts.set(t,e)}unregisterShortcut(e){const t=this.getShortcutKey(e);this.shortcuts.delete(t)}getShortcutKey(e){const t=[];return e.ctrl&&t.push("ctrl"),e.alt&&t.push("alt"),e.shift&&t.push("shift"),e.meta&&t.push("meta"),t.push(e.key.toLowerCase()),t.join("+")}getEventKey(e){const t=[];return e.ctrlKey&&t.push("ctrl"),e.altKey&&t.push("alt"),e.shiftKey&&t.push("shift"),e.metaKey&&t.push("meta"),t.push(e.key.toLowerCase()),t.join("+")}handleKeyDown(e,t){if(!this.enabled)return!1;const i=this.getEventKey(e),r=this.shortcuts.get(i);return r?(r.preventDefault!==!1&&(e.preventDefault(),e.stopPropagation()),t(r.command,r.params),!0):!1}enable(){this.enabled=!0}disable(){this.enabled=!1}isEnabled(){return this.enabled}getAllShortcuts(){return Array.from(this.shortcuts.values())}getShortcutForCommand(e){return Array.from(this.shortcuts.values()).find(t=>t.command===e)}getShortcutDescription(e){const t=[];this.isMac?(e.meta&&t.push("⌘"),e.ctrl&&t.push("⌃"),e.alt&&t.push("⌥"),e.shift&&t.push("⇧")):(e.ctrl&&t.push("Ctrl"),e.alt&&t.push("Alt"),e.shift&&t.push("Shift"));const i=e.key.length===1?e.key.toUpperCase():e.key;return t.push(i),t.join("+")}getShortcutsHelp(){const e=this.getAllShortcuts(),t=new Map;e.forEach(r=>{const c=this.getShortcutCategory(r.command);t.has(c)||t.set(c,[]),t.get(c).push(r)});let i=`# Keyboard Shortcuts
1
+ var Editora=(function(c){"use strict";class b{constructor(t,e,i){this.doc=t,this.selection=e,this.schema=i}static create(t,e){const i=e||t.node("doc",{},[t.node("paragraph")]);return new b(i,{anchor:0,head:0},t)}apply(t,e){return new b(t,e||this.selection,this.schema)}}class L{constructor(t,e){this.nodes=new Map(Object.entries(t)),this.marks=new Map(Object.entries(e))}node(t,e,i){return{type:t,attrs:e,content:i}}text(t,e){return{type:"text",text:t,marks:e}}}class v{constructor(){this.plugins=[],this.pluginConfigs=new Map}register(t,e){if(this.plugins.push(t),e&&this.pluginConfigs.set(t.name,e),t.initialize){const i=this.pluginConfigs.get(t.name)||t.config;t.initialize(i)}}unregister(t){const e=this.plugins.findIndex(i=>i.name===t);if(e>-1){const i=this.plugins[e];i.destroy&&i.destroy(),this.plugins.splice(e,1),this.pluginConfigs.delete(t)}}getPlugin(t){return this.plugins.find(e=>e.name===t)}getPluginConfig(t){return this.pluginConfigs.get(t)}buildSchema(){const t={},e={};return this.plugins.forEach(i=>{i.nodes&&Object.assign(t,i.nodes),i.marks&&Object.assign(e,i.marks)}),new L(t,e)}getCommands(){const t={};return this.plugins.forEach(e=>{e.commands&&Object.assign(t,e.commands)}),t}getToolbarItems(){return this.plugins.flatMap(t=>t.toolbar||[])}async executePluginCommand(t,e,...i){const o=this.getPlugin(t);if(!o)throw new Error(`Plugin not found: ${t}`);const n=this.getPluginConfig(t)||o.config||{},s=n.mode||"local";try{switch(s){case"local":return o.executeLocal?o.executeLocal(e,...i):null;case"api":if(!o.executeAPI)throw new Error(`Plugin ${t} does not support API mode`);return await o.executeAPI(e,...i);case"hybrid":if(o.executeHybrid)return await o.executeHybrid(e,...i);try{if(o.executeAPI)return await o.executeAPI(e,...i)}catch(r){if(console.warn(`API execution failed for ${t}, falling back to local`,r),o.executeLocal&&n.fallbackToLocal!==!1)return o.executeLocal(e,...i);throw r}break;default:throw new Error(`Unknown plugin mode: ${s}`)}}catch(r){throw console.error(`Error executing command ${e} on plugin ${t}:`,r),r}}async destroyAll(){const t=this.plugins.filter(e=>e.destroy).map(e=>e.destroy());await Promise.all(t),this.plugins=[],this.pluginConfigs.clear()}}class F{constructor(t){if(this.listeners=[],t instanceof v)this.pluginManager=t;else{const i=t;this.pluginManager=new v,i.plugins&&Array.isArray(i.plugins)&&i.plugins.forEach(o=>{this.pluginManager.register(o)}),i.element&&(this.domElement=i.element,this.setupDOMElement(i))}const e=this.pluginManager.buildSchema();this.state=b.create(e),this.commands=this.pluginManager.getCommands()}setupDOMElement(t){this.domElement&&(t.enableToolbar!==!1&&t.toolbarElement?this.toolbarElement=t.toolbarElement:t.enableToolbar!==!1&&(this.toolbarElement=document.createElement("div"),this.toolbarElement.className="editora-toolbar-container",this.domElement.appendChild(this.toolbarElement)),this.contentElement=document.createElement("div"),this.contentElement.contentEditable="true",this.contentElement.className="editora-content",this.contentElement.style.minHeight="200px",this.contentElement.style.outline="none",this.contentElement.style.padding="12px",t.content&&(this.contentElement.innerHTML=t.content),this.domElement.appendChild(this.contentElement),this.contentElement.addEventListener("input",()=>{this.listeners.forEach(e=>e(this.state))}))}setupKeyboardShortcuts(t){const e={};t.forEach(i=>{i.shortcut&&(e[i.shortcut.toLowerCase()]=i.command)}),document.addEventListener("keydown",i=>{if(this.contentElement!==document.activeElement&&!(document.activeElement instanceof HTMLElement&&document.activeElement.contentEditable==="true"))return;const o=[];(i.ctrlKey||i.metaKey)&&o.push("ctrl"),i.shiftKey&&o.push("shift"),i.altKey&&o.push("alt");const n=i.key.toLowerCase(),s=o.length>0?`${o.join("+")}+${n}`:n,r=e[s];r&&(i.preventDefault(),this.execCommand(r))})}handleToolbarCommand(t,e){const o=this.pluginManager.getToolbarItems().find(n=>n.id&&n.id===t||n.command===t);o&&(e!==void 0?this.execCommand(o.command,e):this.execCommand(o.command))}setState(t){this.state=t,this.listeners.forEach(e=>e(t))}onChange(t){return this.listeners.push(t),()=>{this.listeners=this.listeners.filter(e=>e!==t)}}on(t,e){return t==="change"||t==="input"?this.onChange(e):()=>{}}getElement(){return this.contentElement||this.domElement||null}execCommand(t,e){const i=this.commands[t];if(!i)return console.warn(`Command not found: ${t}`),!1;let o;return e!==void 0?o=i(this.state,e):o=i(this.state),o?(this.setState(o),!0):!1}setContent(t){typeof t=="string"?this.contentElement&&(this.contentElement.innerHTML=t):this.setState(this.state.apply(t))}getContent(){return this.contentElement?this.contentElement.innerHTML:this.state.doc}destroy(){this.listeners=[],this.contentElement&&this.contentElement.removeEventListener("input",()=>{})}}class M{constructor(t){this.initialized=!1,this.plugin=t}initialize(t){var e,i;if(this.initialized)return console.warn(`Plugin "${this.plugin.name}" already initialized`),!1;try{return this.context=t,(e=this.plugin.context)!=null&&e.initialize&&this.plugin.context.initialize(),(i=this.plugin.context)!=null&&i.onEditorReady&&t.provider&&this.plugin.context.onEditorReady(t),this.initialized=!0,!0}catch(o){return console.error(`Failed to initialize plugin "${this.plugin.name}":`,o),!1}}destroy(){var t;if(!this.initialized)return!1;try{return(t=this.plugin.context)!=null&&t.destroy&&this.plugin.context.destroy(),this.initialized=!1,this.context=void 0,!0}catch(e){return console.error(`Failed to destroy plugin "${this.plugin.name}":`,e),!1}}executeCommand(t,...e){var i;if(!this.initialized)return console.warn(`Plugin "${this.plugin.name}" not initialized, cannot execute command "${t}"`),null;try{const o=(i=this.plugin.commands)==null?void 0:i[t];return o?o(...e):(console.warn(`Command "${t}" not found in plugin "${this.plugin.name}"`),null)}catch(o){return console.error(`Error executing command "${t}" in plugin "${this.plugin.name}":`,o),null}}getName(){return this.plugin.name}isInitialized(){return this.initialized}getPlugin(){return this.plugin}getContext(){return this.context}}function j(a){return new M(a)}class ${constructor(t){this.shortcuts=new Map,this.enabled=!0,this.isMac=typeof navigator!="undefined"&&navigator.platform.toUpperCase().indexOf("MAC")>=0,(t==null?void 0:t.enabled)===!1&&(this.enabled=!1),this.registerDefaultShortcuts(),t!=null&&t.shortcuts&&t.shortcuts.forEach(e=>this.registerShortcut(e)),t!=null&&t.customShortcuts&&Object.values(t.customShortcuts).forEach(e=>{this.registerShortcut(e)})}registerDefaultShortcuts(){this.registerShortcut({key:"b",ctrl:!this.isMac,meta:this.isMac,command:"toggleBold",description:"Bold",preventDefault:!0}),this.registerShortcut({key:"i",ctrl:!this.isMac,meta:this.isMac,command:"toggleItalic",description:"Italic",preventDefault:!0}),this.registerShortcut({key:"u",ctrl:!this.isMac,meta:this.isMac,command:"toggleUnderline",description:"Underline",preventDefault:!0}),this.registerShortcut({key:"d",ctrl:!this.isMac,meta:this.isMac,command:"toggleStrikethrough",description:"Strikethrough",preventDefault:!0}),this.registerShortcut({key:"z",ctrl:!this.isMac,meta:this.isMac,command:"undo",description:"Undo",preventDefault:!0}),this.registerShortcut({key:"z",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"redo",description:"Redo",preventDefault:!0}),this.registerShortcut({key:"y",ctrl:!this.isMac,meta:this.isMac,command:"redo",description:"Redo",preventDefault:!0});for(let t=1;t<=6;t++)this.registerShortcut({key:String(t),ctrl:!this.isMac,meta:this.isMac,alt:!0,command:"setBlockType",params:`h${t}`,description:`Heading ${t}`,preventDefault:!0});this.registerShortcut({key:"7",ctrl:!this.isMac,meta:this.isMac,alt:!0,command:"setBlockType",params:"p",description:"Paragraph",preventDefault:!0}),this.registerShortcut({key:"7",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"toggleOrderedList",description:"Numbered List",preventDefault:!0}),this.registerShortcut({key:"8",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"toggleBulletList",description:"Bullet List",preventDefault:!0}),this.registerShortcut({key:"k",ctrl:!this.isMac,meta:this.isMac,command:"openLinkDialog",description:"Insert/Edit Link",preventDefault:!0}),this.registerShortcut({key:"e",ctrl:!this.isMac,meta:this.isMac,alt:!0,command:"insertCodeBlock",description:"Code Block",preventDefault:!0}),this.registerShortcut({key:"q",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"toggleBlockquote",description:"Blockquote",preventDefault:!0}),this.registerShortcut({key:"l",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"setTextAlignment",params:"left",description:"Align Left",preventDefault:!0}),this.registerShortcut({key:"e",ctrl:!this.isMac,meta:this.isMac,shift:!0,alt:!0,command:"setTextAlignment",params:"center",description:"Align Center",preventDefault:!0}),this.registerShortcut({key:"r",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"setTextAlignment",params:"right",description:"Align Right",preventDefault:!0}),this.registerShortcut({key:"j",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"setTextAlignment",params:"justify",description:"Justify",preventDefault:!0}),this.registerShortcut({key:"\\",ctrl:!this.isMac,meta:this.isMac,command:"clearFormatting",description:"Clear Formatting",preventDefault:!0}),this.registerShortcut({key:"]",ctrl:!this.isMac,meta:this.isMac,command:"increaseIndent",description:"Indent",preventDefault:!0}),this.registerShortcut({key:"[",ctrl:!this.isMac,meta:this.isMac,command:"decreaseIndent",description:"Outdent",preventDefault:!0}),this.registerShortcut({key:"g",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"insertImage",description:"Insert Image",preventDefault:!0}),this.registerShortcut({key:"t",ctrl:!this.isMac,meta:this.isMac,shift:!0,alt:!0,command:"insertTable",description:"Insert Table",preventDefault:!0}),this.registerShortcut({key:"f11",command:"toggleFullscreen",description:"Toggle Fullscreen",preventDefault:!0}),this.registerShortcut({key:"p",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"togglePreview",description:"Preview",preventDefault:!0}),this.registerShortcut({key:"p",ctrl:!this.isMac,meta:this.isMac,command:"print",description:"Print",preventDefault:!0}),this.registerShortcut({key:"s",ctrl:!this.isMac,meta:this.isMac,shift:!0,alt:!0,command:"insertSpecialCharacter",description:"Insert Special Character",preventDefault:!0}),this.registerShortcut({key:"m",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"insertEmoji",description:"Insert Emoji",preventDefault:!0}),this.registerShortcut({key:"9",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"toggleChecklist",description:"Checklist",preventDefault:!0}),this.registerShortcut({key:"a",ctrl:!this.isMac,meta:this.isMac,shift:!0,alt:!0,command:"toggleA11yChecker",description:"Accessibility Checker",preventDefault:!0}),this.registerShortcut({key:"F7",command:"toggleSpellCheck",description:"Spell Check",preventDefault:!0}),this.registerShortcut({key:"m",ctrl:!this.isMac,meta:this.isMac,alt:!0,command:"insertMath",description:"Insert Math",preventDefault:!0}),this.registerShortcut({key:"f",ctrl:!this.isMac,meta:this.isMac,alt:!0,command:"insertFootnote",description:"Insert Footnote",preventDefault:!0})}registerShortcut(t){const e=this.getShortcutKey(t);this.shortcuts.set(e,t)}unregisterShortcut(t){const e=this.getShortcutKey(t);this.shortcuts.delete(e)}getShortcutKey(t){const e=[];return t.ctrl&&e.push("ctrl"),t.alt&&e.push("alt"),t.shift&&e.push("shift"),t.meta&&e.push("meta"),e.push(t.key.toLowerCase()),e.join("+")}getEventKey(t){const e=[];return t.ctrlKey&&e.push("ctrl"),t.altKey&&e.push("alt"),t.shiftKey&&e.push("shift"),t.metaKey&&e.push("meta"),e.push(t.key.toLowerCase()),e.join("+")}handleKeyDown(t,e){if(!this.enabled)return!1;const i=this.getEventKey(t),o=this.shortcuts.get(i);return o?(o.preventDefault!==!1&&(t.preventDefault(),t.stopPropagation()),e(o.command,o.params),!0):!1}enable(){this.enabled=!0}disable(){this.enabled=!1}isEnabled(){return this.enabled}getAllShortcuts(){return Array.from(this.shortcuts.values())}getShortcutForCommand(t){return Array.from(this.shortcuts.values()).find(e=>e.command===t)}getShortcutDescription(t){const e=[];this.isMac?(t.meta&&e.push("⌘"),t.ctrl&&e.push("⌃"),t.alt&&e.push("⌥"),t.shift&&e.push("⇧")):(t.ctrl&&e.push("Ctrl"),t.alt&&e.push("Alt"),t.shift&&e.push("Shift"));const i=t.key.length===1?t.key.toUpperCase():t.key;return e.push(i),e.join("+")}getShortcutsHelp(){const t=this.getAllShortcuts(),e=new Map;t.forEach(o=>{const n=this.getShortcutCategory(o.command);e.has(n)||e.set(n,[]),e.get(n).push(o)});let i=`# Keyboard Shortcuts
2
2
 
3
- `;return t.forEach((r,c)=>{i+=`## ${c}
3
+ `;return e.forEach((o,n)=>{i+=`## ${n}
4
4
 
5
- `,r.forEach(o=>{const u=this.getShortcutDescription(o);i+=`- **${u}**: ${o.description||o.command}
5
+ `,o.forEach(s=>{const r=this.getShortcutDescription(s);i+=`- **${r}**: ${s.description||s.command}
6
6
  `}),i+=`
7
- `}),i}getShortcutCategory(e){return e.includes("toggle")&&(e.includes("Bold")||e.includes("Italic")||e.includes("Underline")||e.includes("Strike")||e.includes("Code")||e.includes("Super")||e.includes("Sub"))?"Text Formatting":e.includes("Heading")||e.includes("Paragraph")?"Block Formatting":e.includes("List")||e.includes("Checklist")?"Lists":e.includes("Alignment")||e.includes("Indent")?"Alignment & Indentation":e.includes("undo")||e.includes("redo")?"History":e.includes("insert")?"Insert":e.includes("find")||e.includes("replace")?"Find & Replace":e.includes("Accessibility")||e.includes("spell")?"Tools":"Other"}}function M(a={}){const{enabled:e=!1,provider:t="browser",apiUrl:i="",apiHeaders:r={},language:c="en",customDictionary:o=[],ignoreAllCaps:u=!0,ignoreNumbers:v=!0}=a;return{name:"spellcheck",context:{initialize:()=>{if(e)switch(console.log("[Spellcheck Plugin] Initialized",{provider:t,language:c}),t){case"browser":console.log("[Spellcheck] Using browser spellcheck");break;case"local":console.log("[Spellcheck] Using local dictionary (not implemented)");break;case"api":i?console.log("[Spellcheck] Using API:",i):console.warn("[Spellcheck] API provider selected but no apiUrl provided");break}},destroy:()=>{console.log("[Spellcheck Plugin] Destroyed")},onEditorReady:h=>{console.log("[Spellcheck Plugin] Editor ready")}},commands:{toggleSpellcheck:()=>(console.log("[Spellcheck] Toggle command (not implemented)"),null),addToDictionary:h=>(console.log("[Spellcheck] Add to dictionary:",h),null),checkSpelling:async()=>(console.log("[Spellcheck] Check spelling (not implemented)"),null)},toolbar:e?[{label:"Spellcheck",command:"toggleSpellcheck",icon:"Aa",type:"button"}]:[]}}function b(a={}){const{uploadUrl:e="",libraryUrl:t="",maxFileSize:i=10485760,allowedTypes:r=["image/jpeg","image/png","image/gif","image/webp"],headers:c={},withCredentials:o=!1,chunkSize:u=1048576,enableChunking:v=!0,onProgress:h,onError:m,onSuccess:D}=a;return{name:"media",context:{initialize:()=>{console.log("[Media Plugin] Initialized",{uploadUrl:e,libraryUrl:t,maxFileSize:i,allowedTypes:r}),e||console.warn("[Media] No uploadUrl provided - upload will not work")},destroy:()=>{console.log("[Media Plugin] Destroyed")},onEditorReady:n=>{console.log("[Media Plugin] Editor ready")}},commands:{insertImage:async n=>{if(console.log("[Media] Insert image command (not implemented)",n),!n)return console.log("[Media] No file provided - should open picker"),null;if(!r.includes(n.type)){const d=new Error(`File type ${n.type} not allowed`);return m?.(d),null}if(n.size>i){const d=new Error(`File size ${n.size} exceeds max ${i}`);return m?.(d),null}return null},openMediaLibrary:()=>(console.log("[Media] Open media library (not implemented)"),t||console.warn("[Media] No libraryUrl provided"),null),uploadMedia:async n=>(console.log("[Media] Upload media (not implemented)",{name:n.name,size:n.size,type:n.type}),null)},toolbar:[{label:"Image",command:"insertImage",icon:"🖼️",type:"button"},{label:"Media Library",command:"openMediaLibrary",icon:"📁",type:"button"}]}}return s.Editor=f,s.EditorState=l,s.KeyboardShortcutManager=k,s.PluginManager=y,s.PluginRuntime=p,s.Schema=g,s.createMediaPlugin=b,s.createPluginRuntime=S,s.createSpellcheckPlugin=M,Object.defineProperty(s,Symbol.toStringTag,{value:"Module"}),s})({});
7
+ `}),i}getShortcutCategory(t){return t.includes("toggle")&&(t.includes("Bold")||t.includes("Italic")||t.includes("Underline")||t.includes("Strike")||t.includes("Code")||t.includes("Super")||t.includes("Sub"))?"Text Formatting":t.includes("Heading")||t.includes("Paragraph")?"Block Formatting":t.includes("List")||t.includes("Checklist")?"Lists":t.includes("Alignment")||t.includes("Indent")?"Alignment & Indentation":t.includes("undo")||t.includes("redo")?"History":t.includes("insert")?"Insert":t.includes("find")||t.includes("replace")?"Find & Replace":t.includes("Accessibility")||t.includes("spell")?"Tools":"Other"}}function N(a={}){const{enabled:t=!1,provider:e="browser",apiUrl:i="",apiHeaders:o={},language:n="en",customDictionary:s=[],ignoreAllCaps:r=!0,ignoreNumbers:l=!0}=a;return{name:"spellcheck",context:{initialize:()=>{if(t)switch(console.log("[Spellcheck Plugin] Initialized",{provider:e,language:n}),e){case"browser":console.log("[Spellcheck] Using browser spellcheck");break;case"local":console.log("[Spellcheck] Using local dictionary (not implemented)");break;case"api":i?console.log("[Spellcheck] Using API:",i):console.warn("[Spellcheck] API provider selected but no apiUrl provided");break}},destroy:()=>{console.log("[Spellcheck Plugin] Destroyed")},onEditorReady:p=>{console.log("[Spellcheck Plugin] Editor ready")}},commands:{toggleSpellcheck:()=>(console.log("[Spellcheck] Toggle command (not implemented)"),null),addToDictionary:p=>(console.log("[Spellcheck] Add to dictionary:",p),null),checkSpelling:async()=>(console.log("[Spellcheck] Check spelling (not implemented)"),null)},toolbar:t?[{label:"Spellcheck",command:"toggleSpellcheck",icon:"Aa",type:"button"}]:[]}}function R(a={}){const{uploadUrl:t="",libraryUrl:e="",maxFileSize:i=10485760,allowedTypes:o=["image/jpeg","image/png","image/gif","image/webp"],headers:n={},withCredentials:s=!1,chunkSize:r=1048576,enableChunking:l=!0,onProgress:p,onError:u,onSuccess:m}=a;return{name:"media",context:{initialize:()=>{console.log("[Media Plugin] Initialized",{uploadUrl:t,libraryUrl:e,maxFileSize:i,allowedTypes:o}),t||console.warn("[Media] No uploadUrl provided - upload will not work")},destroy:()=>{console.log("[Media Plugin] Destroyed")},onEditorReady:d=>{console.log("[Media Plugin] Editor ready")}},commands:{insertImage:async d=>{if(console.log("[Media] Insert image command (not implemented)",d),!d)return console.log("[Media] No file provided - should open picker"),null;if(!o.includes(d.type)){const h=new Error(`File type ${d.type} not allowed`);return u==null||u(h),null}if(d.size>i){const h=new Error(`File size ${d.size} exceeds max ${i}`);return u==null||u(h),null}return null},openMediaLibrary:()=>(console.log("[Media] Open media library (not implemented)"),e||console.warn("[Media] No libraryUrl provided"),null),uploadMedia:async d=>(console.log("[Media] Upload media (not implemented)",{name:d.name,size:d.size,type:d.type}),null)},toolbar:[{label:"Image",command:"insertImage",icon:"🖼️",type:"button"},{label:"Media Library",command:"openMediaLibrary",icon:"📁",type:"button"}]}}class T{constructor(t={}){this.commands=new Map,Object.entries(t).forEach(([e,i])=>{this.register(e,i)})}register(t,e){this.commands.has(t)&&console.warn(`Command ${t} is being overwritten`),this.commands.set(t,e)}unregister(t){this.commands.delete(t)}get(t){return this.commands.get(t)}has(t){return this.commands.has(t)}getCommandNames(){return Array.from(this.commands.keys())}clear(){this.commands.clear()}}class E{constructor(t={}){this.listeners=new Map,this.isReadonly=!1,this.isDestroyed=!1,this.isReadonly=t.readonly||!1,this.pluginManager=new v,t.plugins&&Array.isArray(t.plugins)&&t.plugins.forEach(i=>this.pluginManager.register(i));const e=this.pluginManager.buildSchema();this.state=b.create(e),this.commandRegistry=new T(this.pluginManager.getCommands())}execCommand(t,e){if(this.isReadonly)return console.warn("Cannot execute commands in readonly mode"),!1;if(this.isDestroyed)return console.warn("Cannot execute commands on destroyed editor"),!1;const i=this.commandRegistry.get(t);if(!i)return console.warn(`Command not found: ${t}`),!1;let o;return e!==void 0?o=i(this.state,e):o=i(this.state),o?(this.setState(o),this.emit("change",this.state),!0):!1}setState(t){this.isDestroyed||(this.state=t,this.emit("stateChange",t))}getState(){return this.state}setReadonly(t){this.isReadonly=t,this.emit("readonlyChange",t)}isReadOnly(){return this.isReadonly}on(t,e){return this.listeners.has(t)||this.listeners.set(t,[]),this.listeners.get(t).push(e),()=>{const i=this.listeners.get(t);if(i){const o=i.indexOf(e);o>-1&&i.splice(o,1)}}}emit(t,...e){const i=this.listeners.get(t);i&&i.forEach(o=>{try{o(...e)}catch(n){console.error(`Error in ${t} handler:`,n)}})}destroy(){this.isDestroyed||(this.isDestroyed=!0,this.listeners.clear(),this.emit("destroy"))}isEditorDestroyed(){return this.isDestroyed}}class y{constructor(t,e={anchor:0,head:0}){this.doc=t,this.selection=e}getDocument(){return this.doc}setDocument(t){return new y(t,this.selection)}getSelection(){return{...this.selection}}setSelection(t){return new y(this.doc,t)}update(t,e){return new y(t||this.doc,e||this.selection)}getTextContent(){return""}isSelectionEmpty(){return this.selection.anchor===this.selection.head}}class x{constructor(t,e,i){this.config=t,this.plugins=e,this.pluginLoader=i}setCommandHandler(t){this.commandHandler=t}parseToolbarString(t){const e=[],i=t.split("|").map(r=>r.trim()),o=this.getAvailableToolbarItems(),n=new Map;o.forEach(r=>{r.command&&n.set(r.command,r),r.type==="group"&&r.label&&n.set(r.label,r)});const s={bold:"toggleBold",italic:"toggleItalic",underline:"toggleUnderline",strikethrough:"toggleStrikethrough",bullist:"toggleBulletList",numlist:"toggleOrderedList",checklist:"toggleChecklist",link:"openLinkDialog",image:"openImageDialog",table:"insertTable",anchor:"insertAnchor",code:"toggleSourceView",blockquote:"toggleBlockquote",undo:"undo",redo:"redo",textColor:"openTextColorPicker",backgroundColor:"openBackgroundColorPicker",fontSize:"fontSize",fontFamily:"setFontFamily",lineHeight:"setLineHeight",heading:"setBlockType",paragraph:"setParagraph",textAlignment:"setTextAlignment",direction:"setDirectionLTR",indent:"increaseIndent",outdent:"decreaseIndent",capitalization:"setCapitalization",math:"insertMath",specialCharacters:"insertSpecialCharacter",emojis:"openEmojiDialog",embedIframe:"openEmbedIframeDialog",fullscreen:"toggleFullscreen",preview:"togglePreview",print:"print",a11yChecker:"toggleA11yChecker",spellCheck:"toggleSpellCheck",comments:"addComment",showHideComments:"toggleComments",toggleComments:"toggleComments",footnote:"insertFootnote",mergeTags:"insertMergeTag",pageBreak:"insertPageBreak",template:"insertTemplate",importWord:"importWord",exportWord:"exportWord",exportPdf:"exportPdf",insertImage:"insertImage",insertVideo:"insertVideo",codeBlock:"insertCodeBlock"};return i.forEach(r=>{const l=[];r.split(/\s+/).filter(Boolean).forEach(u=>{if(u==="direction"){const h=n.get("setDirectionLTR"),g=n.get("setDirectionRTL");h&&l.push({id:"directionLTR",label:h.label,command:h.command,icon:h.icon,type:h.type||"button",options:h.options}),g&&l.push({id:"directionRTL",label:g.label,command:g.command,icon:g.icon,type:g.type||"button",options:g.options});return}if(u==="comments"){const h=n.get("addComment"),g=n.get("toggleComments");h&&l.push({id:"addComment",label:h.label,command:h.command,icon:h.icon,type:h.type||"button",options:h.options}),g&&l.push({id:"toggleComments",label:g.label,command:g.command,icon:g.icon,type:g.type||"button",options:g.options});return}const m=s[u]||u;let d=n.get(m);d||(d=n.get(u)),d&&l.push({id:u,label:d.label,command:d.command,icon:d.icon,type:d.type==="separator"?"separator":d.type||"button",options:d.options,items:d.items})}),l.length>0&&e.push(l)}),e}getAvailableToolbarItems(){let t=this.plugins;return this.pluginLoader&&(t=this.pluginLoader.getRegisteredPluginNames().map(n=>this.pluginLoader.load(n)).filter(n=>n!==null)),t.flatMap(i=>i.toolbar||[])}render(t){this.container=t,t.innerHTML="",t.className="editora-toolbar",this.config.sticky&&t.classList.add("editora-toolbar-sticky"),this.config.position&&t.classList.add(`editora-toolbar-${this.config.position}`);const e=this.config.items||this.getDefaultToolbarString(),i=this.parseToolbarString(e);i.forEach((o,n)=>{const s=document.createElement("div");if(s.className="editora-toolbar-group",o.forEach(r=>{this.appendToolbarButton(s,r)}),t.appendChild(s),n<i.length-1){const r=document.createElement("div");r.className="editora-toolbar-separator",t.appendChild(r)}})}appendToolbarButton(t,e){if(e.type==="separator"){const i=document.createElement("div");i.className="editora-toolbar-separator",t.appendChild(i)}else if(e.type==="dropdown"){const i=this.createDropdown(e);t.appendChild(i)}else if(e.type==="inline-menu"){const i=this.createInlineMenu(e);t.appendChild(i)}else if(e.type==="group"&&e.items&&e.items.length){const i=this.createGroupButton(e);t.appendChild(i)}else if(e.type==="input"){const i=this.createInput(e);t.appendChild(i)}else{const i=this.createButton(e);t.appendChild(i)}}createGroupButton(t){const e=document.createElement("div");if(e.className="editora-toolbar-group-button",e.title=t.label,t.icon)if(t.icon.startsWith("<svg")&&t.icon.endsWith("</svg>")){const i=document.createElement("span");i.className="editora-toolbar-icon",i.innerHTML=t.icon,e.appendChild(i)}else e.innerHTML=t.icon;if(t.items&&t.items.length){const i=document.createElement("div");i.className="editora-toolbar-group-items",t.items.forEach(o=>{this.appendToolbarButton(i,o)}),e.appendChild(i)}return e}createInput(t){const e=document.createElement("input");return e.className=`editora-toolbar-input ${t.label.toLowerCase().replace(/\s+/g,"-")}`,e.type="text",e.title=t.label,e.placeholder=t.placeholder||"",e.setAttribute("data-command",t.command),t.active&&e.classList.add("active"),t.disabled&&(e.disabled=!0),e.addEventListener("click",i=>{i.preventDefault(),this.commandHandler&&this.commandHandler(t.command)}),e}createButton(t){const e=document.createElement("button");if(e.className="editora-toolbar-button",e.type="button",e.title=t.label,e.setAttribute("data-command",t.command),t.icon)if(t.icon.startsWith("<svg")&&t.icon.endsWith("</svg>")){const i=document.createElement("span");i.className="editora-toolbar-icon",i.innerHTML=t.icon,e.appendChild(i)}else e.innerHTML=t.icon;else e.textContent=t.label;return t.active&&e.classList.add("active"),t.disabled&&(e.disabled=!0),e.addEventListener("click",i=>{i.preventDefault(),this.commandHandler&&this.commandHandler(t.command)}),e}createDropdown(t){const e=document.createElement("div");e.className="editora-toolbar-dropdown";const i=document.createElement("button");i.className="editora-toolbar-button editora-toolbar-dropdown-trigger",i.type="button",i.textContent=t.label;const o=document.createElement("div");o.className="editora-toolbar-dropdown-menu",o.style.display="none",t.options&&t.options.forEach(s=>{const r=document.createElement("button");r.className="editora-toolbar-dropdown-item",r.type="button",r.textContent=s.label,r.setAttribute("data-value",s.value),r.addEventListener("click",l=>{l.preventDefault(),this.commandHandler&&this.commandHandler(t.command,s.value),o.style.display="none"}),o.appendChild(r)}),i.addEventListener("click",s=>{s.preventDefault(),s.stopPropagation();const r=o.style.display==="block";o.style.display=r?"none":"block"});const n=s=>{e.contains(s.target)||(o.style.display="none")};return document.addEventListener("click",n),e._cleanupDropdown=()=>{document.removeEventListener("click",n)},e.appendChild(i),e.appendChild(o),e}createInlineMenu(t){const e=document.createElement("div");e.className="editora-toolbar-dropdown editora-toolbar-inline-menu";const i=document.createElement("button");if(i.className="editora-toolbar-button",i.type="button",i.title=t.label,t.icon)if(t.icon.startsWith("<svg")&&t.icon.endsWith("</svg>")){const n=document.createElement("span");n.className="editora-toolbar-icon",n.innerHTML=t.icon,i.appendChild(n)}else i.innerHTML=t.icon;else i.textContent=t.label;const o=document.createElement("div");return o.className="editora-toolbar-dropdown-menu",o.style.display="none",t.options&&t.options.forEach(n=>{const s=document.createElement("button");s.className="editora-toolbar-dropdown-item",s.type="button",s.textContent=n.label,s.setAttribute("data-value",n.value),s.addEventListener("click",r=>{r.preventDefault(),r.stopPropagation(),this.commandHandler&&this.commandHandler(t.command,n.value),o.style.display="none"}),o.appendChild(s)}),i.addEventListener("click",n=>{var r;n.preventDefault(),n.stopPropagation();const s=(r=this.container)==null?void 0:r.querySelectorAll(".editora-toolbar-dropdown-menu");s==null||s.forEach(l=>{l!==o&&(l.style.display="none")}),o.style.display=o.style.display==="none"?"block":"none"}),document.addEventListener("click",n=>{e.contains(n.target)||(o.style.display="none")}),e.appendChild(i),e.appendChild(o),e}getDefaultToolbarString(){return this.getAvailableToolbarItems().map(e=>e.command).join(" ")}updateButtonState(t,e){if(!this.container)return;const i=this.container.querySelector(`[data-command="${t}"]`);i&&(e.active!==void 0&&i.classList.toggle("active",e.active),e.disabled!==void 0&&(i.disabled=e.disabled))}destroy(){this.container&&(this.container.querySelectorAll(".editora-toolbar-dropdown").forEach(e=>{const i=e._cleanupDropdown;i&&i()}),this.container.innerHTML=""),this.commandHandler=void 0}}class I{constructor(t){this.visible=!1,this.config=t}create(t){const e=document.createElement("div");return e.className="editora-floating-toolbar",e.style.display="none",e.style.position="absolute",e.style.zIndex="1000",this.container=e,t.appendChild(e),e}show(t,e){this.container&&(this.container.style.display="block",this.container.style.left=`${t}px`,this.container.style.top=`${e}px`,this.visible=!0)}hide(){this.container&&(this.container.style.display="none",this.visible=!1)}updatePosition(t,e){!this.container||!this.visible||(this.container.style.left=`${t}px`,this.container.style.top=`${e}px`)}isVisible(){return this.visible}destroy(){this.container&&this.container.parentNode&&this.container.parentNode.removeChild(this.container),this.container=void 0,this.visible=!1}}class D{constructor(t={}){this.statusInfo={},this.config=t}create(t){const e=document.createElement("div");return e.className="editora-statusbar",this.config.position&&e.classList.add(`editora-statusbar-${this.config.position}`),this.container=e,t.appendChild(e),e}update(t){this.statusInfo={...this.statusInfo,...t},this.render()}render(){if(!this.container)return;this.container.innerHTML="";const t=[];this.statusInfo.wordCount!==void 0&&t.push(`Words: ${this.statusInfo.wordCount}`),this.statusInfo.charCount!==void 0&&t.push(`Characters: ${this.statusInfo.charCount}`),this.statusInfo.lineCount!==void 0&&t.push(`Lines: ${this.statusInfo.lineCount}`),this.statusInfo.language&&t.push(`Language: ${this.statusInfo.language}`),this.statusInfo.custom&&Object.entries(this.statusInfo.custom).forEach(([e,i])=>{t.push(`${e}: ${i}`)}),t.forEach((e,i)=>{const o=document.createElement("span");if(o.className="editora-statusbar-item",o.textContent=e,this.container.appendChild(o),i<t.length-1){const n=document.createElement("span");n.className="editora-statusbar-separator",n.textContent="|",this.container.appendChild(n)}})}destroy(){this.container&&this.container.parentNode&&this.container.parentNode.removeChild(this.container),this.container=void 0}}class f{constructor(t){this.config={closeOnEscape:!0,closeOnBackdrop:!0,...t},this.element=this.createElement(),this.attachEventListeners()}createElement(){const t=document.createElement("dialog");if(t.className="editora-dialog",this.config.width&&(t.style.width=this.config.width),this.config.height&&(t.style.height=this.config.height),t.innerHTML=`
8
+ <div class="editora-dialog-container">
9
+ <div class="editora-dialog-header">
10
+ <h3>${this.config.title}</h3>
11
+ <button class="editora-dialog-close" aria-label="Close">&times;</button>
12
+ </div>
13
+ <div class="editora-dialog-body">
14
+ ${typeof this.config.content=="string"?this.config.content:""}
15
+ </div>
16
+ <div class="editora-dialog-footer">
17
+ <button type="button" class="editora-btn editora-btn-cancel">Cancel</button>
18
+ <button type="button" class="editora-btn editora-btn-primary">OK</button>
19
+ </div>
20
+ </div>
21
+ `,typeof this.config.content!="string"){const e=t.querySelector(".editora-dialog-body");e&&(e.innerHTML="",e.appendChild(this.config.content))}return t}attachEventListeners(){const t=this.element.querySelector(".editora-dialog-close");t==null||t.addEventListener("click",()=>this.close());const e=this.element.querySelector(".editora-btn-cancel");e==null||e.addEventListener("click",()=>{var o,n;(n=(o=this.config).onCancel)==null||n.call(o),this.close()});const i=this.element.querySelector(".editora-btn-primary");i==null||i.addEventListener("click",()=>this.handleSubmit()),this.config.closeOnEscape&&this.element.addEventListener("cancel",o=>{o.preventDefault(),this.close()}),this.config.closeOnBackdrop&&this.element.addEventListener("click",o=>{const n=this.element.getBoundingClientRect();(o.clientX<n.left||o.clientX>n.right||o.clientY<n.top||o.clientY>n.bottom)&&this.close()})}handleSubmit(){var e,i,o,n;const t=this.element.querySelector("form");if(t){const s=new FormData(t);(i=(e=this.config).onSubmit)==null||i.call(e,s)}else{const s=this.element.querySelectorAll("input, select, textarea"),r=new FormData;s.forEach(l=>{l.name&&r.append(l.name,l.value)}),(n=(o=this.config).onSubmit)==null||n.call(o,r)}this.close()}show(){document.body.appendChild(this.element),this.element.showModal()}close(){this.element.close(),this.element.remove()}destroy(){this.close()}}class z{constructor(t){this.isOpen=!1,this.config=t,this.selectedValue=t.value,this.element=this.createElement(),this.attachEventListeners()}createElement(){const t=document.createElement("div");t.className="editora-dropdown",this.config.width&&(t.style.width=this.config.width);const e=this.config.options.find(o=>o.value===this.selectedValue),i=(e==null?void 0:e.label)||this.config.placeholder||"Select...";return t.innerHTML=`
22
+ <button class="editora-dropdown-toggle" type="button">
23
+ <span class="editora-dropdown-label">${i}</span>
24
+ <span class="editora-dropdown-arrow">▼</span>
25
+ </button>
26
+ <div class="editora-dropdown-menu" style="display: none;">
27
+ ${this.config.options.map(o=>`
28
+ <div class="editora-dropdown-item" data-value="${o.value}">
29
+ ${o.icon?`<span class="editora-dropdown-icon">${o.icon}</span>`:""}
30
+ <span>${o.label}</span>
31
+ </div>
32
+ `).join("")}
33
+ </div>
34
+ `,t}attachEventListeners(){const t=this.element.querySelector(".editora-dropdown-toggle"),e=this.element.querySelector(".editora-dropdown-menu");t.addEventListener("click",o=>{o.stopPropagation(),this.isOpen=!this.isOpen,e.style.display=this.isOpen?"block":"none"}),this.element.querySelectorAll(".editora-dropdown-item").forEach(o=>{o.addEventListener("click",()=>{var s,r;const n=o.getAttribute("data-value");n&&(this.setValue(n),(r=(s=this.config).onChange)==null||r.call(s,n),this.close())})}),document.addEventListener("click",o=>{this.element.contains(o.target)||this.close()})}setValue(t){this.selectedValue=t;const e=this.config.options.find(o=>o.value===t),i=this.element.querySelector(".editora-dropdown-label");i&&e&&(i.textContent=e.label)}getValue(){return this.selectedValue}close(){this.isOpen=!1;const t=this.element.querySelector(".editora-dropdown-menu");t&&(t.style.display="none")}getElement(){return this.element}destroy(){this.element.remove()}}class q{constructor(t){this.defaultPresets=["#000000","#434343","#666666","#999999","#B7B7B7","#CCCCCC","#D9D9D9","#EFEFEF","#F3F3F3","#FFFFFF","#980000","#FF0000","#FF9900","#FFFF00","#00FF00","#00FFFF","#4A86E8","#0000FF","#9900FF","#FF00FF","#E6B8AF","#F4CCCC","#FCE5CD","#FFF2CC","#D9EAD3","#D0E0E3","#C9DAF8","#CFE2F3","#D9D2E9","#EAD1DC"],this.config={presetColors:this.defaultPresets,...t},this.selectedColor=t.value,this.element=this.createElement(),this.attachEventListeners()}createElement(){var e;const t=document.createElement("div");return t.className="editora-color-picker",t.innerHTML=`
35
+ <div class="editora-color-picker-input">
36
+ <input type="color" value="${this.selectedColor||"#000000"}" />
37
+ <input type="text" value="${this.selectedColor||"#000000"}" placeholder="#000000" />
38
+ </div>
39
+ <div class="editora-color-picker-presets">
40
+ ${(e=this.config.presetColors)==null?void 0:e.map(i=>`
41
+ <button
42
+ class="editora-color-preset"
43
+ style="background-color: ${i};"
44
+ data-color="${i}"
45
+ title="${i}"
46
+ ></button>
47
+ `).join("")}
48
+ </div>
49
+ `,t}attachEventListeners(){const t=this.element.querySelector('input[type="color"]'),e=this.element.querySelector('input[type="text"]');t.addEventListener("input",o=>{var s,r;const n=o.target.value;e.value=n,this.selectedColor=n,(r=(s=this.config).onChange)==null||r.call(s,n)}),e.addEventListener("input",o=>{var s,r;const n=o.target.value;/^#[0-9A-Fa-f]{6}$/.test(n)&&(t.value=n,this.selectedColor=n,(r=(s=this.config).onChange)==null||r.call(s,n))}),this.element.querySelectorAll(".editora-color-preset").forEach(o=>{o.addEventListener("click",()=>{var s,r;const n=o.getAttribute("data-color");n&&(t.value=n,e.value=n,this.selectedColor=n,(r=(s=this.config).onChange)==null||r.call(s,n))})})}getValue(){return this.selectedColor}setValue(t){this.selectedColor=t;const e=this.element.querySelector('input[type="color"]'),i=this.element.querySelector('input[type="text"]');e&&(e.value=t),i&&(i.value=t)}getElement(){return this.element}destroy(){this.element.remove()}}class B{constructor(t){const{initialUrl:e="",initialText:i="",onSubmit:o,onCancel:n}=t;this.dialog=new f({title:"Insert/Edit Link",content:this.createFormHTML(e,i),onSubmit:s=>{const r=(s.get("url")||"").trim(),l=(s.get("text")||"").trim(),p=s.get("openInNewTab")==="on";if(!r){alert("Please enter a URL");return}o({url:r,text:l,openInNewTab:p}),this.dialog.close()},onCancel:()=>{n==null||n(),this.dialog.close()},width:"500px"})}createFormHTML(t,e){return`
50
+ <form class="link-dialog-form">
51
+ <div class="form-group">
52
+ <label for="link-url">URL</label>
53
+ <input
54
+ type="url"
55
+ id="link-url"
56
+ name="url"
57
+ placeholder="https://example.com"
58
+ value="${this.escapeHtml(t)}"
59
+ required
60
+ autofocus
61
+ />
62
+ <small>Enter the web address (URL) for the link</small>
63
+ </div>
64
+
65
+ <div class="form-group">
66
+ <label for="link-text">Link Text</label>
67
+ <input
68
+ type="text"
69
+ id="link-text"
70
+ name="text"
71
+ placeholder="Click here"
72
+ value="${this.escapeHtml(e)}"
73
+ />
74
+ <small>Text to display for the link (leave empty to use URL)</small>
75
+ </div>
76
+
77
+ <div class="form-group">
78
+ <label class="checkbox-label">
79
+ <input
80
+ type="checkbox"
81
+ name="openInNewTab"
82
+ id="link-new-tab"
83
+ />
84
+ <span>Open link in new tab</span>
85
+ </label>
86
+ </div>
87
+
88
+ <div class="form-actions">
89
+ <button type="button" class="btn btn-secondary" data-action="cancel">
90
+ Cancel
91
+ </button>
92
+ <button type="submit" class="btn btn-primary">
93
+ Insert Link
94
+ </button>
95
+ </div>
96
+ </form>
97
+ `}escapeHtml(t){const e=document.createElement("div");return e.textContent=t,e.innerHTML}show(){this.dialog.show()}close(){this.dialog.close()}}class O{constructor(t){const{onSubmit:e,onCancel:i}=t;this.dialog=new f({title:"Insert Table",content:this.createFormHTML(),onSubmit:o=>{const n=parseInt(o.get("rows"),10),s=parseInt(o.get("cols"),10),r=o.get("headerRow")==="on";if(n<1||n>100){alert("Please enter a valid number of rows (1-100)");return}if(s<1||s>20){alert("Please enter a valid number of columns (1-20)");return}e({rows:n,cols:s,headerRow:r}),this.dialog.close()},onCancel:()=>{i==null||i(),this.dialog.close()},width:"400px"})}createFormHTML(){return`
98
+ <form class="table-dialog-form">
99
+ <div class="form-group">
100
+ <label for="table-rows">Rows</label>
101
+ <input
102
+ type="number"
103
+ id="table-rows"
104
+ name="rows"
105
+ min="1"
106
+ max="100"
107
+ value="3"
108
+ required
109
+ autofocus
110
+ />
111
+ <small>Number of rows (1-100)</small>
112
+ </div>
113
+
114
+ <div class="form-group">
115
+ <label for="table-cols">Columns</label>
116
+ <input
117
+ type="number"
118
+ id="table-cols"
119
+ name="cols"
120
+ min="1"
121
+ max="20"
122
+ value="3"
123
+ required
124
+ />
125
+ <small>Number of columns (1-20)</small>
126
+ </div>
127
+
128
+ <div class="form-group">
129
+ <label class="checkbox-label">
130
+ <input
131
+ type="checkbox"
132
+ name="headerRow"
133
+ id="table-header"
134
+ checked
135
+ />
136
+ <span>Include header row</span>
137
+ </label>
138
+ </div>
139
+
140
+ <div class="table-preview">
141
+ <strong>Preview:</strong>
142
+ <div id="table-preview-content" style="margin-top: 8px; font-size: 12px; color: #666;">
143
+ 3 rows × 3 columns with header
144
+ </div>
145
+ </div>
146
+
147
+ <div class="form-actions">
148
+ <button type="button" class="btn btn-secondary" data-action="cancel">
149
+ Cancel
150
+ </button>
151
+ <button type="submit" class="btn btn-primary">
152
+ Insert Table
153
+ </button>
154
+ </div>
155
+ </form>
156
+ `}show(){this.dialog.show(),this.attachPreviewListeners()}close(){this.dialog.close()}attachPreviewListeners(){const t=document.querySelector(".table-dialog-form");if(!t)return;const e=t.querySelector("#table-rows"),i=t.querySelector("#table-cols"),o=t.querySelector("#table-header"),n=t.querySelector("#table-preview-content"),s=()=>{const r=parseInt((e==null?void 0:e.value)||"3",10),l=parseInt((i==null?void 0:i.value)||"3",10),p=o==null?void 0:o.checked;n&&(n.textContent=`${r} rows × ${l} columns${p?" with header":""}`)};e==null||e.addEventListener("input",s),i==null||i.addEventListener("input",s),o==null||o.addEventListener("change",s)}}class U{constructor(t){this.config=t;const{onSubmit:e,onCancel:i}=t;this.dialog=new f({title:"Insert Image",content:this.createFormHTML(),onSubmit:o=>{const n=(o.get("src")||"").trim(),s=(o.get("alt")||"").trim(),r=(o.get("width")||"").trim(),l=(o.get("height")||"").trim();if(!n){alert("Please enter an image URL or upload an image");return}e({src:n,alt:s,width:r||void 0,height:l||void 0}),this.dialog.close()},onCancel:()=>{i==null||i(),this.dialog.close()},width:"500px"})}createFormHTML(){return`
157
+ <form class="image-dialog-form">
158
+ ${this.config.allowUpload?`
159
+ <div class="form-group">
160
+ <label for="image-upload">Upload Image</label>
161
+ <input
162
+ type="file"
163
+ id="image-upload"
164
+ accept="image/*"
165
+ />
166
+ <small>Or upload an image from your computer</small>
167
+ </div>
168
+ <div class="form-divider">OR</div>
169
+ `:""}
170
+
171
+ <div class="form-group">
172
+ <label for="image-src">Image URL</label>
173
+ <input
174
+ type="url"
175
+ id="image-src"
176
+ name="src"
177
+ placeholder="https://example.com/image.jpg"
178
+ ${this.config.allowUpload?"":"required autofocus"}
179
+ />
180
+ <small>Enter the web address (URL) of the image</small>
181
+ </div>
182
+
183
+ <div class="form-group">
184
+ <label for="image-alt">Alt Text</label>
185
+ <input
186
+ type="text"
187
+ id="image-alt"
188
+ name="alt"
189
+ placeholder="Description of the image"
190
+ />
191
+ <small>Alternative text for accessibility (recommended)</small>
192
+ </div>
193
+
194
+ <div class="form-row">
195
+ <div class="form-group">
196
+ <label for="image-width">Width</label>
197
+ <input
198
+ type="text"
199
+ id="image-width"
200
+ name="width"
201
+ placeholder="auto"
202
+ />
203
+ </div>
204
+
205
+ <div class="form-group">
206
+ <label for="image-height">Height</label>
207
+ <input
208
+ type="text"
209
+ id="image-height"
210
+ name="height"
211
+ placeholder="auto"
212
+ />
213
+ </div>
214
+ </div>
215
+
216
+ <div class="image-preview" id="image-preview" style="display: none;">
217
+ <strong>Preview:</strong>
218
+ <img id="preview-img" style="max-width: 100%; max-height: 200px; margin-top: 8px;" />
219
+ </div>
220
+
221
+ <div class="form-actions">
222
+ <button type="button" class="btn btn-secondary" data-action="cancel">
223
+ Cancel
224
+ </button>
225
+ <button type="submit" class="btn btn-primary">
226
+ Insert Image
227
+ </button>
228
+ </div>
229
+ </form>
230
+ `}show(){this.dialog.show(),this.attachImagePreview(),this.attachFileUpload()}close(){this.dialog.close()}attachImagePreview(){const t=document.querySelector(".image-dialog-form");if(!t)return;const e=t.querySelector("#image-src"),i=t.querySelector("#image-preview"),o=t.querySelector("#preview-img");e==null||e.addEventListener("input",()=>{const n=e.value.trim();n&&this.isValidImageUrl(n)?(o.src=n,i.style.display="block",o.onerror=()=>{i.style.display="none"}):i.style.display="none"})}attachFileUpload(){if(!this.config.allowUpload)return;const t=document.querySelector(".image-dialog-form");if(!t)return;const e=t.querySelector("#image-upload"),i=t.querySelector("#image-src");e==null||e.addEventListener("change",async o=>{var r;const n=(r=o.target.files)==null?void 0:r[0];if(!n)return;const s=new FileReader;s.onload=l=>{var u;const p=(u=l.target)==null?void 0:u.result;i.value=p,i.dispatchEvent(new Event("input"))},s.readAsDataURL(n)})}isValidImageUrl(t){try{return new URL(t),/\.(jpg|jpeg|png|gif|svg|webp|bmp)$/i.test(t)||t.startsWith("data:image/")}catch(e){return!1}}}class G{constructor(t){this.onSubmit=t.onSubmit;const e=this.createContent();this.dialog=new f({title:"Insert Math Equation",content:e,buttons:[{label:"Cancel",onClick:()=>this.dialog.close()},{label:"Insert",onClick:()=>this.handleSubmit(),primary:!0}]}),this.latexInput=e.querySelector("#math-latex"),this.previewDiv=e.querySelector("#math-preview"),this.displayTypeSelect=e.querySelector("#math-display-type"),this.latexInput.addEventListener("input",()=>this.updatePreview())}createContent(){const t=document.createElement("div");return t.className="math-dialog-content",t.style.minWidth="500px",t.innerHTML=`
231
+ <style>
232
+ .math-dialog-content {
233
+ display: flex;
234
+ flex-direction: column;
235
+ gap: 1rem;
236
+ }
237
+ .math-form-group {
238
+ display: flex;
239
+ flex-direction: column;
240
+ gap: 0.5rem;
241
+ }
242
+ .math-form-group label {
243
+ font-weight: 500;
244
+ color: #333;
245
+ }
246
+ .math-latex-input {
247
+ width: 100%;
248
+ min-height: 80px;
249
+ padding: 0.5rem;
250
+ border: 1px solid #ddd;
251
+ border-radius: 4px;
252
+ font-family: 'Courier New', monospace;
253
+ font-size: 14px;
254
+ resize: vertical;
255
+ }
256
+ .math-preview {
257
+ padding: 1rem;
258
+ background: #f9f9f9;
259
+ border: 1px solid #ddd;
260
+ border-radius: 4px;
261
+ min-height: 60px;
262
+ font-size: 18px;
263
+ text-align: center;
264
+ }
265
+ .math-preview:empty::before {
266
+ content: 'Preview will appear here...';
267
+ color: #999;
268
+ font-style: italic;
269
+ }
270
+ .math-symbols {
271
+ display: grid;
272
+ grid-template-columns: repeat(8, 1fr);
273
+ gap: 0.5rem;
274
+ padding: 0.5rem;
275
+ background: #f5f5f5;
276
+ border-radius: 4px;
277
+ }
278
+ .math-symbol-btn {
279
+ padding: 0.5rem;
280
+ border: 1px solid #ddd;
281
+ background: white;
282
+ border-radius: 4px;
283
+ cursor: pointer;
284
+ font-size: 18px;
285
+ transition: all 0.2s;
286
+ }
287
+ .math-symbol-btn:hover {
288
+ background: #e3f2fd;
289
+ border-color: #2196f3;
290
+ }
291
+ .math-display-select {
292
+ padding: 0.5rem;
293
+ border: 1px solid #ddd;
294
+ border-radius: 4px;
295
+ font-size: 14px;
296
+ }
297
+ </style>
298
+
299
+ <div class="math-form-group">
300
+ <label for="math-latex">LaTeX Expression:</label>
301
+ <textarea
302
+ id="math-latex"
303
+ class="math-latex-input"
304
+ placeholder="Enter LaTeX (e.g., x^2 + y^2 = r^2)"
305
+ ></textarea>
306
+ </div>
307
+
308
+ <div class="math-form-group">
309
+ <label>Common Symbols:</label>
310
+ <div class="math-symbols">
311
+ <button class="math-symbol-btn" data-symbol="\\frac{a}{b}" title="Fraction">a/b</button>
312
+ <button class="math-symbol-btn" data-symbol="x^{2}" title="Superscript">x²</button>
313
+ <button class="math-symbol-btn" data-symbol="x_{i}" title="Subscript">xᵢ</button>
314
+ <button class="math-symbol-btn" data-symbol="\\sqrt{x}" title="Square root">√x</button>
315
+ <button class="math-symbol-btn" data-symbol="\\sum" title="Sum">∑</button>
316
+ <button class="math-symbol-btn" data-symbol="\\int" title="Integral">∫</button>
317
+ <button class="math-symbol-btn" data-symbol="\\pi" title="Pi">π</button>
318
+ <button class="math-symbol-btn" data-symbol="\\alpha" title="Alpha">α</button>
319
+ <button class="math-symbol-btn" data-symbol="\\beta" title="Beta">β</button>
320
+ <button class="math-symbol-btn" data-symbol="\\gamma" title="Gamma">γ</button>
321
+ <button class="math-symbol-btn" data-symbol="\\theta" title="Theta">θ</button>
322
+ <button class="math-symbol-btn" data-symbol="\\lambda" title="Lambda">λ</button>
323
+ <button class="math-symbol-btn" data-symbol="\\infty" title="Infinity">∞</button>
324
+ <button class="math-symbol-btn" data-symbol="\\leq" title="Less or equal">≤</button>
325
+ <button class="math-symbol-btn" data-symbol="\\geq" title="Greater or equal">≥</button>
326
+ <button class="math-symbol-btn" data-symbol="\\neq" title="Not equal">≠</button>
327
+ </div>
328
+ </div>
329
+
330
+ <div class="math-form-group">
331
+ <label for="math-preview">Preview:</label>
332
+ <div id="math-preview" class="math-preview"></div>
333
+ </div>
334
+
335
+ <div class="math-form-group">
336
+ <label for="math-display-type">Display Type:</label>
337
+ <select id="math-display-type" class="math-display-select">
338
+ <option value="inline">Inline (within text)</option>
339
+ <option value="block">Block (centered, new line)</option>
340
+ </select>
341
+ </div>
342
+ `,t.querySelectorAll(".math-symbol-btn").forEach(i=>{i.addEventListener("click",o=>{o.preventDefault();const n=i.getAttribute("data-symbol");if(n&&this.latexInput){const s=this.latexInput.selectionStart,r=this.latexInput.selectionEnd,l=this.latexInput.value;this.latexInput.value=l.substring(0,s)+n+l.substring(r),this.latexInput.focus(),this.latexInput.selectionStart=this.latexInput.selectionEnd=s+n.length,this.updatePreview()}})}),t}updatePreview(){const t=this.latexInput.value.trim();if(!t){this.previewDiv.textContent="";return}let e=t.replace(/\\frac\{([^}]+)\}\{([^}]+)\}/g,"($1)/($2)").replace(/\^\{([^}]+)\}/g,"^$1").replace(/\_\{([^}]+)\}/g,"_$1").replace(/\\sqrt\{([^}]+)\}/g,"√($1)").replace(/\\sum/g,"∑").replace(/\\int/g,"∫").replace(/\\pi/g,"π").replace(/\\alpha/g,"α").replace(/\\beta/g,"β").replace(/\\gamma/g,"γ").replace(/\\theta/g,"θ").replace(/\\lambda/g,"λ").replace(/\\infty/g,"∞").replace(/\\leq/g,"≤").replace(/\\geq/g,"≥").replace(/\\neq/g,"≠");this.previewDiv.textContent=e}handleSubmit(){const t=this.latexInput.value.trim();if(!t){alert("Please enter a LaTeX expression.");return}const e=this.displayTypeSelect.value;this.onSubmit({latex:t,display:e}),this.dialog.close()}show(){this.dialog.show(),this.latexInput.value="",this.previewDiv.textContent="",this.displayTypeSelect.value="inline",setTimeout(()=>this.latexInput.focus(),100)}close(){this.dialog.close()}}class W{constructor(t){this.characters={common:["©","®","™","§","¶","†","‡","•","‣","⁃","◦","▪","▫","◊","○","●","□","■","△","▲","▽","▼","◇","◆","★","☆"],arrows:["←","→","↑","↓","↔","↕","⇐","⇒","⇑","⇓","⇔","⇕","⟵","⟶","⟷","↖","↗","↘","↙","⇖","⇗","⇘","⇙"],currency:["$","€","£","¥","₹","₽","₩","₪","₦","฿","₴","₡","₵","₸","₫","₱","₲","₳","₭"],math:["±","×","÷","=","≠","≈","≡","≤","≥","<",">","∞","∑","∏","∫","∂","√","∛","∜","°","′","″","∠","∟","⊥","∥"],greek:["α","β","γ","δ","ε","ζ","η","θ","ι","κ","λ","μ","ν","ξ","ο","π","ρ","σ","τ","υ","φ","χ","ψ","ω","Α","Β","Γ","Δ","Ε","Ζ","Η","Θ"],punctuation:["‚","„","“","”","‘","’","«","»","‹","›","—","–","…","·","¡","¿","‰","′","″","‴"],superscript:["⁰","¹","²","³","⁴","⁵","⁶","⁷","⁸","⁹","⁺","⁻","⁼","⁽","⁾","ⁿ","ⁱ"],subscript:["₀","₁","₂","₃","₄","₅","₆","₇","₈","₉","₊","₋","₌","₍","₎"]},this.onSelect=t.onSelect;const e=this.createContent();this.dialog=new f({title:"Insert Special Character",content:e,buttons:[{label:"Close",onClick:()=>this.dialog.close()}]}),this.searchInput=e.querySelector("#char-search"),this.categorySelect=e.querySelector("#char-category"),this.charactersGrid=e.querySelector("#char-grid"),this.searchInput.addEventListener("input",()=>this.filterCharacters()),this.categorySelect.addEventListener("change",()=>this.updateGrid()),this.updateGrid()}createContent(){const t=document.createElement("div");return t.className="character-dialog-content",t.style.minWidth="500px",t.innerHTML=`
343
+ <style>
344
+ .character-dialog-content {
345
+ display: flex;
346
+ flex-direction: column;
347
+ gap: 1rem;
348
+ }
349
+ .char-controls {
350
+ display: flex;
351
+ gap: 0.5rem;
352
+ }
353
+ .char-search, .char-category {
354
+ padding: 0.5rem;
355
+ border: 1px solid #ddd;
356
+ border-radius: 4px;
357
+ font-size: 14px;
358
+ }
359
+ .char-search {
360
+ flex: 1;
361
+ }
362
+ .char-category {
363
+ min-width: 150px;
364
+ }
365
+ .char-grid {
366
+ display: grid;
367
+ grid-template-columns: repeat(10, 1fr);
368
+ gap: 0.5rem;
369
+ max-height: 300px;
370
+ overflow-y: auto;
371
+ padding: 1rem;
372
+ background: #f9f9f9;
373
+ border: 1px solid #ddd;
374
+ border-radius: 4px;
375
+ }
376
+ .char-button {
377
+ aspect-ratio: 1;
378
+ display: flex;
379
+ align-items: center;
380
+ justify-content: center;
381
+ padding: 0.5rem;
382
+ border: 1px solid #ddd;
383
+ background: white;
384
+ border-radius: 4px;
385
+ cursor: pointer;
386
+ font-size: 20px;
387
+ transition: all 0.2s;
388
+ }
389
+ .char-button:hover {
390
+ background: #e3f2fd;
391
+ border-color: #2196f3;
392
+ transform: scale(1.1);
393
+ }
394
+ .char-info {
395
+ padding: 0.5rem;
396
+ background: #f5f5f5;
397
+ border-radius: 4px;
398
+ font-size: 12px;
399
+ color: #666;
400
+ text-align: center;
401
+ }
402
+ </style>
403
+
404
+ <div class="char-controls">
405
+ <input
406
+ type="text"
407
+ id="char-search"
408
+ class="char-search"
409
+ placeholder="Search characters..."
410
+ />
411
+ <select id="char-category" class="char-category">
412
+ <option value="all">All Categories</option>
413
+ <option value="common">Common Symbols</option>
414
+ <option value="arrows">Arrows</option>
415
+ <option value="currency">Currency</option>
416
+ <option value="math">Mathematics</option>
417
+ <option value="greek">Greek Letters</option>
418
+ <option value="punctuation">Punctuation</option>
419
+ <option value="superscript">Superscript</option>
420
+ <option value="subscript">Subscript</option>
421
+ </select>
422
+ </div>
423
+
424
+ <div id="char-grid" class="char-grid"></div>
425
+
426
+ <div class="char-info">
427
+ Click any character to insert it into your document.
428
+ </div>
429
+ `,t}updateGrid(){const t=this.categorySelect.value;this.charactersGrid.innerHTML="";let e=[];t==="all"?e=Object.values(this.characters).flat():e=this.characters[t]||[],e.forEach(i=>{const o=document.createElement("button");o.className="char-button",o.textContent=i,o.title=`Insert ${i} (U+${i.charCodeAt(0).toString(16).toUpperCase()})`,o.addEventListener("click",n=>{n.preventDefault(),this.handleSelect(i)}),this.charactersGrid.appendChild(o)})}filterCharacters(){const t=this.searchInput.value.toLowerCase();this.charactersGrid.querySelectorAll(".char-button").forEach(i=>{const o=i.textContent||"",n=`u+${o.charCodeAt(0).toString(16)}`,s=!t||o.includes(t)||n.includes(t);i.style.display=s?"flex":"none"})}handleSelect(t){this.onSelect(t),this.dialog.close()}show(){this.dialog.show(),this.searchInput.value="",this.categorySelect.value="all",this.updateGrid(),setTimeout(()=>this.searchInput.focus(),100)}close(){this.dialog.close()}}class K{constructor(t){this.emojis={popular:["😀","😃","😄","😁","😊","😍","🤩","😘","😗","😚","😙","🙂","🤗","🤔","🤨","😐","😑","😶","🙄","😏","👍","👎","👌","✌️","🤞","🤝","👏","🙌","👋","🤚","✋","🖐️","🖖","👊","✊","🤛","🤜","💪"],smileys:["😀","😃","😄","😁","😆","😅","🤣","😂","🙂","🙃","😉","😊","😇","🥰","😍","🤩","😘","😗","😚","😙","😋","😛","😜","🤪","😝","🤑","🤗","🤭","🤫","🤔"],emotions:["😳","😞","😟","😠","😡","🤬","😔","😕","🙁","😬","🥺","😣","😖","😫","😩","🥱","😤","😮","😱","😨","😰","😥","😢","😭","😪","😓","🤤","😴","😷","🤒"],gestures:["👍","👎","👌","✌️","🤞","🤟","🤘","🤙","👈","👉","👆","👇","☝️","👋","🤚","✋","🖐️","🖖","👏","🙌","👐","🤲","🤝","🙏","✍️","💅","🤳","💪","🦾","🦿"],people:["👶","👧","🧒","👦","👩","🧑","👨","👵","🧓","👴","👲","👳","🧕","👮","👷","💂","🕵️","👩‍⚕️","👨‍⚕️","👩‍🎓","👨‍🎓","👩‍🏫","👨‍🏫","👩‍⚖️","👨‍⚖️","👩‍🌾","👨‍🌾","👩‍🍳","👨‍🍳","👩‍🔧"],animals:["🐶","🐱","🐭","🐹","🐰","🦊","🐻","🐼","🐨","🐯","🦁","🐮","🐷","🐸","🐵","🙈","🙉","🙊","🐔","🐧","🐦","🐤","🐣","🐥","🦆","🦅","🦉","🦇","🐺","🐗"],nature:["🌵","🎄","🌲","🌳","🌴","🌱","🌿","☘️","🍀","🎍","🎋","🍃","🍂","🍁","🍄","🌾","💐","🌷","🌹","🥀","🌺","🌸","🌼","🌻","🌞","🌝","🌛","🌜","⭐","🌟"],food:["🍏","🍎","🍐","🍊","🍋","🍌","🍉","🍇","🍓","🍈","🍒","🍑","🥭","🍍","🥥","🥝","🍅","🍆","🥑","🥦","🥬","🥒","🌶️","🌽","🥕","🧄","🧅","🥔","🍠","🥐"],objects:["⌚","📱","💻","⌨️","🖥️","🖨️","🖱️","🕹️","💾","💿","📀","📷","📹","🎥","📞","☎️","📟","📠","📺","📻","🎙️","🎚️","🎛️","🧭","⏱️","⏰","📡","🔋","🔌","💡"],symbols:["❤️","🧡","💛","💚","💙","💜","🖤","🤍","🤎","💔","❣️","💕","💞","💓","💗","💖","💘","💝","✨","💫","⭐","🌟","✔️","✅","❌","❎","➕","➖","✖️","➗"],activities:["⚽","🏀","🏈","⚾","🥎","🎾","🏐","🏉","🥏","🎱","🪀","🏓","🏸","🏒","🏑","🥍","🏏","🪃","🥅","⛳","🪁","🏹","🎣","🤿","🥊","🥋","🎽","🛹","🛼","🛷"]},this.onSelect=t.onSelect;const e=this.createContent();this.dialog=new f({title:"Insert Emoji",content:e,buttons:[{label:"Close",onClick:()=>this.dialog.close()}]}),this.searchInput=e.querySelector("#emoji-search"),this.categorySelect=e.querySelector("#emoji-category"),this.emojisGrid=e.querySelector("#emoji-grid"),this.searchInput.addEventListener("input",()=>this.filterEmojis()),this.categorySelect.addEventListener("change",()=>this.updateGrid()),this.updateGrid()}createContent(){const t=document.createElement("div");return t.className="emoji-dialog-content",t.style.minWidth="500px",t.innerHTML=`
430
+ <style>
431
+ .emoji-dialog-content {
432
+ display: flex;
433
+ flex-direction: column;
434
+ gap: 1rem;
435
+ }
436
+ .emoji-controls {
437
+ display: flex;
438
+ gap: 0.5rem;
439
+ }
440
+ .emoji-search, .emoji-category {
441
+ padding: 0.5rem;
442
+ border: 1px solid #ddd;
443
+ border-radius: 4px;
444
+ font-size: 14px;
445
+ }
446
+ .emoji-search {
447
+ flex: 1;
448
+ }
449
+ .emoji-category {
450
+ min-width: 150px;
451
+ }
452
+ .emoji-grid {
453
+ display: grid;
454
+ grid-template-columns: repeat(10, 1fr);
455
+ gap: 0.5rem;
456
+ max-height: 350px;
457
+ overflow-y: auto;
458
+ padding: 1rem;
459
+ background: #f9f9f9;
460
+ border: 1px solid #ddd;
461
+ border-radius: 4px;
462
+ }
463
+ .emoji-button {
464
+ aspect-ratio: 1;
465
+ display: flex;
466
+ align-items: center;
467
+ justify-content: center;
468
+ padding: 0.5rem;
469
+ border: 1px solid #ddd;
470
+ background: white;
471
+ border-radius: 4px;
472
+ cursor: pointer;
473
+ font-size: 24px;
474
+ transition: all 0.2s;
475
+ }
476
+ .emoji-button:hover {
477
+ background: #fff3e0;
478
+ border-color: #ff9800;
479
+ transform: scale(1.15);
480
+ }
481
+ .emoji-info {
482
+ padding: 0.5rem;
483
+ background: #f5f5f5;
484
+ border-radius: 4px;
485
+ font-size: 12px;
486
+ color: #666;
487
+ text-align: center;
488
+ }
489
+ </style>
490
+
491
+ <div class="emoji-controls">
492
+ <input
493
+ type="text"
494
+ id="emoji-search"
495
+ class="emoji-search"
496
+ placeholder="Search emojis..."
497
+ />
498
+ <select id="emoji-category" class="emoji-category">
499
+ <option value="all">All Emojis</option>
500
+ <option value="popular">Popular</option>
501
+ <option value="smileys">Smileys & Faces</option>
502
+ <option value="emotions">Emotions</option>
503
+ <option value="gestures">Gestures & Hands</option>
504
+ <option value="people">People</option>
505
+ <option value="animals">Animals</option>
506
+ <option value="nature">Nature</option>
507
+ <option value="food">Food & Drink</option>
508
+ <option value="objects">Objects</option>
509
+ <option value="symbols">Symbols</option>
510
+ <option value="activities">Activities & Sports</option>
511
+ </select>
512
+ </div>
513
+
514
+ <div id="emoji-grid" class="emoji-grid"></div>
515
+
516
+ <div class="emoji-info">
517
+ Click any emoji to insert it into your document.
518
+ </div>
519
+ `,t}updateGrid(){const t=this.categorySelect.value;this.emojisGrid.innerHTML="";let e=[];t==="all"?e=Object.values(this.emojis).flat():e=this.emojis[t]||[],e.forEach(i=>{const o=document.createElement("button");o.className="emoji-button",o.textContent=i,o.title=`Insert ${i}`,o.addEventListener("click",n=>{n.preventDefault(),this.handleSelect(i)}),this.emojisGrid.appendChild(o)})}filterEmojis(){const t=this.searchInput.value.toLowerCase();this.emojisGrid.querySelectorAll(".emoji-button").forEach(i=>{const o=i.textContent||"",n=!t||o.includes(t);i.style.display=n?"flex":"none"})}handleSelect(t){this.onSelect(t),this.dialog.close()}show(){this.dialog.show(),this.searchInput.value="",this.categorySelect.value="popular",this.updateGrid(),setTimeout(()=>this.searchInput.focus(),100)}close(){this.dialog.close()}}const S=class S{static resolve(t){const e={};if(Object.assign(e,this.EDITOR_DEFAULTS),t.pluginDefaults&&Object.assign(e,t.pluginDefaults),t.attributes){const i=this.parseAttributes(t.attributes);Object.assign(e,i)}return t.jsConfig&&Object.assign(e,t.jsConfig),e}static parseAttributes(t){const e={};for(const[i,o]of Object.entries(t)){const n=this.kebabToCamel(i);e[n]=this.parseAttributeValue(o)}return e}static parseAttributeValue(t){if(t==="true")return!0;if(t==="false")return!1;if(/^\d+$/.test(t))return parseInt(t,10);if(/^\d+\.\d+$/.test(t))return parseFloat(t);if(t.startsWith("{")||t.startsWith("["))try{return JSON.parse(t)}catch(e){return t}return t}static kebabToCamel(t){return t.replace(/-([a-z])/g,(e,i)=>i.toUpperCase())}static validate(t){const e=[];return t.height!==void 0&&typeof t.height=="number"&&t.height<0&&e.push("height must be a positive number"),t.width!==void 0&&typeof t.width=="number"&&t.width<0&&e.push("width must be a positive number"),t.plugins!==void 0&&!Array.isArray(t.plugins)&&typeof t.plugins!="string"&&e.push("plugins must be an array or string"),t.theme!==void 0&&typeof t.theme!="string"&&e.push("theme must be a string"),{valid:e.length===0,errors:e}}static getDefaults(){return{...this.EDITOR_DEFAULTS}}static merge(...t){const e={};for(const i of t)for(const[o,n]of Object.entries(i))n!=null&&(typeof n=="object"&&!Array.isArray(n)&&e[o]?e[o]=this.merge(e[o],n):e[o]=n);return e}};S.EDITOR_DEFAULTS={height:400,width:"100%",readonly:!1,disabled:!1,menubar:!0,toolbar:!0,plugins:[],theme:"light",content:"",placeholder:"Start typing...",autofocus:!1,autosave:!1,spellcheck:!1,language:"en"};let w=S;class P{constructor(){this.loadedPlugins=new Map,this.pluginRegistry=new Map}register(t,e){this.pluginRegistry.set(t,e)}load(t,e){if(this.loadedPlugins.has(t))return this.loadedPlugins.get(t);const i=this.pluginRegistry.get(t);if(!i)return console.warn(`Plugin not found: ${t}`),null;const o=i();return e&&this.applyPluginConfig(o,e),this.loadedPlugins.set(t,o),o}loadMultiple(t,e){return t.map(i=>this.load(i,e)).filter(i=>i!==null)}parsePluginString(t,e){const i=t.split(/\s+/).filter(Boolean);return this.loadMultiple(i,e)}applyPluginConfig(t,e){t.__pluginConfig=e}unload(t){this.loadedPlugins.delete(t)}clear(){this.loadedPlugins.clear()}getLoadedPluginNames(){return Array.from(this.loadedPlugins.keys())}getRegisteredPluginNames(){return Array.from(this.pluginRegistry.keys())}isLoaded(t){return this.loadedPlugins.has(t)}}class A{constructor(t={}){this.changeListeners=[],this.options=t,this.engine=new E({content:t.content,plugins:t.plugins||[],readonly:t.readonly}),t.onChange&&this.onChange(t.onChange),this.engine.on("change",()=>{const e=this.getHTML();this.changeListeners.forEach(i=>i(e))})}mount(t,e){this.contentElement=t,this.toolbarElement=e,this.contentElement.contentEditable=this.options.readonly?"false":"true",this.contentElement.className="rte-content",this.options.content&&(this.contentElement.innerHTML=this.options.content),this.options.toolbar!==!1&&this.toolbarElement&&(this.toolbar=new x({items:typeof this.options.toolbar=="string"?this.options.toolbar:void 0},this.options.plugins||[]),this.toolbar.setCommandHandler((i,o)=>{this.execCommand(i,o)}),this.toolbar.render(this.toolbarElement)),this.contentElement.addEventListener("input",()=>{const i=this.getHTML();this.changeListeners.forEach(o=>o(i))}),this.options.onInit&&this.options.onInit(this.getAPI())}getHTML(){var t;return((t=this.contentElement)==null?void 0:t.innerHTML)||""}setHTML(t){this.contentElement&&(this.contentElement.innerHTML=t)}execCommand(t,e){const i=this.engine.execCommand(t,e);return this.toolbar,i}focus(){var t;(t=this.contentElement)==null||t.focus()}blur(){var t;(t=this.contentElement)==null||t.blur()}onChange(t){return this.changeListeners.push(t),()=>{const e=this.changeListeners.indexOf(t);e>-1&&this.changeListeners.splice(e,1)}}registerCommand(t,e){if(typeof window!="undefined"){const i=window.__editorCommands||new Map;i.set(t,e),window.__editorCommands=i}}getState(){return{plugins:this.options.plugins,config:this.options,engine:this.engine.getState()}}getAPI(){var t;return{getHTML:()=>this.getHTML(),setHTML:e=>this.setHTML(e),execCommand:(e,i)=>this.execCommand(e,i),focus:()=>this.focus(),blur:()=>this.blur(),destroy:()=>this.destroy(),registerCommand:(e,i)=>this.registerCommand(e,i),onChange:e=>this.onChange(e),getState:()=>this.getState(),toolbar:{items:((t=this.options.plugins)==null?void 0:t.flatMap(e=>e.toolbar||[]))||[]}}}destroy(){var t;this.engine.destroy(),(t=this.toolbar)==null||t.destroy(),this.changeListeners=[],this.options.onDestroy&&this.options.onDestroy()}}function V(a){return new A(a)}class H{constructor(t){this.options=t,this.containerElement=t.element;const e=this.resolvePlugins(t.plugins);this.engine=new E({content:t.content,plugins:e,readonly:t.readonly}),this.initializeDOM()}resolvePlugins(t){return t?typeof t=="string"?(console.warn("String-based plugin loading not yet implemented for VanillaAdapter"),[]):t:[]}initializeDOM(){this.containerElement.innerHTML="",this.containerElement.classList.add("editora-editor"),this.options.enableToolbar!==!1&&this.options.toolbar!==!1&&(this.toolbarElement=document.createElement("div"),this.toolbarElement.className="editora-toolbar-container",this.containerElement.appendChild(this.toolbarElement),this.toolbar=new x({items:typeof this.options.toolbar=="string"?this.options.toolbar:void 0},this.options.plugins||[]),this.toolbar.setCommandHandler((t,e)=>{this.execCommand(t,e)}),this.toolbar.render(this.toolbarElement)),this.contentElement=document.createElement("div"),this.contentElement.className="editora-content",this.contentElement.contentEditable=this.options.readonly?"false":"true",this.contentElement.style.minHeight="200px",this.contentElement.style.outline="none",this.contentElement.style.padding="12px",this.options.content&&(this.contentElement.innerHTML=this.options.content),this.containerElement.appendChild(this.contentElement),this.contentElement.addEventListener("input",()=>{this.containerElement.dispatchEvent(new CustomEvent("change",{detail:{html:this.getContent()}}))})}getContent(){var t;return((t=this.contentElement)==null?void 0:t.innerHTML)||""}setContent(t){this.contentElement&&(this.contentElement.innerHTML=t)}execCommand(t,e){return this.engine.execCommand(t,e)}focus(){var t;(t=this.contentElement)==null||t.focus()}on(t,e){const i=o=>{e(o.detail)};return this.containerElement.addEventListener(t,i),()=>{this.containerElement.removeEventListener(t,i)}}destroy(){var t;this.engine.destroy(),(t=this.toolbar)==null||t.destroy(),this.containerElement.innerHTML=""}}const _='.editora-editor{display:flex;flex-direction:column;border:1px solid #ddd;border-radius:4px;background:#fff;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,sans-serif;font-size:14px;overflow:hidden}.editora-editor *{box-sizing:border-box}.editora-theme-light{background:#fff;color:#333}.editora-theme-dark{background:#1e1e1e;color:#d4d4d4;border-color:#3c3c3c}.editora-toolbar{display:flex;align-items:center;gap:4px;padding:8px;background:#f5f5f5;border-bottom:1px solid #ddd;flex-wrap:wrap}.editora-theme-dark .editora-toolbar{background:#252526;border-bottom-color:#3c3c3c}.editora-toolbar-sticky{position:sticky;top:0;z-index:100}.editora-toolbar-group{display:flex;align-items:center;gap:2px}.editora-toolbar-button{padding:6px 12px;border:1px solid #ccc;background:#fff;cursor:pointer;border-radius:3px;font-weight:600;font-size:14px;height:30px;display:flex;align-items:center;white-space:nowrap}.editora-toolbar-input.font-size{width:40px;padding:.25rem;text-align:center;font-size:14px;background:#fff;border:1px solid var(--rte-color-border-light);border-radius:var(--rte-radius-sm)}.editora-toolbar-group-items{display:flex;align-items:center;border:1px solid #ccc;.editora-toolbar-button{border:none;border-radius:0;&:first-child{border-right:1px solid #ccc;border-top-left-radius:3px;border-bottom-left-radius:3px}&:last-child{border-left:1px solid #ccc;border-top-right-radius:3px;border-bottom-right-radius:3px}}}.editora-theme-dark .editora-toolbar-button{color:#d4d4d4}.editora-toolbar-button:hover{background:#e0e0e0;border-color:#ccc}.editora-theme-dark .editora-toolbar-button:hover{background:#37373d;border-color:#555}.editora-toolbar-button:active,.editora-toolbar-button.active{background:#d0d0d0;border-color:#999}.editora-theme-dark .editora-toolbar-button:active,.editora-theme-dark .editora-toolbar-button.active{background:#2a2d2e;border-color:#666}.editora-toolbar-button:disabled{opacity:.5;cursor:not-allowed}.editora-toolbar-icon{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;line-height:1}.editora-toolbar-button svg,.editora-toolbar-icon svg{width:24px;height:24px;display:block}.editora-toolbar-separator{width:1px;height:24px;background:#ddd;margin:0 4px}.editora-theme-dark .editora-toolbar-separator{background:#3c3c3c}.editora-toolbar-dropdown{position:relative}.editora-toolbar-dropdown-menu{position:absolute;top:100%;left:0;min-width:150px;margin-top:4px;padding:4px 0;background:#fff;border:1px solid #ddd;border-radius:4px;box-shadow:0 2px 8px #00000026;z-index:1000}.editora-theme-dark .editora-toolbar-dropdown-menu{background:#252526;border-color:#3c3c3c;box-shadow:0 2px 8px #00000080}.editora-toolbar-dropdown-item{display:block;width:100%;padding:8px 12px;border:none;background:transparent;color:#333;text-align:left;cursor:pointer;font-size:13px;transition:background .15s ease}.editora-theme-dark .editora-toolbar-dropdown-item{color:#d4d4d4}.editora-toolbar-dropdown-item:hover{background:#f5f5f5}.editora-theme-dark .editora-toolbar-dropdown-item:hover{background:#37373d}.editora-content{flex:1;min-height:200px;padding:16px;outline:none;overflow-y:auto;line-height:1.6}.editora-content:empty:before{content:attr(data-placeholder);color:#999;pointer-events:none}.editora-theme-dark .editora-content:empty:before{color:#6a6a6a}.editora-content h1{font-size:2em;margin:.67em 0;font-weight:600}.editora-content h2{font-size:1.5em;margin:.75em 0;font-weight:600}.editora-content h3{font-size:1.17em;margin:.83em 0;font-weight:600}.editora-content p{margin:1em 0}.editora-content ul,.editora-content ol{margin:1em 0;padding-left:2em}.editora-content a{color:#06c;text-decoration:underline}.editora-theme-dark .editora-content a{color:#4db8ff}.editora-content code{padding:2px 4px;background:#f5f5f5;border-radius:3px;font-family:Monaco,Menlo,Consolas,monospace;font-size:.9em}.editora-theme-dark .editora-content code{background:#1e1e1e}.editora-content pre{padding:12px;background:#f5f5f5;border-radius:4px;overflow-x:auto;margin:1em 0}.editora-theme-dark .editora-content pre{background:#1e1e1e}.editora-content blockquote{margin:1em 0;padding-left:1em;border-left:4px solid #ddd;color:#666}.editora-theme-dark .editora-content blockquote{border-left-color:#3c3c3c;color:#9a9a9a}.editora-floating-toolbar{position:absolute;padding:4px;background:#fff;border:1px solid #ddd;border-radius:4px;box-shadow:0 2px 8px #00000026;z-index:1000}.editora-theme-dark .editora-floating-toolbar{background:#252526;border-color:#3c3c3c;box-shadow:0 2px 8px #00000080}.editora-statusbar{display:flex;align-items:center;gap:12px;padding:6px 12px;background:#f5f5f5;border-top:1px solid #ddd;font-size:12px;color:#666}.editora-theme-dark .editora-statusbar{background:#252526;border-top-color:#3c3c3c;color:#9a9a9a}.editora-statusbar-item{white-space:nowrap}.editora-statusbar-separator{color:#ddd}.editora-theme-dark .editora-statusbar-separator{color:#3c3c3c}.editora-editor[readonly] .editora-content{background:#fafafa;cursor:not-allowed}.editora-theme-dark.editora-editor[readonly] .editora-content{background:#1a1a1a}.editora-editor:focus-within{border-color:#06c;box-shadow:0 0 0 3px #0066cc1a}.editora-theme-dark.editora-editor:focus-within{border-color:#4db8ff;box-shadow:0 0 0 3px #4db8ff1a}.editora-editor[disabled]{opacity:.6;pointer-events:none}@media(max-width:768px){.editora-toolbar{padding:4px}.editora-toolbar-button{min-width:28px;min-height:28px;padding:4px 8px;font-size:12px}.editora-content{padding:12px}}.editora-content ::selection{background:#06c3}.editora-theme-dark .editora-content ::selection{background:#4db8ff33}.editora-content table{border-collapse:collapse;width:100%;margin:1em 0}.editora-content th,.editora-content td{border:1px solid #ddd;padding:8px 12px;text-align:left}.editora-theme-dark .editora-content th,.editora-theme-dark .editora-content td{border-color:#3c3c3c}.editora-content th{background:#f5f5f5;font-weight:600}.editora-theme-dark .editora-content th{background:#252526}.editora-content img{max-width:100%;height:auto;border-radius:4px}.editora-editor.loading{opacity:.7;pointer-events:none}.editora-editor.loading:after{content:"";position:absolute;top:50%;left:50%;width:24px;height:24px;margin:-12px 0 0 -12px;border:3px solid #ddd;border-top-color:#06c;border-radius:50%;animation:editora-spin .8s linear infinite}@keyframes editora-spin{to{transform:rotate(360deg)}}';let C;function X(){const a="editora-webcomponent-styles";if(!document.getElementById(a)){const t=document.createElement("style");t.id=a,t.textContent=_,document.head.appendChild(t)}}function J(){if(!C){const a=k.__globalPluginLoader;a?C=a:C=new P}return C}class k extends HTMLElement{constructor(){if(super(),this.config={},this.isInitialized=!1,this.pluginLoader=J(),X(),!this.hasAttribute("data-initial-content")){const t=this.innerHTML.trim();t&&this.setAttribute("data-initial-content",t)}}static get observedAttributes(){return["height","width","menubar","plugins","toolbar","toolbar-items","readonly","disabled","theme","placeholder","autofocus","language","spellcheck"]}connectedCallback(){this.config=this.resolveConfig(),setTimeout(()=>{this.initialize()},0)}disconnectedCallback(){this.destroy()}attributeChangedCallback(t,e,i){e!==i&&(this.config=this.resolveConfig(),this.handleAttributeChange(t,i))}setConfig(t){this.jsConfig=t,this.config=this.resolveConfig(),this.isConnected&&(this.destroy(),this.initialize())}initialize(){if(this.querySelector(".editora-toolbar")||this.isInitialized)return;this.setAttribute("data-editora-editor","true"),this.config.height&&(this.style.height=typeof this.config.height=="number"?`${this.config.height}px`:this.config.height),this.config.width&&(this.style.width=typeof this.config.width=="number"?`${this.config.width}px`:this.config.width),this.classList.add("editora-editor"),this.config.theme&&this.classList.add(`editora-theme-${this.config.theme}`);const t=this.loadPlugins();t.forEach(i=>{if(i.init&&typeof i.init=="function")try{i.init()}catch(o){console.error(`[RichTextEditor] Error initializing plugin ${i.name}:`,o)}});const e=this.getAttribute("data-initial-content")||"";this.engine=new E({content:e,plugins:t,readonly:this.config.readonly}),this.createUI(t,e),this.setupEventListeners(),this.isInitialized=!0,this.dispatchEvent(new CustomEvent("editor-ready",{detail:{api:this.getAPI()},bubbles:!0}))}getInitialContent(){if(this.config.content)return this.config.content;const t=this.querySelector("[slot]");return t?t.innerHTML:this.hasChildNodes()?Array.from(this.childNodes).map(i=>i.nodeType===Node.TEXT_NODE?i.textContent:i.nodeType===Node.ELEMENT_NODE?i.outerHTML:"").join("").trim():""}loadPlugins(){const t=[];if(this.config.plugins&&(typeof this.config.plugins=="string"&&this.config.plugins.length>0||Array.isArray(this.config.plugins)&&this.config.plugins.length>0))if(typeof this.config.plugins=="string"){const i=this.pluginLoader.parsePluginString(this.config.plugins);t.push(...i)}else Array.isArray(this.config.plugins)&&this.config.plugins.forEach(i=>{if(typeof i=="string"){const o=this.pluginLoader.load(i);o&&t.push(o)}else t.push(i)});else{const i=this.pluginLoader.getRegisteredPluginNames(),o=this.pluginLoader.loadMultiple(i);t.push(...o)}return t}createUI(t,e){const i=this.querySelector('[slot="toolbar"]'),o=this.querySelector('[slot="statusbar"]');if(this.innerHTML="",this.config.toolbar!==!1&&!i){this.toolbarElement=document.createElement("div"),this.toolbarElement.className="editora-toolbar-container",this.appendChild(this.toolbarElement);const n=this.config.toolbarItems||this.config.toolbar;this.toolbar=new x({items:typeof n=="string"?n:void 0,sticky:this.config.toolbar&&typeof this.config.toolbar=="object"?this.config.toolbar.sticky:!1,position:"top"},t,this.pluginLoader),this.toolbar.setCommandHandler((s,r)=>{var p,u;if(this.contentElement){this.contentElement.focus();const m=window.getSelection();if(!m||m.rangeCount===0||!this.contentElement.contains(m.anchorNode)){const d=document.createRange(),h=this.contentElement.lastChild||this.contentElement;h.nodeType===Node.TEXT_NODE?d.setStart(h,((p=h.textContent)==null?void 0:p.length)||0):h.nodeType===Node.ELEMENT_NODE?(d.selectNodeContents(h),d.collapse(!1)):d.setStart(this.contentElement,0),d.collapse(!0),m==null||m.removeAllRanges(),m==null||m.addRange(d)}}const l=t.find(m=>m.commands&&m.commands[s]);if(l&&l.commands){const m=l.commands[s];if(typeof m=="function")try{return m(s==="toggleFullscreen"?this:r)}catch(d){return console.error(`[RichTextEditor] Error executing native command ${s}:`,d),!1}}return((u=this.engine)==null?void 0:u.execCommand(s,r))||!1}),this.toolbar.render(this.toolbarElement)}else i&&this.appendChild(i);this.contentElement=document.createElement("div"),this.contentElement.className="editora-content rte-content",this.contentElement.contentEditable=this.config.readonly?"false":"true",this.contentElement.setAttribute("role","textbox"),this.contentElement.setAttribute("aria-multiline","true"),this.config.placeholder&&this.contentElement.setAttribute("data-placeholder",this.config.placeholder);try{document.execCommand("defaultParagraphSeparator",!1,"p")}catch(n){console.warn("defaultParagraphSeparator not supported:",n)}if(e){const n=document.createElement("div");n.innerHTML=e.trim(),!Array.from(n.childNodes).some(r=>{if(r.nodeType===Node.ELEMENT_NODE){const l=r.tagName;return["P","DIV","H1","H2","H3","H4","H5","H6","UL","OL","BLOCKQUOTE","PRE"].includes(l)}return!1})&&e.trim()?this.contentElement.innerHTML=`<p>${e.trim()}</p>`:this.contentElement.innerHTML=e}else this.config.placeholder?this.contentElement.innerHTML="":this.contentElement.innerHTML="<p><br></p>";this.appendChild(this.contentElement),this.config.toolbar&&typeof this.config.toolbar=="object"&&this.config.toolbar.floating&&(this.floatingToolbar=new I({enabled:!0}),this.floatingToolbar.create(this)),o?this.appendChild(o):this.config.statusbar&&(this.statusBarElement=document.createElement("div"),this.statusBarElement.className="editora-statusbar-container",this.appendChild(this.statusBarElement),this.statusBar=new D({position:"bottom"}),this.statusBar.create(this.statusBarElement)),this.config.autofocus&&setTimeout(()=>{var n;return(n=this.contentElement)==null?void 0:n.focus()},0)}setupEventListeners(){!this.contentElement||!this.engine||(this.contentElement.addEventListener("input",()=>{const t=this.contentElement.innerHTML;if(this.dispatchEvent(new CustomEvent("content-change",{detail:{html:t},bubbles:!0})),this.statusBar){const e=this.contentElement.textContent||"",i=e.trim().split(/\s+/).filter(Boolean).length,o=e.length;this.statusBar.update({wordCount:i,charCount:o})}}),this.contentElement.addEventListener("focus",()=>{this.dispatchEvent(new Event("editor-focus",{bubbles:!0}))}),this.contentElement.addEventListener("blur",()=>{this.dispatchEvent(new Event("editor-blur",{bubbles:!0}))}),this.floatingToolbar&&document.addEventListener("selectionchange",()=>{this.updateFloatingToolbar()}))}updateFloatingToolbar(){if(!this.floatingToolbar)return;const t=window.getSelection();if(!t||t.rangeCount===0){this.floatingToolbar.hide();return}const e=t.getRangeAt(0);if(e.collapsed){this.floatingToolbar.hide();return}const i=e.getBoundingClientRect();this.floatingToolbar.show(i.left,i.top-40)}handleAttributeChange(t,e){switch(t){case"readonly":this.contentElement&&(this.contentElement.contentEditable=e==="true"?"false":"true"),this.engine&&this.engine.setReadonly(e==="true");break;case"theme":this.classList.forEach(i=>{i.startsWith("editora-theme-")&&this.classList.remove(i)}),e&&this.classList.add(`editora-theme-${e}`);break;case"placeholder":this.contentElement&&this.contentElement.setAttribute("data-placeholder",e);break;case"toolbar":case"plugins":this.isConnected&&(this.destroy(),this.initialize());break}}resolveConfig(){const t={};for(let e=0;e<this.attributes.length;e++){const i=this.attributes[e];t[i.name]=i.value}return w.resolve({jsConfig:this.jsConfig,attributes:t})}getAPI(){return{getContent:()=>{var t;return((t=this.contentElement)==null?void 0:t.innerHTML)||""},setContent:t=>{this.contentElement&&(this.contentElement.innerHTML=t)},execCommand:(t,e)=>{var i;return((i=this.engine)==null?void 0:i.execCommand(t,e))||!1},focus:()=>{var t;(t=this.contentElement)==null||t.focus()},blur:()=>{var t;(t=this.contentElement)==null||t.blur()},destroy:()=>{this.destroy()},on:(t,e)=>(this.addEventListener(t,e),()=>this.removeEventListener(t,e)),getConfig:()=>({...this.config}),setReadonly:t=>{this.setAttribute("readonly",t.toString())}}}destroy(){var t,e,i,o;(t=this.engine)==null||t.destroy(),(e=this.toolbar)==null||e.destroy(),(i=this.floatingToolbar)==null||i.destroy(),(o=this.statusBar)==null||o.destroy(),this.innerHTML="",this.isInitialized=!1,this.dispatchEvent(new Event("editor-destroy",{bubbles:!0}))}getContent(){var t;return((t=this.contentElement)==null?void 0:t.innerHTML)||""}setContent(t){this.contentElement&&(this.contentElement.innerHTML=t)}execCommand(t,e){var i;return((i=this.engine)==null?void 0:i.execCommand(t,e))||!1}focus(){var t;(t=this.contentElement)==null||t.focus()}blur(){var t;(t=this.contentElement)==null||t.blur()}}function Y(a){return new H(a)}function Q(){typeof window!="undefined"&&!customElements.get("editora-editor")&&customElements.define("editora-editor",k)}return c.CharacterDialog=W,c.ColorPicker=q,c.CommandRegistry=T,c.ConfigResolver=w,c.Dialog=f,c.DocumentModel=y,c.Dropdown=z,c.Editor=F,c.EditorEngine=E,c.EditorState=b,c.EmojiDialog=K,c.FloatingToolbar=I,c.ImageDialog=U,c.KeyboardShortcutManager=$,c.LinkDialog=B,c.MathDialog=G,c.PluginLoader=P,c.PluginManager=v,c.PluginRuntime=M,c.ReactAdapter=A,c.RichTextEditorElement=k,c.Schema=L,c.StatusBar=D,c.TableDialog=O,c.ToolbarRenderer=x,c.VanillaAdapter=H,c.createEditor=Y,c.createMediaPlugin=R,c.createPluginRuntime=j,c.createReactAdapter=V,c.createSpellcheckPlugin=N,c.initWebComponent=Q,Object.defineProperty(c,Symbol.toStringTag,{value:"Module"}),c})({});
520
+ //# sourceMappingURL=editora.min.js.map