@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.
- package/README.md +9 -0
- package/dist/A11yCheckerPlugin.native-CZKpi3uF.mjs +475 -0
- package/dist/A11yCheckerPlugin.native-CZKpi3uF.mjs.map +1 -0
- package/dist/AnchorPlugin.native-7es9PVZ9.mjs +340 -0
- package/dist/AnchorPlugin.native-7es9PVZ9.mjs.map +1 -0
- package/dist/BackgroundColorPlugin.native-Dip5uqTg.mjs +449 -0
- package/dist/BackgroundColorPlugin.native-Dip5uqTg.mjs.map +1 -0
- package/dist/BlockquotePlugin.native-JFmOLsxN.mjs +48 -0
- package/dist/BlockquotePlugin.native-JFmOLsxN.mjs.map +1 -0
- package/dist/BoldPlugin.native-BAzzoqU5.mjs +45 -0
- package/dist/BoldPlugin.native-BAzzoqU5.mjs.map +1 -0
- package/dist/CapitalizationPlugin.native-DOMsh5R7.mjs +79 -0
- package/dist/CapitalizationPlugin.native-DOMsh5R7.mjs.map +1 -0
- package/dist/ChecklistPlugin.native-Dccs3nLe.mjs +153 -0
- package/dist/ChecklistPlugin.native-Dccs3nLe.mjs.map +1 -0
- package/dist/ClearFormattingPlugin.native-BZPDHswo.mjs +27 -0
- package/dist/ClearFormattingPlugin.native-BZPDHswo.mjs.map +1 -0
- package/dist/CodePlugin.native-DD9xFIid.mjs +1679 -0
- package/dist/CodePlugin.native-DD9xFIid.mjs.map +1 -0
- package/dist/CodeSamplePlugin.native-DMbEdO9j.mjs +326 -0
- package/dist/CodeSamplePlugin.native-DMbEdO9j.mjs.map +1 -0
- package/dist/CommentsPlugin.native-2zQV8Ia4.mjs +473 -0
- package/dist/CommentsPlugin.native-2zQV8Ia4.mjs.map +1 -0
- package/dist/DirectionPlugin.native-Be7wCzkI.mjs +59 -0
- package/dist/DirectionPlugin.native-Be7wCzkI.mjs.map +1 -0
- package/dist/DocumentManagerPlugin.native-BvZL5CSG.mjs +116 -0
- package/dist/DocumentManagerPlugin.native-BvZL5CSG.mjs.map +1 -0
- package/dist/EmbedIframePlugin.native-ifr9KLdN.mjs +461 -0
- package/dist/EmbedIframePlugin.native-ifr9KLdN.mjs.map +1 -0
- package/dist/EmojisPlugin.native-D6mJSnSR.mjs +1033 -0
- package/dist/EmojisPlugin.native-D6mJSnSR.mjs.map +1 -0
- package/dist/FontFamilyPlugin.native-BzS_9qbM.mjs +106 -0
- package/dist/FontFamilyPlugin.native-BzS_9qbM.mjs.map +1 -0
- package/dist/FontSizePlugin.native-DkLMLPue.mjs +186 -0
- package/dist/FontSizePlugin.native-DkLMLPue.mjs.map +1 -0
- package/dist/FootnotePlugin.native-BciVc9W6.mjs +128 -0
- package/dist/FootnotePlugin.native-BciVc9W6.mjs.map +1 -0
- package/dist/FullscreenPlugin.native-ChXyxeNw.mjs +77 -0
- package/dist/FullscreenPlugin.native-ChXyxeNw.mjs.map +1 -0
- package/dist/HeadingPlugin.native-DrLYwQnQ.mjs +64 -0
- package/dist/HeadingPlugin.native-DrLYwQnQ.mjs.map +1 -0
- package/dist/HistoryPlugin.native-DoDRifCf.mjs +89 -0
- package/dist/HistoryPlugin.native-DoDRifCf.mjs.map +1 -0
- package/dist/IndentPlugin.native-CbFugPoi.mjs +133 -0
- package/dist/IndentPlugin.native-CbFugPoi.mjs.map +1 -0
- package/dist/ItalicPlugin.native-CQjjDyUL.mjs +43 -0
- package/dist/ItalicPlugin.native-CQjjDyUL.mjs.map +1 -0
- package/dist/LineHeightPlugin.native-CWQT2FIa.mjs +73 -0
- package/dist/LineHeightPlugin.native-CWQT2FIa.mjs.map +1 -0
- package/dist/LinkPlugin.native-BdAOV-iu.mjs +206 -0
- package/dist/LinkPlugin.native-BdAOV-iu.mjs.map +1 -0
- package/dist/ListPlugin.native-CLFU5AUQ.mjs +59 -0
- package/dist/ListPlugin.native-CLFU5AUQ.mjs.map +1 -0
- package/dist/MathPlugin.native-DE_ii-LA.mjs +182 -0
- package/dist/MathPlugin.native-DE_ii-LA.mjs.map +1 -0
- package/dist/MediaManagerPlugin.native-DaYFDzNM.mjs +533 -0
- package/dist/MediaManagerPlugin.native-DaYFDzNM.mjs.map +1 -0
- package/dist/MergeTagPlugin.native-CrxyThyn.mjs +178 -0
- package/dist/MergeTagPlugin.native-CrxyThyn.mjs.map +1 -0
- package/dist/PageBreakPlugin.native-DDjcDyRW.mjs +172 -0
- package/dist/PageBreakPlugin.native-DDjcDyRW.mjs.map +1 -0
- package/dist/PreviewPlugin.native-DBvfpmIv.mjs +322 -0
- package/dist/PreviewPlugin.native-DBvfpmIv.mjs.map +1 -0
- package/dist/PrintPlugin.native-BUpm52VJ.mjs +311 -0
- package/dist/PrintPlugin.native-BUpm52VJ.mjs.map +1 -0
- package/dist/SpecialCharactersPlugin.native-x7a2SWXc.mjs +731 -0
- package/dist/SpecialCharactersPlugin.native-x7a2SWXc.mjs.map +1 -0
- package/dist/SpellCheckPlugin.native-B7yTh0iE.mjs +465 -0
- package/dist/SpellCheckPlugin.native-B7yTh0iE.mjs.map +1 -0
- package/dist/StrikethroughPlugin.native-ChaZLaXw.mjs +43 -0
- package/dist/StrikethroughPlugin.native-ChaZLaXw.mjs.map +1 -0
- package/dist/TablePlugin.native-EEWXn1-s.mjs +491 -0
- package/dist/TablePlugin.native-EEWXn1-s.mjs.map +1 -0
- package/dist/TemplatePlugin.native-BlSn1c9h.mjs +564 -0
- package/dist/TemplatePlugin.native-BlSn1c9h.mjs.map +1 -0
- package/dist/TextAlignmentPlugin.native-CQIs1m7R.mjs +97 -0
- package/dist/TextAlignmentPlugin.native-CQIs1m7R.mjs.map +1 -0
- package/dist/TextColorPlugin.native-D6SmTglm.mjs +432 -0
- package/dist/TextColorPlugin.native-D6SmTglm.mjs.map +1 -0
- package/dist/UnderlinePlugin.native-QpIcK4L2.mjs +35 -0
- package/dist/UnderlinePlugin.native-QpIcK4L2.mjs.map +1 -0
- package/dist/core.css +1 -0
- package/dist/documentManager-irzj9n3V.mjs +37627 -0
- package/dist/documentManager-irzj9n3V.mjs.map +1 -0
- package/dist/editorContainerHelpers-C7kdWnS0.mjs +27 -0
- package/dist/editorContainerHelpers-C7kdWnS0.mjs.map +1 -0
- package/dist/editora.min.js +519 -4
- package/dist/editora.min.js.map +1 -0
- package/dist/editora.umd.js +519 -4
- package/dist/editora.umd.js.map +1 -0
- package/dist/index-BF5RBhL9.js +4 -0
- package/dist/index-BF5RBhL9.js.map +1 -0
- package/dist/index-BPsf460l.mjs +1243 -0
- package/dist/index-BPsf460l.mjs.map +1 -0
- package/dist/index.cjs.js +517 -4
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.es-CuicffkQ.mjs +6665 -0
- package/dist/index.es-CuicffkQ.mjs.map +1 -0
- package/dist/index.esm.js +1403 -122
- package/dist/index.esm.js.map +1 -0
- package/dist/plugin-loader.js +55 -0
- package/dist/plugin-loader.js.map +1 -0
- package/dist/purify.es-CKpwg8Tk.mjs +471 -0
- package/dist/purify.es-CKpwg8Tk.mjs.map +1 -0
- package/dist/webcomponent-core.js +1243 -0
- package/dist/webcomponent-core.js.map +1 -0
- package/dist/webcomponent-core.min.css +1 -0
- package/dist/webcomponent-core.min.js +597 -0
- package/dist/webcomponent-core.min.js.map +1 -0
- package/dist/webcomponent.cjs.js +2 -0
- package/dist/webcomponent.cjs.js.map +1 -0
- package/dist/webcomponent.esm.js +6 -0
- package/dist/webcomponent.esm.js.map +1 -0
- package/dist/webcomponent.js +1286 -0
- package/dist/webcomponent.js.map +1 -0
- package/dist/webcomponent.min.css +1 -0
- package/dist/webcomponent.min.js +4076 -0
- package/dist/webcomponent.min.js.map +1 -0
- package/package.json +64 -6
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"editora.min.js","sources":["../src/EditorState.ts","../src/schema/Node.ts","../src/plugins/Plugin.ts","../src/Editor.ts","../src/plugins/PluginRuntime.ts","../src/KeyboardShortcuts.ts","../src/plugins/enterprise/SpellcheckPlugin.ts","../src/plugins/enterprise/MediaPlugin.ts","../src/core/CommandRegistry.ts","../src/core/EditorEngine.ts","../src/core/DocumentModel.ts","../src/ui/ToolbarRenderer.ts","../src/ui/FloatingToolbar.ts","../src/ui/StatusBar.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/utils/statusBarUtils.ts","../src/config/ConfigResolver.ts","../src/config/PluginLoader.ts","../src/adapters/ReactAdapter.ts","../src/adapters/VanillaAdapter.ts","../src/webcomponent/RichTextEditor.ts","../src/index.ts"],"sourcesContent":["import { Node, Schema } from './schema/Node';\n\nexport interface EditorSelection {\n anchor: number;\n head: number;\n}\n\nexport class EditorState {\n doc: Node;\n selection: EditorSelection;\n schema: Schema;\n\n constructor(doc: Node, selection: EditorSelection, schema: Schema) {\n this.doc = doc;\n this.selection = selection;\n this.schema = schema;\n }\n\n static create(schema: Schema, content?: Node): EditorState {\n const doc = content || schema.node('doc', {}, [schema.node('paragraph')]);\n return new EditorState(doc, { anchor: 0, head: 0 }, schema);\n }\n\n apply(doc: Node, selection?: EditorSelection): EditorState {\n return new EditorState(doc, selection || this.selection, this.schema);\n }\n}\n","export interface NodeSpec {\n content?: string;\n marks?: string;\n group?: string;\n inline?: boolean;\n attrs?: Record<string, any>;\n toDOM?: (node: Node) => [string, Record<string, any>?, ...any[]];\n parseDOM?: Array<{\n tag: string;\n getAttrs?: (dom: HTMLElement) => Record<string, any> | null;\n }>;\n}\n\nexport interface Node {\n type: string;\n content?: Node[];\n text?: string;\n marks?: string[];\n attrs?: Record<string, any>;\n}\n\nexport class Schema {\n nodes: Map<string, NodeSpec>;\n marks: Map<string, NodeSpec>;\n\n constructor(nodes: Record<string, NodeSpec>, marks: Record<string, NodeSpec>) {\n this.nodes = new Map(Object.entries(nodes));\n this.marks = new Map(Object.entries(marks));\n }\n\n node(type: string, attrs?: Record<string, any>, content?: Node[]): Node {\n return { type, attrs, content };\n }\n\n text(text: string, marks?: string[]): Node {\n return { type: 'text', text, marks };\n }\n}\n","import { Schema, NodeSpec } from '../schema/Node';\nimport { EditorState } from '../EditorState';\nimport React from 'react';\n\nexport interface ToolbarItem {\n id?: string;\n label: string;\n command?: string;\n icon?: string;\n type?:\n | \"button\"\n | \"dropdown\"\n | \"input\"\n | \"inline-menu\"\n | \"separator\"\n | \"group\";\n options?: Array<{ label: string; value: string }>;\n placeholder?: string;\n shortcut?: string;\n items?: ToolbarItem[]; // For groups and dropdowns\n}\n\nexport interface PluginContext {\n provider?: React.FC<{ children: React.ReactNode }>;\n initialize?: () => void;\n destroy?: () => void;\n onEditorReady?: (editor: any) => void;\n}\n\n/**\n * Plugin operation modes\n * - local: All operations happen client-side only\n * - api: All operations require API calls\n * - hybrid: Tries API first, falls back to local\n */\nexport type PluginMode = 'local' | 'api' | 'hybrid';\n\n/**\n * Plugin configuration\n */\nexport interface PluginConfig {\n mode?: PluginMode;\n apiUrl?: string;\n apiKey?: string;\n timeout?: number;\n fallbackToLocal?: boolean;\n retryAttempts?: number;\n offline?: {\n enabled?: boolean;\n cacheStrategy?: 'memory' | 'indexeddb' | 'localstorage';\n };\n [key: string]: any;\n}\n\nexport interface Plugin {\n name: string;\n nodes?: Record<string, NodeSpec>;\n marks?: Record<string, NodeSpec>;\n commands?: Record<string, (state: EditorState, ...args: any[]) => EditorState | null>;\n toolbar?: ToolbarItem[];\n context?: PluginContext;\n config?: PluginConfig;\n \n // Lifecycle hooks\n initialize?: (config?: PluginConfig) => void | Promise<void>;\n destroy?: () => void | Promise<void>;\n \n // Mode-specific operations\n executeLocal?: (command: string, ...args: any[]) => any;\n executeAPI?: (command: string, ...args: any[]) => Promise<any>;\n executeHybrid?: (command: string, ...args: any[]) => Promise<any>;\n}\n\nexport class PluginManager {\n plugins: Plugin[] = [];\n private pluginConfigs: Map<string, PluginConfig> = new Map();\n\n register(plugin: Plugin, config?: PluginConfig): void {\n this.plugins.push(plugin);\n \n if (config) {\n this.pluginConfigs.set(plugin.name, config);\n }\n \n // Initialize plugin if it has an initialize method\n if (plugin.initialize) {\n const pluginConfig = this.pluginConfigs.get(plugin.name) || plugin.config;\n plugin.initialize(pluginConfig);\n }\n }\n\n unregister(pluginName: string): void {\n const index = this.plugins.findIndex(p => p.name === pluginName);\n if (index > -1) {\n const plugin = this.plugins[index];\n \n // Destroy plugin if it has a destroy method\n if (plugin.destroy) {\n plugin.destroy();\n }\n \n this.plugins.splice(index, 1);\n this.pluginConfigs.delete(pluginName);\n }\n }\n\n getPlugin(name: string): Plugin | undefined {\n return this.plugins.find(p => p.name === name);\n }\n\n getPluginConfig(name: string): PluginConfig | undefined {\n return this.pluginConfigs.get(name);\n }\n\n buildSchema(): Schema {\n const nodes: Record<string, NodeSpec> = {};\n const marks: Record<string, NodeSpec> = {};\n\n this.plugins.forEach(plugin => {\n if (plugin.nodes) Object.assign(nodes, plugin.nodes);\n if (plugin.marks) Object.assign(marks, plugin.marks);\n });\n\n return new Schema(nodes, marks);\n }\n\n getCommands(): Record<string, (state: EditorState, ...args: any[]) => EditorState | null> {\n const commands: Record<string, (state: EditorState, ...args: any[]) => EditorState | null> = {};\n this.plugins.forEach(plugin => {\n if (plugin.commands) Object.assign(commands, plugin.commands);\n });\n return commands;\n }\n\n getToolbarItems(): ToolbarItem[] {\n return this.plugins.flatMap(p => p.toolbar || []);\n }\n\n /**\n * Execute plugin command with mode awareness\n */\n async executePluginCommand(\n pluginName: string,\n command: string,\n ...args: any[]\n ): Promise<any> {\n const plugin = this.getPlugin(pluginName);\n if (!plugin) {\n throw new Error(`Plugin not found: ${pluginName}`);\n }\n\n const config = this.getPluginConfig(pluginName) || plugin.config || {};\n const mode = config.mode || 'local';\n\n try {\n switch (mode) {\n case 'local':\n return plugin.executeLocal ? plugin.executeLocal(command, ...args) : null;\n\n case 'api':\n if (!plugin.executeAPI) {\n throw new Error(`Plugin ${pluginName} does not support API mode`);\n }\n return await plugin.executeAPI(command, ...args);\n\n case 'hybrid':\n if (plugin.executeHybrid) {\n return await plugin.executeHybrid(command, ...args);\n }\n \n // Default hybrid implementation: try API, fall back to local\n try {\n if (plugin.executeAPI) {\n return await plugin.executeAPI(command, ...args);\n }\n } catch (error) {\n console.warn(`API execution failed for ${pluginName}, falling back to local`, error);\n if (plugin.executeLocal && config.fallbackToLocal !== false) {\n return plugin.executeLocal(command, ...args);\n }\n throw error;\n }\n break;\n\n default:\n throw new Error(`Unknown plugin mode: ${mode}`);\n }\n } catch (error) {\n console.error(`Error executing command ${command} on plugin ${pluginName}:`, error);\n throw error;\n }\n }\n\n /**\n * Destroy all plugins\n */\n async destroyAll(): Promise<void> {\n const destroyPromises = this.plugins\n .filter(p => p.destroy)\n .map(p => p.destroy!());\n\n await Promise.all(destroyPromises);\n this.plugins = [];\n this.pluginConfigs.clear();\n }\n}\n","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 * CommandRegistry - Centralized command management\n */\n\nimport { EditorState } from '../EditorState';\n\nexport type CommandHandler = (state: EditorState, value?: any) => EditorState | null;\n\nexport class CommandRegistry {\n private commands: Map<string, CommandHandler> = new Map();\n\n constructor(initialCommands: Record<string, CommandHandler> = {}) {\n Object.entries(initialCommands).forEach(([name, handler]) => {\n this.register(name, handler);\n });\n }\n\n /**\n * Register a command\n */\n register(name: string, handler: CommandHandler): void {\n if (this.commands.has(name)) {\n console.warn(`Command ${name} is being overwritten`);\n }\n this.commands.set(name, handler);\n }\n\n /**\n * Unregister a command\n */\n unregister(name: string): void {\n this.commands.delete(name);\n }\n\n /**\n * Get a command handler\n */\n get(name: string): CommandHandler | undefined {\n return this.commands.get(name);\n }\n\n /**\n * Check if command exists\n */\n has(name: string): boolean {\n return this.commands.has(name);\n }\n\n /**\n * Get all command names\n */\n getCommandNames(): string[] {\n return Array.from(this.commands.keys());\n }\n\n /**\n * Clear all commands\n */\n clear(): void {\n this.commands.clear();\n }\n}\n","/**\n * EditorEngine - Core editor logic, framework-agnostic\n * Manages document model, selection, commands, and plugin registry\n */\n\nimport { EditorState } from '../EditorState';\nimport { PluginManager } from '../plugins/Plugin';\nimport { Schema } from '../schema/Node';\nimport { CommandRegistry } from './CommandRegistry';\n\nexport interface EditorEngineConfig {\n content?: string;\n plugins?: any[];\n readonly?: boolean;\n autofocus?: boolean;\n sanitize?: boolean;\n maxLength?: number;\n debounceDelay?: number;\n}\n\nexport class EditorEngine {\n state: EditorState;\n pluginManager: PluginManager;\n commandRegistry: CommandRegistry;\n private listeners: Map<string, Array<(...args: any[]) => void>> = new Map();\n private isReadonly: boolean = false;\n private isDestroyed: boolean = false;\n\n constructor(config: EditorEngineConfig = {}) {\n this.isReadonly = config.readonly || false;\n \n // Initialize plugin manager\n this.pluginManager = new PluginManager();\n if (config.plugins && Array.isArray(config.plugins)) {\n config.plugins.forEach(plugin => this.pluginManager.register(plugin));\n }\n \n // Build schema from plugins\n const schema = this.pluginManager.buildSchema();\n this.state = EditorState.create(schema);\n \n // Initialize command registry\n this.commandRegistry = new CommandRegistry(this.pluginManager.getCommands());\n }\n\n /**\n * Execute a command\n */\n execCommand(name: string, value?: any): boolean {\n if (this.isReadonly) {\n console.warn('Cannot execute commands in readonly mode');\n return false;\n }\n\n if (this.isDestroyed) {\n console.warn('Cannot execute commands on destroyed editor');\n return false;\n }\n\n const command = this.commandRegistry.get(name);\n if (!command) {\n console.warn(`Command not found: ${name}`);\n return false;\n }\n \n let newState: EditorState | null;\n \n if (value !== undefined) {\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 this.emit('change', this.state);\n return true;\n }\n return false;\n }\n\n /**\n * Update editor state\n */\n setState(state: EditorState): void {\n if (this.isDestroyed) return;\n \n this.state = state;\n this.emit('stateChange', state);\n }\n\n /**\n * Get current state\n */\n getState(): EditorState {\n return this.state;\n }\n\n /**\n * Set readonly mode\n */\n setReadonly(readonly: boolean): void {\n this.isReadonly = readonly;\n this.emit('readonlyChange', readonly);\n }\n\n /**\n * Check if readonly\n */\n isReadOnly(): boolean {\n return this.isReadonly;\n }\n\n /**\n * Event emitter\n */\n on(event: string, handler: (...args: any[]) => void): () => void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, []);\n }\n \n this.listeners.get(event)!.push(handler);\n \n // Return unsubscribe function\n return () => {\n const handlers = this.listeners.get(event);\n if (handlers) {\n const index = handlers.indexOf(handler);\n if (index > -1) {\n handlers.splice(index, 1);\n }\n }\n };\n }\n\n /**\n * Emit event\n */\n private emit(event: string, ...args: any[]): void {\n const handlers = this.listeners.get(event);\n if (handlers) {\n handlers.forEach(handler => {\n try {\n handler(...args);\n } catch (error) {\n console.error(`Error in ${event} handler:`, error);\n }\n });\n }\n }\n\n /**\n * Destroy editor instance\n */\n destroy(): void {\n if (this.isDestroyed) return;\n \n this.isDestroyed = true;\n this.listeners.clear();\n this.emit('destroy');\n }\n\n /**\n * Check if destroyed\n */\n isEditorDestroyed(): boolean {\n return this.isDestroyed;\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 * ToolbarRenderer - Framework-agnostic toolbar rendering\n */\n\nimport { Plugin, ToolbarItem } from '../plugins/Plugin';\n\nexport interface ToolbarConfig {\n items?: string; // \"undo redo | bold italic | media table\"\n sticky?: boolean;\n position?: 'top' | 'bottom';\n floating?: boolean;\n}\n\nexport interface ToolbarButton {\n id: string;\n label: string;\n command?: string;\n icon?: string;\n type?: 'button' | 'dropdown' | 'input' | 'separator' | 'inline-menu' | 'group';\n options?: Array<{ label: string; value: string }>;\n active?: boolean;\n disabled?: boolean;\n items?: ToolbarButton[]; // For groups\n}\n\nexport class ToolbarRenderer {\n private config: ToolbarConfig;\n private plugins: Plugin[];\n private container?: HTMLElement;\n private commandHandler?: (command: string, value?: any) => void;\n private pluginLoader?: any; // PluginLoader instance to get all registered plugins\n\n constructor(config: ToolbarConfig, plugins: Plugin[], pluginLoader?: any) {\n this.config = config;\n this.plugins = plugins;\n this.pluginLoader = pluginLoader;\n }\n\n /**\n * Set command handler for toolbar buttons\n */\n setCommandHandler(handler: (command: string, value?: any) => void): void {\n this.commandHandler = handler;\n }\n\n /**\n * Parse toolbar string into button groups\n */\n private parseToolbarString(toolbarString: string): ToolbarButton[][] {\n const groups: ToolbarButton[][] = [];\n const sections = toolbarString.split(\"|\").map((s) => s.trim());\n\n const allToolbarItems = this.getAvailableToolbarItems();\n // Index items by command and by label (for group types with no command)\n const itemMap = new Map<string, ToolbarItem>();\n allToolbarItems.forEach((item) => {\n if (item.command) itemMap.set(item.command, item);\n if (item.type === \"group\" && item.label) itemMap.set(item.label, item);\n });\n\n // Common command aliases for backward compatibility\n const aliases: Record<string, string> = {\n bold: \"toggleBold\",\n italic: \"toggleItalic\",\n underline: \"toggleUnderline\",\n strikethrough: \"toggleStrikethrough\",\n bullist: \"toggleBulletList\",\n numlist: \"toggleOrderedList\",\n checklist: \"toggleChecklist\",\n link: \"openLinkDialog\",\n image: \"openImageDialog\",\n table: \"insertTable\",\n anchor: \"insertAnchor\",\n code: \"toggleSourceView\",\n blockquote: \"toggleBlockquote\",\n undo: \"undo\",\n redo: \"redo\",\n textColor: \"openTextColorPicker\",\n backgroundColor: \"openBackgroundColorPicker\",\n fontSize: \"fontSize\",\n fontFamily: \"setFontFamily\",\n lineHeight: \"setLineHeight\",\n heading: \"setBlockType\",\n paragraph: \"setParagraph\",\n textAlignment: \"setTextAlignment\",\n direction: \"setDirectionLTR\",\n indent: \"increaseIndent\",\n outdent: \"decreaseIndent\",\n capitalization: \"setCapitalization\",\n math: \"insertMath\",\n specialCharacters: \"insertSpecialCharacter\",\n emojis: \"openEmojiDialog\",\n embedIframe: \"openEmbedIframeDialog\",\n fullscreen: \"toggleFullscreen\",\n preview: \"togglePreview\",\n print: \"print\",\n a11yChecker: \"toggleA11yChecker\",\n spellCheck: \"toggleSpellCheck\",\n comments: \"addComment\",\n showHideComments: \"toggleComments\",\n toggleComments: \"toggleComments\",\n footnote: \"insertFootnote\",\n mergeTags: \"insertMergeTag\",\n pageBreak: \"insertPageBreak\",\n template: \"insertTemplate\",\n importWord: \"importWord\",\n exportWord: \"exportWord\",\n exportPdf: \"exportPdf\",\n insertImage: \"insertImage\",\n insertVideo: \"insertVideo\",\n codeBlock: \"insertCodeBlock\",\n };\n\n sections.forEach((section) => {\n const buttons: ToolbarButton[] = [];\n const commands = section.split(/\\s+/).filter(Boolean);\n\n commands.forEach((cmd) => {\n // Special handling for multi-button shortcuts\n if (cmd === \"direction\") {\n // Direction has two buttons: LTR and RTL\n const ltrItem = itemMap.get(\"setDirectionLTR\");\n const rtlItem = itemMap.get(\"setDirectionRTL\");\n if (ltrItem) {\n buttons.push({\n id: \"directionLTR\",\n label: ltrItem.label,\n command: ltrItem.command,\n icon: ltrItem.icon,\n type: ltrItem.type || \"button\",\n options: ltrItem.options,\n });\n }\n if (rtlItem) {\n buttons.push({\n id: \"directionRTL\",\n label: rtlItem.label,\n command: rtlItem.command,\n icon: rtlItem.icon,\n type: rtlItem.type || \"button\",\n options: rtlItem.options,\n });\n }\n return;\n }\n\n if (cmd === \"comments\") {\n // Comments has two buttons: Add Comment and Toggle Comments\n const addCommentItem = itemMap.get(\"addComment\");\n const toggleCommentsItem = itemMap.get(\"toggleComments\");\n if (addCommentItem) {\n buttons.push({\n id: \"addComment\",\n label: addCommentItem.label,\n command: addCommentItem.command,\n icon: addCommentItem.icon,\n type: addCommentItem.type || \"button\",\n options: addCommentItem.options,\n });\n }\n if (toggleCommentsItem) {\n buttons.push({\n id: \"toggleComments\",\n label: toggleCommentsItem.label,\n command: toggleCommentsItem.command,\n icon: toggleCommentsItem.icon,\n type: toggleCommentsItem.type || \"button\",\n options: toggleCommentsItem.options,\n });\n }\n return;\n }\n\n // Try direct command first, then alias\n const actualCommand = aliases[cmd] || cmd;\n let item = itemMap.get(actualCommand);\n // If not found by command, try by label (for group type)\n if (!item) item = itemMap.get(cmd);\n if (item) {\n buttons.push({\n id: cmd,\n label: item.label,\n command: item.command,\n icon: item.icon,\n type:\n item.type === \"separator\" ? \"separator\" : item.type || \"button\",\n options: item.options,\n items: item.items,\n });\n }\n });\n\n if (buttons.length > 0) {\n groups.push(buttons);\n }\n });\n\n return groups;\n }\n\n /**\n * Get all available toolbar items from plugins\n */\n private getAvailableToolbarItems(): ToolbarItem[] {\n // Use the plugins that were passed to the constructor - they should be loaded\n const items = this.plugins.flatMap((p) => p.toolbar || []);\n return items;\n }\n\n /**\n * Render toolbar to DOM element\n */\n render(container: HTMLElement): void {\n this.container = container;\n container.innerHTML = \"\";\n container.className = \"editora-toolbar\";\n\n if (this.config.sticky) {\n container.classList.add(\"editora-toolbar-sticky\");\n }\n\n if (this.config.position) {\n container.classList.add(`editora-toolbar-${this.config.position}`);\n }\n\n const toolbarString = this.config.items || this.getDefaultToolbarString();\n const buttonGroups = this.parseToolbarString(toolbarString);\n buttonGroups.forEach((group, groupIndex) => {\n const groupEl = document.createElement(\"div\");\n groupEl.className = \"editora-toolbar-group\";\n group.forEach((button) => {\n this.appendToolbarButton(groupEl, button);\n });\n container.appendChild(groupEl);\n // Add separator between groups (except last)\n if (groupIndex < buttonGroups.length - 1) {\n const separator = document.createElement(\"div\");\n separator.className = \"editora-toolbar-separator\";\n container.appendChild(separator);\n }\n });\n }\n\n /**\n * Append a toolbar button or group to a parent element\n */\n private appendToolbarButton(\n parent: HTMLElement,\n button: ToolbarButton,\n ): void {\n if (button.type === \"separator\") {\n const separator = document.createElement(\"div\");\n separator.className = \"editora-toolbar-separator\";\n parent.appendChild(separator);\n } else if (button.type === \"dropdown\") {\n const dropdownEl = this.createDropdown(button);\n parent.appendChild(dropdownEl);\n } else if (button.type === \"inline-menu\") {\n const inlineMenuEl = this.createInlineMenu(button);\n parent.appendChild(inlineMenuEl);\n } else if (button.type === \"group\" && button.items && button.items.length) {\n const groupButtonEl = this.createGroupButton(button);\n parent.appendChild(groupButtonEl);\n } else if (button.type === \"input\") {\n const inputEl = this.createInput(button);\n parent.appendChild(inputEl);\n } else {\n const buttonEl = this.createButton(button);\n parent.appendChild(buttonEl);\n }\n }\n\n /**\n * Create a toolbar button element\n */\n private createGroupButton(button: ToolbarButton): HTMLElement {\n const el = document.createElement(\"div\");\n el.className = \"editora-toolbar-group-button\";\n el.title = button.label;\n // Optionally add a label or icon for the group itself\n if (button.icon) {\n if (button.icon.startsWith(\"<svg\") && button.icon.endsWith(\"</svg>\")) {\n const iconWrapper = document.createElement(\"span\");\n iconWrapper.className = \"editora-toolbar-icon\";\n iconWrapper.innerHTML = button.icon;\n el.appendChild(iconWrapper);\n } else {\n el.innerHTML = button.icon;\n }\n }\n // Recursively render group items\n if (button.items && button.items.length) {\n const itemsContainer = document.createElement(\"div\");\n itemsContainer.className = \"editora-toolbar-group-items\";\n button.items.forEach((child) => {\n this.appendToolbarButton(itemsContainer, child);\n });\n el.appendChild(itemsContainer);\n }\n return el;\n }\n\n /**\n * Create a toolbar button element\n */\n private createInput(button: ToolbarButton): HTMLElement {\n const el = document.createElement(\"input\");\n el.className = `editora-toolbar-input ${button.label.toLowerCase().replace(/\\s+/g, \"-\")}`;\n el.type = \"text\";\n el.title = button.label;\n el.placeholder = button.placeholder || \"\";\n el.setAttribute(\"data-command\", button.command);\n\n if (button.active) {\n el.classList.add(\"active\");\n }\n\n if (button.disabled) {\n el.disabled = true;\n }\n\n el.addEventListener(\"click\", (e) => {\n e.preventDefault();\n if (this.commandHandler) {\n this.commandHandler(button.command);\n }\n });\n\n return el;\n }\n\n /**\n * Create a toolbar button element\n */\n private createButton(button: ToolbarButton): HTMLElement {\n const el = document.createElement(\"button\");\n el.className = \"editora-toolbar-button\";\n el.type = \"button\";\n el.title = button.label;\n el.setAttribute(\"data-command\", button.command);\n\n if (button.icon) {\n // Check if it's an SVG icon\n if (button.icon.startsWith(\"<svg\") && button.icon.endsWith(\"</svg>\")) {\n // Create a wrapper span for the SVG with proper styling\n const iconWrapper = document.createElement(\"span\");\n iconWrapper.className = \"editora-toolbar-icon\";\n iconWrapper.innerHTML = button.icon;\n el.appendChild(iconWrapper);\n } else {\n // Plain text icon or HTML\n el.innerHTML = button.icon;\n }\n } else {\n el.textContent = button.label;\n }\n\n if (button.active) {\n el.classList.add(\"active\");\n }\n\n if (button.disabled) {\n el.disabled = true;\n }\n\n el.addEventListener(\"click\", (e) => {\n e.preventDefault();\n if (this.commandHandler) {\n this.commandHandler(button.command);\n }\n });\n\n return el;\n }\n\n /**\n * Create a dropdown element\n */\n private createDropdown(button: ToolbarButton): HTMLElement {\n const container = document.createElement(\"div\");\n container.className = \"editora-toolbar-dropdown\";\n\n const trigger = document.createElement(\"button\");\n trigger.className =\n \"editora-toolbar-button editora-toolbar-dropdown-trigger\";\n trigger.type = \"button\";\n trigger.textContent = button.label;\n\n const menu = document.createElement(\"div\");\n menu.className = \"editora-toolbar-dropdown-menu\";\n menu.style.display = \"none\";\n\n if (button.options) {\n button.options.forEach((option) => {\n const item = document.createElement(\"button\");\n item.className = \"editora-toolbar-dropdown-item\";\n item.type = \"button\";\n item.textContent = option.label;\n item.setAttribute(\"data-value\", option.value);\n\n item.addEventListener(\"click\", (e) => {\n e.preventDefault();\n if (this.commandHandler) {\n this.commandHandler(button.command, option.value);\n }\n menu.style.display = \"none\";\n });\n\n menu.appendChild(item);\n });\n }\n\n trigger.addEventListener(\"click\", (e) => {\n e.preventDefault();\n e.stopPropagation();\n const isOpen = menu.style.display === \"block\";\n menu.style.display = isOpen ? \"none\" : \"block\";\n });\n\n // Close dropdown when clicking outside\n const closeDropdown = (e: Event) => {\n if (!container.contains(e.target as Node)) {\n menu.style.display = \"none\";\n }\n };\n\n document.addEventListener(\"click\", closeDropdown);\n\n // Store the cleanup function for later removal\n (container as any)._cleanupDropdown = () => {\n document.removeEventListener(\"click\", closeDropdown);\n };\n\n container.appendChild(trigger);\n container.appendChild(menu);\n\n return container;\n }\n\n /**\n * Create an inline menu element (like dropdown but triggered by button click)\n */\n private createInlineMenu(button: ToolbarButton): HTMLElement {\n const container = document.createElement(\"div\");\n container.className =\n \"editora-toolbar-dropdown editora-toolbar-inline-menu\";\n\n const trigger = document.createElement(\"button\");\n trigger.className = \"editora-toolbar-button\";\n trigger.type = \"button\";\n trigger.title = button.label;\n\n // Add icon if available\n if (button.icon) {\n if (button.icon.startsWith(\"<svg\") && button.icon.endsWith(\"</svg>\")) {\n const iconWrapper = document.createElement(\"span\");\n iconWrapper.className = \"editora-toolbar-icon\";\n iconWrapper.innerHTML = button.icon;\n trigger.appendChild(iconWrapper);\n } else {\n trigger.innerHTML = button.icon;\n }\n } else {\n trigger.textContent = button.label;\n }\n\n const menu = document.createElement(\"div\");\n menu.className = \"editora-toolbar-dropdown-menu\";\n menu.style.display = \"none\";\n\n if (button.options) {\n button.options.forEach((option) => {\n const item = document.createElement(\"button\");\n item.className = \"editora-toolbar-dropdown-item\";\n item.type = \"button\";\n item.textContent = option.label;\n item.setAttribute(\"data-value\", option.value);\n\n item.addEventListener(\"click\", (e) => {\n e.preventDefault();\n e.stopPropagation();\n if (this.commandHandler) {\n this.commandHandler(button.command, option.value);\n }\n menu.style.display = \"none\";\n });\n\n menu.appendChild(item);\n });\n }\n\n trigger.addEventListener(\"click\", (e) => {\n e.preventDefault();\n e.stopPropagation();\n\n // Close all other menus\n const allMenus = this.container?.querySelectorAll(\n \".editora-toolbar-dropdown-menu\",\n );\n allMenus?.forEach((m) => {\n if (m !== menu) {\n (m as HTMLElement).style.display = \"none\";\n }\n });\n\n // Toggle this menu\n menu.style.display = menu.style.display === \"none\" ? \"block\" : \"none\";\n });\n\n // Close menu when clicking outside\n document.addEventListener(\"click\", (e) => {\n if (!container.contains(e.target as Node)) {\n menu.style.display = \"none\";\n }\n });\n\n container.appendChild(trigger);\n container.appendChild(menu);\n\n return container;\n }\n\n /**\n * Get default toolbar string if none provided\n */\n private getDefaultToolbarString(): string {\n const items = this.getAvailableToolbarItems();\n return items.map((item) => item.command).join(\" \");\n }\n\n /**\n * Update button state\n */\n updateButtonState(\n command: string,\n state: { active?: boolean; disabled?: boolean },\n ): void {\n if (!this.container) return;\n\n const button = this.container.querySelector(\n `[data-command=\"${command}\"]`,\n ) as HTMLButtonElement;\n if (button) {\n if (state.active !== undefined) {\n button.classList.toggle(\"active\", state.active);\n }\n if (state.disabled !== undefined) {\n button.disabled = state.disabled;\n }\n }\n }\n\n /**\n * Destroy toolbar\n */\n destroy(): void {\n if (this.container) {\n // Clean up dropdown event listeners\n const dropdowns = this.container.querySelectorAll('.editora-toolbar-dropdown');\n dropdowns.forEach(dropdown => {\n const cleanup = (dropdown as any)._cleanupDropdown;\n if (cleanup) {\n cleanup();\n }\n });\n this.container.innerHTML = \"\";\n }\n this.commandHandler = undefined;\n }\n}\n","/**\n * FloatingToolbar - Context-sensitive floating toolbar\n */\n\nexport interface FloatingToolbarConfig {\n enabled?: boolean;\n items?: string;\n anchorToSelection?: boolean;\n}\n\nexport class FloatingToolbar {\n private config: FloatingToolbarConfig;\n private container?: HTMLElement;\n private visible: boolean = false;\n\n constructor(config: FloatingToolbarConfig) {\n this.config = config;\n }\n\n /**\n * Create and mount floating toolbar\n */\n create(parentElement: HTMLElement): HTMLElement {\n const container = document.createElement('div');\n container.className = 'editora-floating-toolbar';\n container.style.display = 'none';\n container.style.position = 'absolute';\n container.style.zIndex = '1000';\n \n this.container = container;\n parentElement.appendChild(container);\n \n return container;\n }\n\n /**\n * Show toolbar at position\n */\n show(x: number, y: number): void {\n if (!this.container) return;\n \n this.container.style.display = 'block';\n this.container.style.left = `${x}px`;\n this.container.style.top = `${y}px`;\n this.visible = true;\n }\n\n /**\n * Hide toolbar\n */\n hide(): void {\n if (!this.container) return;\n \n this.container.style.display = 'none';\n this.visible = false;\n }\n\n /**\n * Update position\n */\n updatePosition(x: number, y: number): void {\n if (!this.container || !this.visible) return;\n \n this.container.style.left = `${x}px`;\n this.container.style.top = `${y}px`;\n }\n\n /**\n * Check if visible\n */\n isVisible(): boolean {\n return this.visible;\n }\n\n /**\n * Destroy floating toolbar\n */\n destroy(): void {\n if (this.container && this.container.parentNode) {\n this.container.parentNode.removeChild(this.container);\n }\n this.container = undefined;\n this.visible = false;\n }\n}\n","/**\n * StatusBar - Editor status information display\n */\n\nexport interface StatusBarConfig {\n enabled?: boolean;\n position?: 'top' | 'bottom';\n}\n\nexport interface StatusInfo {\n wordCount?: number;\n charCount?: number;\n lineCount?: number;\n language?: string;\n cursorPosition?: {\n line: number;\n column: number;\n };\n selectionInfo?: {\n startLine: number;\n startColumn: number;\n endLine: number;\n endColumn: number;\n selectedChars: number;\n selectedWords: number;\n };\n custom?: Record<string, string>;\n}\n\nexport class StatusBar {\n private config: StatusBarConfig;\n private container?: HTMLElement;\n private statusInfo: StatusInfo = {};\n\n constructor(config: StatusBarConfig = {}) {\n this.config = config;\n }\n\n /**\n * Create and mount status bar\n */\n create(parentElement: HTMLElement): HTMLElement {\n const container = document.createElement('div');\n container.className = 'editora-statusbar';\n \n if (this.config.position) {\n container.classList.add(`editora-statusbar-${this.config.position}`);\n }\n \n this.container = container;\n parentElement.appendChild(container);\n \n return container;\n }\n\n /**\n * Update status information\n */\n update(info: StatusInfo): void {\n this.statusInfo = { ...this.statusInfo, ...info };\n this.render();\n }\n\n /**\n * Render status bar content\n */\n private render(): void {\n if (!this.container) return;\n\n this.container.innerHTML = '';\n\n // Create left section\n const leftSection = document.createElement('div');\n leftSection.className = 'editora-statusbar-left';\n\n // Create right section\n const rightSection = document.createElement('div');\n rightSection.className = 'editora-statusbar-right';\n\n // Left section: Cursor position and selection info\n const leftItems: string[] = [];\n\n if (this.statusInfo.selectionInfo) {\n const sel = this.statusInfo.selectionInfo;\n if (sel.startLine === sel.endLine && sel.startColumn === sel.endColumn) {\n // Cursor position only\n leftItems.push(`Ln ${sel.startLine}, Col ${sel.startColumn}`);\n } else {\n // Selection info\n if (sel.startLine === sel.endLine) {\n leftItems.push(`Ln ${sel.startLine}, Col ${sel.startColumn}-${sel.endColumn}`);\n } else {\n leftItems.push(`Ln ${sel.startLine}:${sel.startColumn} - ${sel.endLine}:${sel.endColumn}`);\n }\n leftItems.push(`${sel.selectedChars} chars selected`);\n }\n } else if (this.statusInfo.cursorPosition) {\n const pos = this.statusInfo.cursorPosition;\n leftItems.push(`Ln ${pos.line}, Col ${pos.column}`);\n }\n\n if (this.statusInfo.language) {\n leftItems.push(this.statusInfo.language);\n }\n\n // Right section: Word count and character count\n const rightItems: string[] = [];\n\n if (this.statusInfo.wordCount !== undefined) {\n rightItems.push(`${this.statusInfo.wordCount} words`);\n }\n\n if (this.statusInfo.charCount !== undefined) {\n rightItems.push(`${this.statusInfo.charCount} chars`);\n }\n\n if (this.statusInfo.lineCount !== undefined) {\n rightItems.push(`${this.statusInfo.lineCount} lines`);\n }\n\n // Add custom items to right section\n if (this.statusInfo.custom) {\n Object.entries(this.statusInfo.custom).forEach(([key, value]) => {\n rightItems.push(`${key}: ${value}`);\n });\n }\n\n // Render left section\n leftItems.forEach((item, index) => {\n const span = document.createElement('span');\n span.className = 'editora-statusbar-item';\n span.textContent = item;\n leftSection.appendChild(span);\n\n if (index < leftItems.length - 1) {\n const separator = document.createElement('span');\n separator.className = 'editora-statusbar-separator';\n separator.textContent = '|';\n leftSection.appendChild(separator);\n }\n });\n\n // Render right section\n rightItems.forEach((item, index) => {\n const span = document.createElement('span');\n span.className = 'editora-statusbar-item';\n span.textContent = item;\n rightSection.appendChild(span);\n\n if (index < rightItems.length - 1) {\n const separator = document.createElement('span');\n separator.className = 'editora-statusbar-separator';\n separator.textContent = '|';\n rightSection.appendChild(separator);\n }\n });\n\n // Add sections to container\n this.container.appendChild(leftSection);\n this.container.appendChild(rightSection);\n }\n\n /**\n * Destroy status bar\n */\n destroy(): void {\n if (this.container && this.container.parentNode) {\n this.container.parentNode.removeChild(this.container);\n }\n this.container = undefined;\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\">×</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 * Utility functions for status bar calculations\n */\n\n/**\n * Get cursor position (line and column) from a range within a content element\n */\nexport function getCursorPosition(contentElement: HTMLElement, range: Range): { line: number; column: number } {\n const text = contentElement.textContent || '';\n const startOffset = getTextOffset(contentElement, range.startContainer, range.startOffset);\n\n // Count lines up to the cursor position\n const textBeforeCursor = text.substring(0, startOffset);\n const lines = textBeforeCursor.split('\\n');\n const line = lines.length;\n const column = lines[lines.length - 1].length + 1;\n\n return { line, column };\n}\n\n/**\n * Get text offset from a DOM node and offset within a root element\n */\nexport function getTextOffset(rootElement: HTMLElement, node: Node, offset: number): number {\n let textOffset = 0;\n const walker = document.createTreeWalker(\n rootElement,\n NodeFilter.SHOW_TEXT,\n null\n );\n\n let currentNode = walker.firstChild();\n while (currentNode) {\n if (currentNode === node) {\n textOffset += offset;\n break;\n } else if (currentNode.nodeType === Node.TEXT_NODE) {\n textOffset += currentNode.textContent?.length || 0;\n }\n currentNode = walker.nextNode();\n }\n\n return textOffset;\n}\n\n/**\n * Count lines in a contentEditable element by analyzing block-level elements\n */\nexport function countLines(contentElement: HTMLElement): number {\n // Count block-level elements and br tags that represent line breaks\n const blocks = contentElement.querySelectorAll('div, p, br, h1, h2, h3, h4, h5, h6, blockquote, li, pre');\n let lineCount = 1; // At least 1 line\n\n // If there are block elements, count them as separate lines\n if (blocks.length > 0) {\n lineCount = blocks.length;\n // If the last element is empty or just a br, it might represent an additional empty line\n const lastBlock = blocks[blocks.length - 1];\n if (lastBlock.tagName === 'BR' ||\n (lastBlock as HTMLElement).innerHTML?.trim() === '' ||\n lastBlock.textContent?.trim() === '') {\n lineCount++;\n }\n } else {\n // No block elements, fall back to text-based line counting\n const text = contentElement.textContent || '';\n const textLines = text.split('\\n').length;\n lineCount = Math.max(1, textLines);\n }\n\n return lineCount;\n}\n\n/**\n * Calculate word and character counts from text\n */\nexport function calculateTextStats(text: string): { words: number; chars: number } {\n const words = text.trim() ? text.trim().split(/\\s+/).length : 0;\n const chars = text.length;\n return { words, chars };\n}\n\n/**\n * Get selection information from a range\n */\nexport function getSelectionInfo(range: Range, cursorPosition: { line: number; column: number }) {\n const selectedText = range.toString();\n return {\n startLine: cursorPosition.line,\n startColumn: cursorPosition.column,\n endLine: cursorPosition.line, // For now, assuming single line selections\n endColumn: cursorPosition.column + selectedText.length,\n selectedChars: selectedText.length,\n selectedWords: selectedText.trim().split(/\\s+/).filter(Boolean).length\n };\n}","/**\n * ConfigResolver - Configuration resolution with priority handling\n * Priority: Explicit JS config > Web Component attributes > Plugin defaults > Editor defaults\n */\n\nexport interface EditorConfigDefaults {\n height?: number | string;\n width?: number | string;\n readonly?: boolean;\n disabled?: boolean;\n menubar?: boolean;\n toolbar?: string | boolean;\n plugins?: string | string[];\n theme?: string;\n content?: string;\n placeholder?: string;\n autofocus?: boolean;\n autosave?: boolean | { interval?: number };\n spellcheck?: boolean | { mode?: 'local' | 'api' | 'hybrid'; apiUrl?: string };\n language?: string;\n [key: string]: any;\n}\n\nexport interface ConfigSource {\n jsConfig?: EditorConfigDefaults;\n attributes?: Record<string, string>;\n pluginDefaults?: EditorConfigDefaults;\n editorDefaults?: EditorConfigDefaults;\n}\n\nexport class ConfigResolver {\n private static readonly EDITOR_DEFAULTS: EditorConfigDefaults = {\n height: 400,\n width: '100%',\n readonly: false,\n disabled: false,\n menubar: true,\n toolbar: true,\n plugins: [],\n theme: 'light',\n content: '',\n placeholder: 'Start typing...',\n autofocus: false,\n autosave: false,\n spellcheck: false,\n language: 'en',\n };\n\n /**\n * Resolve configuration from multiple sources with priority\n */\n static resolve(sources: ConfigSource): EditorConfigDefaults {\n const config: EditorConfigDefaults = {};\n \n // Start with editor defaults\n Object.assign(config, this.EDITOR_DEFAULTS);\n \n // Apply plugin defaults\n if (sources.pluginDefaults) {\n Object.assign(config, sources.pluginDefaults);\n }\n \n // Apply web component attributes\n if (sources.attributes) {\n const parsedAttributes = this.parseAttributes(sources.attributes);\n Object.assign(config, parsedAttributes);\n }\n \n // Apply explicit JS config (highest priority)\n if (sources.jsConfig) {\n Object.assign(config, sources.jsConfig);\n }\n \n return config;\n }\n\n /**\n * Parse web component attributes\n */\n private static parseAttributes(attributes: Record<string, string>): EditorConfigDefaults {\n const config: EditorConfigDefaults = {};\n \n for (const [key, value] of Object.entries(attributes)) {\n const camelKey = this.kebabToCamel(key);\n config[camelKey] = this.parseAttributeValue(value);\n }\n \n return config;\n }\n\n /**\n * Parse attribute value to appropriate type\n */\n private static parseAttributeValue(value: string): any {\n // Boolean\n if (value === 'true') return true;\n if (value === 'false') return false;\n \n // Number\n if (/^\\d+$/.test(value)) return parseInt(value, 10);\n if (/^\\d+\\.\\d+$/.test(value)) return parseFloat(value);\n \n // JSON\n if (value.startsWith('{') || value.startsWith('[')) {\n try {\n return JSON.parse(value);\n } catch {\n return value;\n }\n }\n \n // String\n return value;\n }\n\n /**\n * Convert kebab-case to camelCase\n */\n private static kebabToCamel(str: string): string {\n return str.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());\n }\n\n /**\n * Validate configuration\n */\n static validate(config: EditorConfigDefaults): { valid: boolean; errors: string[] } {\n const errors: string[] = [];\n \n // Validate height\n if (config.height !== undefined) {\n if (typeof config.height === 'number' && config.height < 0) {\n errors.push('height must be a positive number');\n }\n }\n \n // Validate width\n if (config.width !== undefined) {\n if (typeof config.width === 'number' && config.width < 0) {\n errors.push('width must be a positive number');\n }\n }\n \n // Validate plugins\n if (config.plugins !== undefined) {\n if (!Array.isArray(config.plugins) && typeof config.plugins !== 'string') {\n errors.push('plugins must be an array or string');\n }\n }\n \n // Validate theme\n if (config.theme !== undefined) {\n if (typeof config.theme !== 'string') {\n errors.push('theme must be a string');\n }\n }\n \n return {\n valid: errors.length === 0,\n errors,\n };\n }\n\n /**\n * Get default configuration\n */\n static getDefaults(): EditorConfigDefaults {\n return { ...this.EDITOR_DEFAULTS };\n }\n\n /**\n * Merge configurations (deep merge)\n */\n static merge(...configs: EditorConfigDefaults[]): EditorConfigDefaults {\n const result: EditorConfigDefaults = {};\n \n for (const config of configs) {\n for (const [key, value] of Object.entries(config)) {\n if (value !== undefined && value !== null) {\n if (typeof value === 'object' && !Array.isArray(value) && result[key]) {\n // Deep merge objects\n result[key] = this.merge(result[key], value);\n } else {\n result[key] = value;\n }\n }\n }\n }\n \n return result;\n }\n}\n","/**\n * PluginLoader - Dynamic plugin loading and resolution\n */\n\nimport { Plugin } from '../plugins/Plugin';\n\nexport interface PluginLoadConfig {\n mode?: 'local' | 'api' | 'hybrid';\n apiUrl?: string;\n fallbackToLocal?: boolean;\n}\n\nexport class PluginLoader {\n private loadedPlugins: Map<string, Plugin> = new Map();\n private pluginRegistry: Map<string, () => Plugin | Promise<Plugin>> = new Map();\n\n /**\n * Register a plugin factory (sync or async)\n */\n register(name: string, factory: () => Plugin | Promise<Plugin>): void {\n this.pluginRegistry.set(name, factory);\n }\n\n /**\n * Load a plugin by name (async)\n */\n async load(name: string, config?: PluginLoadConfig): Promise<Plugin | null> {\n // Check if already loaded\n if (this.loadedPlugins.has(name)) {\n return this.loadedPlugins.get(name)!;\n }\n \n // Check if registered\n const factory = this.pluginRegistry.get(name);\n if (!factory) {\n console.warn(`Plugin not found: ${name}`);\n return null;\n }\n \n // Create plugin instance (may be async)\n const plugin = await factory();\n \n // Apply config if provided\n if (config) {\n this.applyPluginConfig(plugin, config);\n }\n \n this.loadedPlugins.set(name, plugin);\n return plugin;\n }\n\n /**\n * Load multiple plugins\n */\n async loadMultiple(names: string[], config?: PluginLoadConfig): Promise<Plugin[]> {\n const plugins = await Promise.all(\n names.map(name => this.load(name, config))\n );\n return plugins.filter((p): p is Plugin => p !== null);\n }\n\n /**\n * Parse plugin string \"lists link image media\"\n */\n async parsePluginString(pluginString: string, config?: PluginLoadConfig): Promise<Plugin[]> {\n const names = pluginString.split(/\\s+/).filter(Boolean);\n return this.loadMultiple(names, config);\n }\n\n /**\n * Apply configuration to plugin\n */\n private applyPluginConfig(plugin: Plugin, config: PluginLoadConfig): void {\n // Store config on plugin instance for runtime use\n (plugin as any).__pluginConfig = config;\n }\n\n /**\n * Unload a plugin\n */\n unload(name: string): void {\n this.loadedPlugins.delete(name);\n }\n\n /**\n * Clear all loaded plugins\n */\n clear(): void {\n this.loadedPlugins.clear();\n }\n\n /**\n * Get all loaded plugins\n */\n getLoadedPlugins(): Plugin[] {\n return Array.from(this.loadedPlugins.values());\n }\n\n /**\n * Get all registered plugin names (available for loading)\n */\n getRegisteredPluginNames(): string[] {\n return Array.from(this.pluginRegistry.keys());\n }\n\n /**\n * Check if plugin is loaded\n */\n isLoaded(name: string): boolean {\n return this.loadedPlugins.has(name);\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","/**\n * RichTextEditor Web Component\n * TinyMCE-style declarative API for framework-agnostic usage\n */\n\nimport { EditorEngine } from '../core/EditorEngine';\nimport { ToolbarRenderer } from '../ui/ToolbarRenderer';\nimport { FloatingToolbar } from '../ui/FloatingToolbar';\nimport { StatusBar } from '../ui/StatusBar';\nimport { getCursorPosition, countLines, calculateTextStats, getSelectionInfo } from '../utils/statusBarUtils';\nimport { ConfigResolver, EditorConfigDefaults } from '../config/ConfigResolver';\nimport { PluginLoader } from '../config/PluginLoader';\nimport { Plugin } from '../plugins/Plugin';\n\n// Import styles\nimport styles from './styles.css?inline';\n\n// Global plugin registry for the web component\n// Will be set by standalone.ts before custom element definition\nlet globalPluginRegistry: PluginLoader;\n\n/**\n * Inject styles into document head if not already present\n */\nfunction injectStyles(): void {\n const styleId = 'editora-webcomponent-styles';\n if (!document.getElementById(styleId)) {\n const styleElement = document.createElement('style');\n styleElement.id = styleId;\n styleElement.textContent = styles;\n document.head.appendChild(styleElement);\n }\n}\n\n/**\n * Get or create the global plugin registry\n */\nfunction getGlobalRegistry(): PluginLoader {\n if (!globalPluginRegistry) {\n // Check if it was set externally (by standalone.ts)\n const externalRegistry = (RichTextEditorElement as any).__globalPluginLoader;\n if (externalRegistry) {\n globalPluginRegistry = externalRegistry;\n } else {\n // Fallback: create new registry\n globalPluginRegistry = new PluginLoader();\n }\n }\n return globalPluginRegistry;\n}\n\n/**\n * Initialize web component with plugin factories\n * This should be called once to register all available plugins\n */\nexport function initWebComponent(plugins: Record<string, () => Plugin>): void {\n const registry = getGlobalRegistry();\n Object.entries(plugins).forEach(([name, factory]) => {\n registry.register(name, factory);\n });\n}\n\nexport class RichTextEditorElement extends HTMLElement {\n private engine?: EditorEngine;\n private toolbar?: ToolbarRenderer;\n private floatingToolbar?: FloatingToolbar;\n private statusBar?: StatusBar;\n private pluginLoader: PluginLoader;\n private config: EditorConfigDefaults = {};\n private contentElement?: HTMLElement;\n private toolbarElement?: HTMLElement;\n private statusBarElement?: HTMLElement;\n private jsConfig?: EditorConfigDefaults;\n private isInitialized = false;\n\n // Observed attributes for reactive updates\n static get observedAttributes(): string[] {\n return [\n 'height',\n 'width',\n 'menubar',\n 'plugins',\n 'toolbar',\n 'toolbar-items',\n 'readonly',\n 'disabled',\n 'theme',\n 'placeholder',\n 'autofocus',\n 'language',\n 'spellcheck',\n 'statusbar',\n ];\n }\n\n constructor() {\n super();\n \n // Inject styles into document head\n injectStyles();\n\n // Capture initial content before any processing\n if (!this.hasAttribute('data-initial-content')) {\n const content = this.innerHTML.trim();\n if (content) {\n this.setAttribute('data-initial-content', content);\n }\n }\n }\n\n /**\n * Called when element is added to DOM\n */\n connectedCallback(): void {\n // Resolve configuration\n this.config = this.resolveConfig();\n \n // Wait for plugin loader to be available, then initialize\n this.waitForPluginLoader().then(() => {\n // Defer initialization to ensure DOM is fully ready\n setTimeout(async () => {\n await this.initialize();\n }, 0);\n });\n }\n\n /**\n * Wait for the global plugin loader to be available\n */\n private async waitForPluginLoader(): Promise<void> {\n // If already available, return immediately\n if ((RichTextEditorElement as any).__globalPluginLoader) {\n this.pluginLoader = (RichTextEditorElement as any).__globalPluginLoader;\n return;\n }\n \n // Wait for it to become available\n return new Promise((resolve) => {\n const checkLoader = () => {\n if ((RichTextEditorElement as any).__globalPluginLoader) {\n this.pluginLoader = (RichTextEditorElement as any).__globalPluginLoader;\n resolve();\n } else {\n // Check again in next tick\n setTimeout(checkLoader, 0);\n }\n };\n checkLoader();\n });\n }\n\n /**\n * Called when element is removed from DOM\n */\n disconnectedCallback(): void {\n this.destroy();\n }\n\n /**\n * Called when an observed attribute changes\n */\n attributeChangedCallback(name: string, oldValue: string, newValue: string): void {\n if (oldValue === newValue) return;\n \n // Update config and reinitialize affected parts\n this.config = this.resolveConfig();\n this.handleAttributeChange(name, newValue);\n }\n\n /**\n * Set configuration via JavaScript API\n */\n async setConfig(config: EditorConfigDefaults): Promise<void> {\n this.jsConfig = config;\n this.config = this.resolveConfig();\n \n // Reinitialize if already connected\n if (this.isConnected) {\n this.destroy();\n await this.waitForPluginLoader();\n await this.initialize();\n }\n }\n\n /**\n * Initialize the editor\n */\n private async initialize(): Promise<void> {\n // Prevent re-initialization if already has toolbar\n if (this.querySelector('.editora-toolbar')) {\n return;\n }\n \n // Prevent re-initialization\n if (this.isInitialized) return;\n \n // Mark this element as an editor container for multi-instance support\n this.setAttribute('data-editora-editor', 'true');\n \n // Config is already resolved in connectedCallback\n \n // Apply dimensions\n if (this.config.height) {\n this.style.height = typeof this.config.height === 'number'\n ? `${this.config.height}px`\n : this.config.height;\n }\n \n if (this.config.width) {\n this.style.width = typeof this.config.width === 'number'\n ? `${this.config.width}px`\n : this.config.width;\n }\n \n // Add base class\n this.classList.add('editora-editor');\n \n if (this.config.theme) {\n this.classList.add(`editora-theme-${this.config.theme}`);\n }\n \n // Load plugins\n const plugins = await this.loadPlugins();\n \n // Initialize plugins (call init hooks)\n plugins.forEach(plugin => {\n if (plugin.init && typeof plugin.init === 'function') {\n try {\n // Pass the web component element as context for plugins that need it\n plugin.init({ editorElement: this });\n } catch (error) {\n console.error(`[RichTextEditor] Error initializing plugin ${plugin.name}:`, error);\n }\n }\n });\n \n // Get initial content before clearing innerHTML\n const initialContent = this.getAttribute('data-initial-content') || '';\n \n // Create editor engine\n this.engine = new EditorEngine({\n content: initialContent,\n plugins,\n readonly: this.config.readonly,\n });\n \n // Create UI elements\n this.createUI(plugins, initialContent);\n \n // Setup event listeners\n this.setupEventListeners();\n \n // Mark as initialized\n this.isInitialized = true;\n \n // Emit ready event\n this.dispatchEvent(new CustomEvent('editor-ready', {\n detail: { api: this.getAPI() },\n bubbles: true,\n }));\n }\n\n /**\n * Get initial content from slot or attribute\n */\n private getInitialContent(): string {\n // Check for content attribute first\n if (this.config.content) {\n return this.config.content;\n }\n \n // Check for slot\n const slot = this.querySelector('[slot]');\n if (slot) {\n return slot.innerHTML;\n }\n \n // Check for direct child content\n if (this.hasChildNodes()) {\n const content = Array.from(this.childNodes).map(n => {\n if (n.nodeType === Node.TEXT_NODE) {\n return n.textContent;\n } else if (n.nodeType === Node.ELEMENT_NODE) {\n return (n as Element).outerHTML;\n }\n return '';\n }).join('');\n return content.trim();\n }\n \n return '';\n }\n\n /**\n * Load plugins based on configuration\n */\n private async loadPlugins(): Promise<Plugin[]> {\n // Ensure plugin loader is available\n if (!this.pluginLoader) {\n await this.waitForPluginLoader();\n }\n \n const plugins: Plugin[] = [];\n \n // Check if plugins are explicitly configured (non-empty array or string)\n const hasPluginConfig = this.config.plugins && (\n (typeof this.config.plugins === 'string' && this.config.plugins.length > 0) ||\n (Array.isArray(this.config.plugins) && this.config.plugins.length > 0)\n );\n \n if (hasPluginConfig) {\n if (typeof this.config.plugins === 'string') {\n // Parse plugin string\n const loadedPlugins = await this.pluginLoader.parsePluginString(this.config.plugins);\n plugins.push(...loadedPlugins);\n } else if (Array.isArray(this.config.plugins)) {\n // Already plugin instances or names\n for (const p of this.config.plugins) {\n if (typeof p === 'string') {\n const plugin = await this.pluginLoader.load(p);\n if (plugin) plugins.push(plugin);\n } else {\n plugins.push(p as Plugin);\n }\n }\n }\n } else {\n // No plugins specified - load all registered plugins\n const registeredNames = this.pluginLoader.getRegisteredPluginNames();\n const loadedPlugins = await this.pluginLoader.loadMultiple(registeredNames);\n plugins.push(...loadedPlugins);\n }\n return plugins;\n }\n\n /**\n * Create UI elements\n */\n private createUI(plugins: Plugin[], initialContent: string): void {\n // Preserve slot elements and initial content before clearing\n const toolbarSlot = this.querySelector('[slot=\"toolbar\"]');\n const statusBarSlot = this.querySelector('[slot=\"statusbar\"]');\n \n // Clear existing content\n this.innerHTML = '';\n \n // Restore or create toolbar\n if (this.config.toolbar !== false && !toolbarSlot) {\n // Create default toolbar\n this.toolbarElement = document.createElement('div');\n this.toolbarElement.className = 'editora-toolbar-container';\n this.appendChild(this.toolbarElement);\n \n // Support both toolbar and toolbarItems attributes\n const toolbarItems = (this.config as any).toolbarItems || this.config.toolbar;\n \n this.toolbar = new ToolbarRenderer(\n {\n items: typeof toolbarItems === 'string' ? toolbarItems : undefined,\n sticky: this.config.toolbar && typeof this.config.toolbar === 'object'\n ? (this.config.toolbar as any).sticky\n : false,\n position: 'top',\n },\n plugins,\n this.pluginLoader // Pass plugin loader to get all registered plugins\n );\n \n this.toolbar.setCommandHandler((command, value) => {\n // Ensure editor has focus and a valid selection for multi-instance support\n if (this.contentElement) {\n // Focus the editor\n this.contentElement.focus();\n \n // Ensure there's a selection in this editor instance\n const selection = window.getSelection();\n if (!selection || selection.rangeCount === 0 || !this.contentElement.contains(selection.anchorNode)) {\n // Create a selection at the end of the content\n const range = document.createRange();\n const lastChild = this.contentElement.lastChild || this.contentElement;\n \n if (lastChild.nodeType === Node.TEXT_NODE) {\n range.setStart(lastChild, lastChild.textContent?.length || 0);\n } else if (lastChild.nodeType === Node.ELEMENT_NODE) {\n range.selectNodeContents(lastChild);\n range.collapse(false); // Collapse to end\n } else {\n range.setStart(this.contentElement, 0);\n }\n \n range.collapse(true);\n selection?.removeAllRanges();\n selection?.addRange(range);\n }\n }\n \n // Try to find the command in loaded plugins first (for native commands)\n \n const plugin = plugins.find(p => p.commands && p.commands[command]);\n if (plugin && plugin.commands) {\n const commandFn = plugin.commands[command];\n if (typeof commandFn === 'function') {\n // Call native command directly\n try {\n // Pass editor element for fullscreen command\n if (command === 'toggleFullscreen') {\n const result = commandFn(this);\n return result;\n } else {\n const result = commandFn(value);\n return result;\n }\n } catch (error) {\n console.error(`[RichTextEditor] Error executing native command ${command}:`, error);\n return false;\n }\n }\n }\n // Fallback to engine command (ProseMirror-style)\n return this.engine?.execCommand(command, value) || false;\n });\n \n this.toolbar.render(this.toolbarElement);\n } else if (toolbarSlot) {\n // Use custom toolbar from slot\n this.appendChild(toolbarSlot);\n }\n \n // Create content area\n this.contentElement = document.createElement('div');\n this.contentElement.className = 'editora-content rte-content'; // Add rte-content class for plugin helpers\n this.contentElement.contentEditable = this.config.readonly ? 'false' : 'true';\n this.contentElement.setAttribute('role', 'textbox');\n this.contentElement.setAttribute('aria-multiline', 'true');\n \n if (this.config.placeholder) {\n this.contentElement.setAttribute('data-placeholder', this.config.placeholder);\n }\n \n // Set default paragraph separator to <p> for consistency with React\n try {\n document.execCommand('defaultParagraphSeparator', false, 'p');\n } catch (e) {\n // Fallback: some browsers may not support this\n console.warn('defaultParagraphSeparator not supported:', e);\n }\n \n // Set initial content and ensure it's wrapped in <p> tags\n if (initialContent) {\n // Check if content is already wrapped in block elements\n const tempDiv = document.createElement('div');\n tempDiv.innerHTML = initialContent.trim();\n \n // If content has no block-level elements, wrap it in a <p> tag\n const hasBlockElements = Array.from(tempDiv.childNodes).some(node => {\n if (node.nodeType === Node.ELEMENT_NODE) {\n const tagName = (node as Element).tagName;\n return ['P', 'DIV', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'UL', 'OL', 'BLOCKQUOTE', 'PRE'].includes(tagName);\n }\n return false;\n });\n \n if (!hasBlockElements && initialContent.trim()) {\n this.contentElement.innerHTML = `<p>${initialContent.trim()}</p>`;\n } else {\n this.contentElement.innerHTML = initialContent;\n }\n } else {\n // Initialize with an empty paragraph for proper structure, unless we have a placeholder\n if (this.config.placeholder) {\n // Leave empty so placeholder shows\n this.contentElement.innerHTML = '';\n } else {\n this.contentElement.innerHTML = '<p><br></p>';\n }\n }\n \n this.appendChild(this.contentElement);\n \n // Floating toolbar\n if (this.config.toolbar && typeof this.config.toolbar === 'object' && (this.config.toolbar as any).floating) {\n this.floatingToolbar = new FloatingToolbar({ enabled: true });\n this.floatingToolbar.create(this);\n }\n \n // Status bar - restore custom slot if exists\n if (statusBarSlot) {\n this.appendChild(statusBarSlot);\n } else {\n // Create default status bar if configured\n if (this.config.statusbar) {\n this.statusBarElement = document.createElement('div');\n this.statusBarElement.className = 'editora-statusbar-container';\n this.appendChild(this.statusBarElement);\n \n this.statusBar = new StatusBar({ position: 'bottom' });\n this.statusBar.create(this.statusBarElement);\n }\n }\n \n // Auto-focus if configured\n if (this.config.autofocus) {\n setTimeout(() => this.contentElement?.focus(), 0);\n }\n }\n\n /**\n * Setup event listeners\n */\n private setupEventListeners(): void {\n if (!this.contentElement || !this.engine) return;\n \n // Content change\n this.contentElement.addEventListener('input', () => {\n const html = this.contentElement!.innerHTML;\n \n this.dispatchEvent(new CustomEvent('content-change', {\n detail: { html },\n bubbles: true,\n }));\n \n // Update status bar\n this.updateStatusBar();\n });\n \n // Focus/blur\n this.contentElement.addEventListener('focus', () => {\n this.dispatchEvent(new Event('editor-focus', { bubbles: true }));\n });\n \n this.contentElement.addEventListener('blur', () => {\n this.dispatchEvent(new Event('editor-blur', { bubbles: true }));\n });\n \n // Selection change for floating toolbar and status bar\n const updateSelectionInfo = () => {\n this.updateFloatingToolbar();\n this.updateStatusBar();\n };\n\n document.addEventListener('selectionchange', updateSelectionInfo);\n }\n\n /**\n * Update floating toolbar position\n */\n private updateFloatingToolbar(): void {\n if (!this.floatingToolbar) return;\n \n const selection = window.getSelection();\n if (!selection || selection.rangeCount === 0) {\n this.floatingToolbar.hide();\n return;\n }\n \n const range = selection.getRangeAt(0);\n if (range.collapsed) {\n this.floatingToolbar.hide();\n return;\n }\n \n const rect = range.getBoundingClientRect();\n this.floatingToolbar.show(rect.left, rect.top - 40);\n }\n\n /**\n * Update status bar with selection and cursor information\n */\n /**\n * Update status bar with current content and cursor information\n */\n private updateStatusBar(): void {\n if (!this.statusBar || !this.contentElement) return;\n\n const text = this.contentElement.textContent || '';\n const { words, chars } = calculateTextStats(text);\n const lineCount = countLines(this.contentElement);\n\n const selection = window.getSelection();\n let cursorPosition, selectionInfo;\n\n if (selection && selection.rangeCount > 0) {\n const range = selection.getRangeAt(0);\n cursorPosition = getCursorPosition(this.contentElement, range);\n\n if (!range.collapsed) {\n selectionInfo = getSelectionInfo(range, cursorPosition);\n cursorPosition = undefined; // Don't show cursor position when text is selected\n }\n }\n\n this.statusBar.update({\n wordCount: words,\n charCount: chars,\n lineCount,\n cursorPosition,\n selectionInfo\n });\n }\n\n /**\n * Handle attribute changes\n */\n private handleAttributeChange(name: string, value: string): void {\n switch (name) {\n case 'readonly':\n if (this.contentElement) {\n this.contentElement.contentEditable = value === 'true' ? 'false' : 'true';\n }\n if (this.engine) {\n this.engine.setReadonly(value === 'true');\n }\n break;\n \n case 'theme':\n // Remove old theme classes\n this.classList.forEach(cls => {\n if (cls.startsWith('editora-theme-')) {\n this.classList.remove(cls);\n }\n });\n // Add new theme class\n if (value) {\n this.classList.add(`editora-theme-${value}`);\n }\n break;\n \n case 'placeholder':\n if (this.contentElement) {\n this.contentElement.setAttribute('data-placeholder', value);\n }\n break;\n \n case 'toolbar':\n case 'plugins':\n // These require re-initialization\n if (this.isConnected) {\n this.destroy();\n this.waitForPluginLoader().then(() => {\n this.initialize().catch(error => {\n console.error('[RichTextEditor] Error during attribute change re-initialization:', error);\n });\n });\n }\n break;\n }\n }\n\n /**\n * Resolve configuration from all sources\n */\n private resolveConfig(): EditorConfigDefaults {\n const attributes: Record<string, string> = {};\n \n // Collect all attributes\n for (let i = 0; i < this.attributes.length; i++) {\n const attr = this.attributes[i];\n attributes[attr.name] = attr.value;\n }\n \n return ConfigResolver.resolve({\n jsConfig: this.jsConfig,\n attributes,\n });\n }\n\n /**\n * Get public API\n */\n getAPI(): EditorAPI {\n return {\n getContent: () => {\n return this.contentElement?.innerHTML || '';\n },\n \n setContent: (html: string) => {\n if (this.contentElement) {\n this.contentElement.innerHTML = html;\n }\n },\n \n execCommand: (name: string, value?: any) => {\n return this.engine?.execCommand(name, value) || false;\n },\n \n focus: () => {\n this.contentElement?.focus();\n },\n \n blur: () => {\n this.contentElement?.blur();\n },\n \n destroy: () => {\n this.destroy();\n },\n \n on: (event: string, handler: (...args: any[]) => void) => {\n this.addEventListener(event, handler as EventListener);\n return () => this.removeEventListener(event, handler as EventListener);\n },\n \n getConfig: () => {\n return { ...this.config };\n },\n \n setReadonly: (readonly: boolean) => {\n this.setAttribute('readonly', readonly.toString());\n },\n };\n }\n\n /**\n * Destroy the editor\n */\n private destroy(): void {\n this.engine?.destroy();\n this.toolbar?.destroy();\n this.floatingToolbar?.destroy();\n this.statusBar?.destroy();\n \n this.innerHTML = '';\n this.isInitialized = false;\n \n this.dispatchEvent(new Event('editor-destroy', { bubbles: true }));\n }\n\n // Public API methods\n \n public getContent(): string {\n return this.contentElement?.innerHTML || '';\n }\n\n public setContent(html: string): void {\n if (this.contentElement) {\n this.contentElement.innerHTML = html;\n }\n }\n\n public execCommand(name: string, value?: any): boolean {\n return this.engine?.execCommand(name, value) || false;\n }\n\n public focus(): void {\n this.contentElement?.focus();\n }\n\n public blur(): void {\n this.contentElement?.blur();\n }\n}\n\n/**\n * Editor API interface\n */\nexport interface EditorAPI {\n getContent(): string;\n setContent(html: string): void;\n execCommand(name: string, value?: any): boolean;\n focus(): void;\n blur(): void;\n destroy(): void;\n on(event: string, handler: (...args: any[]) => void): () => void;\n getConfig(): EditorConfigDefaults;\n setReadonly(readonly: boolean): void;\n}\n\n// Note: Custom element registration moved to standalone.ts\n// to ensure plugins are registered before element instances are created\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":["EditorState","doc","selection","schema","content","Schema","nodes","marks","type","attrs","text","PluginManager","plugin","config","pluginConfig","pluginName","index","p","name","commands","command","args","mode","error","destroyPromises","Editor","pluginManagerOrOptions","options","fn","toolbarButtons","shortcutMap","button","event","parts","key","shortcut","commandId","value","item","btn","state","l","newState","PluginRuntime","context","_a","_b","commandFn","createPluginRuntime","KeyboardShortcutManager","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","CommandRegistry","initialCommands","handler","EditorEngine","readonly","handlers","DocumentModel","ToolbarRenderer","plugins","pluginLoader","toolbarString","groups","sections","allToolbarItems","itemMap","aliases","section","buttons","cmd","ltrItem","rtlItem","addCommentItem","toggleCommentsItem","actualCommand","container","buttonGroups","group","groupIndex","groupEl","separator","parent","dropdownEl","inlineMenuEl","groupButtonEl","inputEl","buttonEl","el","iconWrapper","itemsContainer","child","e","trigger","menu","option","isOpen","closeDropdown","allMenus","m","dropdown","cleanup","FloatingToolbar","parentElement","x","y","StatusBar","info","leftSection","rightSection","leftItems","sel","pos","rightItems","span","Dialog","dialog","body","closeBtn","cancelBtn","okBtn","rect","form","formData","inputs","input","_d","_c","Dropdown","selected","displayText","opt","toggle","label","ColorPicker","color","colorInput","textInput","preset","LinkDialog","initialUrl","initialText","onSubmit","onCancel","url","openInNewTab","div","TableDialog","rows","cols","headerRow","rowsInput","colsInput","headerCheckbox","preview","updatePreview","hasHeader","ImageDialog","src","alt","width","height","srcInput","previewContainer","previewImg","fileInput","reader","dataUrl","MathDialog","symbol","start","end","latex","displayType","CharacterDialog","charactersToShow","char","searchTerm","unicode","visible","character","EmojiDialog","emojisToShow","emoji","getCursorPosition","contentElement","range","startOffset","getTextOffset","lines","line","column","rootElement","node","offset","textOffset","walker","currentNode","countLines","blocks","lineCount","lastBlock","textLines","calculateTextStats","words","chars","getSelectionInfo","cursorPosition","selectedText","_ConfigResolver","sources","parsedAttributes","attributes","camelKey","str","_","letter","errors","configs","result","ConfigResolver","PluginLoader","factory","names","pluginString","ReactAdapter","html","toolbarElement","success","registry","createReactAdapter","VanillaAdapter","listener","injectStyles","styleId","styleElement","styles","RichTextEditorElement","resolve","checkLoader","oldValue","newValue","initialContent","slot","n","loadedPlugins","registeredNames","toolbarSlot","statusBarSlot","toolbarItems","lastChild","tempDiv","tagName","updateSelectionInfo","selectionInfo","cls","attr","createEditor","initWebComponent"],"mappings":"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"}
|