@editora/core 1.0.0 → 1.0.2

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.
Files changed (119) hide show
  1. package/README.md +9 -0
  2. package/dist/A11yCheckerPlugin.native-CZKpi3uF.mjs +475 -0
  3. package/dist/A11yCheckerPlugin.native-CZKpi3uF.mjs.map +1 -0
  4. package/dist/AnchorPlugin.native-7es9PVZ9.mjs +340 -0
  5. package/dist/AnchorPlugin.native-7es9PVZ9.mjs.map +1 -0
  6. package/dist/BackgroundColorPlugin.native-Dip5uqTg.mjs +449 -0
  7. package/dist/BackgroundColorPlugin.native-Dip5uqTg.mjs.map +1 -0
  8. package/dist/BlockquotePlugin.native-JFmOLsxN.mjs +48 -0
  9. package/dist/BlockquotePlugin.native-JFmOLsxN.mjs.map +1 -0
  10. package/dist/BoldPlugin.native-BAzzoqU5.mjs +45 -0
  11. package/dist/BoldPlugin.native-BAzzoqU5.mjs.map +1 -0
  12. package/dist/CapitalizationPlugin.native-DOMsh5R7.mjs +79 -0
  13. package/dist/CapitalizationPlugin.native-DOMsh5R7.mjs.map +1 -0
  14. package/dist/ChecklistPlugin.native-Dccs3nLe.mjs +153 -0
  15. package/dist/ChecklistPlugin.native-Dccs3nLe.mjs.map +1 -0
  16. package/dist/ClearFormattingPlugin.native-BZPDHswo.mjs +27 -0
  17. package/dist/ClearFormattingPlugin.native-BZPDHswo.mjs.map +1 -0
  18. package/dist/CodePlugin.native-DD9xFIid.mjs +1679 -0
  19. package/dist/CodePlugin.native-DD9xFIid.mjs.map +1 -0
  20. package/dist/CodeSamplePlugin.native-DMbEdO9j.mjs +326 -0
  21. package/dist/CodeSamplePlugin.native-DMbEdO9j.mjs.map +1 -0
  22. package/dist/CommentsPlugin.native-2zQV8Ia4.mjs +473 -0
  23. package/dist/CommentsPlugin.native-2zQV8Ia4.mjs.map +1 -0
  24. package/dist/DirectionPlugin.native-Be7wCzkI.mjs +59 -0
  25. package/dist/DirectionPlugin.native-Be7wCzkI.mjs.map +1 -0
  26. package/dist/DocumentManagerPlugin.native-BvZL5CSG.mjs +116 -0
  27. package/dist/DocumentManagerPlugin.native-BvZL5CSG.mjs.map +1 -0
  28. package/dist/EmbedIframePlugin.native-ifr9KLdN.mjs +461 -0
  29. package/dist/EmbedIframePlugin.native-ifr9KLdN.mjs.map +1 -0
  30. package/dist/EmojisPlugin.native-D6mJSnSR.mjs +1033 -0
  31. package/dist/EmojisPlugin.native-D6mJSnSR.mjs.map +1 -0
  32. package/dist/FontFamilyPlugin.native-BzS_9qbM.mjs +106 -0
  33. package/dist/FontFamilyPlugin.native-BzS_9qbM.mjs.map +1 -0
  34. package/dist/FontSizePlugin.native-DkLMLPue.mjs +186 -0
  35. package/dist/FontSizePlugin.native-DkLMLPue.mjs.map +1 -0
  36. package/dist/FootnotePlugin.native-BciVc9W6.mjs +128 -0
  37. package/dist/FootnotePlugin.native-BciVc9W6.mjs.map +1 -0
  38. package/dist/FullscreenPlugin.native-ChXyxeNw.mjs +77 -0
  39. package/dist/FullscreenPlugin.native-ChXyxeNw.mjs.map +1 -0
  40. package/dist/HeadingPlugin.native-DrLYwQnQ.mjs +64 -0
  41. package/dist/HeadingPlugin.native-DrLYwQnQ.mjs.map +1 -0
  42. package/dist/HistoryPlugin.native-DoDRifCf.mjs +89 -0
  43. package/dist/HistoryPlugin.native-DoDRifCf.mjs.map +1 -0
  44. package/dist/IndentPlugin.native-CbFugPoi.mjs +133 -0
  45. package/dist/IndentPlugin.native-CbFugPoi.mjs.map +1 -0
  46. package/dist/ItalicPlugin.native-CQjjDyUL.mjs +43 -0
  47. package/dist/ItalicPlugin.native-CQjjDyUL.mjs.map +1 -0
  48. package/dist/LineHeightPlugin.native-CWQT2FIa.mjs +73 -0
  49. package/dist/LineHeightPlugin.native-CWQT2FIa.mjs.map +1 -0
  50. package/dist/LinkPlugin.native-BdAOV-iu.mjs +206 -0
  51. package/dist/LinkPlugin.native-BdAOV-iu.mjs.map +1 -0
  52. package/dist/ListPlugin.native-CLFU5AUQ.mjs +59 -0
  53. package/dist/ListPlugin.native-CLFU5AUQ.mjs.map +1 -0
  54. package/dist/MathPlugin.native-DE_ii-LA.mjs +182 -0
  55. package/dist/MathPlugin.native-DE_ii-LA.mjs.map +1 -0
  56. package/dist/MediaManagerPlugin.native-DaYFDzNM.mjs +533 -0
  57. package/dist/MediaManagerPlugin.native-DaYFDzNM.mjs.map +1 -0
  58. package/dist/MergeTagPlugin.native-CrxyThyn.mjs +178 -0
  59. package/dist/MergeTagPlugin.native-CrxyThyn.mjs.map +1 -0
  60. package/dist/PageBreakPlugin.native-DDjcDyRW.mjs +172 -0
  61. package/dist/PageBreakPlugin.native-DDjcDyRW.mjs.map +1 -0
  62. package/dist/PreviewPlugin.native-DBvfpmIv.mjs +322 -0
  63. package/dist/PreviewPlugin.native-DBvfpmIv.mjs.map +1 -0
  64. package/dist/PrintPlugin.native-BUpm52VJ.mjs +311 -0
  65. package/dist/PrintPlugin.native-BUpm52VJ.mjs.map +1 -0
  66. package/dist/SpecialCharactersPlugin.native-x7a2SWXc.mjs +731 -0
  67. package/dist/SpecialCharactersPlugin.native-x7a2SWXc.mjs.map +1 -0
  68. package/dist/SpellCheckPlugin.native-B7yTh0iE.mjs +465 -0
  69. package/dist/SpellCheckPlugin.native-B7yTh0iE.mjs.map +1 -0
  70. package/dist/StrikethroughPlugin.native-ChaZLaXw.mjs +43 -0
  71. package/dist/StrikethroughPlugin.native-ChaZLaXw.mjs.map +1 -0
  72. package/dist/TablePlugin.native-EEWXn1-s.mjs +491 -0
  73. package/dist/TablePlugin.native-EEWXn1-s.mjs.map +1 -0
  74. package/dist/TemplatePlugin.native-BlSn1c9h.mjs +564 -0
  75. package/dist/TemplatePlugin.native-BlSn1c9h.mjs.map +1 -0
  76. package/dist/TextAlignmentPlugin.native-CQIs1m7R.mjs +97 -0
  77. package/dist/TextAlignmentPlugin.native-CQIs1m7R.mjs.map +1 -0
  78. package/dist/TextColorPlugin.native-D6SmTglm.mjs +432 -0
  79. package/dist/TextColorPlugin.native-D6SmTglm.mjs.map +1 -0
  80. package/dist/UnderlinePlugin.native-QpIcK4L2.mjs +35 -0
  81. package/dist/UnderlinePlugin.native-QpIcK4L2.mjs.map +1 -0
  82. package/dist/core.css +1 -0
  83. package/dist/documentManager-irzj9n3V.mjs +37627 -0
  84. package/dist/documentManager-irzj9n3V.mjs.map +1 -0
  85. package/dist/editorContainerHelpers-C7kdWnS0.mjs +27 -0
  86. package/dist/editorContainerHelpers-C7kdWnS0.mjs.map +1 -0
  87. package/dist/editora.min.js +519 -4
  88. package/dist/editora.min.js.map +1 -0
  89. package/dist/editora.umd.js +519 -4
  90. package/dist/editora.umd.js.map +1 -0
  91. package/dist/index-BF5RBhL9.js +4 -0
  92. package/dist/index-BF5RBhL9.js.map +1 -0
  93. package/dist/index-BPsf460l.mjs +1243 -0
  94. package/dist/index-BPsf460l.mjs.map +1 -0
  95. package/dist/index.cjs.js +517 -4
  96. package/dist/index.cjs.js.map +1 -0
  97. package/dist/index.es-CuicffkQ.mjs +6665 -0
  98. package/dist/index.es-CuicffkQ.mjs.map +1 -0
  99. package/dist/index.esm.js +1403 -122
  100. package/dist/index.esm.js.map +1 -0
  101. package/dist/plugin-loader.js +55 -0
  102. package/dist/plugin-loader.js.map +1 -0
  103. package/dist/purify.es-CKpwg8Tk.mjs +471 -0
  104. package/dist/purify.es-CKpwg8Tk.mjs.map +1 -0
  105. package/dist/webcomponent-core.js +1243 -0
  106. package/dist/webcomponent-core.js.map +1 -0
  107. package/dist/webcomponent-core.min.css +1 -0
  108. package/dist/webcomponent-core.min.js +597 -0
  109. package/dist/webcomponent-core.min.js.map +1 -0
  110. package/dist/webcomponent.cjs.js +2 -0
  111. package/dist/webcomponent.cjs.js.map +1 -0
  112. package/dist/webcomponent.esm.js +6 -0
  113. package/dist/webcomponent.esm.js.map +1 -0
  114. package/dist/webcomponent.js +1286 -0
  115. package/dist/webcomponent.js.map +1 -0
  116. package/dist/webcomponent.min.css +1 -0
  117. package/dist/webcomponent.min.js +4076 -0
  118. package/dist/webcomponent.min.js.map +1 -0
  119. package/package.json +64 -6
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs.js","sources":["../src/Editor.ts","../src/plugins/PluginRuntime.ts","../src/KeyboardShortcuts.ts","../src/plugins/enterprise/SpellcheckPlugin.ts","../src/plugins/enterprise/MediaPlugin.ts","../src/core/DocumentModel.ts","../src/ui/Dialog.ts","../src/ui/Dropdown.ts","../src/ui/ColorPicker.ts","../src/ui/dialogs/LinkDialog.ts","../src/ui/dialogs/TableDialog.ts","../src/ui/dialogs/ImageDialog.ts","../src/ui/dialogs/MathDialog.ts","../src/ui/dialogs/CharacterDialog.ts","../src/ui/dialogs/EmojiDialog.ts","../src/adapters/ReactAdapter.ts","../src/adapters/VanillaAdapter.ts","../src/index.ts"],"sourcesContent":["import { EditorState } from './EditorState';\nimport { PluginManager } from './plugins/Plugin';\nimport { Node } from './schema/Node';\n\nexport interface EditorOptions {\n element?: HTMLElement;\n toolbarElement?: HTMLElement;\n content?: string;\n plugins?: any[];\n shortcuts?: boolean;\n enableToolbar?: boolean;\n [key: string]: any;\n}\n\nexport class Editor {\n state: EditorState;\n pluginManager: PluginManager;\n commands: Record<string, (state: EditorState) => EditorState | null>;\n listeners: Array<(state: EditorState) => void> = [];\n domElement?: HTMLElement;\n toolbarElement?: HTMLElement;\n contentElement?: HTMLElement;\n\n constructor(pluginManagerOrOptions: PluginManager | EditorOptions) {\n // Support both constructor patterns\n if (pluginManagerOrOptions instanceof PluginManager) {\n // Traditional: constructor(pluginManager)\n this.pluginManager = pluginManagerOrOptions;\n } else {\n // New: constructor(options: { element, content, plugins, ... })\n const options = pluginManagerOrOptions as EditorOptions;\n \n // Create PluginManager with provided plugins\n this.pluginManager = new PluginManager();\n if (options.plugins && Array.isArray(options.plugins)) {\n options.plugins.forEach(plugin => {\n this.pluginManager.register(plugin);\n });\n }\n \n // Store DOM element for rendering\n if (options.element) {\n this.domElement = options.element;\n this.setupDOMElement(options);\n }\n }\n \n const schema = this.pluginManager.buildSchema();\n this.state = EditorState.create(schema);\n this.commands = this.pluginManager.getCommands();\n }\n\n private setupDOMElement(options: EditorOptions): void {\n if (!this.domElement) return;\n \n // Setup toolbar if enabled and element provided\n if (options.enableToolbar !== false && options.toolbarElement) {\n this.toolbarElement = options.toolbarElement;\n } else if (options.enableToolbar !== false) {\n // Auto-create toolbar element above content\n this.toolbarElement = document.createElement('div');\n this.toolbarElement.className = 'editora-toolbar-container';\n this.domElement.appendChild(this.toolbarElement);\n }\n \n // Create editor content area\n this.contentElement = document.createElement('div');\n this.contentElement.contentEditable = 'true';\n this.contentElement.className = 'editora-content';\n this.contentElement.style.minHeight = '200px';\n this.contentElement.style.outline = 'none';\n this.contentElement.style.padding = '12px';\n \n // Set initial content if provided\n if (options.content) {\n this.contentElement.innerHTML = options.content;\n }\n \n // Append to element\n this.domElement.appendChild(this.contentElement);\n \n // Setup input listener\n this.contentElement.addEventListener('input', () => {\n this.listeners.forEach(fn => fn(this.state));\n });\n }\n\n private setupKeyboardShortcuts(toolbarButtons: any[]): void {\n const shortcutMap: Record<string, string> = {};\n \n toolbarButtons.forEach(button => {\n if (button.shortcut) {\n shortcutMap[button.shortcut.toLowerCase()] = button.command;\n }\n });\n\n document.addEventListener('keydown', (event: KeyboardEvent) => {\n // Skip if input is focused unless it's contentEditable\n if (this.contentElement !== document.activeElement && \n !(document.activeElement instanceof HTMLElement && \n (document.activeElement as HTMLElement).contentEditable === 'true')) {\n return;\n }\n\n const parts: string[] = [];\n if (event.ctrlKey || event.metaKey) parts.push('ctrl');\n if (event.shiftKey) parts.push('shift');\n if (event.altKey) parts.push('alt');\n \n const key = event.key.toLowerCase();\n const shortcut = parts.length > 0 ? `${parts.join('+')}+${key}` : key;\n const command = shortcutMap[shortcut];\n\n if (command) {\n event.preventDefault();\n this.execCommand(command);\n }\n });\n }\n\n private handleToolbarCommand(commandId: string, value?: any): void {\n // Find the actual command name (in case id differs from command)\n const toolbarItems = this.pluginManager.getToolbarItems();\n const item = toolbarItems.find(btn => (btn.id && btn.id === commandId) || btn.command === commandId);\n \n if (item) {\n if (value !== undefined) {\n // For commands with values (dropdowns, inputs)\n this.execCommand(item.command, value);\n } else {\n this.execCommand(item.command);\n }\n }\n }\n\n\n setState(state: EditorState): void {\n this.state = state;\n this.listeners.forEach(fn => fn(state));\n }\n\n onChange(fn: (state: EditorState) => void): () => void {\n this.listeners.push(fn);\n return () => {\n this.listeners = this.listeners.filter(l => l !== fn);\n };\n }\n\n // Alias for onChange to support both patterns\n on(event: string, fn: (state: EditorState | string) => void): () => void {\n if (event === 'change' || event === 'input') {\n return this.onChange(fn as (state: EditorState) => void);\n }\n return () => {};\n }\n\n getElement(): HTMLElement | null {\n return this.contentElement || this.domElement || null;\n }\n\n execCommand(name: string, value?: any): boolean {\n const command = this.commands[name];\n if (!command) {\n console.warn(`Command not found: ${name}`);\n return false;\n }\n \n let newState: EditorState | null;\n \n // Pass value to command if provided\n if (value !== undefined) {\n // For commands that accept values\n newState = (command as any)(this.state, value);\n } else {\n newState = command(this.state);\n }\n \n if (newState) {\n this.setState(newState);\n return true;\n }\n return false;\n }\n\n setContent(doc: Node | string): void {\n if (typeof doc === 'string') {\n // HTML string provided\n if (this.contentElement) {\n this.contentElement.innerHTML = doc;\n }\n } else {\n // Node object provided\n this.setState(this.state.apply(doc));\n }\n }\n\n getContent(): Node | string {\n if (this.contentElement) {\n return this.contentElement.innerHTML;\n }\n return this.state.doc;\n }\n\n destroy(): void {\n // Cleanup listeners\n this.listeners = [];\n\n // Cleanup DOM\n if (this.contentElement) {\n this.contentElement.removeEventListener('input', () => {});\n }\n }\n}\n","/**\n * Plugin Runtime - Safe plugin lifecycle execution\n * Ensures plugin failures don't crash the editor\n */\n\nimport { Plugin, PluginContext } from './Plugin';\n\n/**\n * Runtime context passed to plugins\n */\nexport interface PluginRuntimeContext extends PluginContext {\n config?: Record<string, unknown>;\n editorId?: string;\n}\n\n/**\n * Plugin runtime wrapper\n * Provides isolation and safe execution\n */\nexport class PluginRuntime {\n private plugin: Plugin;\n private initialized = false;\n private context?: PluginRuntimeContext;\n\n constructor(plugin: Plugin) {\n this.plugin = plugin;\n }\n\n /**\n * Safe initialization\n */\n initialize(context: PluginRuntimeContext): boolean {\n if (this.initialized) {\n console.warn(`Plugin \"${this.plugin.name}\" already initialized`);\n return false;\n }\n\n try {\n this.context = context;\n \n // Call plugin-specific initialization if exists\n if (this.plugin.context?.initialize) {\n this.plugin.context.initialize();\n }\n \n // Call onEditorReady if provided\n if (this.plugin.context?.onEditorReady && context.provider) {\n // Editor ready hook - safe to call\n this.plugin.context.onEditorReady(context);\n }\n\n this.initialized = true;\n return true;\n } catch (error) {\n console.error(`Failed to initialize plugin \"${this.plugin.name}\":`, error);\n return false;\n }\n }\n\n /**\n * Safe destruction\n */\n destroy(): boolean {\n if (!this.initialized) {\n return false;\n }\n\n try {\n // Call plugin-specific destruction if exists\n if (this.plugin.context?.destroy) {\n this.plugin.context.destroy();\n }\n\n this.initialized = false;\n this.context = undefined;\n return true;\n } catch (error) {\n console.error(`Failed to destroy plugin \"${this.plugin.name}\":`, error);\n return false;\n }\n }\n\n /**\n * Safe command execution\n */\n executeCommand(command: string, ...args: any[]): any {\n if (!this.initialized) {\n console.warn(`Plugin \"${this.plugin.name}\" not initialized, cannot execute command \"${command}\"`);\n return null;\n }\n\n try {\n const commandFn = this.plugin.commands?.[command];\n if (!commandFn) {\n console.warn(`Command \"${command}\" not found in plugin \"${this.plugin.name}\"`);\n return null;\n }\n\n return (commandFn as any)(...args);\n } catch (error) {\n console.error(`Error executing command \"${command}\" in plugin \"${this.plugin.name}\":`, error);\n return null;\n }\n }\n\n /**\n * Get plugin name\n */\n getName(): string {\n return this.plugin.name;\n }\n\n /**\n * Check if initialized\n */\n isInitialized(): boolean {\n return this.initialized;\n }\n\n /**\n * Get underlying plugin\n */\n getPlugin(): Plugin {\n return this.plugin;\n }\n\n /**\n * Get context\n */\n getContext(): PluginRuntimeContext | undefined {\n return this.context;\n }\n}\n\n/**\n * Create plugin runtime wrapper\n */\nexport function createPluginRuntime(plugin: Plugin): PluginRuntime {\n return new PluginRuntime(plugin);\n}\n","/**\n * Keyboard Shortcuts Manager\n * Provides keyboard shortcut handling for the rich text editor.\n */\n\nexport interface KeyboardShortcut {\n key: string;\n ctrl?: boolean;\n alt?: boolean;\n shift?: boolean;\n meta?: boolean; // Command key on Mac\n command: string;\n params?: any;\n description?: string;\n preventDefault?: boolean;\n}\n\nexport interface KeyboardShortcutConfig {\n shortcuts?: KeyboardShortcut[];\n enabled?: boolean;\n customShortcuts?: Record<string, KeyboardShortcut>;\n}\n\nexport class KeyboardShortcutManager {\n private shortcuts: Map<string, KeyboardShortcut> = new Map();\n private enabled: boolean = true;\n private isMac: boolean;\n\n constructor(config?: KeyboardShortcutConfig) {\n this.isMac = typeof navigator !== 'undefined' && \n navigator.platform.toUpperCase().indexOf('MAC') >= 0;\n \n if (config?.enabled === false) {\n this.enabled = false;\n }\n\n // Register default shortcuts\n this.registerDefaultShortcuts();\n\n // Register custom shortcuts\n if (config?.shortcuts) {\n config.shortcuts.forEach(shortcut => this.registerShortcut(shortcut));\n }\n\n if (config?.customShortcuts) {\n Object.values(config.customShortcuts).forEach(shortcut => {\n this.registerShortcut(shortcut);\n });\n }\n }\n\n private registerDefaultShortcuts(): void {\n // Text Formatting Shortcuts\n this.registerShortcut({\n key: 'b',\n ctrl: !this.isMac,\n meta: this.isMac,\n command: 'toggleBold',\n description: 'Bold',\n preventDefault: true\n });\n\n this.registerShortcut({\n key: 'i',\n ctrl: !this.isMac,\n meta: this.isMac,\n command: 'toggleItalic',\n description: 'Italic',\n preventDefault: true\n });\n\n this.registerShortcut({\n key: 'u',\n ctrl: !this.isMac,\n meta: this.isMac,\n command: 'toggleUnderline',\n description: 'Underline',\n preventDefault: true\n });\n\n this.registerShortcut({\n key: 'd',\n ctrl: !this.isMac,\n meta: this.isMac,\n command: 'toggleStrikethrough',\n description: 'Strikethrough',\n preventDefault: true\n });\n\n // History Shortcuts\n this.registerShortcut({\n key: 'z',\n ctrl: !this.isMac,\n meta: this.isMac,\n command: 'undo',\n description: 'Undo',\n preventDefault: true\n });\n\n this.registerShortcut({\n key: 'z',\n ctrl: !this.isMac,\n meta: this.isMac,\n shift: true,\n command: 'redo',\n description: 'Redo',\n preventDefault: true\n });\n\n this.registerShortcut({\n key: 'y',\n ctrl: !this.isMac,\n meta: this.isMac,\n command: 'redo',\n description: 'Redo',\n preventDefault: true\n });\n\n // Heading Shortcuts (Ctrl+Alt+1-6)\n for (let i = 1; i <= 6; i++) {\n this.registerShortcut({\n key: String(i),\n ctrl: !this.isMac,\n meta: this.isMac,\n alt: true,\n command: 'setBlockType',\n params: `h${i}`,\n description: `Heading ${i}`,\n preventDefault: true\n });\n }\n\n // Paragraph shortcut\n this.registerShortcut({\n key: '7',\n ctrl: !this.isMac,\n meta: this.isMac,\n alt: true,\n command: 'setBlockType',\n params: 'p',\n description: 'Paragraph',\n preventDefault: true\n });\n\n // List Shortcuts\n this.registerShortcut({\n key: '7',\n ctrl: !this.isMac,\n meta: this.isMac,\n shift: true,\n command: 'toggleOrderedList',\n description: 'Numbered List',\n preventDefault: true\n });\n\n this.registerShortcut({\n key: '8',\n ctrl: !this.isMac,\n meta: this.isMac,\n shift: true,\n command: 'toggleBulletList',\n description: 'Bullet List',\n preventDefault: true\n });\n\n // Link Shortcut\n this.registerShortcut({\n key: 'k',\n ctrl: !this.isMac,\n meta: this.isMac,\n command: 'openLinkDialog',\n description: 'Insert/Edit Link',\n preventDefault: true\n });\n\n // Code Block Shortcut\n this.registerShortcut({\n key: 'e',\n ctrl: !this.isMac,\n meta: this.isMac,\n alt: true,\n command: 'insertCodeBlock',\n description: 'Code Block',\n preventDefault: true\n });\n\n // Blockquote Shortcut\n this.registerShortcut({\n key: 'q',\n ctrl: !this.isMac,\n meta: this.isMac,\n shift: true,\n command: 'toggleBlockquote',\n description: 'Blockquote',\n preventDefault: true\n });\n\n // Alignment Shortcuts\n this.registerShortcut({\n key: 'l',\n ctrl: !this.isMac,\n meta: this.isMac,\n shift: true,\n command: 'setTextAlignment',\n params: 'left',\n description: 'Align Left',\n preventDefault: true\n });\n\n this.registerShortcut({\n key: 'e',\n ctrl: !this.isMac,\n meta: this.isMac,\n shift: true,\n alt: true,\n command: 'setTextAlignment',\n params: 'center',\n description: 'Align Center',\n preventDefault: true\n });\n\n this.registerShortcut({\n key: 'r',\n ctrl: !this.isMac,\n meta: this.isMac,\n shift: true,\n command: 'setTextAlignment',\n params: 'right',\n description: 'Align Right',\n preventDefault: true\n });\n\n this.registerShortcut({\n key: 'j',\n ctrl: !this.isMac,\n meta: this.isMac,\n shift: true,\n command: 'setTextAlignment',\n params: 'justify',\n description: 'Justify',\n preventDefault: true\n });\n\n // Clear Formatting\n this.registerShortcut({\n key: '\\\\',\n ctrl: !this.isMac,\n meta: this.isMac,\n command: 'clearFormatting',\n description: 'Clear Formatting',\n preventDefault: true\n });\n\n // Indent/Outdent\n this.registerShortcut({\n key: ']',\n ctrl: !this.isMac,\n meta: this.isMac,\n command: 'increaseIndent',\n description: 'Indent',\n preventDefault: true\n });\n\n this.registerShortcut({\n key: '[',\n ctrl: !this.isMac,\n meta: this.isMac,\n command: 'decreaseIndent',\n description: 'Outdent',\n preventDefault: true\n });\n\n // Insert Image\n this.registerShortcut({\n key: 'g',\n ctrl: !this.isMac,\n meta: this.isMac,\n shift: true,\n command: 'insertImage',\n description: 'Insert Image',\n preventDefault: true\n });\n\n // Insert Table\n this.registerShortcut({\n key: 't',\n ctrl: !this.isMac,\n meta: this.isMac,\n shift: true,\n alt: true,\n command: 'insertTable',\n description: 'Insert Table',\n preventDefault: true\n });\n\n // Fullscreen\n this.registerShortcut({\n key: 'f11',\n command: 'toggleFullscreen',\n description: 'Toggle Fullscreen',\n preventDefault: true\n });\n\n // Preview\n this.registerShortcut({\n key: 'p',\n ctrl: !this.isMac,\n meta: this.isMac,\n shift: true,\n command: 'togglePreview',\n description: 'Preview',\n preventDefault: true\n });\n\n // Print\n this.registerShortcut({\n key: 'p',\n ctrl: !this.isMac,\n meta: this.isMac,\n command: 'print',\n description: 'Print',\n preventDefault: true\n });\n\n // Special Characters\n this.registerShortcut({\n key: 's',\n ctrl: !this.isMac,\n meta: this.isMac,\n shift: true,\n alt: true,\n command: 'insertSpecialCharacter',\n description: 'Insert Special Character',\n preventDefault: true\n });\n\n // Insert Emoji\n this.registerShortcut({\n key: 'm',\n ctrl: !this.isMac,\n meta: this.isMac,\n shift: true,\n command: 'insertEmoji',\n description: 'Insert Emoji',\n preventDefault: true\n });\n\n // Checklist\n this.registerShortcut({\n key: '9',\n ctrl: !this.isMac,\n meta: this.isMac,\n shift: true,\n command: 'toggleChecklist',\n description: 'Checklist',\n preventDefault: true\n });\n\n // Accessibility Checker\n this.registerShortcut({\n key: 'a',\n ctrl: !this.isMac,\n meta: this.isMac,\n shift: true,\n alt: true,\n command: 'toggleA11yChecker',\n description: 'Accessibility Checker',\n preventDefault: true\n });\n\n // Spell Check\n this.registerShortcut({\n key: 'F7',\n command: 'toggleSpellCheck',\n description: 'Spell Check',\n preventDefault: true\n });\n\n // Insert Math\n this.registerShortcut({\n key: 'm',\n ctrl: !this.isMac,\n meta: this.isMac,\n alt: true,\n command: 'insertMath',\n description: 'Insert Math',\n preventDefault: true\n });\n\n // Insert Footnote\n this.registerShortcut({\n key: 'f',\n ctrl: !this.isMac,\n meta: this.isMac,\n alt: true,\n command: 'insertFootnote',\n description: 'Insert Footnote',\n preventDefault: true\n });\n }\n\n registerShortcut(shortcut: KeyboardShortcut): void {\n const key = this.getShortcutKey(shortcut);\n this.shortcuts.set(key, shortcut);\n }\n\n unregisterShortcut(shortcut: KeyboardShortcut): void {\n const key = this.getShortcutKey(shortcut);\n this.shortcuts.delete(key);\n }\n\n private getShortcutKey(shortcut: KeyboardShortcut): string {\n const parts = [];\n if (shortcut.ctrl) parts.push('ctrl');\n if (shortcut.alt) parts.push('alt');\n if (shortcut.shift) parts.push('shift');\n if (shortcut.meta) parts.push('meta');\n parts.push(shortcut.key.toLowerCase());\n return parts.join('+');\n }\n\n private getEventKey(event: KeyboardEvent): string {\n const parts = [];\n if (event.ctrlKey) parts.push('ctrl');\n if (event.altKey) parts.push('alt');\n if (event.shiftKey) parts.push('shift');\n if (event.metaKey) parts.push('meta');\n parts.push(event.key.toLowerCase());\n return parts.join('+');\n }\n\n handleKeyDown(event: KeyboardEvent, commandExecutor: (command: string, params?: any) => void): boolean {\n if (!this.enabled) return false;\n\n const eventKey = this.getEventKey(event);\n const shortcut = this.shortcuts.get(eventKey);\n\n if (shortcut) {\n if (shortcut.preventDefault !== false) {\n event.preventDefault();\n event.stopPropagation();\n }\n \n commandExecutor(shortcut.command, shortcut.params);\n return true;\n }\n\n return false;\n }\n\n enable(): void {\n this.enabled = true;\n }\n\n disable(): void {\n this.enabled = false;\n }\n\n isEnabled(): boolean {\n return this.enabled;\n }\n\n getAllShortcuts(): KeyboardShortcut[] {\n return Array.from(this.shortcuts.values());\n }\n\n getShortcutForCommand(command: string): KeyboardShortcut | undefined {\n return Array.from(this.shortcuts.values()).find(s => s.command === command);\n }\n\n getShortcutDescription(shortcut: KeyboardShortcut): string {\n const parts = [];\n if (this.isMac) {\n if (shortcut.meta) parts.push('⌘');\n if (shortcut.ctrl) parts.push('⌃');\n if (shortcut.alt) parts.push('⌥');\n if (shortcut.shift) parts.push('⇧');\n } else {\n if (shortcut.ctrl) parts.push('Ctrl');\n if (shortcut.alt) parts.push('Alt');\n if (shortcut.shift) parts.push('Shift');\n }\n \n // Capitalize single letters\n const key = shortcut.key.length === 1 \n ? shortcut.key.toUpperCase() \n : shortcut.key;\n \n parts.push(key);\n return parts.join('+');\n }\n\n getShortcutsHelp(): string {\n const shortcuts = this.getAllShortcuts();\n const grouped = new Map<string, KeyboardShortcut[]>();\n\n shortcuts.forEach(shortcut => {\n const category = this.getShortcutCategory(shortcut.command);\n if (!grouped.has(category)) {\n grouped.set(category, []);\n }\n grouped.get(category)!.push(shortcut);\n });\n\n let help = '# Keyboard Shortcuts\\n\\n';\n grouped.forEach((shortcuts, category) => {\n help += `## ${category}\\n\\n`;\n shortcuts.forEach(shortcut => {\n const desc = this.getShortcutDescription(shortcut);\n help += `- **${desc}**: ${shortcut.description || shortcut.command}\\n`;\n });\n help += '\\n';\n });\n\n return help;\n }\n\n private getShortcutCategory(command: string): string {\n if (command.includes('toggle') && \n (command.includes('Bold') || command.includes('Italic') || \n command.includes('Underline') || command.includes('Strike') ||\n command.includes('Code') || command.includes('Super') || command.includes('Sub'))) {\n return 'Text Formatting';\n }\n if (command.includes('Heading') || command.includes('Paragraph')) {\n return 'Block Formatting';\n }\n if (command.includes('List') || command.includes('Checklist')) {\n return 'Lists';\n }\n if (command.includes('Alignment') || command.includes('Indent')) {\n return 'Alignment & Indentation';\n }\n if (command.includes('undo') || command.includes('redo')) {\n return 'History';\n }\n if (command.includes('insert')) {\n return 'Insert';\n }\n if (command.includes('find') || command.includes('replace')) {\n return 'Find & Replace';\n }\n if (command.includes('Accessibility') || command.includes('spell')) {\n return 'Tools';\n }\n return 'Other';\n }\n}\n","/**\n * Spellcheck Plugin - Enterprise-grade spell checking\n * Supports browser, local, and API-based providers\n */\n\nimport { Plugin, ToolbarItem } from '../Plugin';\nimport { PluginRuntimeContext } from '../PluginRuntime';\n\nexport interface SpellcheckConfig {\n enabled?: boolean;\n provider?: 'browser' | 'local' | 'api';\n apiUrl?: string;\n apiHeaders?: Record<string, string>;\n language?: string;\n customDictionary?: string[];\n ignoreAllCaps?: boolean;\n ignoreNumbers?: boolean;\n}\n\n/**\n * Spellcheck plugin\n * Non-functional scaffold - demonstrates enterprise plugin structure\n */\nexport function SpellcheckPlugin(config: SpellcheckConfig = {}): Plugin {\n const {\n enabled = false,\n provider = 'browser',\n apiUrl = '',\n apiHeaders = {},\n language = 'en',\n customDictionary = [],\n ignoreAllCaps = true,\n ignoreNumbers = true,\n } = config;\n\n return {\n name: 'spellcheck',\n \n context: {\n initialize: () => {\n if (!enabled) return;\n \n console.log('[Spellcheck Plugin] Initialized', {\n provider,\n language,\n });\n \n // TODO: Initialize spellcheck based on provider\n switch (provider) {\n case 'browser':\n // Use native browser spellcheck\n console.log('[Spellcheck] Using browser spellcheck');\n break;\n case 'local':\n // Use lightweight local dictionary\n console.log('[Spellcheck] Using local dictionary (not implemented)');\n break;\n case 'api':\n // Use backend API for spellcheck\n if (!apiUrl) {\n console.warn('[Spellcheck] API provider selected but no apiUrl provided');\n } else {\n console.log('[Spellcheck] Using API:', apiUrl);\n }\n break;\n }\n },\n \n destroy: () => {\n console.log('[Spellcheck Plugin] Destroyed');\n // TODO: Cleanup spellcheck resources\n },\n \n onEditorReady: (context: PluginRuntimeContext) => {\n console.log('[Spellcheck Plugin] Editor ready');\n \n // TODO: Attach spellcheck to content area\n // TODO: Handle viewport-based scanning for performance\n // TODO: Add context menu suggestions\n },\n },\n \n commands: {\n 'toggleSpellcheck': () => {\n console.log('[Spellcheck] Toggle command (not implemented)');\n // TODO: Toggle spellcheck on/off\n return null;\n },\n \n 'addToDictionary': (word: string) => {\n console.log('[Spellcheck] Add to dictionary:', word);\n // TODO: Add word to custom dictionary\n // TODO: Persist to localStorage or API\n return null;\n },\n \n 'checkSpelling': async () => {\n console.log('[Spellcheck] Check spelling (not implemented)');\n // TODO: Run full document spellcheck\n // TODO: Return errors and suggestions\n return null;\n },\n },\n \n toolbar: enabled ? [\n {\n label: 'Spellcheck',\n command: 'toggleSpellcheck',\n icon: 'Aa',\n type: 'button',\n },\n ] : [],\n };\n}\n","/**\n * Media Plugin - Enterprise media upload & management\n * Supports chunked uploads, progress tracking, and error recovery\n */\n\nimport { Plugin, ToolbarItem } from '../Plugin';\nimport { PluginRuntimeContext } from '../PluginRuntime';\n\nexport interface MediaConfig {\n uploadUrl?: string;\n libraryUrl?: string;\n maxFileSize?: number;\n allowedTypes?: string[];\n headers?: Record<string, string>;\n withCredentials?: boolean;\n chunkSize?: number;\n enableChunking?: boolean;\n onProgress?: (progress: number) => void;\n onError?: (error: Error) => void;\n onSuccess?: (url: string) => void;\n}\n\n/**\n * Media upload plugin\n * Non-functional scaffold - demonstrates enterprise media handling\n */\nexport function MediaPlugin(config: MediaConfig = {}): Plugin {\n const {\n uploadUrl = '',\n libraryUrl = '',\n maxFileSize = 10 * 1024 * 1024, // 10MB\n allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'],\n headers = {},\n withCredentials = false,\n chunkSize = 1024 * 1024, // 1MB chunks\n enableChunking = true,\n onProgress,\n onError,\n onSuccess,\n } = config;\n\n return {\n name: 'media',\n \n context: {\n initialize: () => {\n console.log('[Media Plugin] Initialized', {\n uploadUrl,\n libraryUrl,\n maxFileSize,\n allowedTypes,\n });\n \n // TODO: Validate config\n if (!uploadUrl) {\n console.warn('[Media] No uploadUrl provided - upload will not work');\n }\n },\n \n destroy: () => {\n console.log('[Media Plugin] Destroyed');\n // TODO: Cancel any in-progress uploads\n // TODO: Cleanup resources\n },\n \n onEditorReady: (context: PluginRuntimeContext) => {\n console.log('[Media Plugin] Editor ready');\n \n // TODO: Setup drag-and-drop\n // TODO: Setup paste handling for images\n },\n },\n \n commands: {\n 'insertImage': async (file?: File) => {\n console.log('[Media] Insert image command (not implemented)', file);\n \n if (!file) {\n // TODO: Open file picker\n console.log('[Media] No file provided - should open picker');\n return null;\n }\n \n // TODO: Validate file\n if (!allowedTypes.includes(file.type)) {\n const error = new Error(`File type ${file.type} not allowed`);\n onError?.(error);\n return null;\n }\n \n if (file.size > maxFileSize) {\n const error = new Error(`File size ${file.size} exceeds max ${maxFileSize}`);\n onError?.(error);\n return null;\n }\n \n // TODO: Upload file\n // TODO: If chunking enabled, use chunked upload\n // TODO: Track progress\n // TODO: Handle errors and retry\n // TODO: Insert image into editor\n \n return null;\n },\n \n 'openMediaLibrary': () => {\n console.log('[Media] Open media library (not implemented)');\n \n if (!libraryUrl) {\n console.warn('[Media] No libraryUrl provided');\n return null;\n }\n \n // TODO: Open media library modal\n // TODO: Fetch existing media from libraryUrl\n // TODO: Allow selection and insertion\n \n return null;\n },\n \n 'uploadMedia': async (file: File) => {\n console.log('[Media] Upload media (not implemented)', {\n name: file.name,\n size: file.size,\n type: file.type,\n });\n \n // TODO: Implement chunked upload if enabled\n // TODO: Track progress with onProgress callback\n // TODO: Handle errors with onError callback\n // TODO: Call onSuccess with final URL\n \n return null;\n },\n },\n \n toolbar: [\n {\n label: 'Image',\n command: 'insertImage',\n icon: '🖼️',\n type: 'button',\n },\n {\n label: 'Media Library',\n command: 'openMediaLibrary',\n icon: '📁',\n type: 'button',\n },\n ],\n };\n}\n","/**\n * DocumentModel - Represents the editor content\n */\n\nimport { Node } from '../schema/Node';\n\nexport interface Selection {\n anchor: number;\n head: number;\n from?: number;\n to?: number;\n}\n\nexport class DocumentModel {\n private doc: Node;\n private selection: Selection;\n\n constructor(doc: Node, selection: Selection = { anchor: 0, head: 0 }) {\n this.doc = doc;\n this.selection = selection;\n }\n\n getDocument(): Node {\n return this.doc;\n }\n\n setDocument(doc: Node): DocumentModel {\n return new DocumentModel(doc, this.selection);\n }\n\n getSelection(): Selection {\n return { ...this.selection };\n }\n\n setSelection(selection: Selection): DocumentModel {\n return new DocumentModel(this.doc, selection);\n }\n\n /**\n * Create a new model with updated document and selection\n */\n update(doc?: Node, selection?: Selection): DocumentModel {\n return new DocumentModel(\n doc || this.doc,\n selection || this.selection\n );\n }\n\n /**\n * Get text content\n */\n getTextContent(): string {\n // This would traverse the node tree to extract text\n // Simplified for now\n return '';\n }\n\n /**\n * Check if selection is empty\n */\n isSelectionEmpty(): boolean {\n return this.selection.anchor === this.selection.head;\n }\n}\n","/**\n * Native Dialog System\n * Framework-agnostic dialog using HTML <dialog> element\n */\n\nexport interface DialogConfig {\n title: string;\n content: string | HTMLElement;\n width?: string;\n height?: string;\n closeOnEscape?: boolean;\n closeOnBackdrop?: boolean;\n onSubmit?: (data: FormData) => void;\n onCancel?: () => void;\n}\n\nexport class Dialog {\n private element: HTMLDialogElement;\n private config: DialogConfig;\n private formElement?: HTMLFormElement;\n\n constructor(config: DialogConfig) {\n this.config = {\n closeOnEscape: true,\n closeOnBackdrop: true,\n ...config\n };\n this.element = this.createElement();\n this.attachEventListeners();\n }\n\n private createElement(): HTMLDialogElement {\n const dialog = document.createElement('dialog');\n dialog.className = 'editora-dialog';\n \n if (this.config.width) {\n dialog.style.width = this.config.width;\n }\n if (this.config.height) {\n dialog.style.height = this.config.height;\n }\n\n dialog.innerHTML = `\n <div class=\"editora-dialog-container\">\n <div class=\"editora-dialog-header\">\n <h3>${this.config.title}</h3>\n <button class=\"editora-dialog-close\" aria-label=\"Close\">&times;</button>\n </div>\n <div class=\"editora-dialog-body\">\n ${typeof this.config.content === 'string' ? this.config.content : ''}\n </div>\n <div class=\"editora-dialog-footer\">\n <button type=\"button\" class=\"editora-btn editora-btn-cancel\">Cancel</button>\n <button type=\"button\" class=\"editora-btn editora-btn-primary\">OK</button>\n </div>\n </div>\n `;\n\n // If content is HTMLElement, append it\n if (typeof this.config.content !== 'string') {\n const body = dialog.querySelector('.editora-dialog-body');\n if (body) {\n body.innerHTML = '';\n body.appendChild(this.config.content);\n }\n }\n\n return dialog;\n }\n\n private attachEventListeners(): void {\n // Close button\n const closeBtn = this.element.querySelector('.editora-dialog-close');\n closeBtn?.addEventListener('click', () => this.close());\n\n // Cancel button\n const cancelBtn = this.element.querySelector('.editora-btn-cancel');\n cancelBtn?.addEventListener('click', () => {\n this.config.onCancel?.();\n this.close();\n });\n\n // OK button\n const okBtn = this.element.querySelector('.editora-btn-primary');\n okBtn?.addEventListener('click', () => this.handleSubmit());\n\n // ESC key\n if (this.config.closeOnEscape) {\n this.element.addEventListener('cancel', (e) => {\n e.preventDefault();\n this.close();\n });\n }\n\n // Backdrop click\n if (this.config.closeOnBackdrop) {\n this.element.addEventListener('click', (e) => {\n const rect = this.element.getBoundingClientRect();\n if (\n e.clientX < rect.left ||\n e.clientX > rect.right ||\n e.clientY < rect.top ||\n e.clientY > rect.bottom\n ) {\n this.close();\n }\n });\n }\n }\n\n private handleSubmit(): void {\n const form = this.element.querySelector('form');\n if (form) {\n const formData = new FormData(form);\n this.config.onSubmit?.(formData);\n } else {\n // Collect all inputs\n const inputs = this.element.querySelectorAll('input, select, textarea');\n const formData = new FormData();\n inputs.forEach((input: any) => {\n if (input.name) {\n formData.append(input.name, input.value);\n }\n });\n this.config.onSubmit?.(formData);\n }\n this.close();\n }\n\n show(): void {\n document.body.appendChild(this.element);\n this.element.showModal();\n }\n\n close(): void {\n this.element.close();\n this.element.remove();\n }\n\n destroy(): void {\n this.close();\n }\n}\n","/**\n * Native Dropdown System\n * Framework-agnostic dropdown component\n */\n\nexport interface DropdownOption {\n label: string;\n value: string;\n icon?: string;\n}\n\nexport interface DropdownConfig {\n options: DropdownOption[];\n value?: string;\n placeholder?: string;\n onChange?: (value: string) => void;\n width?: string;\n}\n\nexport class Dropdown {\n private element: HTMLDivElement;\n private config: DropdownConfig;\n private isOpen = false;\n private selectedValue?: string;\n\n constructor(config: DropdownConfig) {\n this.config = config;\n this.selectedValue = config.value;\n this.element = this.createElement();\n this.attachEventListeners();\n }\n\n private createElement(): HTMLDivElement {\n const container = document.createElement('div');\n container.className = 'editora-dropdown';\n if (this.config.width) {\n container.style.width = this.config.width;\n }\n\n const selected = this.config.options.find(o => o.value === this.selectedValue);\n const displayText = selected?.label || this.config.placeholder || 'Select...';\n\n container.innerHTML = `\n <button class=\"editora-dropdown-toggle\" type=\"button\">\n <span class=\"editora-dropdown-label\">${displayText}</span>\n <span class=\"editora-dropdown-arrow\">▼</span>\n </button>\n <div class=\"editora-dropdown-menu\" style=\"display: none;\">\n ${this.config.options.map(opt => `\n <div class=\"editora-dropdown-item\" data-value=\"${opt.value}\">\n ${opt.icon ? `<span class=\"editora-dropdown-icon\">${opt.icon}</span>` : ''}\n <span>${opt.label}</span>\n </div>\n `).join('')}\n </div>\n `;\n\n return container;\n }\n\n private attachEventListeners(): void {\n const toggle = this.element.querySelector('.editora-dropdown-toggle') as HTMLButtonElement;\n const menu = this.element.querySelector('.editora-dropdown-menu') as HTMLDivElement;\n\n // Toggle dropdown\n toggle.addEventListener('click', (e) => {\n e.stopPropagation();\n this.isOpen = !this.isOpen;\n menu.style.display = this.isOpen ? 'block' : 'none';\n });\n\n // Select option\n const items = this.element.querySelectorAll('.editora-dropdown-item');\n items.forEach(item => {\n item.addEventListener('click', () => {\n const value = item.getAttribute('data-value');\n if (value) {\n this.setValue(value);\n this.config.onChange?.(value);\n this.close();\n }\n });\n });\n\n // Close on outside click\n document.addEventListener('click', (e) => {\n if (!this.element.contains(e.target as Node)) {\n this.close();\n }\n });\n }\n\n setValue(value: string): void {\n this.selectedValue = value;\n const selected = this.config.options.find(o => o.value === value);\n const label = this.element.querySelector('.editora-dropdown-label');\n if (label && selected) {\n label.textContent = selected.label;\n }\n }\n\n getValue(): string | undefined {\n return this.selectedValue;\n }\n\n close(): void {\n this.isOpen = false;\n const menu = this.element.querySelector('.editora-dropdown-menu') as HTMLDivElement;\n if (menu) {\n menu.style.display = 'none';\n }\n }\n\n getElement(): HTMLDivElement {\n return this.element;\n }\n\n destroy(): void {\n this.element.remove();\n }\n}\n","/**\n * Native Color Picker\n * Framework-agnostic color picker component\n */\n\nexport interface ColorPickerConfig {\n value?: string;\n onChange?: (color: string) => void;\n presetColors?: string[];\n}\n\nexport class ColorPicker {\n private element: HTMLDivElement;\n private config: ColorPickerConfig;\n private selectedColor?: string;\n\n private defaultPresets = [\n '#000000', '#434343', '#666666', '#999999', '#B7B7B7', '#CCCCCC', '#D9D9D9', '#EFEFEF', '#F3F3F3', '#FFFFFF',\n '#980000', '#FF0000', '#FF9900', '#FFFF00', '#00FF00', '#00FFFF', '#4A86E8', '#0000FF', '#9900FF', '#FF00FF',\n '#E6B8AF', '#F4CCCC', '#FCE5CD', '#FFF2CC', '#D9EAD3', '#D0E0E3', '#C9DAF8', '#CFE2F3', '#D9D2E9', '#EAD1DC'\n ];\n\n constructor(config: ColorPickerConfig) {\n this.config = {\n presetColors: this.defaultPresets,\n ...config\n };\n this.selectedColor = config.value;\n this.element = this.createElement();\n this.attachEventListeners();\n }\n\n private createElement(): HTMLDivElement {\n const container = document.createElement('div');\n container.className = 'editora-color-picker';\n\n container.innerHTML = `\n <div class=\"editora-color-picker-input\">\n <input type=\"color\" value=\"${this.selectedColor || '#000000'}\" />\n <input type=\"text\" value=\"${this.selectedColor || '#000000'}\" placeholder=\"#000000\" />\n </div>\n <div class=\"editora-color-picker-presets\">\n ${this.config.presetColors?.map(color => `\n <button \n class=\"editora-color-preset\" \n style=\"background-color: ${color};\" \n data-color=\"${color}\"\n title=\"${color}\"\n ></button>\n `).join('')}\n </div>\n `;\n\n return container;\n }\n\n private attachEventListeners(): void {\n const colorInput = this.element.querySelector('input[type=\"color\"]') as HTMLInputElement;\n const textInput = this.element.querySelector('input[type=\"text\"]') as HTMLInputElement;\n\n // Color input change\n colorInput.addEventListener('input', (e) => {\n const color = (e.target as HTMLInputElement).value;\n textInput.value = color;\n this.selectedColor = color;\n this.config.onChange?.(color);\n });\n\n // Text input change\n textInput.addEventListener('input', (e) => {\n const color = (e.target as HTMLInputElement).value;\n if (/^#[0-9A-Fa-f]{6}$/.test(color)) {\n colorInput.value = color;\n this.selectedColor = color;\n this.config.onChange?.(color);\n }\n });\n\n // Preset buttons\n const presets = this.element.querySelectorAll('.editora-color-preset');\n presets.forEach(preset => {\n preset.addEventListener('click', () => {\n const color = preset.getAttribute('data-color');\n if (color) {\n colorInput.value = color;\n textInput.value = color;\n this.selectedColor = color;\n this.config.onChange?.(color);\n }\n });\n });\n }\n\n getValue(): string | undefined {\n return this.selectedColor;\n }\n\n setValue(color: string): void {\n this.selectedColor = color;\n const colorInput = this.element.querySelector('input[type=\"color\"]') as HTMLInputElement;\n const textInput = this.element.querySelector('input[type=\"text\"]') as HTMLInputElement;\n if (colorInput) colorInput.value = color;\n if (textInput) textInput.value = color;\n }\n\n getElement(): HTMLDivElement {\n return this.element;\n }\n\n destroy(): void {\n this.element.remove();\n }\n}\n","import { Dialog } from '../Dialog';\n\nexport interface LinkDialogConfig {\n initialUrl?: string;\n initialText?: string;\n onSubmit: (data: { url: string; text: string; openInNewTab: boolean }) => void;\n onCancel?: () => void;\n}\n\n/**\n * Native link insertion dialog\n * Framework-agnostic implementation using HTML <dialog>\n */\nexport class LinkDialog {\n private dialog: Dialog;\n\n constructor(config: LinkDialogConfig) {\n const { initialUrl = '', initialText = '', onSubmit, onCancel } = config;\n\n this.dialog = new Dialog({\n title: 'Insert/Edit Link',\n content: this.createFormHTML(initialUrl, initialText),\n onSubmit: (formData) => {\n const url = (formData.get('url') as string || '').trim();\n const text = (formData.get('text') as string || '').trim();\n const openInNewTab = formData.get('openInNewTab') === 'on';\n\n if (!url) {\n alert('Please enter a URL');\n return;\n }\n\n onSubmit({ url, text, openInNewTab });\n this.dialog.close();\n },\n onCancel: () => {\n onCancel?.();\n this.dialog.close();\n },\n width: '500px'\n });\n }\n\n private createFormHTML(initialUrl: string, initialText: string): string {\n return `\n <form class=\"link-dialog-form\">\n <div class=\"form-group\">\n <label for=\"link-url\">URL</label>\n <input \n type=\"url\" \n id=\"link-url\"\n name=\"url\" \n placeholder=\"https://example.com\"\n value=\"${this.escapeHtml(initialUrl)}\"\n required \n autofocus\n />\n <small>Enter the web address (URL) for the link</small>\n </div>\n\n <div class=\"form-group\">\n <label for=\"link-text\">Link Text</label>\n <input \n type=\"text\" \n id=\"link-text\"\n name=\"text\" \n placeholder=\"Click here\"\n value=\"${this.escapeHtml(initialText)}\"\n />\n <small>Text to display for the link (leave empty to use URL)</small>\n </div>\n\n <div class=\"form-group\">\n <label class=\"checkbox-label\">\n <input \n type=\"checkbox\" \n name=\"openInNewTab\"\n id=\"link-new-tab\"\n />\n <span>Open link in new tab</span>\n </label>\n </div>\n\n <div class=\"form-actions\">\n <button type=\"button\" class=\"btn btn-secondary\" data-action=\"cancel\">\n Cancel\n </button>\n <button type=\"submit\" class=\"btn btn-primary\">\n Insert Link\n </button>\n </div>\n </form>\n `;\n }\n\n private escapeHtml(text: string): string {\n const div = document.createElement('div');\n div.textContent = text;\n return div.innerHTML;\n }\n\n public show(): void {\n this.dialog.show();\n }\n\n public close(): void {\n this.dialog.close();\n }\n}\n","import { Dialog } from '../Dialog';\n\nexport interface TableDialogConfig {\n onSubmit: (data: { rows: number; cols: number; headerRow: boolean }) => void;\n onCancel?: () => void;\n}\n\n/**\n * Native table insertion dialog\n * Framework-agnostic implementation using HTML <dialog>\n */\nexport class TableDialog {\n private dialog: Dialog;\n\n constructor(config: TableDialogConfig) {\n const { onSubmit, onCancel } = config;\n\n this.dialog = new Dialog({\n title: 'Insert Table',\n content: this.createFormHTML(),\n onSubmit: (formData) => {\n const rows = parseInt(formData.get('rows') as string, 10);\n const cols = parseInt(formData.get('cols') as string, 10);\n const headerRow = formData.get('headerRow') === 'on';\n\n if (rows < 1 || rows > 100) {\n alert('Please enter a valid number of rows (1-100)');\n return;\n }\n\n if (cols < 1 || cols > 20) {\n alert('Please enter a valid number of columns (1-20)');\n return;\n }\n\n onSubmit({ rows, cols, headerRow });\n this.dialog.close();\n },\n onCancel: () => {\n onCancel?.();\n this.dialog.close();\n },\n width: '400px'\n });\n }\n\n private createFormHTML(): string {\n return `\n <form class=\"table-dialog-form\">\n <div class=\"form-group\">\n <label for=\"table-rows\">Rows</label>\n <input \n type=\"number\" \n id=\"table-rows\"\n name=\"rows\" \n min=\"1\" \n max=\"100\" \n value=\"3\"\n required \n autofocus\n />\n <small>Number of rows (1-100)</small>\n </div>\n\n <div class=\"form-group\">\n <label for=\"table-cols\">Columns</label>\n <input \n type=\"number\" \n id=\"table-cols\"\n name=\"cols\" \n min=\"1\" \n max=\"20\" \n value=\"3\"\n required\n />\n <small>Number of columns (1-20)</small>\n </div>\n\n <div class=\"form-group\">\n <label class=\"checkbox-label\">\n <input \n type=\"checkbox\" \n name=\"headerRow\"\n id=\"table-header\"\n checked\n />\n <span>Include header row</span>\n </label>\n </div>\n\n <div class=\"table-preview\">\n <strong>Preview:</strong>\n <div id=\"table-preview-content\" style=\"margin-top: 8px; font-size: 12px; color: #666;\">\n 3 rows × 3 columns with header\n </div>\n </div>\n\n <div class=\"form-actions\">\n <button type=\"button\" class=\"btn btn-secondary\" data-action=\"cancel\">\n Cancel\n </button>\n <button type=\"submit\" class=\"btn btn-primary\">\n Insert Table\n </button>\n </div>\n </form>\n `;\n }\n\n public show(): void {\n this.dialog.show();\n this.attachPreviewListeners();\n }\n\n public close(): void {\n this.dialog.close();\n }\n\n private attachPreviewListeners(): void {\n const form = document.querySelector('.table-dialog-form');\n if (!form) return;\n\n const rowsInput = form.querySelector('#table-rows') as HTMLInputElement;\n const colsInput = form.querySelector('#table-cols') as HTMLInputElement;\n const headerCheckbox = form.querySelector('#table-header') as HTMLInputElement;\n const preview = form.querySelector('#table-preview-content');\n\n const updatePreview = () => {\n const rows = parseInt(rowsInput?.value || '3', 10);\n const cols = parseInt(colsInput?.value || '3', 10);\n const hasHeader = headerCheckbox?.checked;\n\n if (preview) {\n preview.textContent = `${rows} rows × ${cols} columns${hasHeader ? ' with header' : ''}`;\n }\n };\n\n rowsInput?.addEventListener('input', updatePreview);\n colsInput?.addEventListener('input', updatePreview);\n headerCheckbox?.addEventListener('change', updatePreview);\n }\n}\n","import { Dialog } from '../Dialog';\n\nexport interface ImageDialogConfig {\n onSubmit: (data: { src: string; alt: string; width?: string; height?: string }) => void;\n onCancel?: () => void;\n allowUpload?: boolean;\n uploadUrl?: string;\n}\n\n/**\n * Native image insertion dialog\n * Framework-agnostic implementation using HTML <dialog>\n */\nexport class ImageDialog {\n private dialog: Dialog;\n private config: ImageDialogConfig;\n\n constructor(config: ImageDialogConfig) {\n this.config = config;\n const { onSubmit, onCancel } = config;\n\n this.dialog = new Dialog({\n title: 'Insert Image',\n content: this.createFormHTML(),\n onSubmit: (formData) => {\n const src = (formData.get('src') as string || '').trim();\n const alt = (formData.get('alt') as string || '').trim();\n const width = (formData.get('width') as string || '').trim();\n const height = (formData.get('height') as string || '').trim();\n\n if (!src) {\n alert('Please enter an image URL or upload an image');\n return;\n }\n\n onSubmit({ \n src, \n alt, \n width: width || undefined, \n height: height || undefined \n });\n this.dialog.close();\n },\n onCancel: () => {\n onCancel?.();\n this.dialog.close();\n },\n width: '500px'\n });\n }\n\n private createFormHTML(): string {\n const uploadSection = this.config.allowUpload ? `\n <div class=\"form-group\">\n <label for=\"image-upload\">Upload Image</label>\n <input \n type=\"file\" \n id=\"image-upload\"\n accept=\"image/*\"\n />\n <small>Or upload an image from your computer</small>\n </div>\n <div class=\"form-divider\">OR</div>\n ` : '';\n\n return `\n <form class=\"image-dialog-form\">\n ${uploadSection}\n\n <div class=\"form-group\">\n <label for=\"image-src\">Image URL</label>\n <input \n type=\"url\" \n id=\"image-src\"\n name=\"src\" \n placeholder=\"https://example.com/image.jpg\"\n ${!this.config.allowUpload ? 'required autofocus' : ''}\n />\n <small>Enter the web address (URL) of the image</small>\n </div>\n\n <div class=\"form-group\">\n <label for=\"image-alt\">Alt Text</label>\n <input \n type=\"text\" \n id=\"image-alt\"\n name=\"alt\" \n placeholder=\"Description of the image\"\n />\n <small>Alternative text for accessibility (recommended)</small>\n </div>\n\n <div class=\"form-row\">\n <div class=\"form-group\">\n <label for=\"image-width\">Width</label>\n <input \n type=\"text\" \n id=\"image-width\"\n name=\"width\" \n placeholder=\"auto\"\n />\n </div>\n\n <div class=\"form-group\">\n <label for=\"image-height\">Height</label>\n <input \n type=\"text\" \n id=\"image-height\"\n name=\"height\" \n placeholder=\"auto\"\n />\n </div>\n </div>\n\n <div class=\"image-preview\" id=\"image-preview\" style=\"display: none;\">\n <strong>Preview:</strong>\n <img id=\"preview-img\" style=\"max-width: 100%; max-height: 200px; margin-top: 8px;\" />\n </div>\n\n <div class=\"form-actions\">\n <button type=\"button\" class=\"btn btn-secondary\" data-action=\"cancel\">\n Cancel\n </button>\n <button type=\"submit\" class=\"btn btn-primary\">\n Insert Image\n </button>\n </div>\n </form>\n `;\n }\n\n public show(): void {\n this.dialog.show();\n this.attachImagePreview();\n this.attachFileUpload();\n }\n\n public close(): void {\n this.dialog.close();\n }\n\n private attachImagePreview(): void {\n const form = document.querySelector('.image-dialog-form');\n if (!form) return;\n\n const srcInput = form.querySelector('#image-src') as HTMLInputElement;\n const previewContainer = form.querySelector('#image-preview') as HTMLElement;\n const previewImg = form.querySelector('#preview-img') as HTMLImageElement;\n\n srcInput?.addEventListener('input', () => {\n const url = srcInput.value.trim();\n if (url && this.isValidImageUrl(url)) {\n previewImg.src = url;\n previewContainer.style.display = 'block';\n previewImg.onerror = () => {\n previewContainer.style.display = 'none';\n };\n } else {\n previewContainer.style.display = 'none';\n }\n });\n }\n\n private attachFileUpload(): void {\n if (!this.config.allowUpload) return;\n\n const form = document.querySelector('.image-dialog-form');\n if (!form) return;\n\n const fileInput = form.querySelector('#image-upload') as HTMLInputElement;\n const srcInput = form.querySelector('#image-src') as HTMLInputElement;\n\n fileInput?.addEventListener('change', async (e) => {\n const file = (e.target as HTMLInputElement).files?.[0];\n if (!file) return;\n\n // For now, convert to data URL (base64)\n // In production, this should upload to uploadUrl\n const reader = new FileReader();\n reader.onload = (event) => {\n const dataUrl = event.target?.result as string;\n srcInput.value = dataUrl;\n srcInput.dispatchEvent(new Event('input'));\n };\n reader.readAsDataURL(file);\n });\n }\n\n private isValidImageUrl(url: string): boolean {\n try {\n new URL(url);\n return /\\.(jpg|jpeg|png|gif|svg|webp|bmp)$/i.test(url) || url.startsWith('data:image/');\n } catch {\n return false;\n }\n }\n}\n","import { Dialog } from '../Dialog';\n\n/**\n * MathDialog - Native dialog for mathematical equation insertion\n * \n * Features:\n * - LaTeX input with preview\n * - Common math symbols palette\n * - Insert equations as inline or block\n * - Support for basic math notation\n */\n\nexport interface MathDialogOptions {\n onSubmit: (data: { latex: string; display: 'inline' | 'block' }) => void;\n}\n\nexport class MathDialog {\n private dialog: Dialog;\n private latexInput: HTMLTextAreaElement;\n private previewDiv: HTMLDivElement;\n private displayTypeSelect: HTMLSelectElement;\n private onSubmit: (data: { latex: string; display: 'inline' | 'block' }) => void;\n\n constructor(options: MathDialogOptions) {\n this.onSubmit = options.onSubmit;\n\n // Create dialog content\n const content = this.createContent();\n\n // Initialize dialog\n this.dialog = new Dialog({\n title: 'Insert Math Equation',\n content,\n buttons: [\n {\n label: 'Cancel',\n onClick: () => this.dialog.close()\n },\n {\n label: 'Insert',\n onClick: () => this.handleSubmit(),\n primary: true\n }\n ]\n });\n\n // Get references to form elements\n this.latexInput = content.querySelector('#math-latex') as HTMLTextAreaElement;\n this.previewDiv = content.querySelector('#math-preview') as HTMLDivElement;\n this.displayTypeSelect = content.querySelector('#math-display-type') as HTMLSelectElement;\n\n // Add event listeners\n this.latexInput.addEventListener('input', () => this.updatePreview());\n }\n\n private createContent(): HTMLElement {\n const container = document.createElement('div');\n container.className = 'math-dialog-content';\n container.style.minWidth = '500px';\n\n container.innerHTML = `\n <style>\n .math-dialog-content {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n }\n .math-form-group {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n }\n .math-form-group label {\n font-weight: 500;\n color: #333;\n }\n .math-latex-input {\n width: 100%;\n min-height: 80px;\n padding: 0.5rem;\n border: 1px solid #ddd;\n border-radius: 4px;\n font-family: 'Courier New', monospace;\n font-size: 14px;\n resize: vertical;\n }\n .math-preview {\n padding: 1rem;\n background: #f9f9f9;\n border: 1px solid #ddd;\n border-radius: 4px;\n min-height: 60px;\n font-size: 18px;\n text-align: center;\n }\n .math-preview:empty::before {\n content: 'Preview will appear here...';\n color: #999;\n font-style: italic;\n }\n .math-symbols {\n display: grid;\n grid-template-columns: repeat(8, 1fr);\n gap: 0.5rem;\n padding: 0.5rem;\n background: #f5f5f5;\n border-radius: 4px;\n }\n .math-symbol-btn {\n padding: 0.5rem;\n border: 1px solid #ddd;\n background: white;\n border-radius: 4px;\n cursor: pointer;\n font-size: 18px;\n transition: all 0.2s;\n }\n .math-symbol-btn:hover {\n background: #e3f2fd;\n border-color: #2196f3;\n }\n .math-display-select {\n padding: 0.5rem;\n border: 1px solid #ddd;\n border-radius: 4px;\n font-size: 14px;\n }\n </style>\n\n <div class=\"math-form-group\">\n <label for=\"math-latex\">LaTeX Expression:</label>\n <textarea \n id=\"math-latex\" \n class=\"math-latex-input\"\n placeholder=\"Enter LaTeX (e.g., x^2 + y^2 = r^2)\"\n ></textarea>\n </div>\n\n <div class=\"math-form-group\">\n <label>Common Symbols:</label>\n <div class=\"math-symbols\">\n <button class=\"math-symbol-btn\" data-symbol=\"\\\\frac{a}{b}\" title=\"Fraction\">a/b</button>\n <button class=\"math-symbol-btn\" data-symbol=\"x^{2}\" title=\"Superscript\">x²</button>\n <button class=\"math-symbol-btn\" data-symbol=\"x_{i}\" title=\"Subscript\">xᵢ</button>\n <button class=\"math-symbol-btn\" data-symbol=\"\\\\sqrt{x}\" title=\"Square root\">√x</button>\n <button class=\"math-symbol-btn\" data-symbol=\"\\\\sum\" title=\"Sum\">∑</button>\n <button class=\"math-symbol-btn\" data-symbol=\"\\\\int\" title=\"Integral\">∫</button>\n <button class=\"math-symbol-btn\" data-symbol=\"\\\\pi\" title=\"Pi\">π</button>\n <button class=\"math-symbol-btn\" data-symbol=\"\\\\alpha\" title=\"Alpha\">α</button>\n <button class=\"math-symbol-btn\" data-symbol=\"\\\\beta\" title=\"Beta\">β</button>\n <button class=\"math-symbol-btn\" data-symbol=\"\\\\gamma\" title=\"Gamma\">γ</button>\n <button class=\"math-symbol-btn\" data-symbol=\"\\\\theta\" title=\"Theta\">θ</button>\n <button class=\"math-symbol-btn\" data-symbol=\"\\\\lambda\" title=\"Lambda\">λ</button>\n <button class=\"math-symbol-btn\" data-symbol=\"\\\\infty\" title=\"Infinity\">∞</button>\n <button class=\"math-symbol-btn\" data-symbol=\"\\\\leq\" title=\"Less or equal\">≤</button>\n <button class=\"math-symbol-btn\" data-symbol=\"\\\\geq\" title=\"Greater or equal\">≥</button>\n <button class=\"math-symbol-btn\" data-symbol=\"\\\\neq\" title=\"Not equal\">≠</button>\n </div>\n </div>\n\n <div class=\"math-form-group\">\n <label for=\"math-preview\">Preview:</label>\n <div id=\"math-preview\" class=\"math-preview\"></div>\n </div>\n\n <div class=\"math-form-group\">\n <label for=\"math-display-type\">Display Type:</label>\n <select id=\"math-display-type\" class=\"math-display-select\">\n <option value=\"inline\">Inline (within text)</option>\n <option value=\"block\">Block (centered, new line)</option>\n </select>\n </div>\n `;\n\n // Add symbol button handlers\n const symbolButtons = container.querySelectorAll('.math-symbol-btn');\n symbolButtons.forEach(btn => {\n btn.addEventListener('click', (e) => {\n e.preventDefault();\n const symbol = (btn as HTMLElement).getAttribute('data-symbol');\n if (symbol && this.latexInput) {\n const start = this.latexInput.selectionStart;\n const end = this.latexInput.selectionEnd;\n const text = this.latexInput.value;\n \n this.latexInput.value = text.substring(0, start) + symbol + text.substring(end);\n this.latexInput.focus();\n this.latexInput.selectionStart = this.latexInput.selectionEnd = start + symbol.length;\n \n this.updatePreview();\n }\n });\n });\n\n return container;\n }\n\n private updatePreview(): void {\n const latex = this.latexInput.value.trim();\n \n if (!latex) {\n this.previewDiv.textContent = '';\n return;\n }\n\n // Simple LaTeX to Unicode conversion for preview\n // In production, you'd use MathJax or KaTeX here\n let preview = latex\n .replace(/\\\\frac\\{([^}]+)\\}\\{([^}]+)\\}/g, '($1)/($2)')\n .replace(/\\^\\{([^}]+)\\}/g, '^$1')\n .replace(/\\_\\{([^}]+)\\}/g, '_$1')\n .replace(/\\\\sqrt\\{([^}]+)\\}/g, '√($1)')\n .replace(/\\\\sum/g, '∑')\n .replace(/\\\\int/g, '∫')\n .replace(/\\\\pi/g, 'π')\n .replace(/\\\\alpha/g, 'α')\n .replace(/\\\\beta/g, 'β')\n .replace(/\\\\gamma/g, 'γ')\n .replace(/\\\\theta/g, 'θ')\n .replace(/\\\\lambda/g, 'λ')\n .replace(/\\\\infty/g, '∞')\n .replace(/\\\\leq/g, '≤')\n .replace(/\\\\geq/g, '≥')\n .replace(/\\\\neq/g, '≠');\n\n this.previewDiv.textContent = preview;\n }\n\n private handleSubmit(): void {\n const latex = this.latexInput.value.trim();\n \n if (!latex) {\n alert('Please enter a LaTeX expression.');\n return;\n }\n\n const displayType = this.displayTypeSelect.value as 'inline' | 'block';\n\n this.onSubmit({ latex, display: displayType });\n this.dialog.close();\n }\n\n public show(): void {\n this.dialog.show();\n this.latexInput.value = '';\n this.previewDiv.textContent = '';\n this.displayTypeSelect.value = 'inline';\n \n // Focus the input after dialog opens\n setTimeout(() => this.latexInput.focus(), 100);\n }\n\n public close(): void {\n this.dialog.close();\n }\n}\n","import { Dialog } from '../Dialog';\n\n/**\n * CharacterDialog - Native dialog for special character insertion\n * \n * Features:\n * - Categorized special characters\n * - Search/filter characters\n * - Click to insert\n * - Common symbols, arrows, currency, math\n */\n\nexport interface CharacterDialogOptions {\n onSelect: (character: string) => void;\n}\n\nexport class CharacterDialog {\n private dialog: Dialog;\n private searchInput: HTMLInputElement;\n private categorySelect: HTMLSelectElement;\n private charactersGrid: HTMLDivElement;\n private onSelect: (character: string) => void;\n\n private readonly characters = {\n common: ['©', '®', '™', '§', '¶', '†', '‡', '•', '‣', '⁃', '◦', '▪', '▫', '◊', '○', '●', '□', '■', '△', '▲', '▽', '▼', '◇', '◆', '★', '☆'],\n arrows: ['←', '→', '↑', '↓', '↔', '↕', '⇐', '⇒', '⇑', '⇓', '⇔', '⇕', '⟵', '⟶', '⟷', '↖', '↗', '↘', '↙', '⇖', '⇗', '⇘', '⇙'],\n currency: ['$', '€', '£', '¥', '₹', '₽', '₩', '₪', '₦', '฿', '₴', '₡', '₵', '₸', '₫', '₱', '₲', '₳', '₭'],\n math: ['±', '×', '÷', '=', '≠', '≈', '≡', '≤', '≥', '<', '>', '∞', '∑', '∏', '∫', '∂', '√', '∛', '∜', '°', '′', '″', '∠', '∟', '⊥', '∥'],\n greek: ['α', 'β', 'γ', 'δ', 'ε', 'ζ', 'η', 'θ', 'ι', 'κ', 'λ', 'μ', 'ν', 'ξ', 'ο', 'π', 'ρ', 'σ', 'τ', 'υ', 'φ', 'χ', 'ψ', 'ω', 'Α', 'Β', 'Γ', 'Δ', 'Ε', 'Ζ', 'Η', 'Θ'],\n punctuation: ['\\u201A', '\\u201E', '\\u201C', '\\u201D', '\\u2018', '\\u2019', '«', '»', '‹', '›', '—', '–', '…', '·', '¡', '¿', '‰', '′', '″', '‴'],\n superscript: ['⁰', '¹', '²', '³', '⁴', '⁵', '⁶', '⁷', '⁸', '⁹', '⁺', '⁻', '⁼', '⁽', '⁾', 'ⁿ', 'ⁱ'],\n subscript: ['₀', '₁', '₂', '₃', '₄', '₅', '₆', '₇', '₈', '₉', '₊', '₋', '₌', '₍', '₎']\n };\n\n constructor(options: CharacterDialogOptions) {\n this.onSelect = options.onSelect;\n\n const content = this.createContent();\n\n this.dialog = new Dialog({\n title: 'Insert Special Character',\n content,\n buttons: [\n {\n label: 'Close',\n onClick: () => this.dialog.close()\n }\n ]\n });\n\n this.searchInput = content.querySelector('#char-search') as HTMLInputElement;\n this.categorySelect = content.querySelector('#char-category') as HTMLSelectElement;\n this.charactersGrid = content.querySelector('#char-grid') as HTMLDivElement;\n\n // Add event listeners\n this.searchInput.addEventListener('input', () => this.filterCharacters());\n this.categorySelect.addEventListener('change', () => this.updateGrid());\n\n // Initial render\n this.updateGrid();\n }\n\n private createContent(): HTMLElement {\n const container = document.createElement('div');\n container.className = 'character-dialog-content';\n container.style.minWidth = '500px';\n\n container.innerHTML = `\n <style>\n .character-dialog-content {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n }\n .char-controls {\n display: flex;\n gap: 0.5rem;\n }\n .char-search, .char-category {\n padding: 0.5rem;\n border: 1px solid #ddd;\n border-radius: 4px;\n font-size: 14px;\n }\n .char-search {\n flex: 1;\n }\n .char-category {\n min-width: 150px;\n }\n .char-grid {\n display: grid;\n grid-template-columns: repeat(10, 1fr);\n gap: 0.5rem;\n max-height: 300px;\n overflow-y: auto;\n padding: 1rem;\n background: #f9f9f9;\n border: 1px solid #ddd;\n border-radius: 4px;\n }\n .char-button {\n aspect-ratio: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0.5rem;\n border: 1px solid #ddd;\n background: white;\n border-radius: 4px;\n cursor: pointer;\n font-size: 20px;\n transition: all 0.2s;\n }\n .char-button:hover {\n background: #e3f2fd;\n border-color: #2196f3;\n transform: scale(1.1);\n }\n .char-info {\n padding: 0.5rem;\n background: #f5f5f5;\n border-radius: 4px;\n font-size: 12px;\n color: #666;\n text-align: center;\n }\n </style>\n\n <div class=\"char-controls\">\n <input \n type=\"text\" \n id=\"char-search\" \n class=\"char-search\" \n placeholder=\"Search characters...\"\n />\n <select id=\"char-category\" class=\"char-category\">\n <option value=\"all\">All Categories</option>\n <option value=\"common\">Common Symbols</option>\n <option value=\"arrows\">Arrows</option>\n <option value=\"currency\">Currency</option>\n <option value=\"math\">Mathematics</option>\n <option value=\"greek\">Greek Letters</option>\n <option value=\"punctuation\">Punctuation</option>\n <option value=\"superscript\">Superscript</option>\n <option value=\"subscript\">Subscript</option>\n </select>\n </div>\n\n <div id=\"char-grid\" class=\"char-grid\"></div>\n\n <div class=\"char-info\">\n Click any character to insert it into your document.\n </div>\n `;\n\n return container;\n }\n\n private updateGrid(): void {\n const category = this.categorySelect.value;\n this.charactersGrid.innerHTML = '';\n\n let charactersToShow: string[] = [];\n\n if (category === 'all') {\n charactersToShow = Object.values(this.characters).flat();\n } else {\n charactersToShow = this.characters[category as keyof typeof this.characters] || [];\n }\n\n charactersToShow.forEach(char => {\n const button = document.createElement('button');\n button.className = 'char-button';\n button.textContent = char;\n button.title = `Insert ${char} (U+${char.charCodeAt(0).toString(16).toUpperCase()})`;\n button.addEventListener('click', (e) => {\n e.preventDefault();\n this.handleSelect(char);\n });\n this.charactersGrid.appendChild(button);\n });\n }\n\n private filterCharacters(): void {\n const searchTerm = this.searchInput.value.toLowerCase();\n const buttons = this.charactersGrid.querySelectorAll('.char-button');\n\n buttons.forEach(button => {\n const char = button.textContent || '';\n const unicode = `u+${char.charCodeAt(0).toString(16)}`;\n const visible = !searchTerm || char.includes(searchTerm) || unicode.includes(searchTerm);\n (button as HTMLElement).style.display = visible ? 'flex' : 'none';\n });\n }\n\n private handleSelect(character: string): void {\n this.onSelect(character);\n this.dialog.close();\n }\n\n public show(): void {\n this.dialog.show();\n this.searchInput.value = '';\n this.categorySelect.value = 'all';\n this.updateGrid();\n \n setTimeout(() => this.searchInput.focus(), 100);\n }\n\n public close(): void {\n this.dialog.close();\n }\n}\n","import { Dialog } from '../Dialog';\n\n/**\n * EmojiDialog - Native dialog for emoji insertion\n * \n * Features:\n * - Categorized emojis\n * - Search/filter emojis\n * - Click to insert\n * - Popular emojis, smileys, objects, symbols\n */\n\nexport interface EmojiDialogOptions {\n onSelect: (emoji: string) => void;\n}\n\nexport class EmojiDialog {\n private dialog: Dialog;\n private searchInput: HTMLInputElement;\n private categorySelect: HTMLSelectElement;\n private emojisGrid: HTMLDivElement;\n private onSelect: (emoji: string) => void;\n\n private readonly emojis = {\n popular: ['😀', '😃', '😄', '😁', '😊', '😍', '🤩', '😘', '😗', '😚', '😙', '🙂', '🤗', '🤔', '🤨', '😐', '😑', '😶', '🙄', '😏', '👍', '👎', '👌', '✌️', '🤞', '🤝', '👏', '🙌', '👋', '🤚', '✋', '🖐️', '🖖', '👊', '✊', '🤛', '🤜', '💪'],\n smileys: ['😀', '😃', '😄', '😁', '😆', '😅', '🤣', '😂', '🙂', '🙃', '😉', '😊', '😇', '🥰', '😍', '🤩', '😘', '😗', '😚', '😙', '😋', '😛', '😜', '🤪', '😝', '🤑', '🤗', '🤭', '🤫', '🤔'],\n emotions: ['😳', '😞', '😟', '😠', '😡', '🤬', '😔', '😕', '🙁', '😬', '🥺', '😣', '😖', '😫', '😩', '🥱', '😤', '😮', '😱', '😨', '😰', '😥', '😢', '😭', '😪', '😓', '🤤', '😴', '😷', '🤒'],\n gestures: ['👍', '👎', '👌', '✌️', '🤞', '🤟', '🤘', '🤙', '👈', '👉', '👆', '👇', '☝️', '👋', '🤚', '✋', '🖐️', '🖖', '👏', '🙌', '👐', '🤲', '🤝', '🙏', '✍️', '💅', '🤳', '💪', '🦾', '🦿'],\n people: ['👶', '👧', '🧒', '👦', '👩', '🧑', '👨', '👵', '🧓', '👴', '👲', '👳', '🧕', '👮', '👷', '💂', '🕵️', '👩‍⚕️', '👨‍⚕️', '👩‍🎓', '👨‍🎓', '👩‍🏫', '👨‍🏫', '👩‍⚖️', '👨‍⚖️', '👩‍🌾', '👨‍🌾', '👩‍🍳', '👨‍🍳', '👩‍🔧'],\n animals: ['🐶', '🐱', '🐭', '🐹', '🐰', '🦊', '🐻', '🐼', '🐨', '🐯', '🦁', '🐮', '🐷', '🐸', '🐵', '🙈', '🙉', '🙊', '🐔', '🐧', '🐦', '🐤', '🐣', '🐥', '🦆', '🦅', '🦉', '🦇', '🐺', '🐗'],\n nature: ['🌵', '🎄', '🌲', '🌳', '🌴', '🌱', '🌿', '☘️', '🍀', '🎍', '🎋', '🍃', '🍂', '🍁', '🍄', '🌾', '💐', '🌷', '🌹', '🥀', '🌺', '🌸', '🌼', '🌻', '🌞', '🌝', '🌛', '🌜', '⭐', '🌟'],\n food: ['🍏', '🍎', '🍐', '🍊', '🍋', '🍌', '🍉', '🍇', '🍓', '🍈', '🍒', '🍑', '🥭', '🍍', '🥥', '🥝', '🍅', '🍆', '🥑', '🥦', '🥬', '🥒', '🌶️', '🌽', '🥕', '🧄', '🧅', '🥔', '🍠', '🥐'],\n objects: ['⌚', '📱', '💻', '⌨️', '🖥️', '🖨️', '🖱️', '🕹️', '💾', '💿', '📀', '📷', '📹', '🎥', '📞', '☎️', '📟', '📠', '📺', '📻', '🎙️', '🎚️', '🎛️', '🧭', '⏱️', '⏰', '📡', '🔋', '🔌', '💡'],\n symbols: ['❤️', '🧡', '💛', '💚', '💙', '💜', '🖤', '🤍', '🤎', '💔', '❣️', '💕', '💞', '💓', '💗', '💖', '💘', '💝', '✨', '💫', '⭐', '🌟', '✔️', '✅', '❌', '❎', '➕', '➖', '✖️', '➗'],\n activities: ['⚽', '🏀', '🏈', '⚾', '🥎', '🎾', '🏐', '🏉', '🥏', '🎱', '🪀', '🏓', '🏸', '🏒', '🏑', '🥍', '🏏', '🪃', '🥅', '⛳', '🪁', '🏹', '🎣', '🤿', '🥊', '🥋', '🎽', '🛹', '🛼', '🛷']\n };\n\n constructor(options: EmojiDialogOptions) {\n this.onSelect = options.onSelect;\n\n const content = this.createContent();\n\n this.dialog = new Dialog({\n title: 'Insert Emoji',\n content,\n buttons: [\n {\n label: 'Close',\n onClick: () => this.dialog.close()\n }\n ]\n });\n\n this.searchInput = content.querySelector('#emoji-search') as HTMLInputElement;\n this.categorySelect = content.querySelector('#emoji-category') as HTMLSelectElement;\n this.emojisGrid = content.querySelector('#emoji-grid') as HTMLDivElement;\n\n this.searchInput.addEventListener('input', () => this.filterEmojis());\n this.categorySelect.addEventListener('change', () => this.updateGrid());\n\n this.updateGrid();\n }\n\n private createContent(): HTMLElement {\n const container = document.createElement('div');\n container.className = 'emoji-dialog-content';\n container.style.minWidth = '500px';\n\n container.innerHTML = `\n <style>\n .emoji-dialog-content {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n }\n .emoji-controls {\n display: flex;\n gap: 0.5rem;\n }\n .emoji-search, .emoji-category {\n padding: 0.5rem;\n border: 1px solid #ddd;\n border-radius: 4px;\n font-size: 14px;\n }\n .emoji-search {\n flex: 1;\n }\n .emoji-category {\n min-width: 150px;\n }\n .emoji-grid {\n display: grid;\n grid-template-columns: repeat(10, 1fr);\n gap: 0.5rem;\n max-height: 350px;\n overflow-y: auto;\n padding: 1rem;\n background: #f9f9f9;\n border: 1px solid #ddd;\n border-radius: 4px;\n }\n .emoji-button {\n aspect-ratio: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0.5rem;\n border: 1px solid #ddd;\n background: white;\n border-radius: 4px;\n cursor: pointer;\n font-size: 24px;\n transition: all 0.2s;\n }\n .emoji-button:hover {\n background: #fff3e0;\n border-color: #ff9800;\n transform: scale(1.15);\n }\n .emoji-info {\n padding: 0.5rem;\n background: #f5f5f5;\n border-radius: 4px;\n font-size: 12px;\n color: #666;\n text-align: center;\n }\n </style>\n\n <div class=\"emoji-controls\">\n <input \n type=\"text\" \n id=\"emoji-search\" \n class=\"emoji-search\" \n placeholder=\"Search emojis...\"\n />\n <select id=\"emoji-category\" class=\"emoji-category\">\n <option value=\"all\">All Emojis</option>\n <option value=\"popular\">Popular</option>\n <option value=\"smileys\">Smileys & Faces</option>\n <option value=\"emotions\">Emotions</option>\n <option value=\"gestures\">Gestures & Hands</option>\n <option value=\"people\">People</option>\n <option value=\"animals\">Animals</option>\n <option value=\"nature\">Nature</option>\n <option value=\"food\">Food & Drink</option>\n <option value=\"objects\">Objects</option>\n <option value=\"symbols\">Symbols</option>\n <option value=\"activities\">Activities & Sports</option>\n </select>\n </div>\n\n <div id=\"emoji-grid\" class=\"emoji-grid\"></div>\n\n <div class=\"emoji-info\">\n Click any emoji to insert it into your document.\n </div>\n `;\n\n return container;\n }\n\n private updateGrid(): void {\n const category = this.categorySelect.value;\n this.emojisGrid.innerHTML = '';\n\n let emojisToShow: string[] = [];\n\n if (category === 'all') {\n emojisToShow = Object.values(this.emojis).flat();\n } else {\n emojisToShow = this.emojis[category as keyof typeof this.emojis] || [];\n }\n\n emojisToShow.forEach(emoji => {\n const button = document.createElement('button');\n button.className = 'emoji-button';\n button.textContent = emoji;\n button.title = `Insert ${emoji}`;\n button.addEventListener('click', (e) => {\n e.preventDefault();\n this.handleSelect(emoji);\n });\n this.emojisGrid.appendChild(button);\n });\n }\n\n private filterEmojis(): void {\n const searchTerm = this.searchInput.value.toLowerCase();\n const buttons = this.emojisGrid.querySelectorAll('.emoji-button');\n\n buttons.forEach(button => {\n const emoji = button.textContent || '';\n const visible = !searchTerm || emoji.includes(searchTerm);\n (button as HTMLElement).style.display = visible ? 'flex' : 'none';\n });\n }\n\n private handleSelect(emoji: string): void {\n this.onSelect(emoji);\n this.dialog.close();\n }\n\n public show(): void {\n this.dialog.show();\n this.searchInput.value = '';\n this.categorySelect.value = 'popular';\n this.updateGrid();\n \n setTimeout(() => this.searchInput.focus(), 100);\n }\n\n public close(): void {\n this.dialog.close();\n }\n}\n","/**\n * ReactAdapter - Backward compatibility wrapper for React components\n * Allows existing React usage to work unchanged\n */\n\nimport { Editor, EditorOptions } from '../Editor';\nimport { PluginManager, Plugin } from '../plugins/Plugin';\nimport { EditorEngine } from '../core/EditorEngine';\nimport { ToolbarRenderer } from '../ui/ToolbarRenderer';\nimport { EditorConfigDefaults, ConfigResolver } from '../config/ConfigResolver';\n\nexport interface ReactAdapterOptions {\n plugins?: Plugin[];\n toolbar?: string | boolean | object;\n content?: string;\n readonly?: boolean;\n onChange?: (html: string) => void;\n onInit?: (api: ReactEditorAPI) => void;\n onDestroy?: () => void;\n [key: string]: any;\n}\n\nexport interface ReactEditorAPI {\n getHTML(): string;\n setHTML(html: string): void;\n execCommand(name: string, value?: any): boolean;\n focus(): void;\n blur(): void;\n destroy(): void;\n registerCommand(name: string, fn: (params?: any) => void): void;\n onChange(fn: (html: string) => void): () => void;\n getState(): any;\n toolbar?: { items: any[] };\n}\n\n/**\n * React adapter that wraps the new core engine\n * but provides the same API as the old Editor class\n */\nexport class ReactAdapter {\n private engine: EditorEngine;\n private toolbar?: ToolbarRenderer;\n private contentElement?: HTMLElement;\n private toolbarElement?: HTMLElement;\n private options: ReactAdapterOptions;\n private changeListeners: Array<(html: string) => void> = [];\n\n constructor(options: ReactAdapterOptions = {}) {\n this.options = options;\n \n // Create engine with plugins\n this.engine = new EditorEngine({\n content: options.content,\n plugins: options.plugins || [],\n readonly: options.readonly,\n });\n \n // Setup change listener\n if (options.onChange) {\n this.onChange(options.onChange);\n }\n \n // Setup engine listeners\n this.engine.on('change', () => {\n const html = this.getHTML();\n this.changeListeners.forEach(fn => fn(html));\n });\n }\n\n /**\n * Mount editor to DOM elements\n */\n mount(contentElement: HTMLElement, toolbarElement?: HTMLElement): void {\n this.contentElement = contentElement;\n this.toolbarElement = toolbarElement;\n \n // Setup content element\n this.contentElement.contentEditable = this.options.readonly ? 'false' : 'true';\n this.contentElement.className = 'rte-content';\n \n if (this.options.content) {\n this.contentElement.innerHTML = this.options.content;\n }\n \n // Setup toolbar if enabled\n if (this.options.toolbar !== false && this.toolbarElement) {\n this.toolbar = new ToolbarRenderer(\n {\n items: typeof this.options.toolbar === 'string' ? this.options.toolbar : undefined,\n },\n this.options.plugins || []\n );\n \n this.toolbar.setCommandHandler((command, value) => {\n this.execCommand(command, value);\n });\n \n this.toolbar.render(this.toolbarElement);\n }\n \n // Setup input listener\n this.contentElement.addEventListener('input', () => {\n const html = this.getHTML();\n this.changeListeners.forEach(fn => fn(html));\n });\n \n // Call onInit if provided\n if (this.options.onInit) {\n this.options.onInit(this.getAPI());\n }\n }\n\n /**\n * Get HTML content\n */\n getHTML(): string {\n return this.contentElement?.innerHTML || '';\n }\n\n /**\n * Set HTML content\n */\n setHTML(html: string): void {\n if (this.contentElement) {\n this.contentElement.innerHTML = html;\n }\n }\n\n /**\n * Execute command\n */\n execCommand(name: string, value?: any): boolean {\n const success = this.engine.execCommand(name, value);\n \n // Update toolbar state\n if (this.toolbar && success) {\n // You might want to update button states here\n }\n \n return success;\n }\n\n /**\n * Focus editor\n */\n focus(): void {\n this.contentElement?.focus();\n }\n\n /**\n * Blur editor\n */\n blur(): void {\n this.contentElement?.blur();\n }\n\n /**\n * Register change listener\n */\n onChange(fn: (html: string) => void): () => void {\n this.changeListeners.push(fn);\n \n return () => {\n const index = this.changeListeners.indexOf(fn);\n if (index > -1) {\n this.changeListeners.splice(index, 1);\n }\n };\n }\n\n /**\n * Register command\n */\n registerCommand(name: string, fn: (params?: any) => void): void {\n // Register in global command registry for React components\n if (typeof window !== 'undefined') {\n const registry = (window as any).__editorCommands || new Map();\n registry.set(name, fn);\n (window as any).__editorCommands = registry;\n }\n }\n\n /**\n * Get state\n */\n getState(): any {\n return {\n plugins: this.options.plugins,\n config: this.options,\n engine: this.engine.getState(),\n };\n }\n\n /**\n * Get public API\n */\n getAPI(): ReactEditorAPI {\n return {\n getHTML: () => this.getHTML(),\n setHTML: (html: string) => this.setHTML(html),\n execCommand: (name: string, value?: any) => this.execCommand(name, value),\n focus: () => this.focus(),\n blur: () => this.blur(),\n destroy: () => this.destroy(),\n registerCommand: (name: string, fn: (params?: any) => void) => this.registerCommand(name, fn),\n onChange: (fn: (html: string) => void) => this.onChange(fn),\n getState: () => this.getState(),\n toolbar: {\n items: this.options.plugins?.flatMap(p => p.toolbar || []) || [],\n },\n };\n }\n\n /**\n * Destroy editor\n */\n destroy(): void {\n this.engine.destroy();\n this.toolbar?.destroy();\n this.changeListeners = [];\n \n if (this.options.onDestroy) {\n this.options.onDestroy();\n }\n }\n}\n\n/**\n * Factory function for React adapter\n */\nexport function createReactAdapter(options: ReactAdapterOptions): ReactAdapter {\n return new ReactAdapter(options);\n}\n","/**\n * VanillaAdapter - Pure JavaScript adapter for vanilla JS usage\n */\n\nimport { EditorEngine } from '../core/EditorEngine';\nimport { ToolbarRenderer } from '../ui/ToolbarRenderer';\nimport { Plugin } from '../plugins/Plugin';\n\nexport interface VanillaAdapterOptions {\n element: HTMLElement;\n content?: string;\n plugins?: Plugin[] | string;\n toolbar?: string | boolean;\n readonly?: boolean;\n shortcuts?: boolean;\n enableToolbar?: boolean;\n [key: string]: any;\n}\n\n/**\n * Vanilla JavaScript adapter for browser usage\n */\nexport class VanillaAdapter {\n private engine: EditorEngine;\n private toolbar?: ToolbarRenderer;\n private containerElement: HTMLElement;\n private contentElement?: HTMLElement;\n private toolbarElement?: HTMLElement;\n private options: VanillaAdapterOptions;\n\n constructor(options: VanillaAdapterOptions) {\n this.options = options;\n this.containerElement = options.element;\n \n // Resolve plugins\n const plugins = this.resolvePlugins(options.plugins);\n \n // Create engine\n this.engine = new EditorEngine({\n content: options.content,\n plugins,\n readonly: options.readonly,\n });\n \n // Initialize DOM\n this.initializeDOM();\n }\n\n /**\n * Resolve plugins from string or array\n */\n private resolvePlugins(plugins?: Plugin[] | string): Plugin[] {\n if (!plugins) return [];\n \n if (typeof plugins === 'string') {\n // Parse plugin string and load from registry\n // For now, return empty array\n console.warn('String-based plugin loading not yet implemented for VanillaAdapter');\n return [];\n }\n \n return plugins;\n }\n\n /**\n * Initialize DOM elements\n */\n private initializeDOM(): void {\n this.containerElement.innerHTML = '';\n this.containerElement.classList.add('editora-editor');\n \n // Create toolbar if enabled\n if (this.options.enableToolbar !== false && this.options.toolbar !== false) {\n this.toolbarElement = document.createElement('div');\n this.toolbarElement.className = 'editora-toolbar-container';\n this.containerElement.appendChild(this.toolbarElement);\n \n this.toolbar = new ToolbarRenderer(\n {\n items: typeof this.options.toolbar === 'string' ? this.options.toolbar : undefined,\n },\n this.options.plugins as Plugin[] || []\n );\n \n this.toolbar.setCommandHandler((command, value) => {\n this.execCommand(command, value);\n });\n \n this.toolbar.render(this.toolbarElement);\n }\n \n // Create content area\n this.contentElement = document.createElement('div');\n this.contentElement.className = 'editora-content';\n this.contentElement.contentEditable = this.options.readonly ? 'false' : 'true';\n this.contentElement.style.minHeight = '200px';\n this.contentElement.style.outline = 'none';\n this.contentElement.style.padding = '12px';\n \n if (this.options.content) {\n this.contentElement.innerHTML = this.options.content;\n }\n \n this.containerElement.appendChild(this.contentElement);\n \n // Setup listeners\n this.contentElement.addEventListener('input', () => {\n this.containerElement.dispatchEvent(new CustomEvent('change', {\n detail: { html: this.getContent() },\n }));\n });\n }\n\n /**\n * Get content\n */\n getContent(): string {\n return this.contentElement?.innerHTML || '';\n }\n\n /**\n * Set content\n */\n setContent(html: string): void {\n if (this.contentElement) {\n this.contentElement.innerHTML = html;\n }\n }\n\n /**\n * Execute command\n */\n execCommand(name: string, value?: any): boolean {\n return this.engine.execCommand(name, value);\n }\n\n /**\n * Focus editor\n */\n focus(): void {\n this.contentElement?.focus();\n }\n\n /**\n * Add event listener\n */\n on(event: string, handler: (data: any) => void): () => void {\n const listener = (e: Event) => {\n handler((e as CustomEvent).detail);\n };\n \n this.containerElement.addEventListener(event, listener);\n \n return () => {\n this.containerElement.removeEventListener(event, listener);\n };\n }\n\n /**\n * Destroy editor\n */\n destroy(): void {\n this.engine.destroy();\n this.toolbar?.destroy();\n this.containerElement.innerHTML = '';\n }\n}\n","// Legacy exports (backward compatibility)\nexport { Editor } from './Editor';\nexport { EditorState } from './EditorState';\nexport type { EditorSelection } from './EditorState';\nexport { Schema } from './schema/Node';\nexport type { Node, NodeSpec } from './schema/Node';\nexport { PluginManager } from './plugins/Plugin';\nexport type { Plugin, ToolbarItem } from './plugins/Plugin';\nexport { PluginRuntime, createPluginRuntime } from './plugins/PluginRuntime';\nexport type { PluginRuntimeContext } from './plugins/PluginRuntime';\n\n// Keyboard Shortcuts\nexport { KeyboardShortcutManager } from './KeyboardShortcuts';\nexport type { KeyboardShortcut, KeyboardShortcutConfig } from './KeyboardShortcuts';\n\n// Enterprise plugins\nexport { SpellcheckPlugin, MediaPlugin } from './plugins/enterprise';\nexport type { SpellcheckConfig, MediaConfig } from './plugins/enterprise';\n\n// New architecture exports\n// Core layer\nexport * from './core';\n\n// UI layer\nexport * from './ui';\n\n// Utils\nexport * from './utils/statusBarUtils';\n\n// Config layer\nexport * from './config';\n\n// Adapters\nexport * from './adapters';\n\n// Web Component\nexport * from './webcomponent';\n\n// Convenience factory functions\nimport { VanillaAdapter } from './adapters/VanillaAdapter';\nimport { RichTextEditorElement } from './webcomponent/RichTextEditor';\n\n/**\n * Create editor instance for vanilla JavaScript usage\n * @example\n * const editor = Editora.createEditor({\n * element: document.getElementById('editor'),\n * plugins: 'bold italic link',\n * toolbar: 'undo redo | bold italic | link'\n * });\n */\nexport function createEditor(options: any) {\n return new VanillaAdapter(options);\n}\n\n/**\n * Initialize Web Component globally\n * Allows usage via <editora-editor> HTML tag\n * \n * NOTE: Auto-initialization is disabled here to avoid conflicts.\n * The standalone.native.ts bundle handles web component registration.\n */\nexport function initWebComponent() {\n if (typeof window !== 'undefined' && !customElements.get('editora-editor')) {\n customElements.define('editora-editor', RichTextEditorElement);\n }\n}\n\n// Auto-initialization DISABLED - handled by standalone bundles\n// if (typeof window !== 'undefined') {\n// initWebComponent();\n// }\n"],"names":["Editor","pluginManagerOrOptions","PluginManager","options","plugin","schema","EditorState","fn","toolbarButtons","shortcutMap","button","event","parts","key","shortcut","command","commandId","value","item","btn","state","l","name","newState","doc","PluginRuntime","context","_a","_b","error","args","commandFn","createPluginRuntime","KeyboardShortcutManager","config","i","commandExecutor","eventKey","s","shortcuts","grouped","category","help","desc","SpellcheckPlugin","enabled","provider","apiUrl","apiHeaders","language","customDictionary","ignoreAllCaps","ignoreNumbers","word","MediaPlugin","uploadUrl","libraryUrl","maxFileSize","allowedTypes","headers","withCredentials","chunkSize","enableChunking","onProgress","onError","onSuccess","file","DocumentModel","selection","Dialog","dialog","body","closeBtn","cancelBtn","okBtn","e","rect","form","formData","inputs","input","_d","_c","Dropdown","container","selected","o","displayText","opt","toggle","menu","label","ColorPicker","color","colorInput","textInput","preset","LinkDialog","initialUrl","initialText","onSubmit","onCancel","url","text","openInNewTab","div","TableDialog","rows","cols","headerRow","rowsInput","colsInput","headerCheckbox","preview","updatePreview","hasHeader","ImageDialog","src","alt","width","height","srcInput","previewContainer","previewImg","fileInput","reader","dataUrl","MathDialog","content","symbol","start","end","latex","displayType","CharacterDialog","charactersToShow","char","searchTerm","unicode","visible","character","EmojiDialog","emojisToShow","emoji","ReactAdapter","EditorEngine","html","contentElement","toolbarElement","ToolbarRenderer","success","index","registry","p","createReactAdapter","VanillaAdapter","plugins","handler","listener","createEditor","initWebComponent","RichTextEditorElement"],"mappings":"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"}