@erag/text-editor-vue 0.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/LICENSE +21 -0
- package/README.md +38 -0
- package/dist/index.d.ts +2 -0
- package/dist/src/commands/clipboardCommands.d.ts +2 -0
- package/dist/src/commands/clipboardCommands.d.ts.map +1 -0
- package/dist/src/commands/commandRegistry.d.ts +5 -0
- package/dist/src/commands/commandRegistry.d.ts.map +1 -0
- package/dist/src/commands/formatCommands.d.ts +3 -0
- package/dist/src/commands/formatCommands.d.ts.map +1 -0
- package/dist/src/commands/historyCommands.d.ts +3 -0
- package/dist/src/commands/historyCommands.d.ts.map +1 -0
- package/dist/src/commands/insertCommands.d.ts +6 -0
- package/dist/src/commands/insertCommands.d.ts.map +1 -0
- package/dist/src/commands/listCommands.d.ts +2 -0
- package/dist/src/commands/listCommands.d.ts.map +1 -0
- package/dist/src/commands/printCommands.d.ts +2 -0
- package/dist/src/commands/printCommands.d.ts.map +1 -0
- package/dist/src/commands/tableCommands.d.ts +4 -0
- package/dist/src/commands/tableCommands.d.ts.map +1 -0
- package/dist/src/components/Editor.vue.d.ts +59 -0
- package/dist/src/components/Editor.vue.d.ts.map +1 -0
- package/dist/src/components/EditorContent.vue.d.ts +37 -0
- package/dist/src/components/EditorContent.vue.d.ts.map +1 -0
- package/dist/src/components/EditorDialogs.vue.d.ts +29 -0
- package/dist/src/components/EditorDialogs.vue.d.ts.map +1 -0
- package/dist/src/components/EditorMenuBar.vue.d.ts +39 -0
- package/dist/src/components/EditorMenuBar.vue.d.ts.map +1 -0
- package/dist/src/components/EditorStatusBar.vue.d.ts +26 -0
- package/dist/src/components/EditorStatusBar.vue.d.ts.map +1 -0
- package/dist/src/components/EditorToolbar.vue.d.ts +29 -0
- package/dist/src/components/EditorToolbar.vue.d.ts.map +1 -0
- package/dist/src/components/dialogs/BaseDialog.vue.d.ts +28 -0
- package/dist/src/components/dialogs/BaseDialog.vue.d.ts.map +1 -0
- package/dist/src/components/dialogs/ColorDialog.vue.d.ts +14 -0
- package/dist/src/components/dialogs/ColorDialog.vue.d.ts.map +1 -0
- package/dist/src/components/dialogs/EmojiDialog.vue.d.ts +10 -0
- package/dist/src/components/dialogs/EmojiDialog.vue.d.ts.map +1 -0
- package/dist/src/components/dialogs/FindReplaceDialog.vue.d.ts +13 -0
- package/dist/src/components/dialogs/FindReplaceDialog.vue.d.ts.map +1 -0
- package/dist/src/components/dialogs/InfoDialog.vue.d.ts +11 -0
- package/dist/src/components/dialogs/InfoDialog.vue.d.ts.map +1 -0
- package/dist/src/components/dialogs/LinkDialog.vue.d.ts +18 -0
- package/dist/src/components/dialogs/LinkDialog.vue.d.ts.map +1 -0
- package/dist/src/components/dialogs/MediaDialog.vue.d.ts +14 -0
- package/dist/src/components/dialogs/MediaDialog.vue.d.ts.map +1 -0
- package/dist/src/components/dialogs/PreviewDialog.vue.d.ts +12 -0
- package/dist/src/components/dialogs/PreviewDialog.vue.d.ts.map +1 -0
- package/dist/src/components/dialogs/SourceDialog.vue.d.ts +13 -0
- package/dist/src/components/dialogs/SourceDialog.vue.d.ts.map +1 -0
- package/dist/src/components/dialogs/SpecialCharacterDialog.vue.d.ts +10 -0
- package/dist/src/components/dialogs/SpecialCharacterDialog.vue.d.ts.map +1 -0
- package/dist/src/components/dialogs/TableDialog.vue.d.ts +13 -0
- package/dist/src/components/dialogs/TableDialog.vue.d.ts.map +1 -0
- package/dist/src/components/dialogs/TablePropertiesDialog.vue.d.ts +10 -0
- package/dist/src/components/dialogs/TablePropertiesDialog.vue.d.ts.map +1 -0
- package/dist/src/components/dialogs/TemplateDialog.vue.d.ts +15 -0
- package/dist/src/components/dialogs/TemplateDialog.vue.d.ts.map +1 -0
- package/dist/src/components/dialogs/WordCountDialog.vue.d.ts +12 -0
- package/dist/src/components/dialogs/WordCountDialog.vue.d.ts.map +1 -0
- package/dist/src/components/icons/EditorIcon.vue.d.ts +8 -0
- package/dist/src/components/icons/EditorIcon.vue.d.ts.map +1 -0
- package/dist/src/components/images/ImageResizeOverlay.vue.d.ts +17 -0
- package/dist/src/components/images/ImageResizeOverlay.vue.d.ts.map +1 -0
- package/dist/src/components/images/InlineImageUpload.vue.d.ts +20 -0
- package/dist/src/components/images/InlineImageUpload.vue.d.ts.map +1 -0
- package/dist/src/components/images/InlineImageUploadPortal.vue.d.ts +19 -0
- package/dist/src/components/images/InlineImageUploadPortal.vue.d.ts.map +1 -0
- package/dist/src/components/mentions/MentionDropdown.vue.d.ts +45 -0
- package/dist/src/components/mentions/MentionDropdown.vue.d.ts.map +1 -0
- package/dist/src/components/mentions/MentionHoverCard.vue.d.ts +14 -0
- package/dist/src/components/mentions/MentionHoverCard.vue.d.ts.map +1 -0
- package/dist/src/components/mentions/MentionItem.vue.d.ts +28 -0
- package/dist/src/components/mentions/MentionItem.vue.d.ts.map +1 -0
- package/dist/src/components/menus/FloatingMenu.vue.d.ts +19 -0
- package/dist/src/components/menus/FloatingMenu.vue.d.ts.map +1 -0
- package/dist/src/components/merge-tags/MergeTagDropdown.vue.d.ts +20 -0
- package/dist/src/components/merge-tags/MergeTagDropdown.vue.d.ts.map +1 -0
- package/dist/src/components/merge-tags/MergeTagSidebar.vue.d.ts +16 -0
- package/dist/src/components/merge-tags/MergeTagSidebar.vue.d.ts.map +1 -0
- package/dist/src/components/toolbar/CaseChangeMenu.vue.d.ts +14 -0
- package/dist/src/components/toolbar/CaseChangeMenu.vue.d.ts.map +1 -0
- package/dist/src/components/toolbar/ColorPalette.vue.d.ts +13 -0
- package/dist/src/components/toolbar/ColorPalette.vue.d.ts.map +1 -0
- package/dist/src/components/toolbar/ToolbarButton.vue.d.ts +15 -0
- package/dist/src/components/toolbar/ToolbarButton.vue.d.ts.map +1 -0
- package/dist/src/composables/useEditor.d.ts +15 -0
- package/dist/src/composables/useEditor.d.ts.map +1 -0
- package/dist/src/composables/useEditorConfig.d.ts +4 -0
- package/dist/src/composables/useEditorConfig.d.ts.map +1 -0
- package/dist/src/composables/useEditorHistory.d.ts +8 -0
- package/dist/src/composables/useEditorHistory.d.ts.map +1 -0
- package/dist/src/composables/useEditorResize.d.ts +8 -0
- package/dist/src/composables/useEditorResize.d.ts.map +1 -0
- package/dist/src/composables/useEditorSelection.d.ts +10 -0
- package/dist/src/composables/useEditorSelection.d.ts.map +1 -0
- package/dist/src/composables/useEditorUpload.d.ts +14 -0
- package/dist/src/composables/useEditorUpload.d.ts.map +1 -0
- package/dist/src/composables/useFloatingPosition.d.ts +6 -0
- package/dist/src/composables/useFloatingPosition.d.ts.map +1 -0
- package/dist/src/composables/useFullscreen.d.ts +6 -0
- package/dist/src/composables/useFullscreen.d.ts.map +1 -0
- package/dist/src/composables/useImageResize.d.ts +15 -0
- package/dist/src/composables/useImageResize.d.ts.map +1 -0
- package/dist/src/composables/useInlineImageUpload.d.ts +19 -0
- package/dist/src/composables/useInlineImageUpload.d.ts.map +1 -0
- package/dist/src/composables/useLinkInitial.d.ts +7 -0
- package/dist/src/composables/useLinkInitial.d.ts.map +1 -0
- package/dist/src/composables/useMentions.d.ts +28 -0
- package/dist/src/composables/useMentions.d.ts.map +1 -0
- package/dist/src/composables/useMergeTagSidebar.d.ts +10 -0
- package/dist/src/composables/useMergeTagSidebar.d.ts.map +1 -0
- package/dist/src/composables/useMergeTags.d.ts +21 -0
- package/dist/src/composables/useMergeTags.d.ts.map +1 -0
- package/dist/src/composables/useToolbarOverflow.d.ts +6 -0
- package/dist/src/composables/useToolbarOverflow.d.ts.map +1 -0
- package/dist/src/composables/useWordCount.d.ts +4 -0
- package/dist/src/composables/useWordCount.d.ts.map +1 -0
- package/dist/src/config/defaultConfig.d.ts +3 -0
- package/dist/src/config/defaultConfig.d.ts.map +1 -0
- package/dist/src/config/mentionConfig.d.ts +4 -0
- package/dist/src/config/mentionConfig.d.ts.map +1 -0
- package/dist/src/config/menuConfig.d.ts +3 -0
- package/dist/src/config/menuConfig.d.ts.map +1 -0
- package/dist/src/config/menuIcons.d.ts +3 -0
- package/dist/src/config/menuIcons.d.ts.map +1 -0
- package/dist/src/config/mergeTagConfig.d.ts +4 -0
- package/dist/src/config/mergeTagConfig.d.ts.map +1 -0
- package/dist/src/config/templateConfig.d.ts +3 -0
- package/dist/src/config/templateConfig.d.ts.map +1 -0
- package/dist/src/config/toolbarConfig.d.ts +5 -0
- package/dist/src/config/toolbarConfig.d.ts.map +1 -0
- package/dist/src/constants/editorCommands.d.ts +2 -0
- package/dist/src/constants/editorCommands.d.ts.map +1 -0
- package/dist/src/constants/editorDefaults.d.ts +44 -0
- package/dist/src/constants/editorDefaults.d.ts.map +1 -0
- package/dist/src/constants/emojis.d.ts +4 -0
- package/dist/src/constants/emojis.d.ts.map +1 -0
- package/dist/src/constants/imageResize.d.ts +3 -0
- package/dist/src/constants/imageResize.d.ts.map +1 -0
- package/dist/src/constants/keyboardShortcuts.d.ts +2 -0
- package/dist/src/constants/keyboardShortcuts.d.ts.map +1 -0
- package/dist/src/constants/packageInfo.d.ts +2 -0
- package/dist/src/constants/packageInfo.d.ts.map +1 -0
- package/dist/src/constants/printStyles.d.ts +2 -0
- package/dist/src/constants/printStyles.d.ts.map +1 -0
- package/dist/src/constants/specialCharacters.d.ts +4 -0
- package/dist/src/constants/specialCharacters.d.ts.map +1 -0
- package/dist/src/index.d.ts +5 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/types/commands.d.ts +17 -0
- package/dist/src/types/commands.d.ts.map +1 -0
- package/dist/src/types/config.d.ts +101 -0
- package/dist/src/types/config.d.ts.map +1 -0
- package/dist/src/types/count.d.ts +10 -0
- package/dist/src/types/count.d.ts.map +1 -0
- package/dist/src/types/dialog.d.ts +41 -0
- package/dist/src/types/dialog.d.ts.map +1 -0
- package/dist/src/types/editor.d.ts +49 -0
- package/dist/src/types/editor.d.ts.map +1 -0
- package/dist/src/types/emoji.d.ts +8 -0
- package/dist/src/types/emoji.d.ts.map +1 -0
- package/dist/src/types/events.d.ts +26 -0
- package/dist/src/types/events.d.ts.map +1 -0
- package/dist/src/types/image.d.ts +22 -0
- package/dist/src/types/image.d.ts.map +1 -0
- package/dist/src/types/index.d.ts +16 -0
- package/dist/src/types/index.d.ts.map +1 -0
- package/dist/src/types/mention.d.ts +63 -0
- package/dist/src/types/mention.d.ts.map +1 -0
- package/dist/src/types/menu.d.ts +21 -0
- package/dist/src/types/menu.d.ts.map +1 -0
- package/dist/src/types/mergeTag.d.ts +47 -0
- package/dist/src/types/mergeTag.d.ts.map +1 -0
- package/dist/src/types/specialCharacter.d.ts +10 -0
- package/dist/src/types/specialCharacter.d.ts.map +1 -0
- package/dist/src/types/template.d.ts +19 -0
- package/dist/src/types/template.d.ts.map +1 -0
- package/dist/src/types/toolbar.d.ts +15 -0
- package/dist/src/types/toolbar.d.ts.map +1 -0
- package/dist/src/types/upload.d.ts +16 -0
- package/dist/src/types/upload.d.ts.map +1 -0
- package/dist/src/utils/config.d.ts +4 -0
- package/dist/src/utils/config.d.ts.map +1 -0
- package/dist/src/utils/dateTime.d.ts +4 -0
- package/dist/src/utils/dateTime.d.ts.map +1 -0
- package/dist/src/utils/dom.d.ts +4 -0
- package/dist/src/utils/dom.d.ts.map +1 -0
- package/dist/src/utils/html.d.ts +11 -0
- package/dist/src/utils/html.d.ts.map +1 -0
- package/dist/src/utils/mention.d.ts +11 -0
- package/dist/src/utils/mention.d.ts.map +1 -0
- package/dist/src/utils/mergeTag.d.ts +11 -0
- package/dist/src/utils/mergeTag.d.ts.map +1 -0
- package/dist/src/utils/sanitizer.d.ts +8 -0
- package/dist/src/utils/sanitizer.d.ts.map +1 -0
- package/dist/src/utils/selection.d.ts +6 -0
- package/dist/src/utils/selection.d.ts.map +1 -0
- package/dist/src/utils/units.d.ts +3 -0
- package/dist/src/utils/units.d.ts.map +1 -0
- package/dist/src/utils/url.d.ts +10 -0
- package/dist/src/utils/url.d.ts.map +1 -0
- package/dist/style.css +2 -0
- package/dist/text-editor-vue.js +6428 -0
- package/dist/text-editor-vue.js.map +1 -0
- package/package.json +102 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-editor-vue.js","names":["$slots","$emit","$emit","$emit","$emit","$slots","$slots","$emit","$emit","$slots","$emit","$slots","$emit","$slots"],"sources":["../src/utils/html.ts","../src/commands/clipboardCommands.ts","../src/constants/editorCommands.ts","../src/utils/selection.ts","../src/commands/formatCommands.ts","../src/utils/dom.ts","../src/commands/tableCommands.ts","../src/constants/editorDefaults.ts","../src/constants/printStyles.ts","../src/utils/url.ts","../src/utils/mention.ts","../src/utils/mergeTag.ts","../src/utils/sanitizer.ts","../src/commands/printCommands.ts","../src/commands/commandRegistry.ts","../src/commands/insertCommands.ts","../src/constants/keyboardShortcuts.ts","../src/composables/useEditor.ts","../src/config/mentionConfig.ts","../src/config/mergeTagConfig.ts","../src/config/templateConfig.ts","../src/config/defaultConfig.ts","../src/utils/config.ts","../src/composables/useEditorConfig.ts","../src/commands/historyCommands.ts","../src/composables/useEditorHistory.ts","../src/utils/units.ts","../src/composables/useEditorResize.ts","../src/composables/useEditorSelection.ts","../src/composables/useEditorUpload.ts","../src/composables/useFullscreen.ts","../src/composables/useImageResize.ts","../src/composables/useInlineImageUpload.ts","../src/composables/useLinkInitial.ts","../src/composables/useMentions.ts","../src/composables/useMergeTags.ts","../src/composables/useMergeTagSidebar.ts","../src/composables/useWordCount.ts","../src/utils/dateTime.ts","../src/components/EditorContent.vue","../src/components/EditorContent.vue","../src/components/toolbar/ColorPalette.vue","../src/components/toolbar/ColorPalette.vue","../src/components/dialogs/BaseDialog.vue","../src/components/dialogs/BaseDialog.vue","../src/components/dialogs/ColorDialog.vue","../src/components/dialogs/ColorDialog.vue","../src/constants/emojis.ts","../src/components/dialogs/EmojiDialog.vue","../src/components/dialogs/EmojiDialog.vue","../src/components/dialogs/FindReplaceDialog.vue","../src/components/dialogs/FindReplaceDialog.vue","../package.json","../src/constants/packageInfo.ts","../src/components/icons/EditorIcon.vue","../src/components/icons/EditorIcon.vue","../src/components/dialogs/InfoDialog.vue","../src/components/dialogs/InfoDialog.vue","../src/components/dialogs/LinkDialog.vue","../src/components/dialogs/LinkDialog.vue","../src/components/dialogs/MediaDialog.vue","../src/components/dialogs/MediaDialog.vue","../src/components/dialogs/PreviewDialog.vue","../src/components/dialogs/PreviewDialog.vue","../src/components/dialogs/SourceDialog.vue","../src/components/dialogs/SourceDialog.vue","../src/constants/specialCharacters.ts","../src/components/dialogs/SpecialCharacterDialog.vue","../src/components/dialogs/SpecialCharacterDialog.vue","../src/components/dialogs/TableDialog.vue","../src/components/dialogs/TableDialog.vue","../src/components/dialogs/TablePropertiesDialog.vue","../src/components/dialogs/TablePropertiesDialog.vue","../src/components/dialogs/TemplateDialog.vue","../src/components/dialogs/TemplateDialog.vue","../src/components/dialogs/WordCountDialog.vue","../src/components/dialogs/WordCountDialog.vue","../src/components/EditorDialogs.vue","../src/components/EditorDialogs.vue","../src/config/menuConfig.ts","../src/config/menuIcons.ts","../src/components/menus/FloatingMenu.vue","../src/components/menus/FloatingMenu.vue","../src/components/EditorMenuBar.vue","../src/components/EditorMenuBar.vue","../src/components/EditorStatusBar.vue","../src/components/EditorStatusBar.vue","../src/config/toolbarConfig.ts","../src/composables/useToolbarOverflow.ts","../src/components/toolbar/CaseChangeMenu.vue","../src/components/toolbar/CaseChangeMenu.vue","../src/components/toolbar/ToolbarButton.vue","../src/components/toolbar/ToolbarButton.vue","../src/components/EditorToolbar.vue","../src/components/EditorToolbar.vue","../src/components/mentions/MentionItem.vue","../src/components/mentions/MentionItem.vue","../src/components/mentions/MentionDropdown.vue","../src/components/mentions/MentionDropdown.vue","../src/components/mentions/MentionHoverCard.vue","../src/components/mentions/MentionHoverCard.vue","../src/components/merge-tags/MergeTagDropdown.vue","../src/components/merge-tags/MergeTagDropdown.vue","../src/components/merge-tags/MergeTagSidebar.vue","../src/components/merge-tags/MergeTagSidebar.vue","../src/constants/imageResize.ts","../src/components/images/ImageResizeOverlay.vue","../src/components/images/ImageResizeOverlay.vue","../src/composables/useFloatingPosition.ts","../src/components/images/InlineImageUpload.vue","../src/components/images/InlineImageUpload.vue","../src/components/images/InlineImageUploadPortal.vue","../src/components/images/InlineImageUploadPortal.vue","../src/components/Editor.vue","../src/components/Editor.vue"],"sourcesContent":["import type { TextCountStatistics } from '../types';\n\nconst TRANSIENT_CONTENT_SELECTOR = '[data-erag-transient=\"true\"]';\n\nexport function getPersistentHtml(root: HTMLElement): string {\n if (!root.querySelector(TRANSIENT_CONTENT_SELECTOR)) return root.innerHTML;\n const clone = root.cloneNode(true) as HTMLElement;\n clone.querySelectorAll(TRANSIENT_CONTENT_SELECTOR).forEach((element) => element.remove());\n return clone.innerHTML;\n}\n\nexport function getPersistentText(root: HTMLElement): string {\n if (!root.querySelector(TRANSIENT_CONTENT_SELECTOR)) return root.textContent ?? '';\n const clone = root.cloneNode(true) as HTMLElement;\n clone.querySelectorAll(TRANSIENT_CONTENT_SELECTOR).forEach((element) => element.remove());\n return clone.textContent ?? '';\n}\n\nexport function getTextCounts(root: HTMLElement): { words: number; characters: number } {\n const text = getPersistentText(root)\n .replace(/\\u00a0/g, ' ')\n .trim();\n return { words: text ? text.split(/\\s+/u).length : 0, characters: text.length };\n}\nexport function getDetailedTextCounts(value: string): TextCountStatistics {\n const text = value.replace(/\\u00a0/g, ' ');\n const trimmed = text.trim();\n return {\n words: trimmed ? trimmed.split(/\\s+/u).length : 0,\n charactersWithoutSpaces: text.replace(/\\s/gu, '').length,\n characters: text.length,\n };\n}\nexport function escapeHtml(value: string): string {\n const element = document.createElement('div');\n element.textContent = value;\n return element.innerHTML;\n}\nexport function insertAtSelection(root: HTMLElement, html: string): boolean {\n const selection = root.ownerDocument.defaultView?.getSelection();\n if (!selection) return false;\n const selectedRange = selection.rangeCount ? selection.getRangeAt(0) : null;\n const range =\n selectedRange && root.contains(selectedRange.commonAncestorContainer)\n ? selectedRange\n : createRangeAtEnd(root);\n\n root.focus({ preventScroll: true });\n range.deleteContents();\n const fragment = range.createContextualFragment(html);\n const last = fragment.lastChild;\n range.insertNode(fragment);\n if (last) {\n range.setStartAfter(last);\n range.collapse(true);\n selection.removeAllRanges();\n selection.addRange(range);\n }\n return true;\n}\n\nfunction createRangeAtEnd(root: HTMLElement): Range {\n const range = root.ownerDocument.createRange();\n range.selectNodeContents(root);\n range.collapse(false);\n return range;\n}\n","import { escapeHtml, insertAtSelection } from '../utils/html';\nimport type { ClipboardContent } from '../types';\n\nlet editorClipboard: ClipboardContent | null = null;\n\nfunction selectedContent(root: HTMLElement): ClipboardContent | null {\n const selection = window.getSelection();\n if (!selection?.rangeCount || selection.isCollapsed) return null;\n const range = selection.getRangeAt(0);\n if (!root.contains(range.commonAncestorContainer)) return null;\n const container = document.createElement('div');\n container.append(range.cloneContents());\n return { html: container.innerHTML, text: selection.toString() };\n}\n\nasync function writeSelection(root: HTMLElement, cut: boolean): Promise<boolean> {\n const content = selectedContent(root);\n if (!content) return false;\n editorClipboard = content;\n if (document.execCommand(cut ? 'cut' : 'copy', false)) return true;\n if (!navigator.clipboard?.writeText) return false;\n await navigator.clipboard.writeText(content.text);\n if (cut) document.execCommand('delete', false);\n return true;\n}\n\nasync function readSystemClipboard(): Promise<string | null> {\n if (!navigator.clipboard?.readText) return null;\n try {\n return await navigator.clipboard.readText();\n } catch {\n return null;\n }\n}\n\nasync function pasteSelection(root: HTMLElement, plainText: boolean): Promise<boolean> {\n if (document.execCommand('paste', false)) return true;\n const systemText = await readSystemClipboard();\n if (systemText !== null) return insertAtSelection(root, escapeHtml(systemText));\n if (!editorClipboard) return false;\n const html = plainText ? escapeHtml(editorClipboard.text) : editorClipboard.html;\n return insertAtSelection(root, html);\n}\n\nexport async function executeClipboardCommand(\n root: HTMLElement,\n id: 'cut' | 'copy' | 'paste' | 'pasteText',\n): Promise<boolean> {\n try {\n if (id === 'copy' || id === 'cut') return writeSelection(root, id === 'cut');\n return pasteSelection(root, id === 'pasteText');\n } catch {\n return false;\n }\n}\n","export const FORMAT_COMMANDS: Record<string, string> = {\n bold: 'bold',\n italic: 'italic',\n underline: 'underline',\n strikethrough: 'strikeThrough',\n superscript: 'superscript',\n subscript: 'subscript',\n alignleft: 'justifyLeft',\n aligncenter: 'justifyCenter',\n alignright: 'justifyRight',\n alignjustify: 'justifyFull',\n bullist: 'insertUnorderedList',\n numlist: 'insertOrderedList',\n outdent: 'outdent',\n indent: 'indent',\n removeformat: 'removeFormat',\n undo: 'undo',\n redo: 'redo',\n selectall: 'selectAll',\n};\n","export function saveSelection(root: HTMLElement): Range | null {\n const selection = window.getSelection();\n if (!selection?.rangeCount) return null;\n const range = selection.getRangeAt(0);\n return root.contains(range.commonAncestorContainer) ? range.cloneRange() : null;\n}\nexport function restoreSelection(range: Range | null, root: HTMLElement): boolean {\n if (!range || !root.isConnected || !root.contains(range.commonAncestorContainer)) return false;\n const selection = root.ownerDocument.defaultView?.getSelection();\n if (!selection) return false;\n try {\n root.focus({ preventScroll: true });\n selection.removeAllRanges();\n selection.addRange(range);\n return true;\n } catch {\n return false;\n }\n}\nexport function selectionElement(root: HTMLElement): HTMLElement | null {\n const node = window.getSelection()?.anchorNode;\n const element = node instanceof HTMLElement ? node : node?.parentElement;\n return element && root.contains(element) ? element : null;\n}\nexport function elementPath(root: HTMLElement): string {\n const parts: string[] = [];\n let current = selectionElement(root);\n while (current && current !== root) {\n parts.unshift(current.tagName.toLowerCase());\n current = current.parentElement;\n }\n return parts.join(' > ') || 'p';\n}\n\nexport function getCaretRect(range: Range): DOMRect {\n const caret = range.cloneRange();\n caret.collapse(false);\n const rect = caret.getBoundingClientRect();\n if (rect.width || rect.height) return rect;\n const clientRect = caret.getClientRects().item(0);\n if (clientRect) return clientRect;\n const element =\n caret.endContainer instanceof HTMLElement\n ? caret.endContainer\n : caret.endContainer.parentElement;\n return element?.getBoundingClientRect() ?? new DOMRect();\n}\n","import { FORMAT_COMMANDS } from '../constants/editorCommands';\nimport type { TextCaseMode } from '../types';\nimport { selectionElement } from '../utils/selection';\n\nexport function executeFormatCommand(root: HTMLElement, id: string, value?: string): boolean {\n root.focus({ preventScroll: true });\n if (id === 'removeformat') return clearFormatting(root);\n if (id === 'formatBlock') return document.execCommand('formatBlock', false, value ?? 'p');\n if (id === 'fontfamily') return document.execCommand('fontName', false, value ?? 'Arial');\n if (id === 'fontsize') return applyInlineStyle(root, 'fontSize', value ?? '12pt');\n if (id === 'lineheight') return applyInlineStyle(root, 'lineHeight', value ?? '1.5');\n if (id === 'forecolor') return document.execCommand('foreColor', false, value ?? '#000000');\n if (id === 'backcolor')\n return document.execCommand('hiliteColor', false, value ?? 'transparent');\n if (id === 'inlineCode') return document.execCommand('formatBlock', false, 'pre');\n if (id === 'changeCase' && isTextCaseMode(value)) return changeSelectionCase(root, value);\n const command = FORMAT_COMMANDS[id];\n return command ? document.execCommand(command, false) : false;\n}\n\nfunction changeSelectionCase(root: HTMLElement, mode: TextCaseMode): boolean {\n const selection = window.getSelection();\n if (!selection?.rangeCount || selection.isCollapsed) return false;\n const range = selection.getRangeAt(0);\n if (!root.contains(range.commonAncestorContainer)) return false;\n const fragment = range.extractContents();\n const first = fragment.firstChild;\n const last = fragment.lastChild;\n if (!first || !last) return false;\n const walker = document.createTreeWalker(fragment, NodeFilter.SHOW_TEXT);\n let node = walker.nextNode();\n while (node) {\n node.textContent = transformCase(node.textContent ?? '', mode);\n node = walker.nextNode();\n }\n range.insertNode(fragment);\n const selectedRange = document.createRange();\n selectedRange.setStartBefore(first);\n selectedRange.setEndAfter(last);\n selection.removeAllRanges();\n selection.addRange(selectedRange);\n return true;\n}\n\nfunction transformCase(value: string, mode: TextCaseMode): string {\n if (mode === 'lowercase') return value.toLocaleLowerCase();\n if (mode === 'uppercase') return value.toLocaleUpperCase();\n return value\n .toLocaleLowerCase()\n .replace(\n /(^|[^\\p{L}\\p{N}])(\\p{L})/gu,\n (_, boundary: string, letter: string) => `${boundary}${letter.toLocaleUpperCase()}`,\n );\n}\n\nfunction isTextCaseMode(value: string | undefined): value is TextCaseMode {\n return value === 'lowercase' || value === 'uppercase' || value === 'titlecase';\n}\n\nfunction clearFormatting(root: HTMLElement): boolean {\n const selection = window.getSelection();\n if (!selection?.rangeCount || !root.contains(selection.getRangeAt(0).commonAncestorContainer))\n return false;\n const removedInlineFormatting = document.execCommand('removeFormat', false);\n const removedLink = document.execCommand('unlink', false);\n const resetBlock = document.execCommand('formatBlock', false, 'p');\n return removedInlineFormatting || removedLink || resetBlock;\n}\n\nfunction applyInlineStyle(\n root: HTMLElement,\n property: keyof CSSStyleDeclaration,\n value: string,\n): boolean {\n const selection = window.getSelection();\n if (!selection?.rangeCount) return false;\n if (selection.isCollapsed) {\n const element = selectionElement(root);\n if (!element) return false;\n Object.assign(element.style, { [property]: value });\n return true;\n }\n const span = document.createElement('span');\n Object.assign(span.style, { [property]: value });\n const range = selection.getRangeAt(0);\n span.append(range.extractContents());\n range.insertNode(span);\n selection.selectAllChildren(span);\n return true;\n}\n\nexport function queryFormatState(id: string): boolean {\n const command = FORMAT_COMMANDS[id];\n if (!command) return false;\n try {\n return document.queryCommandState(command);\n } catch {\n return false;\n }\n}\n","export function closestElement<T extends keyof HTMLElementTagNameMap>(\n root: HTMLElement,\n tag: T,\n range?: Range | null,\n): HTMLElementTagNameMap[T] | null {\n const current = range?.startContainer ?? window.getSelection()?.anchorNode;\n const element = current instanceof Element ? current : current?.parentElement;\n const closest = element?.closest(tag) as HTMLElementTagNameMap[T] | null;\n return closest && root.contains(closest) ? closest : null;\n}\nexport function focusableElements(container: HTMLElement): HTMLElement[] {\n return [\n ...container.querySelectorAll<HTMLElement>(\n 'button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex=\"-1\"])',\n ),\n ];\n}\nexport function replaceTextInElement(\n element: HTMLElement,\n search: RegExp,\n replacement: string,\n replaceAll: boolean,\n): void {\n const walker = document.createTreeWalker(element, NodeFilter.SHOW_TEXT);\n let node = walker.nextNode();\n while (node) {\n const value = node.textContent ?? '';\n const next = value.replace(search, replacement);\n if (next !== value) {\n node.textContent = next;\n if (!replaceAll) return;\n }\n node = walker.nextNode();\n }\n}\n","import { closestElement } from '../utils/dom';\n\nexport function executeTableCommand(root: HTMLElement, id: string): boolean {\n const cell = closestElement(root, 'td') ?? closestElement(root, 'th');\n const row = cell?.parentElement as HTMLTableRowElement | null;\n const table = closestElement(root, 'table');\n if (!table || !cell || !row) return false;\n if (id === 'deleteTable') {\n table.remove();\n return true;\n }\n if (id === 'deleteRow') {\n row.remove();\n return true;\n }\n if (id === 'rowBefore' || id === 'rowAfter') {\n const clone = emptyRow(row);\n row.parentElement?.insertBefore(clone, id === 'rowBefore' ? row : row.nextSibling);\n return true;\n }\n const index = cell.cellIndex;\n if (id === 'columnBefore' || id === 'columnAfter') {\n for (const currentRow of [...table.rows])\n currentRow.insertCell(index + (id === 'columnAfter' ? 1 : 0)).innerHTML = '<br>';\n return true;\n }\n if (id === 'deleteColumn') {\n for (const currentRow of [...table.rows])\n if (currentRow.cells[index]) currentRow.deleteCell(index);\n return true;\n }\n if (id === 'mergeCells') {\n cell.colSpan += 1;\n cell.nextElementSibling?.remove();\n return true;\n }\n if (id === 'splitCell' && cell.colSpan > 1) {\n cell.colSpan -= 1;\n const next = document.createElement(cell.tagName.toLowerCase());\n next.innerHTML = '<br>';\n cell.after(next);\n return true;\n }\n if (id === 'cellProperties') {\n cell.toggleAttribute('data-erag-selected');\n return true;\n }\n return false;\n}\nfunction emptyRow(source: HTMLTableRowElement): HTMLTableRowElement {\n const row = document.createElement('tr');\n for (const sourceCell of [...source.cells]) {\n const cell = document.createElement(sourceCell.tagName.toLowerCase());\n cell.innerHTML = '<br>';\n row.append(cell);\n }\n return row;\n}\n\nexport function applyTableProperties(root: HTMLElement, values: Record<string, string>): boolean {\n const table = closestElement(root, 'table');\n if (!table) return false;\n table.style.width = values.width || '';\n table.style.borderWidth = values.borderWidth || '';\n table.style.borderStyle = values.borderStyle || '';\n table.style.borderColor = values.borderColor || '';\n table.style.backgroundColor = values.backgroundColor || '';\n table.style.marginLeft =\n values.alignment === 'center' ? 'auto' : values.alignment === 'right' ? 'auto' : '0';\n table.style.marginRight =\n values.alignment === 'left' ? 'auto' : values.alignment === 'center' ? 'auto' : '0';\n for (const cell of table.querySelectorAll<HTMLElement>('td,th'))\n cell.style.padding = values.cellPadding || '';\n return true;\n}\n\nexport function navigateTableCell(root: HTMLElement, backwards: boolean): boolean {\n const cell = closestElement(root, 'td') ?? closestElement(root, 'th');\n const table = closestElement(root, 'table');\n if (!cell || !table) return false;\n const cells = [...table.querySelectorAll<HTMLElement>('td,th')];\n const index = cells.indexOf(cell);\n const next = cells[index + (backwards ? -1 : 1)];\n if (!next) return false;\n const range = document.createRange();\n range.selectNodeContents(next);\n range.collapse(true);\n const selection = window.getSelection();\n selection?.removeAllRanges();\n selection?.addRange(range);\n next.scrollIntoView({ block: 'nearest' });\n return true;\n}\n","export const DEFAULT_COLORS = [\n '#000000',\n '#434343',\n '#666666',\n '#999999',\n '#b7b7b7',\n '#cccccc',\n '#d9d9d9',\n '#efefef',\n '#f3f3f3',\n '#ffffff',\n '#980000',\n '#ff0000',\n '#ff9900',\n '#ffff00',\n '#00ff00',\n '#00ffff',\n '#4a86e8',\n '#0000ff',\n '#9900ff',\n '#ff00ff',\n '#e6b8af',\n '#f4cccc',\n '#fce5cd',\n '#fff2cc',\n '#d9ead3',\n '#d0e0e3',\n '#c9daf8',\n '#cfe2f3',\n '#d9d2e9',\n '#ead1dc',\n '#dd7e6b',\n '#ea9999',\n '#f9cb9c',\n '#ffe599',\n '#b6d7a8',\n '#a2c4c9',\n '#a4c2f4',\n '#9fc5e8',\n '#b4a7d6',\n '#d5a6bd',\n];\nexport const DEFAULT_FONT_FAMILIES = [\n 'Arial',\n 'Book Antiqua',\n 'Comic Sans MS',\n 'Courier New',\n 'Georgia',\n 'Helvetica',\n 'Impact',\n 'Symbol',\n 'Tahoma',\n 'Terminal',\n 'Times New Roman',\n 'Trebuchet MS',\n 'Verdana',\n].map((value) => ({ label: value, value }));\nexport const DEFAULT_FONT_SIZES = ['8pt', '10pt', '12pt', '14pt', '18pt', '24pt', '36pt'].map(\n (value) => ({ label: value, value }),\n);\nexport const DEFAULT_LINE_HEIGHTS = ['1', '1.1', '1.2', '1.3', '1.4', '1.5', '1.75', '2'].map(\n (value) => ({ label: value, value }),\n);\nexport const DEFAULT_BLOCKS = [\n { label: 'Paragraph', value: 'p' },\n { label: 'Heading 1', value: 'h1' },\n { label: 'Heading 2', value: 'h2' },\n { label: 'Heading 3', value: 'h3' },\n { label: 'Heading 4', value: 'h4' },\n { label: 'Heading 5', value: 'h5' },\n { label: 'Heading 6', value: 'h6' },\n { label: 'Preformatted', value: 'pre' },\n { label: 'Blockquote', value: 'blockquote' },\n] as const;\nexport const DEFAULT_ALLOWED_TAGS = [\n 'p',\n 'br',\n 'div',\n 'span',\n 'strong',\n 'b',\n 'em',\n 'i',\n 'u',\n 's',\n 'strike',\n 'sup',\n 'sub',\n 'code',\n 'pre',\n 'blockquote',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'ul',\n 'ol',\n 'li',\n 'a',\n 'img',\n 'figure',\n 'figcaption',\n 'table',\n 'thead',\n 'tbody',\n 'tfoot',\n 'tr',\n 'th',\n 'td',\n 'caption',\n 'hr',\n 'video',\n 'audio',\n 'source',\n 'iframe',\n];\nexport const DEFAULT_ALLOWED_ATTRIBUTES: Record<string, string[]> = {\n '*': ['class', 'style', 'title', 'dir', 'id'],\n span: [\n 'data-erag-mention',\n 'data-erag-mention-id',\n 'data-erag-mention-label',\n 'data-erag-mention-value',\n 'data-erag-merge-tag',\n 'data-erag-merge-tag-value',\n 'contenteditable',\n ],\n a: ['href', 'target', 'rel', 'name'],\n img: ['src', 'alt', 'width', 'height'],\n table: ['width', 'cellpadding', 'cellspacing', 'border'],\n td: ['colspan', 'rowspan', 'width', 'height'],\n th: ['colspan', 'rowspan', 'scope', 'width', 'height'],\n video: ['src', 'controls', 'width', 'height', 'poster'],\n audio: ['src', 'controls'],\n source: ['src', 'type'],\n iframe: ['src', 'width', 'height', 'allow', 'allowfullscreen', 'title'],\n};\n","export const PRINT_CONTENT_STYLES = `\n.erag-print-portal { display: none; }\n@media print {\n@page { margin: 16mm; }\nbody.erag-is-printing { margin: 0; padding: 0; }\nbody.erag-is-printing > :not(.erag-print-portal) { display: none; }\nbody.erag-is-printing > .erag-print-portal { display: block; }\nbody.erag-is-printing .erag-print-content {\n color: #111827;\n font: 14px/1.5 Arial, Helvetica, sans-serif;\n overflow-wrap: anywhere;\n}\nbody.erag-is-printing .erag-print-content h1,\nbody.erag-is-printing .erag-print-content h2,\nbody.erag-is-printing .erag-print-content h3,\nbody.erag-is-printing .erag-print-content h4,\nbody.erag-is-printing .erag-print-content h5,\nbody.erag-is-printing .erag-print-content h6 { margin: 0.65em 0 0.4em; line-height: 1.25; }\nbody.erag-is-printing .erag-print-content p { margin: 0.5em 0; }\nbody.erag-is-printing .erag-print-content ul,\nbody.erag-is-printing .erag-print-content ol { margin: 0.5em 0; padding-inline-start: 1.75em; }\nbody.erag-is-printing .erag-print-content ul { list-style: disc outside; }\nbody.erag-is-printing .erag-print-content ol { list-style: decimal outside; }\nbody.erag-is-printing .erag-print-content li { display: list-item; margin: 0.2em 0; }\nbody.erag-is-printing .erag-print-content img,\nbody.erag-is-printing .erag-print-content video,\nbody.erag-is-printing .erag-print-content iframe { max-width: 100%; }\nbody.erag-is-printing .erag-print-content table {\n width: 100%;\n border-spacing: 0;\n border-collapse: collapse;\n}\nbody.erag-is-printing .erag-print-content td,\nbody.erag-is-printing .erag-print-content th {\n min-width: 36px;\n padding: 8px;\n border: 1px solid #94a3b8;\n}\nbody.erag-is-printing .erag-print-content blockquote {\n margin-inline: 0;\n padding-inline-start: 16px;\n color: #475569;\n border-inline-start: 3px solid #cbd5e1;\n}\nbody.erag-is-printing .erag-print-content pre {\n padding: 12px;\n overflow: hidden;\n white-space: pre-wrap;\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n background: #f1f5f9;\n border-radius: 5px;\n}\nbody.erag-is-printing .erag-print-content .erag-mention {\n display: inline;\n padding: 1px 5px;\n color: #1659a7;\n white-space: nowrap;\n background: #eaf2ff;\n border-radius: 4px;\n}\n}\n`;\n","export function isSafeUrl(\n value: string,\n options: { allowRelative: boolean; allowDataImage?: boolean },\n): boolean {\n const trimmed = value.trim();\n if (!trimmed) return false;\n if (/^(javascript|vbscript):/i.test(trimmed)) return false;\n if (/^data:/i.test(trimmed))\n return Boolean(\n options.allowDataImage && /^data:image\\/(png|jpeg|gif|webp);base64,/i.test(trimmed),\n );\n if (/^(https?:|mailto:|tel:|blob:|#)/i.test(trimmed)) return true;\n return options.allowRelative && !/^[a-z][a-z\\d+.-]*:/i.test(trimmed);\n}\nexport function normalizeUrl(\n value: string,\n options: { relativeUrls: boolean; removeScriptHost: boolean; convertUrls: boolean },\n): string {\n const trimmed = value.trim();\n if (\n !options.convertUrls ||\n options.relativeUrls ||\n /^(data:|blob:|#|mailto:|tel:)/i.test(trimmed)\n )\n return trimmed;\n try {\n const url = new URL(trimmed, window.location.href);\n return options.removeScriptHost && url.origin === window.location.origin\n ? `${url.pathname}${url.search}${url.hash}`\n : url.href;\n } catch {\n return trimmed;\n }\n}\n","import type { MentionItem, MentionQueryMatch } from '../types';\n\nconst MENTION_QUERY_PATTERN = /(?:^|[\\s([{])@([\\p{L}\\p{N}._-]*)$/u;\nconst MENTION_SELECTOR = 'span.erag-mention[data-erag-mention=\"true\"]';\n\nexport function closestMentionElement(\n target: EventTarget | null,\n root: HTMLElement,\n): HTMLElement | null {\n if (!(target instanceof Element)) return null;\n const mention = target.closest<HTMLElement>(MENTION_SELECTOR);\n return mention && root.contains(mention) ? mention : null;\n}\n\nexport function detectMentionQuery(root: HTMLElement): MentionQueryMatch | null {\n const selection = window.getSelection();\n if (!selection?.rangeCount || !selection.isCollapsed) return null;\n\n const activeRange = selection.getRangeAt(0);\n if (!root.contains(activeRange.commonAncestorContainer)) return null;\n const node = activeRange.startContainer;\n if (!(node instanceof Text)) return null;\n\n const parent = node.parentElement;\n if (!parent || isBlockedMentionContext(root, parent)) return null;\n\n const caretOffset = activeRange.startOffset;\n const prefix = node.data.slice(0, caretOffset);\n const match = prefix.match(MENTION_QUERY_PATTERN);\n const query = match?.[1];\n if (query === undefined) return null;\n\n const range = document.createRange();\n range.setStart(node, caretOffset - query.length - 1);\n range.setEnd(node, caretOffset);\n return { query, range };\n}\n\nexport function createMentionElement(item: MentionItem): HTMLSpanElement {\n const mention = document.createElement('span');\n mention.className = 'erag-mention';\n mention.dataset.eragMention = 'true';\n mention.dataset.eragMentionId = String(item.id);\n mention.dataset.eragMentionLabel = item.label;\n if (item.value !== undefined) mention.dataset.eragMentionValue = item.value;\n mention.contentEditable = 'false';\n mention.textContent = `@${item.label}`;\n return mention;\n}\n\nexport function insertMentionAtRange(root: HTMLElement, range: Range, item: MentionItem): boolean {\n if (!root.contains(range.commonAncestorContainer) || range.toString().charAt(0) !== '@') {\n return false;\n }\n\n root.focus({ preventScroll: true });\n const selection = window.getSelection();\n if (!selection) return false;\n selection.removeAllRanges();\n selection.addRange(range);\n\n const mention = createMentionElement(item);\n range.deleteContents();\n const space = document.createTextNode(' ');\n range.insertNode(space);\n range.insertNode(mention);\n range.setStartAfter(space);\n range.collapse(true);\n selection.removeAllRanges();\n selection.addRange(range);\n root.dispatchEvent(\n new InputEvent('input', {\n bubbles: true,\n inputType: 'insertReplacementText',\n data: `@${item.label}`,\n }),\n );\n return true;\n}\n\nexport function parseMentionElement(element: Element): MentionItem | null {\n if (!isValidMentionElement(element)) return null;\n const rawId = element.getAttribute('data-erag-mention-id') ?? '';\n const numericId = Number(rawId);\n const id = Number.isFinite(numericId) && String(numericId) === rawId ? numericId : rawId;\n const item: MentionItem = {\n id,\n label: element.getAttribute('data-erag-mention-label') ?? '',\n };\n const value = element.getAttribute('data-erag-mention-value');\n if (value !== null) item.value = value;\n return item;\n}\n\nexport function isValidMentionElement(element: Element): boolean {\n return (\n element.matches(MENTION_SELECTOR) &&\n element.getAttribute('contenteditable') === 'false' &&\n Boolean(element.getAttribute('data-erag-mention-id')) &&\n Boolean(element.getAttribute('data-erag-mention-label'))\n );\n}\n\nexport function isMentionCandidate(element: Element): boolean {\n if (element.tagName.toLowerCase() !== 'span') return false;\n return (\n [...element.classList].some((name) => name.startsWith('erag-mention')) ||\n [...element.attributes].some((attribute) => attribute.name.startsWith('data-erag-mention'))\n );\n}\n\nexport function normalizeMentionElement(element: Element): boolean {\n const item = parseMentionElement(element);\n if (!item) return false;\n const normalized = createMentionElement(item);\n element.replaceWith(normalized);\n return true;\n}\n\nexport function removeAdjacentMention(\n root: HTMLElement,\n direction: 'backward' | 'forward',\n): MentionItem | null {\n const selection = window.getSelection();\n if (!selection?.rangeCount || !selection.isCollapsed) return null;\n const range = selection.getRangeAt(0);\n if (!root.contains(range.commonAncestorContainer)) return null;\n\n const adjacent = adjacentNode(range, direction);\n const element = adjacent instanceof Element ? adjacent : adjacent?.parentElement;\n const mention = element?.matches(MENTION_SELECTOR)\n ? element\n : element?.closest(MENTION_SELECTOR);\n if (!mention || !root.contains(mention)) return null;\n\n const item = parseMentionElement(mention);\n if (!item) return null;\n\n const deletionRange = document.createRange();\n deletionRange.selectNode(mention);\n selection.removeAllRanges();\n selection.addRange(deletionRange);\n if (!document.execCommand('delete', false)) deletionRange.deleteContents();\n selection.collapseToEnd();\n return item;\n}\n\nfunction adjacentNode(range: Range, direction: 'backward' | 'forward'): Node | null {\n const container = range.startContainer;\n const offset = range.startOffset;\n if (container instanceof Text) {\n if (direction === 'backward' && offset === 0) return container.previousSibling;\n if (direction === 'forward' && offset === container.length) return container.nextSibling;\n return null;\n }\n if (direction === 'backward' && offset === 0) return container.previousSibling;\n return direction === 'backward'\n ? (container.childNodes.item(offset - 1) ?? null)\n : (container.childNodes.item(offset) ?? null);\n}\n\nfunction isBlockedMentionContext(root: HTMLElement, element: HTMLElement): boolean {\n const blocked = element.closest(\n 'a,code,pre,[data-erag-mention=\"true\"],[contenteditable=\"false\"]',\n );\n return Boolean(blocked && blocked !== root && root.contains(blocked));\n}\n","import type { MergeTagItem, MergeTagQueryMatch } from '../types';\n\nconst MERGE_TAG_PATTERN = /\\{\\{([^{}\\n\\r]*)$/u;\nconst MERGE_TAG_SELECTOR = 'span.erag-merge-tag[data-erag-merge-tag=\"true\"]';\nconst MERGE_TAG_BLOCK_SELECTOR = 'p,div,li,h1,h2,h3,h4,h5,h6,blockquote,figcaption,td,th';\n\nexport function detectMergeTagQuery(root: HTMLElement): MergeTagQueryMatch | null {\n const selection = window.getSelection();\n if (!selection?.rangeCount || !selection.isCollapsed) return null;\n const activeRange = selection.getRangeAt(0);\n if (!root.contains(activeRange.commonAncestorContainer)) return null;\n const node = activeRange.startContainer;\n if (!(node instanceof Text) || isBlockedContext(root, node.parentElement)) return null;\n const caretOffset = activeRange.startOffset;\n const block = node.parentElement?.closest<HTMLElement>(MERGE_TAG_BLOCK_SELECTOR) ?? root;\n if (block !== root && !root.contains(block)) return null;\n const prefixRange = document.createRange();\n prefixRange.selectNodeContents(block);\n prefixRange.setEnd(node, caretOffset);\n const prefix = prefixRange.toString();\n const match = prefix.match(MERGE_TAG_PATTERN);\n if (!match?.[0] || match[1] === undefined) return null;\n const range = document.createRange();\n if (!setRangeStartBeforeCaret(block, node, caretOffset, match[0].length, range)) {\n return null;\n }\n range.setEnd(node, caretOffset);\n return { query: normalizeQuery(match[1]), range };\n}\n\nexport function insertMergeTagAtRange(\n root: HTMLElement,\n range: Range,\n item: MergeTagItem,\n): boolean {\n if (!root.contains(range.commonAncestorContainer)) return false;\n root.focus({ preventScroll: true });\n const selection = window.getSelection();\n if (!selection) return false;\n const tag = createMergeTagElement(item);\n range.deleteContents();\n const space = document.createTextNode(' ');\n range.insertNode(space);\n range.insertNode(tag);\n range.setStartAfter(space);\n range.collapse(true);\n selection.removeAllRanges();\n selection.addRange(range);\n root.dispatchEvent(\n new InputEvent('input', {\n bubbles: true,\n inputType: 'insertReplacementText',\n data: formatMergeTagValue(item.value),\n }),\n );\n return true;\n}\n\nexport function createMergeTagElement(item: MergeTagItem): HTMLSpanElement {\n const element = document.createElement('span');\n element.className = 'erag-merge-tag';\n element.dataset.eragMergeTag = 'true';\n element.dataset.eragMergeTagValue = formatMergeTagValue(item.value);\n element.contentEditable = 'false';\n element.textContent = formatMergeTagValue(item.value);\n return element;\n}\n\nexport function parseMergeTagElement(element: Element): MergeTagItem | null {\n if (!isValidMergeTagElement(element)) return null;\n return {\n value: element.getAttribute('data-erag-merge-tag-value') ?? '',\n };\n}\n\nexport function isMergeTagCandidate(element: Element): boolean {\n return (\n element.tagName.toLowerCase() === 'span' &&\n ([...element.classList].some((name) => name.startsWith('erag-merge-tag')) ||\n [...element.attributes].some((attribute) =>\n attribute.name.startsWith('data-erag-merge-tag'),\n ))\n );\n}\n\nexport function normalizeMergeTagElement(element: Element): boolean {\n const item = parseMergeTagElement(element);\n if (!item) return false;\n element.replaceWith(createMergeTagElement(item));\n return true;\n}\n\nexport function removeAdjacentMergeTag(\n root: HTMLElement,\n direction: 'backward' | 'forward',\n): MergeTagItem | null {\n const selection = window.getSelection();\n if (!selection?.rangeCount || !selection.isCollapsed) return null;\n const range = selection.getRangeAt(0);\n if (!root.contains(range.commonAncestorContainer)) return null;\n const adjacent = adjacentNode(range, direction);\n const element = adjacent instanceof Element ? adjacent : adjacent?.parentElement;\n const tag = element?.matches(MERGE_TAG_SELECTOR)\n ? element\n : element?.closest(MERGE_TAG_SELECTOR);\n if (!tag || !root.contains(tag)) return null;\n const item = parseMergeTagElement(tag);\n if (!item) return null;\n const deletionRange = document.createRange();\n deletionRange.selectNode(tag);\n selection.removeAllRanges();\n selection.addRange(deletionRange);\n if (!document.execCommand('delete', false)) deletionRange.deleteContents();\n selection.collapseToEnd();\n return item;\n}\n\nfunction isValidMergeTagElement(element: Element): boolean {\n return (\n element.matches(MERGE_TAG_SELECTOR) &&\n element.getAttribute('contenteditable') === 'false' &&\n Boolean(element.getAttribute('data-erag-merge-tag-value'))\n );\n}\n\nexport function normalizeMergeTagValue(value: string): string {\n const normalized = value.trim();\n if (normalized.startsWith('{{') && normalized.endsWith('}}')) {\n return normalized.slice(2, -2).trim();\n }\n if (normalized.startsWith('{') && normalized.endsWith('}')) {\n return normalized.slice(1, -1).trim();\n }\n return normalized.replace(/[{}]/gu, '').trim();\n}\n\nexport function formatMergeTagValue(value: string): string {\n return `{{${normalizeMergeTagValue(value)}}}`;\n}\n\nfunction isBlockedContext(root: HTMLElement, element: HTMLElement | null): boolean {\n const blocked = element?.closest(\n 'a,code,pre,[data-erag-mention=\"true\"],[data-erag-merge-tag=\"true\"],[contenteditable=\"false\"]',\n );\n return Boolean(blocked && blocked !== root && root.contains(blocked));\n}\n\nfunction normalizeQuery(value: string): string {\n return value.replace(/\\s+/gu, ' ').trim();\n}\n\nfunction setRangeStartBeforeCaret(\n block: HTMLElement,\n caretNode: Text,\n caretOffset: number,\n characterCount: number,\n range: Range,\n): boolean {\n const walker = document.createTreeWalker(block, NodeFilter.SHOW_TEXT);\n const nodes: Text[] = [];\n let current = walker.nextNode();\n while (current) {\n if (current instanceof Text) nodes.push(current);\n current = walker.nextNode();\n }\n let index = nodes.indexOf(caretNode);\n let offset = caretOffset;\n let remaining = characterCount;\n while (index >= 0) {\n if (remaining <= offset) {\n range.setStart(nodes[index] ?? caretNode, offset - remaining);\n return true;\n }\n remaining -= offset;\n index -= 1;\n offset = nodes[index]?.length ?? 0;\n }\n return false;\n}\n\nfunction adjacentNode(range: Range, direction: 'backward' | 'forward'): Node | null {\n const container = range.startContainer;\n const offset = range.startOffset;\n if (container instanceof Text) {\n if (direction === 'backward' && offset === 0) return container.previousSibling;\n if (direction === 'forward' && offset === container.length) return container.nextSibling;\n return null;\n }\n if (direction === 'backward' && offset === 0) return container.previousSibling;\n return direction === 'backward'\n ? (container.childNodes.item(offset - 1) ?? null)\n : (container.childNodes.item(offset) ?? null);\n}\n","import { isSafeUrl } from './url';\nimport { isMentionCandidate, normalizeMentionElement } from './mention';\nimport { isMergeTagCandidate, normalizeMergeTagElement } from './mergeTag';\nexport interface SanitizerOptions {\n allowedTags: string[];\n allowedAttributes: Record<string, string[]>;\n allowRelativeUrls: boolean;\n}\n\nexport function canSanitizeHtml(): boolean {\n return (\n typeof document !== 'undefined' &&\n typeof DOMParser !== 'undefined' &&\n typeof NodeFilter !== 'undefined'\n );\n}\nconst SAFE_STYLES = new Set([\n 'color',\n 'background-color',\n 'font-family',\n 'font-size',\n 'font-weight',\n 'font-style',\n 'text-decoration',\n 'text-align',\n 'line-height',\n 'margin-left',\n 'margin-right',\n 'display',\n 'list-style-type',\n 'width',\n 'height',\n 'border',\n 'border-width',\n 'border-style',\n 'border-color',\n 'border-collapse',\n 'padding',\n 'background',\n]);\n\nexport function sanitizeHtml(html: string, options: SanitizerOptions): string {\n if (!canSanitizeHtml()) return '';\n const documentNode = new DOMParser().parseFromString(html, 'text/html');\n const walker = documentNode.createTreeWalker(documentNode.body, NodeFilter.SHOW_ELEMENT);\n const elements: Element[] = [];\n let node = walker.nextNode();\n while (node) {\n elements.push(node as Element);\n node = walker.nextNode();\n }\n for (const element of elements) sanitizeElement(element, options);\n return documentNode.body.innerHTML;\n}\nfunction sanitizeElement(element: Element, options: SanitizerOptions): void {\n const tag = element.tagName.toLowerCase();\n if (!options.allowedTags.includes(tag)) {\n element.replaceWith(...element.childNodes);\n return;\n }\n if (isMentionCandidate(element)) {\n if (!normalizeMentionElement(element)) {\n element.replaceWith(element.ownerDocument.createTextNode(element.textContent ?? ''));\n }\n return;\n }\n if (isMergeTagCandidate(element)) {\n if (!normalizeMergeTagElement(element)) {\n element.replaceWith(element.ownerDocument.createTextNode(element.textContent ?? ''));\n }\n return;\n }\n if (tag === 'span') element.removeAttribute('contenteditable');\n const allowed = new Set([\n ...(options.allowedAttributes['*'] ?? []),\n ...(options.allowedAttributes[tag] ?? []),\n ]);\n for (const attribute of [...element.attributes]) {\n const name = attribute.name.toLowerCase();\n if (name.startsWith('on') || !allowed.has(name)) {\n element.removeAttribute(attribute.name);\n continue;\n }\n if (\n ['href', 'src', 'poster'].includes(name) &&\n !isSafeUrl(attribute.value, {\n allowRelative: options.allowRelativeUrls,\n allowDataImage: tag === 'img',\n })\n )\n element.removeAttribute(attribute.name);\n if (name === 'style') element.setAttribute('style', sanitizeStyle(attribute.value));\n }\n if (tag === 'iframe') {\n const src = element.getAttribute('src') ?? '';\n if (!/^https:\\/\\//i.test(src)) element.remove();\n else element.setAttribute('sandbox', 'allow-same-origin allow-presentation');\n }\n}\nfunction sanitizeStyle(value: string): string {\n return value\n .split(';')\n .flatMap((rule) => {\n const separator = rule.indexOf(':');\n if (separator < 1) return [];\n const name = rule.slice(0, separator).trim().toLowerCase();\n const raw = rule.slice(separator + 1).trim();\n return SAFE_STYLES.has(name) && raw && !/url\\s*\\(|expression|javascript:/i.test(raw)\n ? [`${name}:${raw}`]\n : [];\n })\n .join(';');\n}\n","import { DEFAULT_ALLOWED_ATTRIBUTES, DEFAULT_ALLOWED_TAGS } from '../constants/editorDefaults';\nimport { PRINT_CONTENT_STYLES } from '../constants/printStyles';\nimport { sanitizeHtml } from '../utils/sanitizer';\n\nexport function printEditorContent(root: HTMLElement): boolean {\n const style = document.createElement('style');\n style.dataset.eragPrintStyle = 'true';\n style.textContent = PRINT_CONTENT_STYLES;\n const content = document.createElement('main');\n content.className = 'erag-print-portal erag-print-content';\n content.dir = root.dir === 'rtl' ? 'rtl' : 'ltr';\n content.innerHTML = sanitizeHtml(root.innerHTML, {\n allowedTags: DEFAULT_ALLOWED_TAGS,\n allowedAttributes: DEFAULT_ALLOWED_ATTRIBUTES,\n allowRelativeUrls: true,\n });\n\n document.head.append(style);\n document.body.append(content);\n document.body.classList.add('erag-is-printing');\n copyComputedTypography(root, content);\n let cleanupTimer: number | undefined;\n const cleanup = (): void => {\n if (cleanupTimer !== undefined) window.clearTimeout(cleanupTimer);\n window.removeEventListener('afterprint', cleanup);\n document.body.classList.remove('erag-is-printing');\n content.remove();\n style.remove();\n };\n\n window.addEventListener('afterprint', cleanup, { once: true });\n try {\n window.print();\n cleanupTimer = window.setTimeout(cleanup, 1_000);\n return true;\n } catch {\n cleanup();\n return false;\n }\n}\n\nfunction copyComputedTypography(source: HTMLElement, target: HTMLElement): void {\n const computed = window.getComputedStyle(source);\n target.style.fontFamily = computed.fontFamily;\n target.style.fontSize = computed.fontSize;\n target.style.lineHeight = computed.lineHeight;\n target.style.color = computed.color;\n}\n","import { executeClipboardCommand } from './clipboardCommands';\nimport { executeFormatCommand, queryFormatState } from './formatCommands';\nimport { insertAtSelection } from '../utils/html';\nimport { executeTableCommand } from './tableCommands';\nimport { printEditorContent } from './printCommands';\n\nconst TABLE_COMMANDS = new Set([\n 'deleteTable',\n 'cellProperties',\n 'mergeCells',\n 'splitCell',\n 'rowBefore',\n 'rowAfter',\n 'deleteRow',\n 'columnBefore',\n 'columnAfter',\n 'deleteColumn',\n]);\nexport function executeEditorCommand(root: HTMLElement, id: string, value?: string): boolean {\n if (TABLE_COMMANDS.has(id)) return executeTableCommand(root, id);\n if (id === 'hr') return insertAtSelection(root, '<hr><p><br></p>');\n if (id === 'anchor')\n return insertAtSelection(\n root,\n `<a id=\"${globalThis.crypto?.randomUUID?.() ?? Date.now()}\" name=\"anchor\"></a>`,\n );\n if (id === 'print') return printEditorContent(root);\n return executeFormatCommand(root, id, value);\n}\nexport async function executeAsyncEditorCommand(root: HTMLElement, id: string): Promise<boolean> {\n return ['cut', 'copy', 'paste', 'pasteText'].includes(id)\n ? executeClipboardCommand(root, id as 'cut' | 'copy' | 'paste' | 'pasteText')\n : false;\n}\nexport function isEditorCommandActive(id: string): boolean {\n return queryFormatState(id);\n}\nexport function isTableCommand(id: string): boolean {\n return TABLE_COMMANDS.has(id);\n}\n","import { escapeHtml, insertAtSelection } from '../utils/html';\nimport { isSafeUrl } from '../utils/url';\nimport type { ImageValue, LinkValue, MediaValue } from '../types';\n\nexport function insertLink(root: HTMLElement, value: LinkValue, allowRelative: boolean): boolean {\n if (!isSafeUrl(value.url, { allowRelative })) return false;\n const selection = window.getSelection();\n const selectedText = selection?.toString() ?? '';\n const text = value.text || selectedText || value.url;\n const target = value.target === '_blank' ? ' target=\"_blank\" rel=\"noopener noreferrer\"' : '';\n return insertAtSelection(\n root,\n `<a href=\"${escapeAttribute(value.url)}\" title=\"${escapeAttribute(value.title)}\"${target}>${escapeHtml(text)}</a>`,\n );\n}\nexport function insertImage(\n root: HTMLElement,\n value: ImageValue,\n allowRelative: boolean,\n defaultWidth?: number,\n): boolean {\n if (!isSafeUrl(value.src, { allowRelative, allowDataImage: true })) return false;\n const width = numericAttribute(value.width || String(defaultWidth ?? ''), 'width');\n const height = numericAttribute(value.height, 'height');\n return insertAtSelection(\n root,\n `<img src=\"${escapeAttribute(value.src)}\" alt=\"${escapeAttribute(value.alt)}\"${width}${height}>`,\n );\n}\nexport function insertMedia(root: HTMLElement, value: MediaValue, allowRelative: boolean): boolean {\n if (!isSafeUrl(value.src, { allowRelative })) return false;\n const size = `${numericAttribute(value.width, 'width')}${numericAttribute(value.height, 'height')}`;\n if (value.type === 'audio')\n return insertAtSelection(\n root,\n `<audio src=\"${escapeAttribute(value.src)}\" controls></audio>`,\n );\n if (value.type === 'iframe') {\n if (!/^https:\\/\\//i.test(value.src)) return false;\n return insertAtSelection(\n root,\n `<iframe src=\"${escapeAttribute(value.src)}\"${size} sandbox=\"allow-same-origin allow-presentation\" title=\"Embedded media\"></iframe>`,\n );\n }\n const poster =\n value.poster && isSafeUrl(value.poster, { allowRelative })\n ? ` poster=\"${escapeAttribute(value.poster)}\"`\n : '';\n return insertAtSelection(\n root,\n `<video src=\"${escapeAttribute(value.src)}\"${size}${poster} controls></video>`,\n );\n}\nexport function insertTable(root: HTMLElement, rows: number, columns: number): boolean {\n const rowHtml = `<tr>${'<td><br></td>'.repeat(Math.max(1, columns))}</tr>`;\n return insertAtSelection(\n root,\n `<table><tbody>${rowHtml.repeat(Math.max(1, rows))}</tbody></table><p><br></p>`,\n );\n}\nfunction numericAttribute(value: string, name: string): string {\n const number = Number.parseInt(value, 10);\n return Number.isFinite(number) && number > 0 ? ` ${name}=\"${number}\"` : '';\n}\nfunction escapeAttribute(value: string): string {\n return value.replaceAll('&', '&').replaceAll('\"', '"').replaceAll('<', '<');\n}\n","export const KEYBOARD_SHORTCUTS: Record<string, string> = {\n 'mod+b': 'bold',\n 'mod+i': 'italic',\n 'mod+u': 'underline',\n 'mod+shift+x': 'strikethrough',\n 'mod+k': 'link',\n 'mod+z': 'undo',\n 'mod+shift+z': 'redo',\n 'mod+y': 'redo',\n 'mod+f': 'find-replace',\n 'mod+shift+p': 'preview',\n};\n","import { computed, shallowRef, type ComputedRef } from 'vue';\nimport { getPersistentHtml, getPersistentText, getTextCounts } from '../utils/html';\nimport { canSanitizeHtml, sanitizeHtml } from '../utils/sanitizer';\nimport { restoreSelection, saveSelection } from '../utils/selection';\nimport type { EditorCounts, ResolvedEditorInit } from '../types';\n\nexport function useEditor(config: ComputedRef<ResolvedEditorInit>, initialHtml: string) {\n const root = shallowRef<HTMLElement | null>(null);\n const html = shallowRef(clean(initialHtml));\n const counts = shallowRef<EditorCounts>({ words: 0, characters: 0 });\n const empty = computed(() => {\n if (!root.value) return !html.value.trim();\n return (\n !getPersistentText(root.value).trim() &&\n !root.value.querySelector('img,video,audio,iframe,table,hr')\n );\n });\n function clean(value: string): string {\n return config.value.sanitize && canSanitizeHtml()\n ? sanitizeHtml(value, {\n allowedTags: config.value.allowedTags,\n allowedAttributes: config.value.allowedAttributes,\n allowRelativeUrls: config.value.relativeUrls,\n })\n : value;\n }\n function connect(element: HTMLElement): void {\n root.value = element;\n if (element.innerHTML !== html.value) element.innerHTML = html.value;\n updateCounts();\n }\n function sync(): string {\n if (!root.value) return html.value;\n html.value = getPersistentHtml(root.value);\n updateCounts();\n return html.value;\n }\n function setHtml(value: string, preserve = true): void {\n const next = clean(value);\n if (next === html.value && root.value?.innerHTML === next) return;\n const range = preserve && root.value ? saveSelection(root.value) : null;\n html.value = next;\n if (root.value) {\n root.value.innerHTML = next;\n restoreSelection(range, root.value);\n }\n updateCounts();\n }\n function updateCounts(): void {\n counts.value = root.value ? getTextCounts(root.value) : { words: 0, characters: 0 };\n }\n function getText(): string {\n return root.value ? getPersistentText(root.value) : '';\n }\n return { root, html, counts, empty, clean, connect, sync, setHtml, getText, updateCounts };\n}\n","import type { MentionConfig, ResolvedMentionConfig } from '../types';\n\nexport const defaultMentionConfig: Required<Omit<MentionConfig, 'items'>> = {\n enabled: true,\n minimumCharacters: 0,\n debounce: 200,\n limit: 8,\n};\n\nexport function normalizeMentionConfig(\n mentions: boolean | MentionConfig | undefined,\n): ResolvedMentionConfig {\n const enabled =\n mentions === true || (typeof mentions === 'object' && mentions.enabled === true);\n const configured = typeof mentions === 'object' ? mentions : undefined;\n const normalized: ResolvedMentionConfig = {\n enabled,\n minimumCharacters: Math.max(\n 0,\n Math.floor(configured?.minimumCharacters ?? defaultMentionConfig.minimumCharacters),\n ),\n debounce: Math.max(0, Math.floor(configured?.debounce ?? defaultMentionConfig.debounce)),\n limit: Math.max(1, Math.floor(configured?.limit ?? defaultMentionConfig.limit)),\n };\n\n if (configured?.items !== undefined) normalized.items = configured.items;\n return normalized;\n}\n","import type { MergeTagConfig, ResolvedMergeTagConfig } from '../types';\nimport { formatMergeTagValue, normalizeMergeTagValue } from '../utils/mergeTag';\n\nexport const defaultMergeTagConfig: Required<Omit<MergeTagConfig, 'items'>> = {\n enabled: true,\n limit: 10,\n};\n\nexport function normalizeMergeTagConfig(\n mergeTags: boolean | MergeTagConfig | undefined,\n): ResolvedMergeTagConfig {\n const configured = typeof mergeTags === 'object' ? mergeTags : undefined;\n return {\n enabled: mergeTags === true || Boolean(configured && configured.enabled !== false),\n limit: Math.max(1, Math.floor(configured?.limit ?? defaultMergeTagConfig.limit)),\n items:\n configured?.items\n ?.filter((item) => normalizeMergeTagValue(item.value).length > 0)\n ?.map((item) => ({\n value: formatMergeTagValue(item.value),\n ...(item.group?.trim() ? { group: item.group.trim() } : {}),\n })) ?? [],\n };\n}\n","import type { EditorTemplatesConfig, ResolvedEditorTemplatesConfig } from '../types';\n\nexport function normalizeEditorTemplatesConfig(\n templates: boolean | EditorTemplatesConfig | undefined,\n): ResolvedEditorTemplatesConfig {\n const configured = typeof templates === 'object' ? templates : undefined;\n return {\n enabled: templates === true || Boolean(configured && configured.enabled !== false),\n items: configured?.items?.map((item) => ({ ...item })) ?? [],\n };\n}\n","import {\n DEFAULT_ALLOWED_ATTRIBUTES,\n DEFAULT_ALLOWED_TAGS,\n DEFAULT_BLOCKS,\n DEFAULT_COLORS,\n DEFAULT_FONT_FAMILIES,\n DEFAULT_FONT_SIZES,\n DEFAULT_LINE_HEIGHTS,\n} from '../constants/editorDefaults';\nimport type { ResolvedEditorInit } from '../types';\nimport { normalizeMentionConfig } from './mentionConfig';\nimport { normalizeMergeTagConfig } from './mergeTagConfig';\nimport { normalizeEditorTemplatesConfig } from './templateConfig';\n\nexport const defaultEditorConfig: ResolvedEditorInit = {\n height: 420,\n minHeight: 240,\n placeholder: 'Write something...',\n menubar: true,\n toolbar: true,\n statusbar: true,\n branding: false,\n promotion: false,\n resize: true,\n readonly: false,\n autofocus: false,\n spellcheck: true,\n direction: 'ltr',\n contentStyle: '',\n contentClass: '',\n fontFamilyFormats: DEFAULT_FONT_FAMILIES,\n fontSizeFormats: DEFAULT_FONT_SIZES,\n lineHeightFormats: DEFAULT_LINE_HEIGHTS,\n blockFormats: [...DEFAULT_BLOCKS],\n textColors: DEFAULT_COLORS,\n backgroundColors: DEFAULT_COLORS,\n plugins: [\n 'history',\n 'formatting',\n 'lists',\n 'link',\n 'image',\n 'media',\n 'table',\n 'code',\n 'preview',\n 'fullscreen',\n 'find-replace',\n 'special-character',\n 'emoji',\n 'horizontal-rule',\n 'anchor',\n 'merge-tags',\n 'templates',\n 'date-time',\n ],\n acceptedFormats: ['image/jpeg', 'image/png', 'image/webp', 'image/gif'],\n maxImageSize: 5 * 1024 * 1024,\n uploadFieldName: 'file',\n uploadHeaders: {},\n uploadCredentials: 'same-origin',\n automaticUploads: true,\n pasteImages: true,\n imageFilePicker: true,\n imageUrlInput: true,\n imageResize: true,\n imageDefaultWidth: 640,\n sanitize: true,\n allowedTags: DEFAULT_ALLOWED_TAGS,\n allowedAttributes: DEFAULT_ALLOWED_ATTRIBUTES,\n relativeUrls: true,\n removeScriptHost: false,\n convertUrls: true,\n dateFormats: [\n {\n label: 'ISO date',\n type: 'date',\n format: 'iso-date',\n options: { year: 'numeric', month: '2-digit', day: '2-digit' },\n },\n {\n label: 'Local numeric date',\n type: 'date',\n options: { year: 'numeric', month: '2-digit', day: '2-digit' },\n },\n {\n label: 'Long date',\n type: 'date',\n options: { year: 'numeric', month: 'long', day: 'numeric' },\n },\n ],\n timeFormats: [\n {\n label: 'Current 24-hour time',\n type: 'time',\n options: { hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false },\n },\n {\n label: 'Current 12-hour time',\n type: 'time',\n options: { hour: 'numeric', minute: '2-digit', second: '2-digit', hour12: true },\n },\n ],\n tableGridSize: 10,\n helpShortcutText: 'Press Alt+0 for help',\n mentions: normalizeMentionConfig(false),\n mergeTags: normalizeMergeTagConfig(false),\n templates: normalizeEditorTemplatesConfig(false),\n};\n","import { defaultEditorConfig } from '../config/defaultConfig';\nimport { normalizeMentionConfig } from '../config/mentionConfig';\nimport { normalizeMergeTagConfig } from '../config/mergeTagConfig';\nimport { normalizeEditorTemplatesConfig } from '../config/templateConfig';\nimport type { EditorInit, ResolvedEditorInit } from '../types';\n\nconst ALIASES = {\n content_style: 'contentStyle',\n font_family_formats: 'fontFamilyFormats',\n font_size_formats: 'fontSizeFormats',\n line_height_formats: 'lineHeightFormats',\n images_upload_url: 'imagesUploadUrl',\n images_upload_handler: 'imagesUploadHandler',\n images_delete_handler: 'imagesDeleteHandler',\n automatic_uploads: 'automaticUploads',\n relative_urls: 'relativeUrls',\n remove_script_host: 'removeScriptHost',\n convert_urls: 'convertUrls',\n} as const;\n\nexport function deepMerge<T extends object>(base: T, override: Partial<T>): T {\n const result = { ...base } as Record<string, unknown>;\n for (const [key, value] of Object.entries(override)) {\n if (value === undefined) continue;\n const current = result[key];\n if (isPlainObject(current) && isPlainObject(value)) {\n result[key] = mergeRecords(current, value);\n } else {\n result[key] = Array.isArray(value) ? [...value] : value;\n }\n }\n return result as T;\n}\n\nfunction mergeRecords(\n base: Record<string, unknown>,\n override: Record<string, unknown>,\n): Record<string, unknown> {\n const result = { ...base };\n for (const [key, value] of Object.entries(override))\n result[key] =\n isPlainObject(result[key]) && isPlainObject(value)\n ? mergeRecords(result[key], value)\n : Array.isArray(value)\n ? [...value]\n : value;\n return result;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nexport function normalizeEditorConfig(init?: EditorInit): ResolvedEditorInit {\n if (!init) return deepMerge(defaultEditorConfig, {});\n const normalized: EditorInit = { ...init };\n for (const [alias, camel] of Object.entries(ALIASES) as [\n keyof typeof ALIASES,\n keyof EditorInit,\n ][]) {\n if (normalized[camel] === undefined && init[alias] !== undefined) {\n Object.assign(normalized, { [camel]: init[alias] });\n }\n delete normalized[alias];\n }\n return deepMerge(defaultEditorConfig, {\n ...normalized,\n mentions: normalizeMentionConfig(init.mentions),\n mergeTags: normalizeMergeTagConfig(init.mergeTags),\n templates: normalizeEditorTemplatesConfig(init.templates),\n });\n}\n","import { computed, type MaybeRefOrGetter, toValue } from 'vue';\nimport { normalizeEditorConfig } from '../utils/config';\nimport type { EditorInit } from '../types';\nexport function useEditorConfig(init: MaybeRefOrGetter<EditorInit | undefined>) {\n return computed(() => normalizeEditorConfig(toValue(init)));\n}\n","export function executeHistoryCommand(id: 'undo' | 'redo'): boolean {\n return document.execCommand(id, false);\n}\nexport function canUseHistory(id: 'undo' | 'redo'): boolean {\n try {\n return document.queryCommandEnabled(id);\n } catch {\n return true;\n }\n}\n","import { onBeforeUnmount, shallowRef, type Ref } from 'vue';\nimport { canUseHistory } from '../commands/historyCommands';\n\nexport function useEditorHistory(root: Ref<HTMLElement | null>) {\n const canUndo = shallowRef(false);\n const canRedo = shallowRef(false);\n let frame = 0;\n\n function update(): void {\n cancelAnimationFrame(frame);\n frame = requestAnimationFrame(() => {\n if (!root.value) {\n canUndo.value = false;\n canRedo.value = false;\n return;\n }\n\n canUndo.value = canUseHistory('undo');\n canRedo.value = canUseHistory('redo');\n });\n }\n\n function reset(): void {\n cancelAnimationFrame(frame);\n canUndo.value = false;\n canRedo.value = false;\n }\n\n onBeforeUnmount(() => cancelAnimationFrame(frame));\n\n return { canUndo, canRedo, update, reset };\n}\n","export function cssUnit(value: number | string | undefined): string | undefined {\n if (value === undefined || value === '') return undefined;\n return typeof value === 'number' ? `${Math.max(0, value)}px` : value;\n}\nexport function pixelValue(value: number | string | undefined, fallback: number): number {\n if (typeof value === 'number' && Number.isFinite(value)) return value;\n const parsed = typeof value === 'string' ? Number.parseFloat(value) : Number.NaN;\n return Number.isFinite(parsed) ? parsed : fallback;\n}\n","import { onBeforeUnmount, shallowRef, type ComputedRef, type Ref } from 'vue';\nimport type { ResolvedEditorInit } from '../types';\nimport { pixelValue } from '../utils/units';\n\nexport function useEditorResize(\n shell: Ref<HTMLElement | null>,\n config: ComputedRef<ResolvedEditorInit>,\n locked: ComputedRef<boolean>,\n resized: (height: number) => void,\n) {\n const currentHeight = shallowRef<number | null>(null);\n let cleanup: null | (() => void) = null;\n\n function start(event: PointerEvent): void {\n if (!shell.value || locked.value) return;\n cleanup?.();\n event.preventDefault();\n const startY = event.clientY;\n const startHeight = shell.value.getBoundingClientRect().height;\n const minimum = pixelValue(config.value.minHeight, 120);\n const maximum = pixelValue(config.value.maxHeight, Number.POSITIVE_INFINITY);\n const move = (moveEvent: PointerEvent): void => {\n const height = Math.min(\n maximum,\n Math.max(minimum, startHeight + moveEvent.clientY - startY),\n );\n currentHeight.value = height;\n resized(height);\n };\n const end = (): void => {\n window.removeEventListener('pointermove', move);\n window.removeEventListener('pointerup', end);\n window.removeEventListener('pointercancel', end);\n cleanup = null;\n };\n cleanup = end;\n window.addEventListener('pointermove', move);\n window.addEventListener('pointerup', end);\n window.addEventListener('pointercancel', end);\n }\n\n function reset(): void {\n currentHeight.value = null;\n }\n\n onBeforeUnmount(() => cleanup?.());\n return { currentHeight, start, reset };\n}\n","import { onBeforeUnmount, shallowRef, type Ref } from 'vue';\nimport { elementPath, restoreSelection, saveSelection, selectionElement } from '../utils/selection';\nimport { isEditorCommandActive } from '../commands/commandRegistry';\nimport type { EditorSelectionState } from '../types';\n\nexport function useEditorSelection(root: Ref<HTMLElement | null>) {\n const savedRange = shallowRef<Range | null>(null);\n const state = shallowRef<EditorSelectionState>({ path: 'p', commands: {}, insideTable: false });\n let frame = 0;\n function save(): void {\n if (!root.value) return;\n const range = saveSelection(root.value);\n if (range) savedRange.value = range;\n }\n function restore(): boolean {\n return root.value ? restoreSelection(savedRange.value, root.value) : false;\n }\n function update(): void {\n cancelAnimationFrame(frame);\n frame = requestAnimationFrame(() => {\n if (!root.value) return;\n const element = selectionElement(root.value);\n state.value = {\n path: elementPath(root.value),\n insideTable: Boolean(element?.closest('table')),\n commands: Object.fromEntries(\n [\n 'bold',\n 'italic',\n 'underline',\n 'strikethrough',\n 'superscript',\n 'subscript',\n 'alignleft',\n 'aligncenter',\n 'alignright',\n 'alignjustify',\n 'bullist',\n 'numlist',\n ].map((id) => [id, isEditorCommandActive(id)]),\n ),\n };\n save();\n });\n }\n onBeforeUnmount(() => cancelAnimationFrame(frame));\n return { savedRange, state, save, restore, update };\n}\n","import { reactive, onBeforeUnmount, type ComputedRef } from 'vue';\nimport type { ImageBlobInfo, ResolvedEditorInit, UploadState } from '../types';\n\nexport function useEditorUpload(config: ComputedRef<ResolvedEditorInit>) {\n const state = reactive<UploadState>({ progress: 0, loading: false, error: '', previewUrl: '' });\n let controller: AbortController | null = null;\n let currentUrl = '';\n async function upload(file: File): Promise<string> {\n validate(file);\n cancel();\n state.loading = true;\n state.error = '';\n state.progress = 0;\n controller = new AbortController();\n setPreview(URL.createObjectURL(file));\n try {\n const created = await createBlobInfo(file);\n try {\n const url = config.value.imagesUploadHandler\n ? await config.value.imagesUploadHandler(created.info, setProgress)\n : await uploadWithFetch(file, controller.signal);\n state.progress = 100;\n return url;\n } finally {\n created.revoke();\n }\n } catch (error) {\n state.error = error instanceof Error ? error.message : 'Image upload failed.';\n throw error;\n } finally {\n state.loading = false;\n controller = null;\n }\n }\n async function uploadWithFetch(file: File, signal: AbortSignal): Promise<string> {\n if (!config.value.imagesUploadUrl)\n throw new Error('No image upload handler or URL was configured.');\n const body = new FormData();\n body.append(config.value.uploadFieldName, file, file.name);\n const response = await fetch(config.value.imagesUploadUrl, {\n method: 'POST',\n headers: config.value.uploadHeaders,\n credentials: config.value.uploadCredentials,\n body,\n signal,\n });\n if (!response.ok) throw new Error(`Image upload failed (${response.status}).`);\n const data: unknown = await response.json();\n if (config.value.resolveUploadedImageUrl) return config.value.resolveUploadedImageUrl(data);\n if (\n typeof data === 'object' &&\n data !== null &&\n 'url' in data &&\n typeof data.url === 'string'\n )\n return data.url;\n throw new Error(\n 'The upload response did not contain a URL. Configure resolveUploadedImageUrl.',\n );\n }\n function validate(file: File): void {\n if (!config.value.acceptedFormats.includes(file.type))\n throw new Error('Invalid image type.');\n if (file.size > config.value.maxImageSize)\n throw new Error(\n `Image exceeds the ${Math.round(config.value.maxImageSize / 1024 / 1024)} MB limit.`,\n );\n }\n function setProgress(value: number): void {\n state.progress = Math.min(100, Math.max(0, value));\n }\n function setPreview(url: string): void {\n if (currentUrl) URL.revokeObjectURL(currentUrl);\n currentUrl = url;\n state.previewUrl = url;\n }\n function cancel(): void {\n controller?.abort();\n controller = null;\n if (currentUrl) URL.revokeObjectURL(currentUrl);\n currentUrl = '';\n state.previewUrl = '';\n }\n onBeforeUnmount(cancel);\n return { state, upload, cancel, validate };\n}\nasync function createBlobInfo(file: File): Promise<{ info: ImageBlobInfo; revoke: () => void }> {\n const base64 = await new Promise<string>((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(String(reader.result).split(',')[1] ?? '');\n reader.onerror = () => reject(new Error('Could not read image.'));\n reader.readAsDataURL(file);\n });\n const uri = URL.createObjectURL(file);\n const id = globalThis.crypto?.randomUUID?.() ?? `${Date.now()}`;\n return {\n info: {\n id: () => id,\n name: () => file.name.replace(/\\.[^.]+$/, ''),\n filename: () => file.name,\n blob: () => file,\n base64: () => base64,\n blobUri: () => uri,\n },\n revoke: () => URL.revokeObjectURL(uri),\n };\n}\n","import { onBeforeUnmount, onMounted, shallowRef, type Ref } from 'vue';\nexport function useFullscreen(root: Ref<HTMLElement | null>) {\n const active = shallowRef(false);\n async function toggle(): Promise<void> {\n if (!root.value) return;\n if (document.fullscreenElement) {\n await document.exitFullscreen();\n active.value = false;\n return;\n }\n try {\n await root.value.requestFullscreen();\n active.value = true;\n } catch {\n root.value.classList.toggle('erag-editor--fullscreen');\n active.value = root.value.classList.contains('erag-editor--fullscreen');\n }\n }\n const listener = (): void => {\n active.value =\n Boolean(document.fullscreenElement) ||\n Boolean(root.value?.classList.contains('erag-editor--fullscreen'));\n };\n onMounted(() => document.addEventListener('fullscreenchange', listener));\n onBeforeUnmount(() => document.removeEventListener('fullscreenchange', listener));\n return { active, toggle };\n}\n","import {\n computed,\n onBeforeUnmount,\n onMounted,\n shallowRef,\n watch,\n type ComputedRef,\n type Ref,\n} from 'vue';\nimport type {\n ImageAlignment,\n ImageDeleteInfo,\n ImageResizeBox,\n ImageResizeHandle,\n ImagesDeleteHandler,\n} from '../types';\n\nconst MINIMUM_IMAGE_SIZE = 40;\n\nexport function useImageResize(\n root: Ref<HTMLElement | null>,\n container: Ref<HTMLElement | null>,\n locked: ComputedRef<boolean>,\n changed: () => void,\n removed: (image: ImageDeleteInfo) => void,\n) {\n const selectedImage = shallowRef<HTMLImageElement | null>(null);\n const box = shallowRef<ImageResizeBox | null>(null);\n const alignment = shallowRef<ImageAlignment | null>(null);\n const deleting = shallowRef(false);\n const deleteError = shallowRef('');\n const activeCommands = computed<Record<string, boolean>>(() => ({\n alignleft: alignment.value === 'alignleft',\n aligncenter: alignment.value === 'aligncenter',\n alignright: alignment.value === 'alignright',\n alignjustify: false,\n }));\n let observer: ResizeObserver | null = null;\n let frame = 0;\n\n function selectFromEvent(event: MouseEvent): void {\n if (deleting.value) return;\n if (locked.value || !(event.target instanceof HTMLImageElement)) {\n clear();\n return;\n }\n if (!root.value?.contains(event.target)) return;\n selectedImage.value = event.target;\n deleteError.value = '';\n alignment.value = getImageAlignment(event.target);\n observeSelectedImage();\n refresh();\n }\n\n function refresh(): void {\n cancelAnimationFrame(frame);\n frame = requestAnimationFrame(updateBox);\n }\n\n function updateBox(): void {\n const image = selectedImage.value;\n const host = container.value;\n if (!image?.isConnected || !host) {\n clear();\n return;\n }\n const imageRect = image.getBoundingClientRect();\n const hostRect = host.getBoundingClientRect();\n box.value = {\n top: imageRect.top - hostRect.top,\n left: imageRect.left - hostRect.left,\n width: imageRect.width,\n height: imageRect.height,\n };\n }\n\n function resizeStart(event: PointerEvent, handle: ImageResizeHandle): void {\n const image = selectedImage.value;\n const editorRoot = root.value;\n if (!image || !editorRoot || locked.value || deleting.value) return;\n event.preventDefault();\n event.stopPropagation();\n const rect = image.getBoundingClientRect();\n const rootRect = editorRoot.getBoundingClientRect();\n const startX = event.clientX;\n const startY = event.clientY;\n const startWidth = rect.width;\n const startHeight = rect.height;\n const aspectRatio = rect.width / rect.height || 1;\n const maximumWidth = Math.max(MINIMUM_IMAGE_SIZE, rootRect.width - 1);\n\n const move = (moveEvent: PointerEvent): void => {\n moveEvent.preventDefault();\n const horizontalDelta =\n (moveEvent.clientX - startX) * (handle.endsWith('east') ? 1 : -1);\n const verticalDelta =\n (moveEvent.clientY - startY) * (handle.startsWith('south') ? 1 : -1);\n const horizontalWidth = startWidth + horizontalDelta;\n const verticalWidth = (startHeight + verticalDelta) * aspectRatio;\n const requestedWidth =\n Math.abs(horizontalWidth - startWidth) >= Math.abs(verticalWidth - startWidth)\n ? horizontalWidth\n : verticalWidth;\n const width = Math.round(\n Math.min(maximumWidth, Math.max(MINIMUM_IMAGE_SIZE, requestedWidth)),\n );\n image.setAttribute('width', String(width));\n image.setAttribute('height', String(Math.round(width / aspectRatio)));\n refresh();\n };\n const end = (): void => {\n window.removeEventListener('pointermove', move);\n window.removeEventListener('pointerup', end);\n window.removeEventListener('pointercancel', end);\n changed();\n refresh();\n };\n window.addEventListener('pointermove', move, { passive: false });\n window.addEventListener('pointerup', end, { once: true });\n window.addEventListener('pointercancel', end, { once: true });\n }\n\n function executeCommand(id: string): boolean {\n const image = selectedImage.value;\n if (!image || deleting.value || !isImageAlignment(id)) return false;\n image.style.display = 'block';\n image.style.marginLeft = id === 'alignright' ? 'auto' : id === 'aligncenter' ? 'auto' : '0';\n image.style.marginRight = id === 'alignleft' ? 'auto' : id === 'aligncenter' ? 'auto' : '0';\n alignment.value = id;\n changed();\n refresh();\n return true;\n }\n\n async function deleteSelected(handler?: ImagesDeleteHandler): Promise<boolean> {\n const image = selectedImage.value;\n if (!image || !image.isConnected || locked.value || deleting.value) return false;\n deleting.value = true;\n deleteError.value = '';\n const info = getDeleteInfo(image);\n try {\n if (handler) await handler(info);\n if (selectedImage.value !== image || !image.isConnected) return false;\n image.remove();\n clear();\n changed();\n removed(info);\n return true;\n } catch {\n deleteError.value = 'Unable to delete image from server';\n return false;\n } finally {\n deleting.value = false;\n }\n }\n\n function clear(): void {\n cancelAnimationFrame(frame);\n observer?.disconnect();\n selectedImage.value = null;\n alignment.value = null;\n box.value = null;\n deleteError.value = '';\n }\n\n function observeSelectedImage(): void {\n observer?.disconnect();\n if (selectedImage.value) observer?.observe(selectedImage.value);\n if (container.value) observer?.observe(container.value);\n }\n\n watch(locked, (value) => {\n if (value) clear();\n });\n onMounted(() => {\n if (typeof ResizeObserver !== 'undefined') observer = new ResizeObserver(refresh);\n window.addEventListener('resize', refresh);\n document.addEventListener('scroll', refresh, true);\n });\n onBeforeUnmount(() => {\n clear();\n window.removeEventListener('resize', refresh);\n document.removeEventListener('scroll', refresh, true);\n });\n\n return {\n box,\n activeCommands,\n deleting,\n deleteError,\n selectFromEvent,\n resizeStart,\n executeCommand,\n deleteSelected,\n refresh,\n clear,\n };\n}\n\nfunction getDeleteInfo(image: HTMLImageElement): ImageDeleteInfo {\n const rect = image.getBoundingClientRect();\n return {\n src: image.getAttribute('src') ?? '',\n alt: image.getAttribute('alt') ?? '',\n width: Math.round(rect.width),\n height: Math.round(rect.height),\n };\n}\n\nfunction getImageAlignment(image: HTMLImageElement): ImageAlignment {\n const style = image.style;\n if (style.marginLeft === 'auto' && style.marginRight === 'auto') return 'aligncenter';\n if (style.marginLeft === 'auto' && style.marginRight !== 'auto') return 'alignright';\n return 'alignleft';\n}\n\nfunction isImageAlignment(value: string): value is ImageAlignment {\n return ['alignleft', 'aligncenter', 'alignright'].includes(value);\n}\n","import {\n computed,\n nextTick,\n onBeforeUnmount,\n shallowRef,\n watch,\n type ComputedRef,\n type Ref,\n} from 'vue';\nimport { insertImage } from '../commands/insertCommands';\nimport type { ImageValue, ResolvedEditorInit } from '../types';\nimport { isSafeUrl } from '../utils/url';\nimport { useEditorUpload } from './useEditorUpload';\n\nexport function useInlineImageUpload(\n root: Ref<HTMLElement | null>,\n config: ComputedRef<ResolvedEditorInit>,\n locked: ComputedRef<boolean>,\n onChange: () => void,\n) {\n const target = shallowRef<HTMLElement | null>(null);\n const error = shallowRef('');\n const { state, upload, cancel: cancelUpload } = useEditorUpload(config);\n const isOpen = computed(() => Boolean(target.value));\n const message = computed(() => error.value || state.error);\n let operation = 0;\n\n async function open(): Promise<void> {\n if (!root.value || locked.value) return;\n await close(false);\n const editorRoot = root.value;\n const selection = editorRoot.ownerDocument.defaultView?.getSelection();\n const selectedRange = selection?.rangeCount ? selection.getRangeAt(0) : null;\n const range =\n selectedRange && editorRoot.contains(selectedRange.commonAncestorContainer)\n ? selectedRange\n : createRangeAtEnd(editorRoot);\n const placeholder = editorRoot.ownerDocument.createElement('span');\n placeholder.className = 'erag-inline-image-upload-anchor';\n placeholder.dataset.eragTransient = 'true';\n placeholder.contentEditable = 'false';\n placeholder.setAttribute('aria-label', 'Image upload');\n range.deleteContents();\n range.insertNode(placeholder);\n moveCaretAfter(editorRoot, placeholder);\n error.value = '';\n target.value = placeholder;\n }\n\n async function uploadFile(file: File): Promise<void> {\n if (!target.value || state.loading) return;\n const currentOperation = ++operation;\n error.value = '';\n try {\n const url = await upload(file);\n if (currentOperation !== operation || !target.value) return;\n await replacePlaceholder({ src: url, alt: file.name, width: '', height: '' });\n } catch (uploadError) {\n if (currentOperation === operation && !(uploadError instanceof DOMException)) {\n error.value =\n uploadError instanceof Error ? uploadError.message : 'Image upload failed.';\n }\n }\n }\n\n async function insertUrl(url: string): Promise<void> {\n const normalized = url.trim();\n error.value = '';\n if (\n !isSafeUrl(normalized, {\n allowRelative: config.value.relativeUrls,\n allowDataImage: true,\n })\n ) {\n error.value = 'Enter a safe image URL.';\n return;\n }\n await replacePlaceholder({ src: normalized, alt: '', width: '', height: '' });\n }\n\n async function replacePlaceholder(value: ImageValue): Promise<void> {\n const editorRoot = root.value;\n const placeholder = target.value;\n if (!editorRoot || !placeholder?.isConnected) return;\n target.value = null;\n await nextTick();\n if (!placeholder.isConnected) return;\n selectNode(editorRoot, placeholder);\n const inserted = insertImage(\n editorRoot,\n value,\n config.value.relativeUrls,\n config.value.imageDefaultWidth,\n );\n if (!inserted) {\n target.value = placeholder;\n error.value = 'The image could not be inserted.';\n return;\n }\n cancelUpload();\n onChange();\n }\n\n async function close(restoreCaret = true): Promise<void> {\n operation += 1;\n cancelUpload();\n error.value = '';\n const editorRoot = root.value;\n const placeholder = target.value;\n target.value = null;\n if (!placeholder) return;\n await nextTick();\n if (!placeholder.isConnected) return;\n if (restoreCaret && editorRoot) moveCaretBefore(editorRoot, placeholder);\n placeholder.remove();\n }\n\n function discard(): void {\n operation += 1;\n cancelUpload();\n error.value = '';\n target.value?.remove();\n target.value = null;\n }\n\n watch(locked, (value) => {\n if (value) discard();\n });\n onBeforeUnmount(discard);\n\n return {\n target,\n state,\n isOpen,\n message,\n open,\n uploadFile,\n insertUrl,\n close,\n discard,\n };\n}\n\nfunction createRangeAtEnd(root: HTMLElement): Range {\n const range = root.ownerDocument.createRange();\n range.selectNodeContents(root);\n range.collapse(false);\n return range;\n}\n\nfunction selectNode(root: HTMLElement, node: Node): void {\n const selection = root.ownerDocument.defaultView?.getSelection();\n if (!selection) return;\n const range = root.ownerDocument.createRange();\n range.selectNode(node);\n selection.removeAllRanges();\n selection.addRange(range);\n}\n\nfunction moveCaretAfter(root: HTMLElement, node: Node): void {\n const selection = root.ownerDocument.defaultView?.getSelection();\n if (!selection) return;\n const range = root.ownerDocument.createRange();\n range.setStartAfter(node);\n range.collapse(true);\n selection.removeAllRanges();\n selection.addRange(range);\n}\n\nfunction moveCaretBefore(root: HTMLElement, node: Node): void {\n root.focus({ preventScroll: true });\n const selection = root.ownerDocument.defaultView?.getSelection();\n if (!selection) return;\n const range = root.ownerDocument.createRange();\n range.setStartBefore(node);\n range.collapse(true);\n selection.removeAllRanges();\n selection.addRange(range);\n}\n","import { computed, type Ref } from 'vue';\nimport type { LinkValue } from '../types';\nimport { closestElement } from '../utils/dom';\n\nexport function useLinkInitial(\n root: Ref<HTMLElement | null>,\n savedRange: Readonly<Ref<Range | null>>,\n) {\n function getSelectedAnchor(): HTMLAnchorElement | null {\n return root.value ? closestElement(root.value, 'a', savedRange.value) : null;\n }\n const initial = computed<LinkValue>(() => {\n const anchor = getSelectedAnchor();\n const selectedText = savedRange.value?.toString() ?? '';\n return {\n url: anchor?.getAttribute('href') ?? '',\n text: anchor?.textContent ?? selectedText,\n title: anchor?.title ?? '',\n target: anchor?.target === '_blank' ? '_blank' : '_self',\n };\n });\n return { initial, getSelectedAnchor };\n}\n","import { computed, nextTick, onBeforeUnmount, onMounted, shallowRef, watch } from 'vue';\nimport type {\n MentionCallbacks,\n MentionComposableSources,\n MentionDropdownState,\n MentionItem,\n MentionPosition,\n} from '../types';\nimport {\n closestMentionElement,\n detectMentionQuery,\n insertMentionAtRange,\n parseMentionElement,\n removeAdjacentMention,\n} from '../utils/mention';\nimport { getCaretRect } from '../utils/selection';\n\nconst DROPDOWN_WIDTH = 280;\nconst DROPDOWN_MAX_HEIGHT = 320;\nconst VIEWPORT_PADDING = 12;\nconst CARET_GAP = 6;\nconst HOVER_CARD_WIDTH = 240;\nconst HOVER_CARD_HEIGHT = 76;\n\nexport function useMentions(sources: MentionComposableSources, callbacks: MentionCallbacks) {\n const isOpen = shallowRef(false);\n const query = shallowRef('');\n const items = shallowRef<MentionItem[]>([]);\n const activeIndex = shallowRef(0);\n const state = shallowRef<MentionDropdownState>('empty');\n const position = shallowRef<MentionPosition>({ left: VIEWPORT_PADDING, top: VIEWPORT_PADDING });\n const dropdownElement = shallowRef<HTMLElement | null>(null);\n const activeItem = computed(() => items.value[activeIndex.value]);\n const hoverItem = shallowRef<MentionItem | null>(null);\n const hoverPosition = shallowRef<MentionPosition>({\n left: VIEWPORT_PADDING,\n top: VIEWPORT_PADDING,\n });\n const positionStyle = computed(() => ({\n left: `${position.value.left}px`,\n top: `${position.value.top}px`,\n }));\n const hoverPositionStyle = computed(() => ({\n left: `${hoverPosition.value.left}px`,\n top: `${hoverPosition.value.top}px`,\n }));\n const cache = new Map<string, MentionItem[]>();\n const knownItems = new Map<string, MentionItem>();\n let queryRange: Range | null = null;\n let debounceTimer: ReturnType<typeof setTimeout> | null = null;\n let controller: AbortController | null = null;\n let resizeObserver: ResizeObserver | null = null;\n let hoverResizeObserver: ResizeObserver | null = null;\n let positionFrame = 0;\n let hoverPositionFrame = 0;\n let requestSequence = 0;\n let hoveredMention: HTMLElement | null = null;\n let hoverCardElement: HTMLElement | null = null;\n\n function handleInput(): void {\n const match = sources.root.value ? detectMentionQuery(sources.root.value) : null;\n if (!canOpen() || !match) {\n close();\n return;\n }\n\n queryRange = match.range.cloneRange();\n query.value = match.query;\n if (match.query.length < sources.config.value.minimumCharacters) {\n close();\n return;\n }\n\n isOpen.value = true;\n state.value = 'loading';\n activeIndex.value = 0;\n updatePosition();\n scheduleSearch(match.query);\n }\n\n function handleSelectionChange(): void {\n if (!isOpen.value || !sources.root.value) return;\n const match = detectMentionQuery(sources.root.value);\n if (!match || match.query.length < sources.config.value.minimumCharacters) {\n close();\n return;\n }\n\n queryRange = match.range.cloneRange();\n if (match.query !== query.value) {\n query.value = match.query;\n state.value = 'loading';\n activeIndex.value = 0;\n scheduleSearch(match.query);\n }\n updatePosition();\n }\n\n function handleKeydown(event: KeyboardEvent): boolean {\n if (!isOpen.value) return false;\n if (event.key === 'Escape') {\n event.preventDefault();\n close();\n return true;\n }\n if (!items.value.length) return false;\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n const offset = event.key === 'ArrowDown' ? 1 : -1;\n activeIndex.value =\n (activeIndex.value + offset + items.value.length) % items.value.length;\n return true;\n }\n if (event.key === 'Home' || event.key === 'End') {\n event.preventDefault();\n activeIndex.value = event.key === 'Home' ? 0 : items.value.length - 1;\n return true;\n }\n if (event.key === 'Enter' || event.key === 'Tab') {\n const item = activeItem.value;\n if (!item) return false;\n event.preventDefault();\n select(item);\n return true;\n }\n return false;\n }\n\n function handleRemoval(event: KeyboardEvent): boolean {\n if (!sources.config.value.enabled || sources.locked.value || !sources.root.value) {\n return false;\n }\n if (event.key !== 'Backspace' && event.key !== 'Delete') return false;\n const item = removeAdjacentMention(\n sources.root.value,\n event.key === 'Backspace' ? 'backward' : 'forward',\n );\n if (!item) return false;\n event.preventDefault();\n callbacks.change();\n callbacks.remove({ item });\n return true;\n }\n\n function setActiveIndex(index: number): void {\n if (index >= 0 && index < items.value.length) activeIndex.value = index;\n }\n\n function select(item: MentionItem): void {\n const root = sources.root.value;\n const range = queryRange;\n const selectedQuery = query.value;\n if (!root || !range || sources.locked.value) return;\n if (!insertMentionAtRange(root, range, item)) {\n close();\n return;\n }\n rememberItems([item]);\n close();\n callbacks.change();\n callbacks.select({ item: { ...item }, query: selectedQuery });\n root.focus({ preventScroll: true });\n }\n\n function retry(): void {\n cache.delete(query.value);\n clearPendingSearch();\n void loadItems(query.value);\n }\n\n function close(): void {\n clearPendingSearch();\n if (typeof cancelAnimationFrame !== 'undefined') cancelAnimationFrame(positionFrame);\n isOpen.value = false;\n items.value = [];\n activeIndex.value = 0;\n queryRange = null;\n resizeObserver?.disconnect();\n resizeObserver = null;\n dropdownElement.value = null;\n }\n\n function setDropdownElement(element: HTMLElement | null): void {\n resizeObserver?.disconnect();\n dropdownElement.value = element;\n if (!element) return;\n resizeObserver = new ResizeObserver(updatePosition);\n resizeObserver.observe(element);\n updatePosition();\n }\n\n function setHoverCardElement(element: HTMLElement | null): void {\n hoverResizeObserver?.disconnect();\n hoverCardElement = element;\n if (!element) return;\n hoverResizeObserver = new ResizeObserver(updateHoverPosition);\n hoverResizeObserver.observe(element);\n updateHoverPosition();\n }\n\n function scheduleSearch(value: string): void {\n clearPendingSearch();\n const cached = cache.get(value);\n if (cached) {\n applyResults(cached);\n return;\n }\n debounceTimer = setTimeout(() => void loadItems(value), sources.config.value.debounce);\n }\n\n async function loadItems(value: string): Promise<void> {\n if (!canOpen() || value !== query.value) return;\n const sequence = ++requestSequence;\n const requestController = new AbortController();\n controller = requestController;\n state.value = 'loading';\n callbacks.search({ query: value });\n try {\n const source = sources.config.value.items;\n const results = Array.isArray(source)\n ? filterStaticItems(source, value, sources.config.value.limit)\n : source\n ? await source(value, requestController.signal)\n : [];\n if (\n sequence !== requestSequence ||\n requestController.signal.aborted ||\n value !== query.value\n ) {\n return;\n }\n const limited = results\n .slice(0, sources.config.value.limit)\n .map((item) => ({ ...item }));\n rememberItems(limited);\n cache.set(value, limited);\n applyResults(limited);\n } catch (error: unknown) {\n if (sequence !== requestSequence || isAbortError(error)) return;\n items.value = [];\n state.value = 'error';\n }\n }\n\n function applyResults(results: MentionItem[]): void {\n items.value = results;\n activeIndex.value = 0;\n state.value = results.length ? 'results' : 'empty';\n void nextTick(updatePosition);\n }\n\n function updatePosition(): void {\n cancelAnimationFrame(positionFrame);\n positionFrame = requestAnimationFrame(() => {\n if (!isOpen.value || !queryRange) return;\n const caret = getCaretRect(queryRange);\n const dropdownRect = dropdownElement.value?.getBoundingClientRect();\n const width = Math.min(\n dropdownRect?.width || DROPDOWN_WIDTH,\n window.innerWidth - VIEWPORT_PADDING * 2,\n );\n const height = Math.min(\n dropdownRect?.height || DROPDOWN_MAX_HEIGHT,\n DROPDOWN_MAX_HEIGHT,\n );\n const spaceBelow = window.innerHeight - caret.bottom - VIEWPORT_PADDING;\n const spaceAbove = caret.top - VIEWPORT_PADDING;\n const placeAbove = spaceBelow < height && spaceAbove > spaceBelow;\n const left = Math.min(\n Math.max(VIEWPORT_PADDING, caret.left),\n Math.max(VIEWPORT_PADDING, window.innerWidth - width - VIEWPORT_PADDING),\n );\n const top = placeAbove\n ? Math.max(VIEWPORT_PADDING, caret.top - height - CARET_GAP)\n : Math.min(window.innerHeight - VIEWPORT_PADDING, caret.bottom + CARET_GAP);\n position.value = { left, top };\n });\n }\n\n function updateHoverPosition(): void {\n cancelAnimationFrame(hoverPositionFrame);\n hoverPositionFrame = requestAnimationFrame(() => {\n if (!hoverItem.value || !hoveredMention) return;\n const mentionRect = hoveredMention.getBoundingClientRect();\n const width = Math.min(HOVER_CARD_WIDTH, window.innerWidth - VIEWPORT_PADDING * 2);\n const height = Math.min(\n hoverCardElement?.getBoundingClientRect().height || HOVER_CARD_HEIGHT,\n window.innerHeight - VIEWPORT_PADDING * 2,\n );\n const placeAbove =\n window.innerHeight - mentionRect.bottom - VIEWPORT_PADDING < height &&\n mentionRect.top > height;\n const left = Math.min(\n Math.max(VIEWPORT_PADDING, mentionRect.left),\n Math.max(VIEWPORT_PADDING, window.innerWidth - width - VIEWPORT_PADDING),\n );\n const top = placeAbove\n ? Math.max(VIEWPORT_PADDING, mentionRect.top - height - CARET_GAP)\n : Math.min(\n window.innerHeight - height - VIEWPORT_PADDING,\n mentionRect.bottom + CARET_GAP,\n );\n hoverPosition.value = { left, top };\n });\n }\n\n function handleMentionPointerOver(event: PointerEvent): void {\n const root = sources.root.value;\n if (!root || !sources.config.value.enabled) return;\n const mention = closestMentionElement(event.target, root);\n if (!mention || mention === hoveredMention) return;\n const item = resolveMentionItem(mention);\n if (!item) return;\n hoveredMention = mention;\n hoverItem.value = item;\n updateHoverPosition();\n }\n\n function handleMentionPointerOut(event: PointerEvent): void {\n if (\n !hoveredMention ||\n (event.relatedTarget instanceof Node && hoveredMention.contains(event.relatedTarget))\n ) {\n return;\n }\n if (event.target instanceof Node && hoveredMention.contains(event.target)) closeHoverCard();\n }\n\n function closeHoverCard(): void {\n if (typeof cancelAnimationFrame !== 'undefined') {\n cancelAnimationFrame(hoverPositionFrame);\n }\n hoveredMention = null;\n hoverItem.value = null;\n hoverResizeObserver?.disconnect();\n hoverResizeObserver = null;\n hoverCardElement = null;\n }\n\n function resolveMentionItem(element: Element): MentionItem | null {\n const parsed = parseMentionElement(element);\n if (!parsed) return null;\n const known = knownItems.get(String(parsed.id));\n return known\n ? {\n ...known,\n id: parsed.id,\n label: parsed.label,\n ...(parsed.value !== undefined ? { value: parsed.value } : {}),\n }\n : parsed;\n }\n\n function rememberItems(values: MentionItem[]): void {\n for (const item of values) knownItems.set(String(item.id), { ...item });\n }\n\n function updateFloatingPositions(): void {\n updatePosition();\n updateHoverPosition();\n }\n\n function clearPendingSearch(): void {\n if (debounceTimer) clearTimeout(debounceTimer);\n debounceTimer = null;\n controller?.abort();\n controller = null;\n requestSequence += 1;\n }\n\n function canOpen(): boolean {\n return sources.config.value.enabled && !sources.locked.value;\n }\n\n function handleOutsidePointer(event: PointerEvent): void {\n if (!isOpen.value || dropdownElement.value?.contains(event.target as Node)) return;\n close();\n }\n\n const configuredItems = sources.config.value.items;\n if (Array.isArray(configuredItems)) rememberItems(configuredItems);\n\n watch(\n sources.config,\n () => {\n cache.clear();\n knownItems.clear();\n const configuredItems = sources.config.value.items;\n if (Array.isArray(configuredItems)) rememberItems(configuredItems);\n close();\n closeHoverCard();\n },\n { deep: true },\n );\n watch(sources.locked, (value) => {\n if (value) close();\n });\n\n onMounted(() => {\n window.addEventListener('resize', updateFloatingPositions);\n window.addEventListener('scroll', updateFloatingPositions, true);\n document.addEventListener('pointerdown', handleOutsidePointer);\n document.addEventListener('pointerover', handleMentionPointerOver);\n document.addEventListener('pointerout', handleMentionPointerOut);\n });\n onBeforeUnmount(() => {\n close();\n closeHoverCard();\n cache.clear();\n knownItems.clear();\n resizeObserver?.disconnect();\n window.removeEventListener('resize', updateFloatingPositions);\n window.removeEventListener('scroll', updateFloatingPositions, true);\n document.removeEventListener('pointerdown', handleOutsidePointer);\n document.removeEventListener('pointerover', handleMentionPointerOver);\n document.removeEventListener('pointerout', handleMentionPointerOut);\n });\n\n return {\n isOpen,\n query,\n items,\n activeIndex,\n state,\n positionStyle,\n hoverItem,\n hoverPositionStyle,\n handleInput,\n handleSelectionChange,\n handleKeydown,\n handleRemoval,\n setActiveIndex,\n select,\n retry,\n close,\n setDropdownElement,\n setHoverCardElement,\n };\n}\n\nfunction filterStaticItems(source: MentionItem[], query: string, limit: number): MentionItem[] {\n const needle = query.toLocaleLowerCase();\n return source\n .map((item, index) => ({ item, index, score: mentionMatchScore(item, needle) }))\n .filter((entry) => entry.score < 2)\n .sort((left, right) => left.score - right.score || left.index - right.index)\n .slice(0, limit)\n .map((entry) => ({ ...entry.item }));\n}\n\nfunction mentionMatchScore(item: MentionItem, query: string): number {\n if (!query) return 0;\n const fields = [item.label, item.description, item.value]\n .filter((value): value is string => Boolean(value))\n .map((value) => value.toLocaleLowerCase());\n if (fields.some((value) => value.startsWith(query))) return 0;\n return fields.some((value) => value.includes(query)) ? 1 : 2;\n}\n\nfunction isAbortError(error: unknown): boolean {\n return error instanceof DOMException && error.name === 'AbortError';\n}\n","import { computed, nextTick, onBeforeUnmount, onMounted, shallowRef, watch } from 'vue';\nimport type {\n MergeTagCallbacks,\n MergeTagComposableSources,\n MergeTagItem,\n MentionPosition,\n} from '../types';\nimport {\n detectMergeTagQuery,\n insertMergeTagAtRange,\n normalizeMergeTagValue,\n removeAdjacentMergeTag,\n} from '../utils/mergeTag';\nimport { getCaretRect } from '../utils/selection';\n\nconst DROPDOWN_WIDTH = 220;\nconst DROPDOWN_HEIGHT = 260;\nconst VIEWPORT_PADDING = 12;\nconst CARET_GAP = 6;\n\nexport function useMergeTags(sources: MergeTagComposableSources, callbacks: MergeTagCallbacks) {\n const isOpen = shallowRef(false);\n const query = shallowRef('');\n const items = shallowRef<MergeTagItem[]>([]);\n const activeIndex = shallowRef(0);\n const position = shallowRef<MentionPosition>({ left: VIEWPORT_PADDING, top: VIEWPORT_PADDING });\n const dropdownElement = shallowRef<HTMLElement | null>(null);\n const positionStyle = computed(() => ({\n left: `${position.value.left}px`,\n top: `${position.value.top}px`,\n }));\n let queryRange: Range | null = null;\n let observer: ResizeObserver | null = null;\n let positionFrame = 0;\n\n function handleInput(): void {\n const match = sources.root.value ? detectMergeTagQuery(sources.root.value) : null;\n if (!canOpen() || !match) {\n close();\n return;\n }\n queryRange = match.range.cloneRange();\n query.value = match.query;\n items.value = filterItems(match.query);\n activeIndex.value = 0;\n isOpen.value = true;\n updatePosition();\n }\n\n function handleSelectionChange(): void {\n const root = sources.root.value;\n if (!isOpen.value || !root) return;\n const match = detectMergeTagQuery(root);\n if (!canOpen() || !match) {\n close();\n return;\n }\n queryRange = match.range.cloneRange();\n if (match.query !== query.value) {\n query.value = match.query;\n items.value = filterItems(match.query);\n activeIndex.value = 0;\n }\n updatePosition();\n }\n\n function handleKeydown(event: KeyboardEvent): boolean {\n if (!isOpen.value) return false;\n if (event.key === 'Escape') {\n event.preventDefault();\n close();\n return true;\n }\n if (!items.value.length) return false;\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n const offset = event.key === 'ArrowDown' ? 1 : -1;\n activeIndex.value =\n (activeIndex.value + offset + items.value.length) % items.value.length;\n return true;\n }\n if (event.key === 'Home' || event.key === 'End') {\n event.preventDefault();\n activeIndex.value = event.key === 'Home' ? 0 : items.value.length - 1;\n return true;\n }\n if (event.key === 'Enter' || event.key === 'Tab') {\n const item = items.value[activeIndex.value];\n if (!item) return false;\n event.preventDefault();\n select(item);\n return true;\n }\n return false;\n }\n\n function handleRemoval(event: KeyboardEvent): boolean {\n if (!canOpen() || !sources.root.value) return false;\n if (event.key !== 'Backspace' && event.key !== 'Delete') return false;\n const item = removeAdjacentMergeTag(\n sources.root.value,\n event.key === 'Backspace' ? 'backward' : 'forward',\n );\n if (!item) return false;\n event.preventDefault();\n callbacks.change();\n callbacks.remove({ item });\n return true;\n }\n\n function select(item: MergeTagItem): void {\n const root = sources.root.value;\n const range = queryRange;\n const selectedQuery = query.value;\n if (!root || !range || sources.locked.value) return;\n if (!insertMergeTagAtRange(root, range, item)) return;\n close();\n callbacks.change();\n callbacks.select({ item: { ...item }, query: selectedQuery });\n }\n\n function insert(item: MergeTagItem): void {\n const root = sources.root.value;\n const selection = window.getSelection();\n if (!root || !selection?.rangeCount || sources.locked.value) return;\n const range = selection.getRangeAt(0);\n if (!root.contains(range.commonAncestorContainer)) return;\n if (!insertMergeTagAtRange(root, range.cloneRange(), item)) return;\n callbacks.change();\n callbacks.select({ item: { ...item }, query: '' });\n }\n\n function setActiveIndex(index: number): void {\n if (index >= 0 && index < items.value.length) activeIndex.value = index;\n }\n\n function setDropdownElement(element: HTMLElement | null): void {\n observer?.disconnect();\n dropdownElement.value = element;\n if (!element) return;\n observer = new ResizeObserver(updatePosition);\n observer.observe(element);\n updatePosition();\n }\n\n function updatePosition(): void {\n cancelAnimationFrame(positionFrame);\n positionFrame = requestAnimationFrame(() => {\n if (!queryRange || !isOpen.value) return;\n const caret = getCaretRect(queryRange);\n const rect = dropdownElement.value?.getBoundingClientRect();\n const width = Math.min(rect?.width || DROPDOWN_WIDTH, window.innerWidth - 24);\n const height = Math.min(rect?.height || DROPDOWN_HEIGHT, DROPDOWN_HEIGHT);\n const spaceBelow = window.innerHeight - caret.bottom - VIEWPORT_PADDING;\n const spaceAbove = caret.top - VIEWPORT_PADDING;\n const placeAbove = spaceBelow < height && spaceAbove > spaceBelow;\n const maximumLeft = Math.max(\n VIEWPORT_PADDING,\n window.innerWidth - width - VIEWPORT_PADDING,\n );\n const maximumTop = Math.max(\n VIEWPORT_PADDING,\n window.innerHeight - height - VIEWPORT_PADDING,\n );\n const preferredTop = placeAbove\n ? caret.top - height - CARET_GAP\n : caret.bottom + CARET_GAP;\n position.value = {\n left: Math.min(Math.max(VIEWPORT_PADDING, caret.left), maximumLeft),\n top: Math.min(Math.max(VIEWPORT_PADDING, preferredTop), maximumTop),\n };\n });\n }\n\n function close(): void {\n cancelAnimationFrame(positionFrame);\n isOpen.value = false;\n queryRange = null;\n query.value = '';\n items.value = [];\n activeIndex.value = 0;\n observer?.disconnect();\n observer = null;\n dropdownElement.value = null;\n }\n\n function filterItems(value: string): MergeTagItem[] {\n const needle = value.replace(/\\s+/gu, ' ').trim().toLocaleLowerCase();\n return sources.config.value.items\n .map((item, index) => ({ item, index, score: matchScore(item, needle) }))\n .filter((entry) => entry.score < 2)\n .sort((left, right) => left.score - right.score || left.index - right.index)\n .slice(0, sources.config.value.limit)\n .map((entry) => ({ ...entry.item }));\n }\n\n function canOpen(): boolean {\n return sources.config.value.enabled && !sources.locked.value;\n }\n\n function outside(event: PointerEvent): void {\n if (!dropdownElement.value?.contains(event.target as Node)) close();\n }\n\n watch(sources.config, close, { deep: true });\n watch(sources.locked, (value) => {\n if (value) close();\n });\n watch(activeIndex, () => void nextTick(scrollActiveItem));\n onMounted(() => {\n window.addEventListener('resize', updatePosition);\n window.addEventListener('scroll', updatePosition, true);\n document.addEventListener('pointerdown', outside);\n });\n onBeforeUnmount(() => {\n close();\n window.removeEventListener('resize', updatePosition);\n window.removeEventListener('scroll', updatePosition, true);\n document.removeEventListener('pointerdown', outside);\n });\n\n function scrollActiveItem(): void {\n dropdownElement.value\n ?.querySelector<HTMLElement>('[aria-selected=\"true\"]')\n ?.scrollIntoView({ block: 'nearest' });\n }\n\n return {\n isOpen,\n query,\n items,\n activeIndex,\n positionStyle,\n handleInput,\n handleSelectionChange,\n handleKeydown,\n handleRemoval,\n setActiveIndex,\n setDropdownElement,\n select,\n insert,\n close,\n };\n}\n\nfunction matchScore(item: MergeTagItem, query: string): number {\n if (!query) return 0;\n const values = [normalizeMergeTagValue(item.value), item.group]\n .filter((value): value is string => Boolean(value))\n .map((value) => value.toLocaleLowerCase());\n if (values.some((value) => value.startsWith(query))) return 0;\n return values.some((value) => value.includes(query)) ? 1 : 2;\n}\n","import { shallowRef, useId, watch } from 'vue';\nimport type {\n EditorMenuName,\n MergeTagItem,\n MergeTagSidebarCallbacks,\n MergeTagSidebarSources,\n} from '../types';\n\nexport function useMergeTagSidebar(\n sources: MergeTagSidebarSources,\n callbacks: MergeTagSidebarCallbacks,\n) {\n const isOpen = shallowRef(false);\n const id = `erag-merge-tag-sidebar-${useId().replaceAll(':', '')}`;\n\n function handleMenubarOpening(name: EditorMenuName): void {\n callbacks.saveSelection();\n if (name !== 'merge-tags') isOpen.value = false;\n }\n\n function toggle(): void {\n if (!sources.disabled.value) isOpen.value = !isOpen.value;\n }\n\n function close(): void {\n isOpen.value = false;\n }\n\n function select(item: MergeTagItem): void {\n if (sources.locked.value) return;\n callbacks.restoreSelection();\n callbacks.insert(item);\n callbacks.saveSelection();\n }\n\n watch(\n sources.config,\n (config) => {\n if (!config.enabled || config.items.length === 0) close();\n },\n { deep: true },\n );\n\n return { isOpen, id, handleMenubarOpening, toggle, close, select };\n}\n","import { computed, type Ref } from 'vue';\nimport type { WordCountData } from '../types';\nimport { getDetailedTextCounts } from '../utils/html';\n\nexport function useWordCount(root: Ref<HTMLElement | null>, selectedRange: Ref<Range | null>) {\n return computed<WordCountData>(() => ({\n document: getDetailedTextCounts(root.value?.innerText ?? ''),\n selection: getDetailedTextCounts(selectedRange.value?.toString() ?? ''),\n }));\n}\n","import type { DateTimeFormatOption } from '../types';\n\nexport function mergeDateTimeFormats(\n dateFormats: DateTimeFormatOption[],\n timeFormats: DateTimeFormatOption[],\n): DateTimeFormatOption[] {\n const formats: DateTimeFormatOption[] = [];\n const length = Math.max(dateFormats.length, timeFormats.length);\n for (let index = 0; index < length; index += 1) {\n const time = timeFormats[index];\n const date = dateFormats[index];\n if (time) formats.push(time);\n if (date) formats.push(date);\n }\n return formats;\n}\n\nexport function formatDateTime(option: DateTimeFormatOption, date: Date): string {\n if (option.format === 'iso-date') {\n const year = String(date.getFullYear());\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n return `${year}-${month}-${day}`;\n }\n return new Intl.DateTimeFormat(undefined, option.options).format(date);\n}\n","<script setup lang=\"ts\">\nimport { onMounted, useTemplateRef } from 'vue';\n\nconst props = defineProps<{\n id: string | undefined;\n html: string;\n disabled: boolean;\n readonly: boolean;\n placeholder: string;\n spellcheck: boolean;\n direction: 'ltr' | 'rtl';\n contentClass: string;\n contentStyle: string;\n label: string;\n}>();\nconst emit = defineEmits<{\n click: [event: MouseEvent];\n focus: [event: FocusEvent];\n blur: [event: FocusEvent];\n input: [event: InputEvent];\n keydown: [event: KeyboardEvent];\n paste: [event: ClipboardEvent];\n selectionchange: [];\n ready: [root: HTMLElement];\n}>();\nconst root = useTemplateRef<HTMLElement>('root');\n\nonMounted(() => {\n if (!root.value) {\n return;\n }\n\n root.value.innerHTML = props.html;\n emit('ready', root.value);\n});\nfunction getRoot(): HTMLElement | null {\n return root.value;\n}\ndefineExpose({ getRoot });\n</script>\n<template>\n <div class=\"erag-editor__canvas\">\n <div\n ref=\"root\"\n class=\"erag-editor__content\"\n :class=\"contentClass\"\n :id=\"id\"\n :contenteditable=\"!disabled && !readonly\"\n :aria-label=\"label\"\n :aria-disabled=\"disabled\"\n :aria-readonly=\"readonly\"\n :data-erag-placeholder=\"placeholder\"\n :spellcheck=\"spellcheck\"\n :dir=\"direction\"\n :style=\"contentStyle\"\n role=\"textbox\"\n aria-multiline=\"true\"\n @click=\"emit('click', $event)\"\n @focus=\"emit('focus', $event)\"\n @blur=\"emit('blur', $event)\"\n @input=\"emit('input', $event as InputEvent)\"\n @keydown=\"emit('keydown', $event)\"\n @keyup=\"emit('selectionchange')\"\n @mouseup=\"emit('selectionchange')\"\n @paste=\"emit('paste', $event)\"\n />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { onMounted, useTemplateRef } from 'vue';\n\nconst props = defineProps<{\n id: string | undefined;\n html: string;\n disabled: boolean;\n readonly: boolean;\n placeholder: string;\n spellcheck: boolean;\n direction: 'ltr' | 'rtl';\n contentClass: string;\n contentStyle: string;\n label: string;\n}>();\nconst emit = defineEmits<{\n click: [event: MouseEvent];\n focus: [event: FocusEvent];\n blur: [event: FocusEvent];\n input: [event: InputEvent];\n keydown: [event: KeyboardEvent];\n paste: [event: ClipboardEvent];\n selectionchange: [];\n ready: [root: HTMLElement];\n}>();\nconst root = useTemplateRef<HTMLElement>('root');\n\nonMounted(() => {\n if (!root.value) {\n return;\n }\n\n root.value.innerHTML = props.html;\n emit('ready', root.value);\n});\nfunction getRoot(): HTMLElement | null {\n return root.value;\n}\ndefineExpose({ getRoot });\n</script>\n<template>\n <div class=\"erag-editor__canvas\">\n <div\n ref=\"root\"\n class=\"erag-editor__content\"\n :class=\"contentClass\"\n :id=\"id\"\n :contenteditable=\"!disabled && !readonly\"\n :aria-label=\"label\"\n :aria-disabled=\"disabled\"\n :aria-readonly=\"readonly\"\n :data-erag-placeholder=\"placeholder\"\n :spellcheck=\"spellcheck\"\n :dir=\"direction\"\n :style=\"contentStyle\"\n role=\"textbox\"\n aria-multiline=\"true\"\n @click=\"emit('click', $event)\"\n @focus=\"emit('focus', $event)\"\n @blur=\"emit('blur', $event)\"\n @input=\"emit('input', $event as InputEvent)\"\n @keydown=\"emit('keydown', $event)\"\n @keyup=\"emit('selectionchange')\"\n @mouseup=\"emit('selectionchange')\"\n @paste=\"emit('paste', $event)\"\n />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { shallowRef } from 'vue';\nconst props = defineProps<{ colors: string[]; current: string; label: string }>();\nconst emit = defineEmits<{ select: [color: string] }>();\nconst custom = shallowRef('#000000');\n</script>\n<template>\n <div\n class=\"erag-color-palette\"\n role=\"grid\"\n :aria-label=\"label\"\n >\n <button\n type=\"button\"\n class=\"erag-color-palette__remove\"\n @click=\"emit('select', '')\"\n >\n Remove color\n </button>\n <button\n v-for=\"color in props.colors\"\n :key=\"color\"\n type=\"button\"\n class=\"erag-color-palette__swatch\"\n :class=\"{ 'erag-is-active': current.toLowerCase() === color.toLowerCase() }\"\n :style=\"{ backgroundColor: color }\"\n :aria-label=\"color\"\n @click=\"emit('select', color)\"\n />\n <label class=\"erag-color-palette__custom\"\n >Custom\n <input\n v-model=\"custom\"\n type=\"color\"\n @change=\"emit('select', custom)\"\n /></label>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { shallowRef } from 'vue';\nconst props = defineProps<{ colors: string[]; current: string; label: string }>();\nconst emit = defineEmits<{ select: [color: string] }>();\nconst custom = shallowRef('#000000');\n</script>\n<template>\n <div\n class=\"erag-color-palette\"\n role=\"grid\"\n :aria-label=\"label\"\n >\n <button\n type=\"button\"\n class=\"erag-color-palette__remove\"\n @click=\"emit('select', '')\"\n >\n Remove color\n </button>\n <button\n v-for=\"color in props.colors\"\n :key=\"color\"\n type=\"button\"\n class=\"erag-color-palette__swatch\"\n :class=\"{ 'erag-is-active': current.toLowerCase() === color.toLowerCase() }\"\n :style=\"{ backgroundColor: color }\"\n :aria-label=\"color\"\n @click=\"emit('select', color)\"\n />\n <label class=\"erag-color-palette__custom\"\n >Custom\n <input\n v-model=\"custom\"\n type=\"color\"\n @change=\"emit('select', custom)\"\n /></label>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { nextTick, onMounted, useTemplateRef } from 'vue';\nimport { focusableElements } from '../../utils/dom';\nconst props = withDefaults(\n defineProps<{\n title: string;\n wide?: boolean;\n closeLabel?: string;\n footerDivider?: boolean;\n }>(),\n { closeLabel: 'Close', footerDivider: true, wide: false },\n);\nconst emit = defineEmits<{ close: [] }>();\ndefineSlots<{ default(): unknown; footer(): unknown }>();\nconst panel = useTemplateRef<HTMLElement>('panel');\nonMounted(async () => {\n await nextTick();\n focusableElements(panel.value as HTMLElement)[0]?.focus();\n});\nfunction keydown(event: KeyboardEvent): void {\n if (event.key === 'Escape') {\n emit('close');\n return;\n }\n if (event.key !== 'Tab' || !panel.value) return;\n const items = focusableElements(panel.value);\n const first = items[0];\n const last = items.at(-1);\n if (event.shiftKey && event.target === first) {\n event.preventDefault();\n last?.focus();\n } else if (!event.shiftKey && event.target === last) {\n event.preventDefault();\n first?.focus();\n }\n}\n</script>\n<template>\n <Teleport to=\"body\">\n <div\n class=\"erag-dialog-backdrop\"\n @mousedown.self=\"emit('close')\"\n >\n <section\n ref=\"panel\"\n class=\"erag-dialog\"\n :class=\"{ 'erag-dialog--wide': wide }\"\n role=\"dialog\"\n aria-modal=\"true\"\n :aria-label=\"title\"\n @keydown=\"keydown\"\n >\n <header class=\"erag-dialog__header\">\n <h2 class=\"erag-dialog__title\">{{ title }}</h2>\n <button\n type=\"button\"\n class=\"erag-dialog__close\"\n :aria-label=\"props.closeLabel\"\n @click=\"emit('close')\"\n >\n ×\n </button>\n </header>\n <div class=\"erag-dialog__body\"><slot /></div>\n <footer\n v-if=\"$slots.footer\"\n class=\"erag-dialog__footer\"\n :class=\"{ 'erag-dialog__footer--divided': props.footerDivider }\"\n >\n <slot name=\"footer\" />\n </footer>\n </section>\n </div>\n </Teleport>\n</template>\n","<script setup lang=\"ts\">\nimport { nextTick, onMounted, useTemplateRef } from 'vue';\nimport { focusableElements } from '../../utils/dom';\nconst props = withDefaults(\n defineProps<{\n title: string;\n wide?: boolean;\n closeLabel?: string;\n footerDivider?: boolean;\n }>(),\n { closeLabel: 'Close', footerDivider: true, wide: false },\n);\nconst emit = defineEmits<{ close: [] }>();\ndefineSlots<{ default(): unknown; footer(): unknown }>();\nconst panel = useTemplateRef<HTMLElement>('panel');\nonMounted(async () => {\n await nextTick();\n focusableElements(panel.value as HTMLElement)[0]?.focus();\n});\nfunction keydown(event: KeyboardEvent): void {\n if (event.key === 'Escape') {\n emit('close');\n return;\n }\n if (event.key !== 'Tab' || !panel.value) return;\n const items = focusableElements(panel.value);\n const first = items[0];\n const last = items.at(-1);\n if (event.shiftKey && event.target === first) {\n event.preventDefault();\n last?.focus();\n } else if (!event.shiftKey && event.target === last) {\n event.preventDefault();\n first?.focus();\n }\n}\n</script>\n<template>\n <Teleport to=\"body\">\n <div\n class=\"erag-dialog-backdrop\"\n @mousedown.self=\"emit('close')\"\n >\n <section\n ref=\"panel\"\n class=\"erag-dialog\"\n :class=\"{ 'erag-dialog--wide': wide }\"\n role=\"dialog\"\n aria-modal=\"true\"\n :aria-label=\"title\"\n @keydown=\"keydown\"\n >\n <header class=\"erag-dialog__header\">\n <h2 class=\"erag-dialog__title\">{{ title }}</h2>\n <button\n type=\"button\"\n class=\"erag-dialog__close\"\n :aria-label=\"props.closeLabel\"\n @click=\"emit('close')\"\n >\n ×\n </button>\n </header>\n <div class=\"erag-dialog__body\"><slot /></div>\n <footer\n v-if=\"$slots.footer\"\n class=\"erag-dialog__footer\"\n :class=\"{ 'erag-dialog__footer--divided': props.footerDivider }\"\n >\n <slot name=\"footer\" />\n </footer>\n </section>\n </div>\n </Teleport>\n</template>\n","<script setup lang=\"ts\">\nimport ColorPalette from '../toolbar/ColorPalette.vue';\nimport BaseDialog from './BaseDialog.vue';\ndefineProps<{ mode: 'forecolor' | 'backcolor'; colors: string[] }>();\nconst emit = defineEmits<{ close: []; select: [color: string] }>();\n</script>\n<template>\n <BaseDialog\n :title=\"mode === 'forecolor' ? 'Text color' : 'Background color'\"\n @close=\"emit('close')\"\n ><ColorPalette\n :colors=\"colors\"\n current=\"\"\n :label=\"mode === 'forecolor' ? 'Text color' : 'Background color'\"\n @select=\"emit('select', $event)\"\n /></BaseDialog>\n</template>\n","<script setup lang=\"ts\">\nimport ColorPalette from '../toolbar/ColorPalette.vue';\nimport BaseDialog from './BaseDialog.vue';\ndefineProps<{ mode: 'forecolor' | 'backcolor'; colors: string[] }>();\nconst emit = defineEmits<{ close: []; select: [color: string] }>();\n</script>\n<template>\n <BaseDialog\n :title=\"mode === 'forecolor' ? 'Text color' : 'Background color'\"\n @close=\"emit('close')\"\n ><ColorPalette\n :colors=\"colors\"\n current=\"\"\n :label=\"mode === 'forecolor' ? 'Text color' : 'Background color'\"\n @select=\"emit('select', $event)\"\n /></BaseDialog>\n</template>\n","import type { EmojiCategory, EmojiCategoryFilter, EmojiItem } from '../types';\n\nexport const EMOJI_CATEGORIES: readonly EmojiCategoryFilter[] = [\n 'All',\n 'Smileys & People',\n 'Animals & Nature',\n 'Food & Drink',\n 'Activity',\n 'Travel & Places',\n 'Objects',\n 'Symbols',\n 'Flags',\n];\n\nexport const EMOJIS: readonly EmojiItem[] = [\n { value: '😀', label: 'Grinning face', category: 'Smileys & People' },\n { value: '😃', label: 'Smiling face with big eyes', category: 'Smileys & People' },\n { value: '😄', label: 'Smiling face', category: 'Smileys & People' },\n { value: '😁', label: 'Beaming face', category: 'Smileys & People' },\n { value: '😂', label: 'Face with tears of joy', category: 'Smileys & People' },\n { value: '🤣', label: 'Rolling on the floor laughing', category: 'Smileys & People' },\n { value: '😊', label: 'Smiling face with smiling eyes', category: 'Smileys & People' },\n { value: '😍', label: 'Smiling face with heart eyes', category: 'Smileys & People' },\n { value: '🥳', label: 'Partying face', category: 'Smileys & People' },\n { value: '😎', label: 'Smiling face with sunglasses', category: 'Smileys & People' },\n { value: '🤔', label: 'Thinking face', category: 'Smileys & People' },\n { value: '😭', label: 'Loudly crying face', category: 'Smileys & People' },\n { value: '👍', label: 'Thumbs up', category: 'Smileys & People' },\n { value: '👏', label: 'Clapping hands', category: 'Smileys & People' },\n { value: '🙏', label: 'Folded hands', category: 'Smileys & People' },\n { value: '💪', label: 'Flexed biceps', category: 'Smileys & People' },\n { value: '🐶', label: 'Dog', category: 'Animals & Nature' },\n { value: '🐱', label: 'Cat', category: 'Animals & Nature' },\n { value: '🐭', label: 'Mouse', category: 'Animals & Nature' },\n { value: '🐰', label: 'Rabbit', category: 'Animals & Nature' },\n { value: '🦊', label: 'Fox', category: 'Animals & Nature' },\n { value: '🐻', label: 'Bear', category: 'Animals & Nature' },\n { value: '🐼', label: 'Panda', category: 'Animals & Nature' },\n { value: '🦁', label: 'Lion', category: 'Animals & Nature' },\n { value: '🐸', label: 'Frog', category: 'Animals & Nature' },\n { value: '🌸', label: 'Cherry blossom', category: 'Animals & Nature' },\n { value: '🌻', label: 'Sunflower', category: 'Animals & Nature' },\n { value: '🌳', label: 'Tree', category: 'Animals & Nature' },\n { value: '🍎', label: 'Red apple', category: 'Food & Drink' },\n { value: '🍌', label: 'Banana', category: 'Food & Drink' },\n { value: '🍇', label: 'Grapes', category: 'Food & Drink' },\n { value: '🍉', label: 'Watermelon', category: 'Food & Drink' },\n { value: '🍕', label: 'Pizza', category: 'Food & Drink' },\n { value: '🍔', label: 'Hamburger', category: 'Food & Drink' },\n { value: '🍟', label: 'French fries', category: 'Food & Drink' },\n { value: '🍰', label: 'Cake', category: 'Food & Drink' },\n { value: '☕', label: 'Hot beverage', category: 'Food & Drink' },\n { value: '🥤', label: 'Cup with straw', category: 'Food & Drink' },\n { value: '⚽', label: 'Soccer ball', category: 'Activity' },\n { value: '🏀', label: 'Basketball', category: 'Activity' },\n { value: '🏏', label: 'Cricket game', category: 'Activity' },\n { value: '🎾', label: 'Tennis', category: 'Activity' },\n { value: '🏆', label: 'Trophy', category: 'Activity' },\n { value: '🎯', label: 'Bullseye', category: 'Activity' },\n { value: '🎮', label: 'Video game', category: 'Activity' },\n { value: '🎨', label: 'Artist palette', category: 'Activity' },\n { value: '🚗', label: 'Car', category: 'Travel & Places' },\n { value: '🚌', label: 'Bus', category: 'Travel & Places' },\n { value: '🚆', label: 'Train', category: 'Travel & Places' },\n { value: '✈️', label: 'Airplane', category: 'Travel & Places' },\n { value: '🚀', label: 'Rocket', category: 'Travel & Places' },\n { value: '🏠', label: 'House', category: 'Travel & Places' },\n { value: '🏖️', label: 'Beach', category: 'Travel & Places' },\n { value: '🌍', label: 'Globe', category: 'Travel & Places' },\n { value: '💡', label: 'Light bulb', category: 'Objects' },\n { value: '📱', label: 'Mobile phone', category: 'Objects' },\n { value: '💻', label: 'Laptop', category: 'Objects' },\n { value: '⌨️', label: 'Keyboard', category: 'Objects' },\n { value: '📷', label: 'Camera', category: 'Objects' },\n { value: '🎁', label: 'Wrapped gift', category: 'Objects' },\n { value: '📌', label: 'Pushpin', category: 'Objects' },\n { value: '🔔', label: 'Bell', category: 'Objects' },\n { value: '❤️', label: 'Red heart', category: 'Symbols' },\n { value: '💯', label: 'Hundred points', category: 'Symbols' },\n { value: '✅', label: 'Check mark button', category: 'Symbols' },\n { value: '❌', label: 'Cross mark', category: 'Symbols' },\n { value: '⚠️', label: 'Warning', category: 'Symbols' },\n { value: '⭐', label: 'Star', category: 'Symbols' },\n { value: '🔥', label: 'Fire', category: 'Symbols' },\n { value: '✨', label: 'Sparkles', category: 'Symbols' },\n { value: '🇮🇳', label: 'Flag India', category: 'Flags' },\n { value: '🇺🇸', label: 'Flag United States', category: 'Flags' },\n { value: '🇬🇧', label: 'Flag United Kingdom', category: 'Flags' },\n { value: '🇨🇦', label: 'Flag Canada', category: 'Flags' },\n { value: '🇦🇺', label: 'Flag Australia', category: 'Flags' },\n { value: '🇯🇵', label: 'Flag Japan', category: 'Flags' },\n { value: '🇩🇪', label: 'Flag Germany', category: 'Flags' },\n { value: '🇫🇷', label: 'Flag France', category: 'Flags' },\n ...createEmojiItems('Smileys & People', [\n ['🙂', 'Slightly smiling face'],\n ['🙃', 'Upside down face'],\n ['😉', 'Winking face'],\n ['😇', 'Smiling face with halo'],\n ['🥰', 'Smiling face with hearts'],\n ['😘', 'Face blowing a kiss'],\n ['😋', 'Face savoring food'],\n ['😜', 'Winking face with tongue'],\n ['🤪', 'Zany face'],\n ['🤨', 'Face with raised eyebrow'],\n ['🧐', 'Face with monocle'],\n ['🤓', 'Nerd face'],\n ['🥸', 'Disguised face'],\n ['🤩', 'Star struck'],\n ['😏', 'Smirking face'],\n ['😒', 'Unamused face'],\n ['😔', 'Pensive face'],\n ['😢', 'Crying face'],\n ['😤', 'Face with steam from nose'],\n ['😡', 'Enraged face'],\n ['🤯', 'Exploding head'],\n ['😱', 'Face screaming in fear'],\n ['😳', 'Flushed face'],\n ['🥺', 'Pleading face'],\n ['😴', 'Sleeping face'],\n ['🤒', 'Face with thermometer'],\n ['🤢', 'Nauseated face'],\n ['🤠', 'Cowboy hat face'],\n ['🤡', 'Clown face'],\n ['👋', 'Waving hand'],\n ['👌', 'OK hand'],\n ['✌️', 'Victory hand'],\n ['🤞', 'Crossed fingers'],\n ['🤝', 'Handshake'],\n ['🙌', 'Raising hands'],\n ['🫶', 'Heart hands'],\n ['👀', 'Eyes'],\n ['🧠', 'Brain'],\n ['👶', 'Baby'],\n ['👩', 'Woman'],\n ['👨', 'Man'],\n ['🧑💻', 'Technologist'],\n ['👩🎨', 'Woman artist'],\n ['👨🚀', 'Man astronaut'],\n ['👨👩👧👦', 'Family'],\n ]),\n ...createEmojiItems('Animals & Nature', [\n ['🐯', 'Tiger'],\n ['🐨', 'Koala'],\n ['🐮', 'Cow'],\n ['🐷', 'Pig'],\n ['🐵', 'Monkey'],\n ['🙈', 'See no evil monkey'],\n ['🙉', 'Hear no evil monkey'],\n ['🙊', 'Speak no evil monkey'],\n ['🐔', 'Chicken'],\n ['🐧', 'Penguin'],\n ['🐦', 'Bird'],\n ['🦄', 'Unicorn'],\n ['🐝', 'Honeybee'],\n ['🦋', 'Butterfly'],\n ['🐌', 'Snail'],\n ['🐞', 'Lady beetle'],\n ['🐢', 'Turtle'],\n ['🐍', 'Snake'],\n ['🦎', 'Lizard'],\n ['🐙', 'Octopus'],\n ['🦀', 'Crab'],\n ['🐬', 'Dolphin'],\n ['🐳', 'Whale'],\n ['🦈', 'Shark'],\n ['🐘', 'Elephant'],\n ['🦒', 'Giraffe'],\n ['🌹', 'Rose'],\n ['🌺', 'Hibiscus'],\n ['🌷', 'Tulip'],\n ['🌱', 'Seedling'],\n ['🍀', 'Four leaf clover'],\n ['🍁', 'Maple leaf'],\n ['🌵', 'Cactus'],\n ['🌴', 'Palm tree'],\n ['🌈', 'Rainbow'],\n ['☀️', 'Sun'],\n ['🌙', 'Crescent moon'],\n ['❄️', 'Snowflake'],\n ]),\n ...createEmojiItems('Food & Drink', [\n ['🍏', 'Green apple'],\n ['🍐', 'Pear'],\n ['🍊', 'Tangerine'],\n ['🍋', 'Lemon'],\n ['🍓', 'Strawberry'],\n ['🫐', 'Blueberries'],\n ['🍒', 'Cherries'],\n ['🥭', 'Mango'],\n ['🍍', 'Pineapple'],\n ['🥝', 'Kiwi fruit'],\n ['🍅', 'Tomato'],\n ['🥑', 'Avocado'],\n ['🥦', 'Broccoli'],\n ['🌽', 'Ear of corn'],\n ['🥕', 'Carrot'],\n ['🥐', 'Croissant'],\n ['🍞', 'Bread'],\n ['🧀', 'Cheese wedge'],\n ['🍳', 'Cooking egg'],\n ['🥞', 'Pancakes'],\n ['🌭', 'Hot dog'],\n ['🌮', 'Taco'],\n ['🍿', 'Popcorn'],\n ['🍣', 'Sushi'],\n ['🍜', 'Steaming bowl'],\n ['🍦', 'Soft ice cream'],\n ['🍩', 'Doughnut'],\n ['🍪', 'Cookie'],\n ['🎂', 'Birthday cake'],\n ['🍫', 'Chocolate bar'],\n ['🍬', 'Candy'],\n ['🍯', 'Honey pot'],\n ['🥛', 'Glass of milk'],\n ['🫖', 'Teapot'],\n ['🍺', 'Beer mug'],\n ['🍷', 'Wine glass'],\n ]),\n ...createEmojiItems('Activity', [\n ['🏈', 'American football'],\n ['⚾', 'Baseball'],\n ['🏐', 'Volleyball'],\n ['🏉', 'Rugby football'],\n ['🥏', 'Flying disc'],\n ['🎱', 'Pool eight ball'],\n ['🏓', 'Ping pong'],\n ['🏸', 'Badminton'],\n ['🥊', 'Boxing glove'],\n ['🥋', 'Martial arts uniform'],\n ['⛳', 'Flag in hole'],\n ['⛸️', 'Ice skate'],\n ['🎿', 'Skis'],\n ['🏋️', 'Weight lifting'],\n ['🚴', 'Cyclist'],\n ['🏃', 'Runner'],\n ['🎲', 'Game die'],\n ['♟️', 'Chess pawn'],\n ['🎭', 'Performing arts'],\n ['🎤', 'Microphone'],\n ['🎸', 'Guitar'],\n ['🎹', 'Musical keyboard'],\n ]),\n ...createEmojiItems('Travel & Places', [\n ['🚕', 'Taxi'],\n ['🚙', 'Sport utility vehicle'],\n ['🏎️', 'Racing car'],\n ['🚓', 'Police car'],\n ['🚑', 'Ambulance'],\n ['🚒', 'Fire engine'],\n ['🚲', 'Bicycle'],\n ['🏍️', 'Motorcycle'],\n ['🚂', 'Locomotive'],\n ['🚇', 'Metro'],\n ['🚁', 'Helicopter'],\n ['🛸', 'Flying saucer'],\n ['⛵', 'Sailboat'],\n ['🚢', 'Ship'],\n ['⛽', 'Fuel pump'],\n ['🚦', 'Traffic light'],\n ['🗺️', 'World map'],\n ['🗽', 'Statue of Liberty'],\n ['🗼', 'Tokyo tower'],\n ['🏰', 'Castle'],\n ['🏯', 'Japanese castle'],\n ['🏟️', 'Stadium'],\n ['⛺', 'Tent'],\n ['🌋', 'Volcano'],\n ['🏔️', 'Snow capped mountain'],\n ['🌅', 'Sunrise'],\n ['🌃', 'Night with stars'],\n ]),\n ...createEmojiItems('Objects', [\n ['🖥️', 'Desktop computer'],\n ['🖨️', 'Printer'],\n ['🖱️', 'Computer mouse'],\n ['💾', 'Floppy disk'],\n ['💿', 'Optical disk'],\n ['🎥', 'Movie camera'],\n ['📺', 'Television'],\n ['📻', 'Radio'],\n ['🎧', 'Headphone'],\n ['🔋', 'Battery'],\n ['🔌', 'Electric plug'],\n ['⌚', 'Watch'],\n ['⏰', 'Alarm clock'],\n ['📚', 'Books'],\n ['📖', 'Open book'],\n ['📝', 'Memo'],\n ['✏️', 'Pencil'],\n ['📎', 'Paperclip'],\n ['📁', 'File folder'],\n ['📅', 'Calendar'],\n ['📦', 'Package'],\n ['✉️', 'Envelope'],\n ['🔒', 'Locked'],\n ['🔑', 'Key'],\n ['🔨', 'Hammer'],\n ['🧰', 'Toolbox'],\n ['🧲', 'Magnet'],\n ['🧪', 'Test tube'],\n ['💊', 'Pill'],\n ['🪥', 'Toothbrush'],\n ['🛒', 'Shopping cart'],\n ['💰', 'Money bag'],\n ['💎', 'Gem stone'],\n ]),\n ...createEmojiItems('Symbols', [\n ['🧡', 'Orange heart'],\n ['💛', 'Yellow heart'],\n ['💚', 'Green heart'],\n ['💙', 'Blue heart'],\n ['💜', 'Purple heart'],\n ['🖤', 'Black heart'],\n ['🤍', 'White heart'],\n ['💔', 'Broken heart'],\n ['💕', 'Two hearts'],\n ['💖', 'Sparkling heart'],\n ['💥', 'Collision'],\n ['💫', 'Dizzy'],\n ['💦', 'Sweat droplets'],\n ['💨', 'Dashing away'],\n ['➕', 'Plus'],\n ['➖', 'Minus'],\n ['➗', 'Divide'],\n ['♾️', 'Infinity'],\n ['❓', 'Question mark'],\n ['❗', 'Exclamation mark'],\n ['⭕', 'Hollow red circle'],\n ['🔴', 'Red circle'],\n ['🟠', 'Orange circle'],\n ['🟡', 'Yellow circle'],\n ['🟢', 'Green circle'],\n ['🔵', 'Blue circle'],\n ['🟣', 'Purple circle'],\n ['⬆️', 'Up arrow'],\n ['➡️', 'Right arrow'],\n ['⬇️', 'Down arrow'],\n ['⬅️', 'Left arrow'],\n ['🔄', 'Counterclockwise arrows'],\n ['▶️', 'Play button'],\n ['⏸️', 'Pause button'],\n ['ℹ️', 'Information'],\n ]),\n ...createEmojiItems('Flags', [\n ['🇧🇷', 'Flag Brazil'],\n ['🇲🇽', 'Flag Mexico'],\n ['🇦🇷', 'Flag Argentina'],\n ['🇪🇸', 'Flag Spain'],\n ['🇮🇹', 'Flag Italy'],\n ['🇵🇹', 'Flag Portugal'],\n ['🇳🇱', 'Flag Netherlands'],\n ['🇧🇪', 'Flag Belgium'],\n ['🇨🇭', 'Flag Switzerland'],\n ['🇸🇪', 'Flag Sweden'],\n ['🇳🇴', 'Flag Norway'],\n ['🇩🇰', 'Flag Denmark'],\n ['🇫🇮', 'Flag Finland'],\n ['🇮🇪', 'Flag Ireland'],\n ['🇵🇱', 'Flag Poland'],\n ['🇺🇦', 'Flag Ukraine'],\n ['🇷🇺', 'Flag Russia'],\n ['🇨🇳', 'Flag China'],\n ['🇰🇷', 'Flag South Korea'],\n ['🇸🇬', 'Flag Singapore'],\n ['🇮🇩', 'Flag Indonesia'],\n ['🇲🇾', 'Flag Malaysia'],\n ['🇹🇭', 'Flag Thailand'],\n ['🇦🇪', 'Flag United Arab Emirates'],\n ['🇸🇦', 'Flag Saudi Arabia'],\n ['🇿🇦', 'Flag South Africa'],\n ['🇳🇿', 'Flag New Zealand'],\n ['🇳🇵', 'Flag Nepal'],\n ['🇧🇩', 'Flag Bangladesh'],\n ['🇱🇰', 'Flag Sri Lanka'],\n ]),\n];\n\nfunction createEmojiItems(\n category: EmojiCategory,\n items: readonly (readonly [value: string, label: string])[],\n): EmojiItem[] {\n return items.map(([value, label]) => ({ value, label, category }));\n}\n","<script setup lang=\"ts\">\nimport { computed, shallowRef } from 'vue';\nimport { EMOJI_CATEGORIES, EMOJIS } from '../../constants/emojis';\nimport type { EmojiCategoryFilter } from '../../types';\nimport BaseDialog from './BaseDialog.vue';\n\nconst emit = defineEmits<{ close: []; select: [value: string] }>();\nconst query = shallowRef('');\nconst category = shallowRef<EmojiCategoryFilter>('All');\nconst visibleEmojis = computed(() => {\n const search = query.value.trim().toLocaleLowerCase();\n return EMOJIS.filter(\n (emoji) =>\n (category.value === 'All' || emoji.category === category.value) &&\n (!search || emoji.label.toLocaleLowerCase().includes(search) || emoji.value === search),\n );\n});\n</script>\n\n<template>\n <BaseDialog\n title=\"Emojis\"\n :footer-divider=\"false\"\n @close=\"emit('close')\"\n >\n <div class=\"erag-emoji-dialog\">\n <nav\n class=\"erag-emoji-dialog__categories\"\n aria-label=\"Emoji categories\"\n >\n <button\n v-for=\"name in EMOJI_CATEGORIES\"\n :key=\"name\"\n type=\"button\"\n class=\"erag-emoji-dialog__category\"\n :class=\"{ 'erag-is-active': category === name }\"\n :aria-pressed=\"category === name\"\n @click=\"category = name\"\n >\n {{ name }}\n </button>\n </nav>\n <div class=\"erag-emoji-dialog__content\">\n <label class=\"erag-field\">\n <span class=\"erag-field__label\">Search</span>\n <input\n v-model=\"query\"\n class=\"erag-field__input\"\n type=\"search\"\n autocomplete=\"off\"\n />\n </label>\n <div\n v-if=\"visibleEmojis.length\"\n class=\"erag-emoji-dialog__grid\"\n role=\"listbox\"\n aria-label=\"Emojis\"\n >\n <button\n v-for=\"emoji in visibleEmojis\"\n :key=\"`${emoji.category}-${emoji.label}`\"\n type=\"button\"\n class=\"erag-emoji-dialog__emoji\"\n role=\"option\"\n :aria-label=\"emoji.label\"\n :title=\"emoji.label\"\n @click=\"emit('select', emoji.value)\"\n >\n {{ emoji.value }}\n </button>\n </div>\n <p\n v-else\n class=\"erag-emoji-dialog__empty\"\n role=\"status\"\n >\n No emojis found\n </p>\n </div>\n </div>\n <template #footer>\n <button\n type=\"button\"\n class=\"erag-button erag-button--primary\"\n @click=\"emit('close')\"\n >\n Close\n </button>\n </template>\n </BaseDialog>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, shallowRef } from 'vue';\nimport { EMOJI_CATEGORIES, EMOJIS } from '../../constants/emojis';\nimport type { EmojiCategoryFilter } from '../../types';\nimport BaseDialog from './BaseDialog.vue';\n\nconst emit = defineEmits<{ close: []; select: [value: string] }>();\nconst query = shallowRef('');\nconst category = shallowRef<EmojiCategoryFilter>('All');\nconst visibleEmojis = computed(() => {\n const search = query.value.trim().toLocaleLowerCase();\n return EMOJIS.filter(\n (emoji) =>\n (category.value === 'All' || emoji.category === category.value) &&\n (!search || emoji.label.toLocaleLowerCase().includes(search) || emoji.value === search),\n );\n});\n</script>\n\n<template>\n <BaseDialog\n title=\"Emojis\"\n :footer-divider=\"false\"\n @close=\"emit('close')\"\n >\n <div class=\"erag-emoji-dialog\">\n <nav\n class=\"erag-emoji-dialog__categories\"\n aria-label=\"Emoji categories\"\n >\n <button\n v-for=\"name in EMOJI_CATEGORIES\"\n :key=\"name\"\n type=\"button\"\n class=\"erag-emoji-dialog__category\"\n :class=\"{ 'erag-is-active': category === name }\"\n :aria-pressed=\"category === name\"\n @click=\"category = name\"\n >\n {{ name }}\n </button>\n </nav>\n <div class=\"erag-emoji-dialog__content\">\n <label class=\"erag-field\">\n <span class=\"erag-field__label\">Search</span>\n <input\n v-model=\"query\"\n class=\"erag-field__input\"\n type=\"search\"\n autocomplete=\"off\"\n />\n </label>\n <div\n v-if=\"visibleEmojis.length\"\n class=\"erag-emoji-dialog__grid\"\n role=\"listbox\"\n aria-label=\"Emojis\"\n >\n <button\n v-for=\"emoji in visibleEmojis\"\n :key=\"`${emoji.category}-${emoji.label}`\"\n type=\"button\"\n class=\"erag-emoji-dialog__emoji\"\n role=\"option\"\n :aria-label=\"emoji.label\"\n :title=\"emoji.label\"\n @click=\"emit('select', emoji.value)\"\n >\n {{ emoji.value }}\n </button>\n </div>\n <p\n v-else\n class=\"erag-emoji-dialog__empty\"\n role=\"status\"\n >\n No emojis found\n </p>\n </div>\n </div>\n <template #footer>\n <button\n type=\"button\"\n class=\"erag-button erag-button--primary\"\n @click=\"emit('close')\"\n >\n Close\n </button>\n </template>\n </BaseDialog>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, shallowRef } from 'vue';\nimport { replaceTextInElement } from '../../utils/dom';\nimport BaseDialog from './BaseDialog.vue';\nconst props = defineProps<{ root: HTMLElement }>();\nconst emit = defineEmits<{ close: []; changed: [] }>();\nconst find = shallowRef('');\nconst replacement = shallowRef('');\nconst matchCase = shallowRef(false);\nconst wholeWord = shallowRef(false);\nconst index = shallowRef(-1);\nconst matches = computed(() => {\n if (!find.value) return [];\n const flags = matchCase.value ? 'g' : 'gi';\n const source = wholeWord.value ? `\\\\b${escapeRegExp(find.value)}\\\\b` : escapeRegExp(find.value);\n return [...(props.root.textContent ?? '').matchAll(new RegExp(source, flags))];\n});\nfunction navigate(offset: number): void {\n if (!matches.value.length) return;\n index.value = (index.value + offset + matches.value.length) % matches.value.length;\n const match = matches.value[index.value];\n if (!match || match.index === undefined) return;\n selectTextOffset(props.root, match.index, match[0].length);\n}\nfunction replace(all: boolean): void {\n const flags = `${matchCase.value ? '' : 'i'}${all ? 'g' : ''}`;\n const source = wholeWord.value ? `\\\\b${escapeRegExp(find.value)}\\\\b` : escapeRegExp(find.value);\n replaceTextInElement(props.root, new RegExp(source, flags), replacement.value, all);\n emit('changed');\n}\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\nfunction selectTextOffset(root: HTMLElement, start: number, length: number): void {\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);\n let offset = 0;\n let node = walker.nextNode();\n while (node) {\n const end = offset + (node.textContent?.length ?? 0);\n if (start >= offset && start < end) {\n const range = document.createRange();\n range.setStart(node, start - offset);\n range.setEnd(node, Math.min(start - offset + length, node.textContent?.length ?? 0));\n const selection = window.getSelection();\n selection?.removeAllRanges();\n selection?.addRange(range);\n return;\n }\n offset = end;\n node = walker.nextNode();\n }\n}\n</script>\n<template>\n <BaseDialog\n title=\"Find and replace\"\n @close=\"emit('close')\"\n ><div class=\"erag-dialog__form\">\n <label class=\"erag-field\"\n ><span class=\"erag-field__label\">Find</span\n ><input\n v-model=\"find\"\n class=\"erag-field__input\" /></label\n ><label class=\"erag-field\"\n ><span class=\"erag-field__label\">Replace with</span\n ><input\n v-model=\"replacement\"\n class=\"erag-field__input\"\n /></label>\n <div class=\"erag-field__row\">\n <label class=\"erag-field__check\"\n ><input\n v-model=\"matchCase\"\n type=\"checkbox\"\n />\n Match case</label\n ><label class=\"erag-field__check\"\n ><input\n v-model=\"wholeWord\"\n type=\"checkbox\"\n />\n Whole word</label\n >\n </div>\n <p class=\"erag-find__count\">\n {{ matches.length ? `${index + 1} of ${matches.length}` : 'No matches' }}\n </p>\n </div>\n <template #footer\n ><button\n type=\"button\"\n class=\"erag-button\"\n @click=\"navigate(-1)\"\n >\n Previous</button\n ><button\n type=\"button\"\n class=\"erag-button\"\n @click=\"navigate(1)\"\n >\n Next</button\n ><button\n type=\"button\"\n class=\"erag-button\"\n @click=\"replace(false)\"\n >\n Replace</button\n ><button\n type=\"button\"\n class=\"erag-button erag-button--primary\"\n @click=\"replace(true)\"\n >\n Replace all\n </button></template\n ></BaseDialog\n >\n</template>\n","<script setup lang=\"ts\">\nimport { computed, shallowRef } from 'vue';\nimport { replaceTextInElement } from '../../utils/dom';\nimport BaseDialog from './BaseDialog.vue';\nconst props = defineProps<{ root: HTMLElement }>();\nconst emit = defineEmits<{ close: []; changed: [] }>();\nconst find = shallowRef('');\nconst replacement = shallowRef('');\nconst matchCase = shallowRef(false);\nconst wholeWord = shallowRef(false);\nconst index = shallowRef(-1);\nconst matches = computed(() => {\n if (!find.value) return [];\n const flags = matchCase.value ? 'g' : 'gi';\n const source = wholeWord.value ? `\\\\b${escapeRegExp(find.value)}\\\\b` : escapeRegExp(find.value);\n return [...(props.root.textContent ?? '').matchAll(new RegExp(source, flags))];\n});\nfunction navigate(offset: number): void {\n if (!matches.value.length) return;\n index.value = (index.value + offset + matches.value.length) % matches.value.length;\n const match = matches.value[index.value];\n if (!match || match.index === undefined) return;\n selectTextOffset(props.root, match.index, match[0].length);\n}\nfunction replace(all: boolean): void {\n const flags = `${matchCase.value ? '' : 'i'}${all ? 'g' : ''}`;\n const source = wholeWord.value ? `\\\\b${escapeRegExp(find.value)}\\\\b` : escapeRegExp(find.value);\n replaceTextInElement(props.root, new RegExp(source, flags), replacement.value, all);\n emit('changed');\n}\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\nfunction selectTextOffset(root: HTMLElement, start: number, length: number): void {\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);\n let offset = 0;\n let node = walker.nextNode();\n while (node) {\n const end = offset + (node.textContent?.length ?? 0);\n if (start >= offset && start < end) {\n const range = document.createRange();\n range.setStart(node, start - offset);\n range.setEnd(node, Math.min(start - offset + length, node.textContent?.length ?? 0));\n const selection = window.getSelection();\n selection?.removeAllRanges();\n selection?.addRange(range);\n return;\n }\n offset = end;\n node = walker.nextNode();\n }\n}\n</script>\n<template>\n <BaseDialog\n title=\"Find and replace\"\n @close=\"emit('close')\"\n ><div class=\"erag-dialog__form\">\n <label class=\"erag-field\"\n ><span class=\"erag-field__label\">Find</span\n ><input\n v-model=\"find\"\n class=\"erag-field__input\" /></label\n ><label class=\"erag-field\"\n ><span class=\"erag-field__label\">Replace with</span\n ><input\n v-model=\"replacement\"\n class=\"erag-field__input\"\n /></label>\n <div class=\"erag-field__row\">\n <label class=\"erag-field__check\"\n ><input\n v-model=\"matchCase\"\n type=\"checkbox\"\n />\n Match case</label\n ><label class=\"erag-field__check\"\n ><input\n v-model=\"wholeWord\"\n type=\"checkbox\"\n />\n Whole word</label\n >\n </div>\n <p class=\"erag-find__count\">\n {{ matches.length ? `${index + 1} of ${matches.length}` : 'No matches' }}\n </p>\n </div>\n <template #footer\n ><button\n type=\"button\"\n class=\"erag-button\"\n @click=\"navigate(-1)\"\n >\n Previous</button\n ><button\n type=\"button\"\n class=\"erag-button\"\n @click=\"navigate(1)\"\n >\n Next</button\n ><button\n type=\"button\"\n class=\"erag-button\"\n @click=\"replace(false)\"\n >\n Replace</button\n ><button\n type=\"button\"\n class=\"erag-button erag-button--primary\"\n @click=\"replace(true)\"\n >\n Replace all\n </button></template\n ></BaseDialog\n >\n</template>\n","{\n \"name\": \"@erag/text-editor-vue\",\n \"version\": \"0.0.2\",\n \"description\": \"A modern dependency-free Vue 3 rich text editor (WYSIWYG) built with native browser APIs. Supports TypeScript, mentions, merge tags, templates, image upload, tables, HTML editing, and customizable toolbars.\",\n \"type\": \"module\",\n \"license\": \"MIT\",\n \"author\": {\n \"name\": \"Er Amit Gupta\",\n \"url\": \"https://github.com/eramitgupta\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/eramitgupta/text-editor-vue.git\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/eramitgupta/text-editor-vue/issues\"\n },\n \"homepage\": \"https://erag.in/text-editor-vue/index.html\",\n \"keywords\": [\n \"vue\",\n \"vue3\",\n \"vue-editor\",\n \"vue-rich-text-editor\",\n \"rich-text-editor\",\n \"text-editor\",\n \"wysiwyg\",\n \"wysiwyg-editor\",\n \"html-editor\",\n \"contenteditable\",\n \"typescript\",\n \"dependency-free\",\n \"zero-dependencies\",\n \"native-browser-api\",\n \"open-source\",\n \"free\",\n \"pro-features\",\n \"enterprise-ready\",\n \"customizable\",\n \"toolbar\",\n \"mentions\",\n \"merge-tags\",\n \"templates\",\n \"email-templates\",\n \"image-upload\",\n \"media-upload\",\n \"table-editor\",\n \"document-editor\",\n \"email-editor\",\n \"cms-editor\",\n \"vite\"\n ],\n \"files\": [\n \"dist\",\n \"README.md\",\n \"LICENSE\"\n ],\n \"main\": \"./dist/text-editor-vue.js\",\n \"module\": \"./dist/text-editor-vue.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/text-editor-vue.js\"\n },\n \"./style.css\": \"./dist/style.css\"\n },\n \"sideEffects\": [\n \"**/*.css\"\n ],\n \"scripts\": {\n \"dev\": \"vite build --watch\",\n \"build\": \"vite build\",\n \"lint\": \"prettier --write src eslint.config.js vite.config.ts package.json \\\"*.md\\\" \\\".github/**/*.md\\\" && eslint src vite.config.ts --fix\",\n \"lint:check\": \"prettier --check src eslint.config.js vite.config.ts package.json \\\"*.md\\\" \\\".github/**/*.md\\\" && eslint src vite.config.ts\",\n \"typecheck\": \"tsc --noEmit -p tsconfig.json\",\n \"prepublishOnly\": \"npm run lint:check && npm run typecheck && npm run build\"\n },\n \"peerDependencies\": {\n \"vue\": \">=3.5.0 <4\"\n },\n \"devDependencies\": {\n \"@babel/eslint-parser\": \"^7.28.0\",\n \"@babel/preset-typescript\": \"^7.28.0\",\n \"@eslint/js\": \"^9.39.0\",\n \"@types/node\": \"^24.13.3\",\n \"@typescript/typescript6\": \"^6.0.0\",\n \"@vitejs/plugin-vue\": \"^6.0.0\",\n \"@vue/language-core\": \"^3.3.7\",\n \"eslint\": \"^9.39.0\",\n \"eslint-config-prettier\": \"^10.1.8\",\n \"eslint-plugin-vue\": \"^10.0.0\",\n \"globals\": \"^16.0.0\",\n \"prettier\": \"^3.6.2\",\n \"typescript\": \"^7.0.0\",\n \"vite\": \"^8.0.0\",\n \"vite-plugin-dts\": \"^5.0.0\",\n \"vue-eslint-parser\": \"^10.0.0\"\n },\n \"engines\": {\n \"node\": \">=24.0.0\"\n }\n}\n","import packageMetadata from '../../package.json';\n\nexport const EDITOR_VERSION = packageMetadata.version;\n","<script setup lang=\"ts\">\ndefineProps<{ name: string; size?: number }>();\n</script>\n\n<template>\n <svg\n class=\"erag-icon\"\n :width=\"size ?? 20\"\n :height=\"size ?? 20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.8\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <template v-if=\"name === 'bold'\">\n <path d=\"M7 4h6a4 4 0 0 1 0 8H7z\" />\n <path d=\"M7 12h7a4 4 0 0 1 0 8H7z\" />\n </template>\n <template v-else-if=\"name === 'italic'\"><path d=\"M10 4h8M6 20h8M14 4 10 20\" /></template>\n <template v-else-if=\"name === 'underline'\">\n <path d=\"M6 4v7a6 6 0 0 0 12 0V4M5 21h14\" />\n </template>\n <template v-else-if=\"name === 'strikethrough'\">\n <path\n d=\"M5 12h14M17 7c-.8-2-2.4-3-5-3-3 0-5 1.5-5 3.5 0 1.7 1.2 2.8 5 3.5m-5 6c1 2 2.5 3 5 3 3 0 5-1.4 5-3.5 0-1.6-1-2.6-3.7-3.5\"\n />\n </template>\n <template v-else-if=\"name === 'superscript'\">\n <path\n d=\"m4 7 9 10M13 7 4 17M16 7c.5-1.3 1.3-2 2.5-2 1.4 0 2.5.8 2.5 2 0 1.5-1.6 2.3-4.7 4H21\"\n />\n </template>\n <template v-else-if=\"name === 'subscript'\">\n <path\n d=\"m4 5 9 10M13 5 4 15M16 15c.5-1.3 1.3-2 2.5-2 1.4 0 2.5.8 2.5 2 0 1.5-1.6 2.3-4.7 4H21\"\n />\n </template>\n <template v-else-if=\"name === 'case-change'\">\n <path d=\"M4 18 9 5l5 13M6 13h6M15 10h5M17.5 7.5 20 10l-2.5 2.5\" />\n </template>\n <template v-else-if=\"name.includes('align')\">\n <path d=\"M4 6h16M4 10h12M4 14h16M4 18h12\" />\n </template>\n <template v-else-if=\"name === 'undo'\">\n <path d=\"m9 7-5 5 5 5M5 12h8a6 6 0 0 1 6 6\" />\n </template>\n <template v-else-if=\"name === 'redo'\">\n <path d=\"m15 7 5 5-5 5M19 12h-8a6 6 0 0 0-6 6\" />\n </template>\n <template v-else-if=\"name === 'file'\">\n <path d=\"M6 3h8l4 4v14H6zM14 3v5h5M9 12h6M9 16h6\" />\n </template>\n <template v-else-if=\"name === 'edit'\">\n <path d=\"m4 20 4.5-1 10-10a2.1 2.1 0 0 0-3-3l-10 10zM14 7l3 3\" />\n </template>\n <template v-else-if=\"name === 'view'\">\n <path d=\"M2 12s3.5-6 10-6 10 6 10 6-3.5 6-10 6S2 12 2 12\" />\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"2.5\"\n />\n </template>\n <template v-else-if=\"name === 'insert'\">\n <rect\n x=\"4\"\n y=\"4\"\n width=\"16\"\n height=\"16\"\n rx=\"3\"\n />\n <path d=\"M12 8v8M8 12h8\" />\n </template>\n <template v-else-if=\"name === 'format'\">\n <path d=\"m5 19 7-15 7 15M8 14h8M4 22h16\" />\n </template>\n <template v-else-if=\"name === 'tools'\">\n <path d=\"M14 7a4 4 0 0 0-5-4l2.2 2.2-3 3L6 6a4 4 0 0 0 5 5l7 7a2 2 0 0 0 3-3z\" />\n </template>\n <template v-else-if=\"name === 'help'\">\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"9\"\n />\n <path d=\"M9.8 9a2.3 2.3 0 1 1 3.7 1.8c-1 .7-1.5 1.1-1.5 2.2M12 17h.01\" />\n </template>\n <template v-else-if=\"name === 'print'\">\n <path\n d=\"M7 8V3h10v5M7 17H5a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2\"\n />\n <path d=\"M7 14h10v7H7zM17 11h.01\" />\n </template>\n <template v-else-if=\"name === 'cut'\">\n <circle\n cx=\"6\"\n cy=\"7\"\n r=\"3\"\n />\n <circle\n cx=\"6\"\n cy=\"17\"\n r=\"3\"\n />\n <path d=\"m8.5 8.5 11 7.5M8.5 15.5 19.5 8\" />\n </template>\n <template v-else-if=\"name === 'copy'\">\n <rect\n x=\"8\"\n y=\"8\"\n width=\"12\"\n height=\"12\"\n rx=\"2\"\n />\n <path d=\"M16 8V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h2\" />\n </template>\n <template v-else-if=\"name === 'paste'\">\n <path d=\"M9 5h6M9 3h6v4H9zM7 5H5v16h14V5h-2\" />\n </template>\n <template v-else-if=\"name === 'select-all'\">\n <path d=\"M4 8V4h4M16 4h4v4M20 16v4h-4M8 20H4v-4M8 9h8v6H8z\" />\n </template>\n <template v-else-if=\"name === 'search'\">\n <circle\n cx=\"11\"\n cy=\"11\"\n r=\"6\"\n />\n <path d=\"m16 16 4 4\" />\n </template>\n <template v-else-if=\"name === 'anchor'\">\n <circle\n cx=\"12\"\n cy=\"5\"\n r=\"2\"\n />\n <path d=\"M12 7v14M7 11h10M5 16c1 3 3.3 5 7 5s6-2 7-5\" />\n </template>\n <template v-else-if=\"name === 'calendar'\">\n <rect\n x=\"3\"\n y=\"5\"\n width=\"18\"\n height=\"16\"\n rx=\"2\"\n />\n <path d=\"M8 3v4M16 3v4M3 10h18M8 14h.01M12 14h.01M16 14h.01M8 18h.01M12 18h.01\" />\n </template>\n <template v-else-if=\"name === 'special-character'\">\n <path d=\"M8 18h8M6 9a6 6 0 1 1 12 0c0 3-2 5-4 6v3M10 18v-3c-2-1-4-3-4-6\" />\n </template>\n <template v-else-if=\"name === 'count'\">\n <path d=\"M4 6h16M4 12h10M4 18h13\" />\n </template>\n <template v-else-if=\"name === 'trash'\">\n <path d=\"M4 7h16M9 7V4h6v3M7 7l1 14h8l1-14M10 11v6M14 11v6\" />\n </template>\n <template v-else-if=\"name === 'keyboard'\">\n <rect\n x=\"3\"\n y=\"6\"\n width=\"18\"\n height=\"12\"\n rx=\"2\"\n />\n <path d=\"M7 10h.01M11 10h.01M15 10h.01M18 10h.01M7 14h.01M10 14h7\" />\n </template>\n <template v-else-if=\"name === 'github'\">\n <path\n d=\"M15 21v-4a4 4 0 0 0-1-3c3.3-.4 6-1.6 6-7a5.4 5.4 0 0 0-1.5-3.8A5 5 0 0 0 18.4 0S17.2-.4 14 1.5a13 13 0 0 0-7 0C3.8-.4 2.6 0 2.6 0a5 5 0 0 0-.1 3.2A5.4 5.4 0 0 0 1 7c0 5.4 2.7 6.6 6 7a4 4 0 0 0-1 3v4M6 18c-3 .9-3-1.5-4-2\"\n />\n </template>\n <template v-else-if=\"name === 'documentation'\">\n <path\n d=\"M4 4.5A2.5 2.5 0 0 1 6.5 2H11v18H6.5A2.5 2.5 0 0 0 4 22zM20 4.5A2.5 2.5 0 0 0 17.5 2H13v18h4.5A2.5 2.5 0 0 1 20 22z\"\n />\n </template>\n <template v-else-if=\"name === 'menu-item'\">\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"3\"\n />\n </template>\n <template v-else-if=\"name === 'link'\">\n <path d=\"m9 15 6-6M7 17H5a4 4 0 0 1 0-8h4M17 7h2a4 4 0 0 1 0 8h-4\" />\n </template>\n <template v-else-if=\"name === 'image'\">\n <rect\n x=\"3\"\n y=\"4\"\n width=\"18\"\n height=\"16\"\n rx=\"2\"\n />\n <circle\n cx=\"9\"\n cy=\"9\"\n r=\"2\"\n />\n <path d=\"m4 17 5-5 4 4 3-3 5 5\" />\n </template>\n <template v-else-if=\"name === 'media'\">\n <rect\n x=\"3\"\n y=\"5\"\n width=\"18\"\n height=\"14\"\n rx=\"2\"\n />\n <path d=\"m10 9 5 3-5 3z\" />\n </template>\n <template v-else-if=\"name === 'table'\">\n <rect\n x=\"3\"\n y=\"4\"\n width=\"18\"\n height=\"16\"\n rx=\"1\"\n />\n <path d=\"M3 9h18M9 4v16M15 4v16\" />\n </template>\n <template v-else-if=\"name === 'list' || name === 'numbered-list'\">\n <path d=\"M9 6h11M9 12h11M9 18h11M4 6h.01M4 12h.01M4 18h.01\" />\n </template>\n <template v-else-if=\"name === 'indent' || name === 'outdent'\">\n <path d=\"M10 6h10M10 12h10M10 18h10M4 8l4 4-4 4\" />\n </template>\n <template v-else-if=\"name === 'code'\">\n <path d=\"m8 8-4 4 4 4M16 8l4 4-4 4M14 5l-4 14\" />\n </template>\n <template v-else-if=\"name === 'preview'\">\n <path d=\"M2 12s3.5-6 10-6 10 6 10 6-3.5 6-10 6S2 12 2 12\" />\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"2.5\"\n />\n </template>\n <template v-else-if=\"name === 'fullscreen'\">\n <path d=\"M8 3H3v5M16 3h5v5M8 21H3v-5M16 21h5v-5\" />\n </template>\n <template v-else-if=\"name === 'horizontal-rule'\"><path d=\"M4 12h16\" /></template>\n <template v-else-if=\"name === 'clear-format'\">\n <path d=\"m4 20 6-6M7 4h10M12 4 8 15M14 15l6 6M20 15l-6 6\" />\n </template>\n <template v-else-if=\"name === 'text-color'\">\n <path d=\"m5 19 7-15 7 15M8 14h8M5 22h14\" />\n </template>\n <template v-else-if=\"name === 'highlight'\">\n <path d=\"m4 16 9-12 5 4-9 12H4zM3 22h18\" />\n </template>\n <template v-else-if=\"name === 'upload'\">\n <path d=\"M12 16V4M7.5 8.5 12 4l4.5 4.5M5 14v5h14v-5\" />\n </template>\n <template v-else-if=\"name === 'emoji'\">\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"9\"\n />\n <path d=\"M8.5 10h.01M15.5 10h.01M8 14c1 2.5 7 2.5 8 0\" />\n </template>\n <template v-else-if=\"name === 'merge-tag'\">\n <path\n d=\"M8 7H5a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h3M16 7h3a2 2 0 0 1 2 2v6a2 2 0 0 1-2 2h-3M14 5l-4 14\"\n />\n </template>\n <template v-else-if=\"name === 'template'\">\n <rect\n x=\"4\"\n y=\"3\"\n width=\"16\"\n height=\"18\"\n rx=\"2\"\n />\n <path d=\"M8 8h8M8 12h8M8 16h5\" />\n </template>\n <template v-else-if=\"name === 'close'\">\n <path d=\"M6 6l12 12M18 6 6 18\" />\n </template>\n <template v-else>\n <circle\n cx=\"5\"\n cy=\"12\"\n r=\"1\"\n fill=\"currentColor\"\n stroke=\"none\"\n />\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"1\"\n fill=\"currentColor\"\n stroke=\"none\"\n />\n <circle\n cx=\"19\"\n cy=\"12\"\n r=\"1\"\n fill=\"currentColor\"\n stroke=\"none\"\n />\n </template>\n </svg>\n</template>\n","<script setup lang=\"ts\">\ndefineProps<{ name: string; size?: number }>();\n</script>\n\n<template>\n <svg\n class=\"erag-icon\"\n :width=\"size ?? 20\"\n :height=\"size ?? 20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.8\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <template v-if=\"name === 'bold'\">\n <path d=\"M7 4h6a4 4 0 0 1 0 8H7z\" />\n <path d=\"M7 12h7a4 4 0 0 1 0 8H7z\" />\n </template>\n <template v-else-if=\"name === 'italic'\"><path d=\"M10 4h8M6 20h8M14 4 10 20\" /></template>\n <template v-else-if=\"name === 'underline'\">\n <path d=\"M6 4v7a6 6 0 0 0 12 0V4M5 21h14\" />\n </template>\n <template v-else-if=\"name === 'strikethrough'\">\n <path\n d=\"M5 12h14M17 7c-.8-2-2.4-3-5-3-3 0-5 1.5-5 3.5 0 1.7 1.2 2.8 5 3.5m-5 6c1 2 2.5 3 5 3 3 0 5-1.4 5-3.5 0-1.6-1-2.6-3.7-3.5\"\n />\n </template>\n <template v-else-if=\"name === 'superscript'\">\n <path\n d=\"m4 7 9 10M13 7 4 17M16 7c.5-1.3 1.3-2 2.5-2 1.4 0 2.5.8 2.5 2 0 1.5-1.6 2.3-4.7 4H21\"\n />\n </template>\n <template v-else-if=\"name === 'subscript'\">\n <path\n d=\"m4 5 9 10M13 5 4 15M16 15c.5-1.3 1.3-2 2.5-2 1.4 0 2.5.8 2.5 2 0 1.5-1.6 2.3-4.7 4H21\"\n />\n </template>\n <template v-else-if=\"name === 'case-change'\">\n <path d=\"M4 18 9 5l5 13M6 13h6M15 10h5M17.5 7.5 20 10l-2.5 2.5\" />\n </template>\n <template v-else-if=\"name.includes('align')\">\n <path d=\"M4 6h16M4 10h12M4 14h16M4 18h12\" />\n </template>\n <template v-else-if=\"name === 'undo'\">\n <path d=\"m9 7-5 5 5 5M5 12h8a6 6 0 0 1 6 6\" />\n </template>\n <template v-else-if=\"name === 'redo'\">\n <path d=\"m15 7 5 5-5 5M19 12h-8a6 6 0 0 0-6 6\" />\n </template>\n <template v-else-if=\"name === 'file'\">\n <path d=\"M6 3h8l4 4v14H6zM14 3v5h5M9 12h6M9 16h6\" />\n </template>\n <template v-else-if=\"name === 'edit'\">\n <path d=\"m4 20 4.5-1 10-10a2.1 2.1 0 0 0-3-3l-10 10zM14 7l3 3\" />\n </template>\n <template v-else-if=\"name === 'view'\">\n <path d=\"M2 12s3.5-6 10-6 10 6 10 6-3.5 6-10 6S2 12 2 12\" />\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"2.5\"\n />\n </template>\n <template v-else-if=\"name === 'insert'\">\n <rect\n x=\"4\"\n y=\"4\"\n width=\"16\"\n height=\"16\"\n rx=\"3\"\n />\n <path d=\"M12 8v8M8 12h8\" />\n </template>\n <template v-else-if=\"name === 'format'\">\n <path d=\"m5 19 7-15 7 15M8 14h8M4 22h16\" />\n </template>\n <template v-else-if=\"name === 'tools'\">\n <path d=\"M14 7a4 4 0 0 0-5-4l2.2 2.2-3 3L6 6a4 4 0 0 0 5 5l7 7a2 2 0 0 0 3-3z\" />\n </template>\n <template v-else-if=\"name === 'help'\">\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"9\"\n />\n <path d=\"M9.8 9a2.3 2.3 0 1 1 3.7 1.8c-1 .7-1.5 1.1-1.5 2.2M12 17h.01\" />\n </template>\n <template v-else-if=\"name === 'print'\">\n <path\n d=\"M7 8V3h10v5M7 17H5a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2\"\n />\n <path d=\"M7 14h10v7H7zM17 11h.01\" />\n </template>\n <template v-else-if=\"name === 'cut'\">\n <circle\n cx=\"6\"\n cy=\"7\"\n r=\"3\"\n />\n <circle\n cx=\"6\"\n cy=\"17\"\n r=\"3\"\n />\n <path d=\"m8.5 8.5 11 7.5M8.5 15.5 19.5 8\" />\n </template>\n <template v-else-if=\"name === 'copy'\">\n <rect\n x=\"8\"\n y=\"8\"\n width=\"12\"\n height=\"12\"\n rx=\"2\"\n />\n <path d=\"M16 8V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h2\" />\n </template>\n <template v-else-if=\"name === 'paste'\">\n <path d=\"M9 5h6M9 3h6v4H9zM7 5H5v16h14V5h-2\" />\n </template>\n <template v-else-if=\"name === 'select-all'\">\n <path d=\"M4 8V4h4M16 4h4v4M20 16v4h-4M8 20H4v-4M8 9h8v6H8z\" />\n </template>\n <template v-else-if=\"name === 'search'\">\n <circle\n cx=\"11\"\n cy=\"11\"\n r=\"6\"\n />\n <path d=\"m16 16 4 4\" />\n </template>\n <template v-else-if=\"name === 'anchor'\">\n <circle\n cx=\"12\"\n cy=\"5\"\n r=\"2\"\n />\n <path d=\"M12 7v14M7 11h10M5 16c1 3 3.3 5 7 5s6-2 7-5\" />\n </template>\n <template v-else-if=\"name === 'calendar'\">\n <rect\n x=\"3\"\n y=\"5\"\n width=\"18\"\n height=\"16\"\n rx=\"2\"\n />\n <path d=\"M8 3v4M16 3v4M3 10h18M8 14h.01M12 14h.01M16 14h.01M8 18h.01M12 18h.01\" />\n </template>\n <template v-else-if=\"name === 'special-character'\">\n <path d=\"M8 18h8M6 9a6 6 0 1 1 12 0c0 3-2 5-4 6v3M10 18v-3c-2-1-4-3-4-6\" />\n </template>\n <template v-else-if=\"name === 'count'\">\n <path d=\"M4 6h16M4 12h10M4 18h13\" />\n </template>\n <template v-else-if=\"name === 'trash'\">\n <path d=\"M4 7h16M9 7V4h6v3M7 7l1 14h8l1-14M10 11v6M14 11v6\" />\n </template>\n <template v-else-if=\"name === 'keyboard'\">\n <rect\n x=\"3\"\n y=\"6\"\n width=\"18\"\n height=\"12\"\n rx=\"2\"\n />\n <path d=\"M7 10h.01M11 10h.01M15 10h.01M18 10h.01M7 14h.01M10 14h7\" />\n </template>\n <template v-else-if=\"name === 'github'\">\n <path\n d=\"M15 21v-4a4 4 0 0 0-1-3c3.3-.4 6-1.6 6-7a5.4 5.4 0 0 0-1.5-3.8A5 5 0 0 0 18.4 0S17.2-.4 14 1.5a13 13 0 0 0-7 0C3.8-.4 2.6 0 2.6 0a5 5 0 0 0-.1 3.2A5.4 5.4 0 0 0 1 7c0 5.4 2.7 6.6 6 7a4 4 0 0 0-1 3v4M6 18c-3 .9-3-1.5-4-2\"\n />\n </template>\n <template v-else-if=\"name === 'documentation'\">\n <path\n d=\"M4 4.5A2.5 2.5 0 0 1 6.5 2H11v18H6.5A2.5 2.5 0 0 0 4 22zM20 4.5A2.5 2.5 0 0 0 17.5 2H13v18h4.5A2.5 2.5 0 0 1 20 22z\"\n />\n </template>\n <template v-else-if=\"name === 'menu-item'\">\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"3\"\n />\n </template>\n <template v-else-if=\"name === 'link'\">\n <path d=\"m9 15 6-6M7 17H5a4 4 0 0 1 0-8h4M17 7h2a4 4 0 0 1 0 8h-4\" />\n </template>\n <template v-else-if=\"name === 'image'\">\n <rect\n x=\"3\"\n y=\"4\"\n width=\"18\"\n height=\"16\"\n rx=\"2\"\n />\n <circle\n cx=\"9\"\n cy=\"9\"\n r=\"2\"\n />\n <path d=\"m4 17 5-5 4 4 3-3 5 5\" />\n </template>\n <template v-else-if=\"name === 'media'\">\n <rect\n x=\"3\"\n y=\"5\"\n width=\"18\"\n height=\"14\"\n rx=\"2\"\n />\n <path d=\"m10 9 5 3-5 3z\" />\n </template>\n <template v-else-if=\"name === 'table'\">\n <rect\n x=\"3\"\n y=\"4\"\n width=\"18\"\n height=\"16\"\n rx=\"1\"\n />\n <path d=\"M3 9h18M9 4v16M15 4v16\" />\n </template>\n <template v-else-if=\"name === 'list' || name === 'numbered-list'\">\n <path d=\"M9 6h11M9 12h11M9 18h11M4 6h.01M4 12h.01M4 18h.01\" />\n </template>\n <template v-else-if=\"name === 'indent' || name === 'outdent'\">\n <path d=\"M10 6h10M10 12h10M10 18h10M4 8l4 4-4 4\" />\n </template>\n <template v-else-if=\"name === 'code'\">\n <path d=\"m8 8-4 4 4 4M16 8l4 4-4 4M14 5l-4 14\" />\n </template>\n <template v-else-if=\"name === 'preview'\">\n <path d=\"M2 12s3.5-6 10-6 10 6 10 6-3.5 6-10 6S2 12 2 12\" />\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"2.5\"\n />\n </template>\n <template v-else-if=\"name === 'fullscreen'\">\n <path d=\"M8 3H3v5M16 3h5v5M8 21H3v-5M16 21h5v-5\" />\n </template>\n <template v-else-if=\"name === 'horizontal-rule'\"><path d=\"M4 12h16\" /></template>\n <template v-else-if=\"name === 'clear-format'\">\n <path d=\"m4 20 6-6M7 4h10M12 4 8 15M14 15l6 6M20 15l-6 6\" />\n </template>\n <template v-else-if=\"name === 'text-color'\">\n <path d=\"m5 19 7-15 7 15M8 14h8M5 22h14\" />\n </template>\n <template v-else-if=\"name === 'highlight'\">\n <path d=\"m4 16 9-12 5 4-9 12H4zM3 22h18\" />\n </template>\n <template v-else-if=\"name === 'upload'\">\n <path d=\"M12 16V4M7.5 8.5 12 4l4.5 4.5M5 14v5h14v-5\" />\n </template>\n <template v-else-if=\"name === 'emoji'\">\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"9\"\n />\n <path d=\"M8.5 10h.01M15.5 10h.01M8 14c1 2.5 7 2.5 8 0\" />\n </template>\n <template v-else-if=\"name === 'merge-tag'\">\n <path\n d=\"M8 7H5a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h3M16 7h3a2 2 0 0 1 2 2v6a2 2 0 0 1-2 2h-3M14 5l-4 14\"\n />\n </template>\n <template v-else-if=\"name === 'template'\">\n <rect\n x=\"4\"\n y=\"3\"\n width=\"16\"\n height=\"18\"\n rx=\"2\"\n />\n <path d=\"M8 8h8M8 12h8M8 16h5\" />\n </template>\n <template v-else-if=\"name === 'close'\">\n <path d=\"M6 6l12 12M18 6 6 18\" />\n </template>\n <template v-else>\n <circle\n cx=\"5\"\n cy=\"12\"\n r=\"1\"\n fill=\"currentColor\"\n stroke=\"none\"\n />\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"1\"\n fill=\"currentColor\"\n stroke=\"none\"\n />\n <circle\n cx=\"19\"\n cy=\"12\"\n r=\"1\"\n fill=\"currentColor\"\n stroke=\"none\"\n />\n </template>\n </svg>\n</template>\n","<script setup lang=\"ts\">\nimport { EDITOR_VERSION } from '../../constants/packageInfo';\nimport EditorIcon from '../icons/EditorIcon.vue';\nimport BaseDialog from './BaseDialog.vue';\ndefineProps<{ kind: 'shortcuts' | 'about' }>();\ndefineEmits<{ close: [] }>();\n</script>\n<template>\n <BaseDialog\n :title=\"kind === 'about' ? 'About' : 'Keyboard shortcuts'\"\n :footer-divider=\"false\"\n @close=\"$emit('close')\"\n ><div\n v-if=\"kind === 'about'\"\n class=\"erag-info\"\n >\n <div class=\"erag-info__product\">\n <h3 class=\"erag-info__heading\">@erag/text-editor-vue</h3>\n <span class=\"erag-info__version\">v{{ EDITOR_VERSION }}</span>\n </div>\n <p class=\"erag-info__description\">\n A dependency-free Vue 3 rich text editor built with native browser APIs, flexible\n configuration, and full TypeScript support.\n </p>\n <p class=\"erag-info__author\">Created and maintained by Er Amit Gupta.</p>\n <div class=\"erag-info__links\">\n <a\n class=\"erag-info__link\"\n href=\"https://github.com/eramitgupta/text-editor-vue\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n <EditorIcon\n class=\"erag-info__link-icon\"\n name=\"github\"\n :size=\"20\"\n />\n <span class=\"erag-info__link-content\">\n <strong class=\"erag-info__link-label\">GitHub repository</strong>\n <span class=\"erag-info__link-url\"\n >github.com/eramitgupta/text-editor-vue</span\n >\n </span>\n </a>\n <a\n class=\"erag-info__link\"\n href=\"https://erag.in/text-editor-vue\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n <EditorIcon\n class=\"erag-info__link-icon\"\n name=\"documentation\"\n :size=\"20\"\n />\n <span class=\"erag-info__link-content\">\n <strong class=\"erag-info__link-label\">Documentation</strong>\n <span class=\"erag-info__link-url\">erag.in/text-editor-vue</span>\n </span>\n </a>\n </div>\n </div>\n <dl\n v-else\n class=\"erag-shortcuts\"\n >\n <template\n v-for=\"entry in [\n ['Bold', 'Ctrl/⌘ B'],\n ['Italic', 'Ctrl/⌘ I'],\n ['Underline', 'Ctrl/⌘ U'],\n ['Undo', 'Ctrl/⌘ Z'],\n ['Redo', 'Ctrl/⌘ Shift Z'],\n ['Link', 'Ctrl/⌘ K'],\n ['Find', 'Ctrl/⌘ F'],\n ['Help', 'Alt 0'],\n ]\"\n :key=\"entry[0]\"\n ><dt>{{ entry[0] }}</dt>\n <dd>{{ entry[1] }}</dd></template\n >\n </dl>\n <template #footer\n ><button\n type=\"button\"\n class=\"erag-button erag-button--primary\"\n @click=\"$emit('close')\"\n >\n Close\n </button></template\n ></BaseDialog\n >\n</template>\n","<script setup lang=\"ts\">\nimport { EDITOR_VERSION } from '../../constants/packageInfo';\nimport EditorIcon from '../icons/EditorIcon.vue';\nimport BaseDialog from './BaseDialog.vue';\ndefineProps<{ kind: 'shortcuts' | 'about' }>();\ndefineEmits<{ close: [] }>();\n</script>\n<template>\n <BaseDialog\n :title=\"kind === 'about' ? 'About' : 'Keyboard shortcuts'\"\n :footer-divider=\"false\"\n @close=\"$emit('close')\"\n ><div\n v-if=\"kind === 'about'\"\n class=\"erag-info\"\n >\n <div class=\"erag-info__product\">\n <h3 class=\"erag-info__heading\">@erag/text-editor-vue</h3>\n <span class=\"erag-info__version\">v{{ EDITOR_VERSION }}</span>\n </div>\n <p class=\"erag-info__description\">\n A dependency-free Vue 3 rich text editor built with native browser APIs, flexible\n configuration, and full TypeScript support.\n </p>\n <p class=\"erag-info__author\">Created and maintained by Er Amit Gupta.</p>\n <div class=\"erag-info__links\">\n <a\n class=\"erag-info__link\"\n href=\"https://github.com/eramitgupta/text-editor-vue\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n <EditorIcon\n class=\"erag-info__link-icon\"\n name=\"github\"\n :size=\"20\"\n />\n <span class=\"erag-info__link-content\">\n <strong class=\"erag-info__link-label\">GitHub repository</strong>\n <span class=\"erag-info__link-url\"\n >github.com/eramitgupta/text-editor-vue</span\n >\n </span>\n </a>\n <a\n class=\"erag-info__link\"\n href=\"https://erag.in/text-editor-vue\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n <EditorIcon\n class=\"erag-info__link-icon\"\n name=\"documentation\"\n :size=\"20\"\n />\n <span class=\"erag-info__link-content\">\n <strong class=\"erag-info__link-label\">Documentation</strong>\n <span class=\"erag-info__link-url\">erag.in/text-editor-vue</span>\n </span>\n </a>\n </div>\n </div>\n <dl\n v-else\n class=\"erag-shortcuts\"\n >\n <template\n v-for=\"entry in [\n ['Bold', 'Ctrl/⌘ B'],\n ['Italic', 'Ctrl/⌘ I'],\n ['Underline', 'Ctrl/⌘ U'],\n ['Undo', 'Ctrl/⌘ Z'],\n ['Redo', 'Ctrl/⌘ Shift Z'],\n ['Link', 'Ctrl/⌘ K'],\n ['Find', 'Ctrl/⌘ F'],\n ['Help', 'Alt 0'],\n ]\"\n :key=\"entry[0]\"\n ><dt>{{ entry[0] }}</dt>\n <dd>{{ entry[1] }}</dd></template\n >\n </dl>\n <template #footer\n ><button\n type=\"button\"\n class=\"erag-button erag-button--primary\"\n @click=\"$emit('close')\"\n >\n Close\n </button></template\n ></BaseDialog\n >\n</template>\n","<script setup lang=\"ts\">\nimport { reactive, shallowRef } from 'vue';\nimport type { LinkValue } from '../../types';\nimport { isSafeUrl } from '../../utils/url';\nimport BaseDialog from './BaseDialog.vue';\nconst props = defineProps<{ initial: LinkValue; allowRelative: boolean; canUnlink: boolean }>();\nconst emit = defineEmits<{ close: []; save: [value: LinkValue]; unlink: [] }>();\nconst form = reactive<LinkValue>({ ...props.initial });\nconst error = shallowRef('');\nfunction save(): void {\n if (!isSafeUrl(form.url, { allowRelative: props.allowRelative })) {\n error.value = 'Enter a safe HTTP, email, telephone, anchor, or allowed relative URL.';\n return;\n }\n emit('save', { ...form });\n}\n</script>\n<template>\n <BaseDialog\n title=\"Insert/edit link\"\n @close=\"emit('close')\"\n ><form\n class=\"erag-dialog__form\"\n @submit.prevent=\"save\"\n >\n <label class=\"erag-field\"\n ><span class=\"erag-field__label\">URL</span\n ><input\n v-model.trim=\"form.url\"\n class=\"erag-field__input\"\n required\n inputmode=\"url\" /></label\n ><label class=\"erag-field\"\n ><span class=\"erag-field__label\">Text to display</span\n ><input\n v-model=\"form.text\"\n class=\"erag-field__input\" /></label\n ><label class=\"erag-field\"\n ><span class=\"erag-field__label\">Title</span\n ><input\n v-model=\"form.title\"\n class=\"erag-field__input\" /></label\n ><label class=\"erag-field\"\n ><span class=\"erag-field__label\">Open link in</span\n ><select\n v-model=\"form.target\"\n class=\"erag-field__input\"\n >\n <option value=\"_self\">Current window</option>\n <option value=\"_blank\">New window</option>\n </select></label\n >\n <p\n v-if=\"error\"\n class=\"erag-field__error\"\n role=\"alert\"\n >\n {{ error }}\n </p>\n </form>\n <template #footer\n ><button\n v-if=\"canUnlink\"\n type=\"button\"\n class=\"erag-button erag-button--danger\"\n @click=\"emit('unlink')\"\n >\n Unlink</button\n ><span class=\"erag-dialog__spacer\" /><button\n type=\"button\"\n class=\"erag-button\"\n @click=\"emit('close')\"\n >\n Cancel</button\n ><button\n type=\"button\"\n class=\"erag-button erag-button--primary\"\n @click=\"save\"\n >\n Save\n </button></template\n ></BaseDialog\n >\n</template>\n","<script setup lang=\"ts\">\nimport { reactive, shallowRef } from 'vue';\nimport type { LinkValue } from '../../types';\nimport { isSafeUrl } from '../../utils/url';\nimport BaseDialog from './BaseDialog.vue';\nconst props = defineProps<{ initial: LinkValue; allowRelative: boolean; canUnlink: boolean }>();\nconst emit = defineEmits<{ close: []; save: [value: LinkValue]; unlink: [] }>();\nconst form = reactive<LinkValue>({ ...props.initial });\nconst error = shallowRef('');\nfunction save(): void {\n if (!isSafeUrl(form.url, { allowRelative: props.allowRelative })) {\n error.value = 'Enter a safe HTTP, email, telephone, anchor, or allowed relative URL.';\n return;\n }\n emit('save', { ...form });\n}\n</script>\n<template>\n <BaseDialog\n title=\"Insert/edit link\"\n @close=\"emit('close')\"\n ><form\n class=\"erag-dialog__form\"\n @submit.prevent=\"save\"\n >\n <label class=\"erag-field\"\n ><span class=\"erag-field__label\">URL</span\n ><input\n v-model.trim=\"form.url\"\n class=\"erag-field__input\"\n required\n inputmode=\"url\" /></label\n ><label class=\"erag-field\"\n ><span class=\"erag-field__label\">Text to display</span\n ><input\n v-model=\"form.text\"\n class=\"erag-field__input\" /></label\n ><label class=\"erag-field\"\n ><span class=\"erag-field__label\">Title</span\n ><input\n v-model=\"form.title\"\n class=\"erag-field__input\" /></label\n ><label class=\"erag-field\"\n ><span class=\"erag-field__label\">Open link in</span\n ><select\n v-model=\"form.target\"\n class=\"erag-field__input\"\n >\n <option value=\"_self\">Current window</option>\n <option value=\"_blank\">New window</option>\n </select></label\n >\n <p\n v-if=\"error\"\n class=\"erag-field__error\"\n role=\"alert\"\n >\n {{ error }}\n </p>\n </form>\n <template #footer\n ><button\n v-if=\"canUnlink\"\n type=\"button\"\n class=\"erag-button erag-button--danger\"\n @click=\"emit('unlink')\"\n >\n Unlink</button\n ><span class=\"erag-dialog__spacer\" /><button\n type=\"button\"\n class=\"erag-button\"\n @click=\"emit('close')\"\n >\n Cancel</button\n ><button\n type=\"button\"\n class=\"erag-button erag-button--primary\"\n @click=\"save\"\n >\n Save\n </button></template\n ></BaseDialog\n >\n</template>\n","<script setup lang=\"ts\">\nimport { reactive, shallowRef } from 'vue';\nimport type { MediaValue } from '../../types';\nimport { isSafeUrl } from '../../utils/url';\nimport BaseDialog from './BaseDialog.vue';\nconst props = defineProps<{ allowRelative: boolean }>();\nconst emit = defineEmits<{ close: []; save: [value: MediaValue] }>();\nconst form = reactive<MediaValue>({\n type: 'video',\n src: '',\n width: '640',\n height: '360',\n poster: '',\n});\nconst error = shallowRef('');\nfunction save(): void {\n if (\n !isSafeUrl(form.src, { allowRelative: props.allowRelative }) ||\n (form.type === 'iframe' && !/^https:\\/\\//i.test(form.src))\n ) {\n error.value = 'Enter a safe media URL. Embeds must use HTTPS.';\n return;\n }\n emit('save', { ...form });\n}\n</script>\n<template>\n <BaseDialog\n title=\"Insert media\"\n @close=\"emit('close')\"\n ><div class=\"erag-dialog__form\">\n <label class=\"erag-field\"\n ><span class=\"erag-field__label\">Media type</span\n ><select\n v-model=\"form.type\"\n class=\"erag-field__input\"\n >\n <option value=\"video\">Video</option>\n <option value=\"audio\">Audio</option>\n <option value=\"iframe\">Secure embed</option>\n </select></label\n ><label class=\"erag-field\"\n ><span class=\"erag-field__label\">Source URL</span\n ><input\n v-model.trim=\"form.src\"\n class=\"erag-field__input\"\n required\n /></label>\n <div\n v-if=\"form.type !== 'audio'\"\n class=\"erag-field__row\"\n >\n <label class=\"erag-field\"\n ><span class=\"erag-field__label\">Width</span\n ><input\n v-model=\"form.width\"\n class=\"erag-field__input\"\n type=\"number\" /></label\n ><label class=\"erag-field\"\n ><span class=\"erag-field__label\">Height</span\n ><input\n v-model=\"form.height\"\n class=\"erag-field__input\"\n type=\"number\"\n /></label>\n </div>\n <label\n v-if=\"form.type === 'video'\"\n class=\"erag-field\"\n ><span class=\"erag-field__label\">Poster image</span\n ><input\n v-model.trim=\"form.poster\"\n class=\"erag-field__input\"\n /></label>\n <p\n v-if=\"error\"\n class=\"erag-field__error\"\n >\n {{ error }}\n </p>\n </div>\n <template #footer\n ><button\n type=\"button\"\n class=\"erag-button\"\n @click=\"emit('close')\"\n >\n Cancel</button\n ><button\n type=\"button\"\n class=\"erag-button erag-button--primary\"\n @click=\"save\"\n >\n Save\n </button></template\n ></BaseDialog\n >\n</template>\n","<script setup lang=\"ts\">\nimport { reactive, shallowRef } from 'vue';\nimport type { MediaValue } from '../../types';\nimport { isSafeUrl } from '../../utils/url';\nimport BaseDialog from './BaseDialog.vue';\nconst props = defineProps<{ allowRelative: boolean }>();\nconst emit = defineEmits<{ close: []; save: [value: MediaValue] }>();\nconst form = reactive<MediaValue>({\n type: 'video',\n src: '',\n width: '640',\n height: '360',\n poster: '',\n});\nconst error = shallowRef('');\nfunction save(): void {\n if (\n !isSafeUrl(form.src, { allowRelative: props.allowRelative }) ||\n (form.type === 'iframe' && !/^https:\\/\\//i.test(form.src))\n ) {\n error.value = 'Enter a safe media URL. Embeds must use HTTPS.';\n return;\n }\n emit('save', { ...form });\n}\n</script>\n<template>\n <BaseDialog\n title=\"Insert media\"\n @close=\"emit('close')\"\n ><div class=\"erag-dialog__form\">\n <label class=\"erag-field\"\n ><span class=\"erag-field__label\">Media type</span\n ><select\n v-model=\"form.type\"\n class=\"erag-field__input\"\n >\n <option value=\"video\">Video</option>\n <option value=\"audio\">Audio</option>\n <option value=\"iframe\">Secure embed</option>\n </select></label\n ><label class=\"erag-field\"\n ><span class=\"erag-field__label\">Source URL</span\n ><input\n v-model.trim=\"form.src\"\n class=\"erag-field__input\"\n required\n /></label>\n <div\n v-if=\"form.type !== 'audio'\"\n class=\"erag-field__row\"\n >\n <label class=\"erag-field\"\n ><span class=\"erag-field__label\">Width</span\n ><input\n v-model=\"form.width\"\n class=\"erag-field__input\"\n type=\"number\" /></label\n ><label class=\"erag-field\"\n ><span class=\"erag-field__label\">Height</span\n ><input\n v-model=\"form.height\"\n class=\"erag-field__input\"\n type=\"number\"\n /></label>\n </div>\n <label\n v-if=\"form.type === 'video'\"\n class=\"erag-field\"\n ><span class=\"erag-field__label\">Poster image</span\n ><input\n v-model.trim=\"form.poster\"\n class=\"erag-field__input\"\n /></label>\n <p\n v-if=\"error\"\n class=\"erag-field__error\"\n >\n {{ error }}\n </p>\n </div>\n <template #footer\n ><button\n type=\"button\"\n class=\"erag-button\"\n @click=\"emit('close')\"\n >\n Cancel</button\n ><button\n type=\"button\"\n class=\"erag-button erag-button--primary\"\n @click=\"save\"\n >\n Save\n </button></template\n ></BaseDialog\n >\n</template>\n","<script setup lang=\"ts\">\nimport { useTemplateRef } from 'vue';\nimport { printEditorContent } from '../../commands/printCommands';\nimport BaseDialog from './BaseDialog.vue';\ndefineProps<{ html: string; contentStyle: string }>();\ndefineEmits<{ close: [] }>();\nconst preview = useTemplateRef<HTMLElement>('preview');\nfunction print(): void {\n if (preview.value) printEditorContent(preview.value);\n}\n</script>\n<template>\n <BaseDialog\n title=\"Preview\"\n wide\n @close=\"$emit('close')\"\n ><div\n ref=\"preview\"\n class=\"erag-preview\"\n :style=\"contentStyle\"\n v-html=\"html\"\n />\n <template #footer\n ><button\n type=\"button\"\n class=\"erag-button\"\n @click=\"print\"\n >\n Print</button\n ><button\n type=\"button\"\n class=\"erag-button erag-button--primary\"\n @click=\"$emit('close')\"\n >\n Close\n </button></template\n ></BaseDialog\n >\n</template>\n","<script setup lang=\"ts\">\nimport { useTemplateRef } from 'vue';\nimport { printEditorContent } from '../../commands/printCommands';\nimport BaseDialog from './BaseDialog.vue';\ndefineProps<{ html: string; contentStyle: string }>();\ndefineEmits<{ close: [] }>();\nconst preview = useTemplateRef<HTMLElement>('preview');\nfunction print(): void {\n if (preview.value) printEditorContent(preview.value);\n}\n</script>\n<template>\n <BaseDialog\n title=\"Preview\"\n wide\n @close=\"$emit('close')\"\n ><div\n ref=\"preview\"\n class=\"erag-preview\"\n :style=\"contentStyle\"\n v-html=\"html\"\n />\n <template #footer\n ><button\n type=\"button\"\n class=\"erag-button\"\n @click=\"print\"\n >\n Print</button\n ><button\n type=\"button\"\n class=\"erag-button erag-button--primary\"\n @click=\"$emit('close')\"\n >\n Close\n </button></template\n ></BaseDialog\n >\n</template>\n","<script setup lang=\"ts\">\nimport { shallowRef } from 'vue';\nimport BaseDialog from './BaseDialog.vue';\nconst props = defineProps<{ html: string }>();\nconst emit = defineEmits<{ close: []; save: [html: string] }>();\nconst source = shallowRef(props.html);\nfunction close(): void {\n emit('close');\n}\nfunction keydown(event: KeyboardEvent): void {\n if (event.key !== 'Tab') return;\n event.preventDefault();\n const target = event.target as HTMLTextAreaElement;\n const start = target.selectionStart;\n source.value = `${source.value.slice(0, start)} ${source.value.slice(target.selectionEnd)}`;\n requestAnimationFrame(() => target.setSelectionRange(start + 4, start + 4));\n}\n</script>\n<template>\n <BaseDialog\n title=\"Source code\"\n wide\n @close=\"close\"\n >\n <textarea\n v-model=\"source\"\n class=\"erag-source-editor\"\n spellcheck=\"false\"\n aria-label=\"HTML source\"\n @keydown=\"keydown\"\n /><template #footer\n ><button\n type=\"button\"\n class=\"erag-button\"\n @click=\"close\"\n >\n Cancel</button\n ><button\n type=\"button\"\n class=\"erag-button erag-button--primary\"\n @click=\"emit('save', source)\"\n >\n Apply\n </button></template\n ></BaseDialog\n >\n</template>\n","<script setup lang=\"ts\">\nimport { shallowRef } from 'vue';\nimport BaseDialog from './BaseDialog.vue';\nconst props = defineProps<{ html: string }>();\nconst emit = defineEmits<{ close: []; save: [html: string] }>();\nconst source = shallowRef(props.html);\nfunction close(): void {\n emit('close');\n}\nfunction keydown(event: KeyboardEvent): void {\n if (event.key !== 'Tab') return;\n event.preventDefault();\n const target = event.target as HTMLTextAreaElement;\n const start = target.selectionStart;\n source.value = `${source.value.slice(0, start)} ${source.value.slice(target.selectionEnd)}`;\n requestAnimationFrame(() => target.setSelectionRange(start + 4, start + 4));\n}\n</script>\n<template>\n <BaseDialog\n title=\"Source code\"\n wide\n @close=\"close\"\n >\n <textarea\n v-model=\"source\"\n class=\"erag-source-editor\"\n spellcheck=\"false\"\n aria-label=\"HTML source\"\n @keydown=\"keydown\"\n /><template #footer\n ><button\n type=\"button\"\n class=\"erag-button\"\n @click=\"close\"\n >\n Cancel</button\n ><button\n type=\"button\"\n class=\"erag-button erag-button--primary\"\n @click=\"emit('save', source)\"\n >\n Apply\n </button></template\n ></BaseDialog\n >\n</template>\n","import type { SpecialCharacterCategory, SpecialCharacterItem } from '../types';\n\nfunction characters(label: string, values: string): SpecialCharacterItem[] {\n return [...values].filter((value) => value !== ' ').map((value) => ({ value, label }));\n}\n\nconst currency: SpecialCharacterItem[] = [\n ...characters('Currency symbol', '$¢€£¥¤₠₡₢₣₤₥₦₧₨₩₪₫₭₮₯₰₱₲₳₴₵₶₷₸₹₺₼₽₾₿'),\n];\nconst text: SpecialCharacterItem[] = [...characters('Text symbol', '©®™℠℗§¶†‡•‣‧‰‱№℅ℓ℮℞ℹ')];\nconst quotations: SpecialCharacterItem[] = [...characters('Quotation mark', '‘’‚‛“”„‟‹›«»′″‴‵‶‷')];\nconst mathematical: SpecialCharacterItem[] = [\n ...characters('Mathematical symbol', '±×÷−√∞≈≠≤≥∑∏∫∂∆∇∈∉∋∅∧∨∩∪∝∠∴∵⊂⊃⊆⊇⊕⊗'),\n];\nconst extendedLatin: SpecialCharacterItem[] = [\n ...characters(\n 'Extended Latin character',\n 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ',\n ),\n];\nconst symbols: SpecialCharacterItem[] = [...characters('Symbol', '✓✔✕✖★☆♠♣♥♦♪♫☀☁☂☃☎⌛⌚⚑⚐⚠⚡')];\nconst arrows: SpecialCharacterItem[] = [...characters('Arrow', '←↑→↓↔↕↖↗↘↙⇐⇑⇒⇓⇔⇕➔➜➝➞➟➠')];\nconst greek: SpecialCharacterItem[] = [\n ...characters('Greek character', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψω'),\n];\n\nexport const SPECIAL_CHARACTER_CATEGORIES: SpecialCharacterCategory[] = [\n { name: 'Currency', items: currency },\n { name: 'Text', items: text },\n { name: 'Quotations', items: quotations },\n { name: 'Mathematical', items: mathematical },\n { name: 'Extended Latin', items: extendedLatin },\n { name: 'Symbols', items: symbols },\n { name: 'Arrows', items: arrows },\n { name: 'Greek', items: greek },\n];\n\nexport const ALL_SPECIAL_CHARACTERS = SPECIAL_CHARACTER_CATEGORIES.flatMap(\n (category) => category.items,\n);\n","<script setup lang=\"ts\">\nimport { computed, shallowRef } from 'vue';\nimport {\n ALL_SPECIAL_CHARACTERS,\n SPECIAL_CHARACTER_CATEGORIES,\n} from '../../constants/specialCharacters';\nimport BaseDialog from './BaseDialog.vue';\n\nconst emit = defineEmits<{ close: []; select: [value: string] }>();\nconst query = shallowRef('');\nconst category = shallowRef('All');\nconst categories = computed(() => [\n 'All',\n ...SPECIAL_CHARACTER_CATEGORIES.map((item) => item.name),\n]);\nconst symbols = computed(() => {\n const source =\n category.value === 'All'\n ? ALL_SPECIAL_CHARACTERS\n : (SPECIAL_CHARACTER_CATEGORIES.find((item) => item.name === category.value)?.items ??\n []);\n const search = query.value.trim().toLocaleLowerCase();\n return search\n ? source.filter(\n (item) =>\n item.value.includes(search) || item.label.toLocaleLowerCase().includes(search),\n )\n : source;\n});\n</script>\n\n<template>\n <BaseDialog\n title=\"Special Character\"\n @close=\"emit('close')\"\n >\n <div class=\"erag-character-dialog\">\n <div\n class=\"erag-character-dialog__categories\"\n role=\"tablist\"\n aria-label=\"Special character categories\"\n >\n <button\n v-for=\"name in categories\"\n :key=\"name\"\n type=\"button\"\n class=\"erag-character-dialog__category\"\n :class=\"{ 'erag-is-active': category === name }\"\n role=\"tab\"\n :aria-selected=\"category === name\"\n @click=\"category = name\"\n >\n {{ name }}\n </button>\n </div>\n <div class=\"erag-character-dialog__content\">\n <label class=\"erag-character-dialog__search\">\n <span class=\"erag-character-dialog__search-label\">Search</span>\n <input\n v-model=\"query\"\n class=\"erag-field__input\"\n type=\"search\"\n placeholder=\"Search\"\n />\n </label>\n <div\n class=\"erag-character-dialog__grid\"\n role=\"tabpanel\"\n >\n <button\n v-for=\"(symbol, index) in symbols\"\n :key=\"`${symbol.value}-${index}`\"\n type=\"button\"\n class=\"erag-character-dialog__symbol\"\n :aria-label=\"`Insert ${symbol.label}: ${symbol.value}`\"\n :title=\"symbol.label\"\n @click=\"emit('select', symbol.value)\"\n >\n {{ symbol.value }}\n </button>\n <p\n v-if=\"symbols.length === 0\"\n class=\"erag-character-dialog__empty\"\n >\n No characters found\n </p>\n </div>\n </div>\n </div>\n <template #footer>\n <button\n type=\"button\"\n class=\"erag-button erag-button--primary\"\n @click=\"emit('close')\"\n >\n Close\n </button>\n </template>\n </BaseDialog>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, shallowRef } from 'vue';\nimport {\n ALL_SPECIAL_CHARACTERS,\n SPECIAL_CHARACTER_CATEGORIES,\n} from '../../constants/specialCharacters';\nimport BaseDialog from './BaseDialog.vue';\n\nconst emit = defineEmits<{ close: []; select: [value: string] }>();\nconst query = shallowRef('');\nconst category = shallowRef('All');\nconst categories = computed(() => [\n 'All',\n ...SPECIAL_CHARACTER_CATEGORIES.map((item) => item.name),\n]);\nconst symbols = computed(() => {\n const source =\n category.value === 'All'\n ? ALL_SPECIAL_CHARACTERS\n : (SPECIAL_CHARACTER_CATEGORIES.find((item) => item.name === category.value)?.items ??\n []);\n const search = query.value.trim().toLocaleLowerCase();\n return search\n ? source.filter(\n (item) =>\n item.value.includes(search) || item.label.toLocaleLowerCase().includes(search),\n )\n : source;\n});\n</script>\n\n<template>\n <BaseDialog\n title=\"Special Character\"\n @close=\"emit('close')\"\n >\n <div class=\"erag-character-dialog\">\n <div\n class=\"erag-character-dialog__categories\"\n role=\"tablist\"\n aria-label=\"Special character categories\"\n >\n <button\n v-for=\"name in categories\"\n :key=\"name\"\n type=\"button\"\n class=\"erag-character-dialog__category\"\n :class=\"{ 'erag-is-active': category === name }\"\n role=\"tab\"\n :aria-selected=\"category === name\"\n @click=\"category = name\"\n >\n {{ name }}\n </button>\n </div>\n <div class=\"erag-character-dialog__content\">\n <label class=\"erag-character-dialog__search\">\n <span class=\"erag-character-dialog__search-label\">Search</span>\n <input\n v-model=\"query\"\n class=\"erag-field__input\"\n type=\"search\"\n placeholder=\"Search\"\n />\n </label>\n <div\n class=\"erag-character-dialog__grid\"\n role=\"tabpanel\"\n >\n <button\n v-for=\"(symbol, index) in symbols\"\n :key=\"`${symbol.value}-${index}`\"\n type=\"button\"\n class=\"erag-character-dialog__symbol\"\n :aria-label=\"`Insert ${symbol.label}: ${symbol.value}`\"\n :title=\"symbol.label\"\n @click=\"emit('select', symbol.value)\"\n >\n {{ symbol.value }}\n </button>\n <p\n v-if=\"symbols.length === 0\"\n class=\"erag-character-dialog__empty\"\n >\n No characters found\n </p>\n </div>\n </div>\n </div>\n <template #footer>\n <button\n type=\"button\"\n class=\"erag-button erag-button--primary\"\n @click=\"emit('close')\"\n >\n Close\n </button>\n </template>\n </BaseDialog>\n</template>\n","<script setup lang=\"ts\">\nimport { shallowRef } from 'vue';\nimport BaseDialog from './BaseDialog.vue';\nconst props = defineProps<{ size: number }>();\nconst emit = defineEmits<{ close: []; save: [rows: number, columns: number] }>();\nconst rows = shallowRef(2);\nconst columns = shallowRef(2);\n</script>\n<template>\n <BaseDialog\n title=\"Insert table\"\n @close=\"emit('close')\"\n ><div\n class=\"erag-table-grid\"\n role=\"grid\"\n :aria-label=\"`${rows} by ${columns} table`\"\n >\n <button\n v-for=\"index in props.size * props.size\"\n :key=\"index\"\n type=\"button\"\n class=\"erag-table-grid__cell\"\n :class=\"{\n 'erag-is-active':\n Math.ceil(index / props.size) <= rows &&\n ((index - 1) % props.size) + 1 <= columns,\n }\"\n :aria-label=\"`${Math.ceil(index / props.size)} rows by ${((index - 1) % props.size) + 1} columns`\"\n @mouseenter=\"\n rows = Math.ceil(index / props.size);\n columns = ((index - 1) % props.size) + 1;\n \"\n @click=\"emit('save', rows, columns)\"\n />\n </div>\n <p class=\"erag-table-grid__label\">{{ rows }} × {{ columns }}</p>\n <template #footer\n ><button\n type=\"button\"\n class=\"erag-button\"\n @click=\"emit('close')\"\n >\n Cancel</button\n ><button\n type=\"button\"\n class=\"erag-button erag-button--primary\"\n @click=\"emit('save', rows, columns)\"\n >\n Insert\n </button></template\n ></BaseDialog\n >\n</template>\n","<script setup lang=\"ts\">\nimport { shallowRef } from 'vue';\nimport BaseDialog from './BaseDialog.vue';\nconst props = defineProps<{ size: number }>();\nconst emit = defineEmits<{ close: []; save: [rows: number, columns: number] }>();\nconst rows = shallowRef(2);\nconst columns = shallowRef(2);\n</script>\n<template>\n <BaseDialog\n title=\"Insert table\"\n @close=\"emit('close')\"\n ><div\n class=\"erag-table-grid\"\n role=\"grid\"\n :aria-label=\"`${rows} by ${columns} table`\"\n >\n <button\n v-for=\"index in props.size * props.size\"\n :key=\"index\"\n type=\"button\"\n class=\"erag-table-grid__cell\"\n :class=\"{\n 'erag-is-active':\n Math.ceil(index / props.size) <= rows &&\n ((index - 1) % props.size) + 1 <= columns,\n }\"\n :aria-label=\"`${Math.ceil(index / props.size)} rows by ${((index - 1) % props.size) + 1} columns`\"\n @mouseenter=\"\n rows = Math.ceil(index / props.size);\n columns = ((index - 1) % props.size) + 1;\n \"\n @click=\"emit('save', rows, columns)\"\n />\n </div>\n <p class=\"erag-table-grid__label\">{{ rows }} × {{ columns }}</p>\n <template #footer\n ><button\n type=\"button\"\n class=\"erag-button\"\n @click=\"emit('close')\"\n >\n Cancel</button\n ><button\n type=\"button\"\n class=\"erag-button erag-button--primary\"\n @click=\"emit('save', rows, columns)\"\n >\n Insert\n </button></template\n ></BaseDialog\n >\n</template>\n","<script setup lang=\"ts\">\nimport { reactive } from 'vue';\nimport BaseDialog from './BaseDialog.vue';\nconst emit = defineEmits<{ close: []; save: [values: Record<string, string>] }>();\nconst form = reactive({\n width: '100%',\n cellPadding: '8px',\n borderWidth: '1px',\n borderStyle: 'solid',\n borderColor: '#d9dce1',\n backgroundColor: '#ffffff',\n alignment: 'left',\n});\n</script>\n<template>\n <BaseDialog\n title=\"Table properties\"\n @close=\"emit('close')\"\n ><div class=\"erag-dialog__form erag-dialog__form--grid\">\n <label\n v-for=\"field in [\n 'width',\n 'cellPadding',\n 'borderWidth',\n 'borderColor',\n 'backgroundColor',\n ]\"\n :key=\"field\"\n class=\"erag-field\"\n ><span class=\"erag-field__label\">{{ field }}</span\n ><input\n v-model=\"form[field as keyof typeof form]\"\n class=\"erag-field__input\"\n :type=\"field.includes('Color') ? 'color' : 'text'\" /></label\n ><label class=\"erag-field\"\n ><span class=\"erag-field__label\">Border style</span\n ><select\n v-model=\"form.borderStyle\"\n class=\"erag-field__input\"\n >\n <option>solid</option>\n <option>dashed</option>\n <option>dotted</option>\n <option>double</option>\n <option>none</option>\n </select></label\n ><label class=\"erag-field\"\n ><span class=\"erag-field__label\">Alignment</span\n ><select\n v-model=\"form.alignment\"\n class=\"erag-field__input\"\n >\n <option>left</option>\n <option>center</option>\n <option>right</option>\n </select></label\n >\n </div>\n <template #footer\n ><button\n type=\"button\"\n class=\"erag-button\"\n @click=\"emit('close')\"\n >\n Cancel</button\n ><button\n type=\"button\"\n class=\"erag-button erag-button--primary\"\n @click=\"emit('save', { ...form })\"\n >\n Apply\n </button></template\n ></BaseDialog\n >\n</template>\n","<script setup lang=\"ts\">\nimport { reactive } from 'vue';\nimport BaseDialog from './BaseDialog.vue';\nconst emit = defineEmits<{ close: []; save: [values: Record<string, string>] }>();\nconst form = reactive({\n width: '100%',\n cellPadding: '8px',\n borderWidth: '1px',\n borderStyle: 'solid',\n borderColor: '#d9dce1',\n backgroundColor: '#ffffff',\n alignment: 'left',\n});\n</script>\n<template>\n <BaseDialog\n title=\"Table properties\"\n @close=\"emit('close')\"\n ><div class=\"erag-dialog__form erag-dialog__form--grid\">\n <label\n v-for=\"field in [\n 'width',\n 'cellPadding',\n 'borderWidth',\n 'borderColor',\n 'backgroundColor',\n ]\"\n :key=\"field\"\n class=\"erag-field\"\n ><span class=\"erag-field__label\">{{ field }}</span\n ><input\n v-model=\"form[field as keyof typeof form]\"\n class=\"erag-field__input\"\n :type=\"field.includes('Color') ? 'color' : 'text'\" /></label\n ><label class=\"erag-field\"\n ><span class=\"erag-field__label\">Border style</span\n ><select\n v-model=\"form.borderStyle\"\n class=\"erag-field__input\"\n >\n <option>solid</option>\n <option>dashed</option>\n <option>dotted</option>\n <option>double</option>\n <option>none</option>\n </select></label\n ><label class=\"erag-field\"\n ><span class=\"erag-field__label\">Alignment</span\n ><select\n v-model=\"form.alignment\"\n class=\"erag-field__input\"\n >\n <option>left</option>\n <option>center</option>\n <option>right</option>\n </select></label\n >\n </div>\n <template #footer\n ><button\n type=\"button\"\n class=\"erag-button\"\n @click=\"emit('close')\"\n >\n Cancel</button\n ><button\n type=\"button\"\n class=\"erag-button erag-button--primary\"\n @click=\"emit('save', { ...form })\"\n >\n Apply\n </button></template\n ></BaseDialog\n >\n</template>\n","<script setup lang=\"ts\">\nimport { computed, shallowRef, watch } from 'vue';\nimport type {\n EditorTemplateItem,\n ResolvedEditorInit,\n ResolvedEditorTemplatesConfig,\n} from '../../types';\nimport { sanitizeHtml } from '../../utils/sanitizer';\nimport BaseDialog from './BaseDialog.vue';\n\nconst props = defineProps<{\n templates: ResolvedEditorTemplatesConfig;\n config: ResolvedEditorInit;\n}>();\nconst emit = defineEmits<{\n close: [];\n insert: [item: EditorTemplateItem];\n}>();\nconst search = shallowRef('');\nconst selectedId = shallowRef<string | number | null>(null);\nconst filteredItems = computed(() => {\n const query = search.value.trim().toLocaleLowerCase();\n if (!query) return props.templates.items;\n return props.templates.items.filter((item) =>\n [item.label, item.description, item.group]\n .filter((value): value is string => Boolean(value))\n .some((value) => value.toLocaleLowerCase().includes(query)),\n );\n});\nconst groups = computed(() => {\n const result = new Map<string, EditorTemplateItem[]>();\n for (const item of filteredItems.value) {\n const group = item.group?.trim() || 'General';\n const items = result.get(group) ?? [];\n items.push(item);\n result.set(group, items);\n }\n return [...result].map(([label, items]) => ({ label, items }));\n});\nconst selected = computed(\n () => props.templates.items.find((item) => item.id === selectedId.value) ?? null,\n);\nconst previewHtml = computed(() =>\n selected.value\n ? sanitizeHtml(selected.value.content, {\n allowedTags: props.config.allowedTags,\n allowedAttributes: props.config.allowedAttributes,\n allowRelativeUrls: props.config.relativeUrls,\n })\n : '',\n);\n\nwatch(\n filteredItems,\n (items) => {\n if (!items.some((item) => item.id === selectedId.value)) {\n selectedId.value = items[0]?.id ?? null;\n }\n },\n { immediate: true },\n);\n\nfunction insert(): void {\n if (selected.value) emit('insert', selected.value);\n}\n</script>\n\n<template>\n <BaseDialog\n title=\"Templates\"\n wide\n :footer-divider=\"false\"\n @close=\"emit('close')\"\n >\n <div class=\"erag-template-dialog\">\n <aside class=\"erag-template-dialog__sidebar\">\n <label class=\"erag-template-dialog__search\">\n <span class=\"erag-template-dialog__search-label\">Search templates</span>\n <input\n v-model=\"search\"\n type=\"search\"\n class=\"erag-template-dialog__search-input\"\n placeholder=\"Search\"\n />\n </label>\n <div class=\"erag-template-dialog__groups\">\n <section\n v-for=\"group in groups\"\n :key=\"group.label\"\n class=\"erag-template-dialog__group\"\n >\n <h3 class=\"erag-template-dialog__group-title\">{{ group.label }}</h3>\n <button\n v-for=\"item in group.items\"\n :key=\"item.id\"\n type=\"button\"\n class=\"erag-template-dialog__item\"\n :class=\"{ 'erag-is-active': item.id === selectedId }\"\n :aria-pressed=\"item.id === selectedId\"\n @click=\"selectedId = item.id\"\n @dblclick=\"emit('insert', item)\"\n >\n <span class=\"erag-template-dialog__item-label\">{{ item.label }}</span>\n <span\n v-if=\"item.description\"\n class=\"erag-template-dialog__item-description\"\n >{{ item.description }}</span\n >\n </button>\n </section>\n <p\n v-if=\"groups.length === 0\"\n class=\"erag-template-dialog__empty\"\n >\n No templates found\n </p>\n </div>\n </aside>\n <section\n class=\"erag-template-dialog__preview\"\n aria-label=\"Template preview\"\n >\n <div\n v-if=\"selected\"\n class=\"erag-template-dialog__preview-content\"\n v-html=\"previewHtml\"\n />\n <p\n v-else\n class=\"erag-template-dialog__empty\"\n >\n Select a template to preview it\n </p>\n </section>\n </div>\n <template #footer>\n <button\n type=\"button\"\n class=\"erag-button\"\n @click=\"emit('close')\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n class=\"erag-button erag-button--primary\"\n :disabled=\"!selected\"\n @click=\"insert\"\n >\n Insert\n </button>\n </template>\n </BaseDialog>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, shallowRef, watch } from 'vue';\nimport type {\n EditorTemplateItem,\n ResolvedEditorInit,\n ResolvedEditorTemplatesConfig,\n} from '../../types';\nimport { sanitizeHtml } from '../../utils/sanitizer';\nimport BaseDialog from './BaseDialog.vue';\n\nconst props = defineProps<{\n templates: ResolvedEditorTemplatesConfig;\n config: ResolvedEditorInit;\n}>();\nconst emit = defineEmits<{\n close: [];\n insert: [item: EditorTemplateItem];\n}>();\nconst search = shallowRef('');\nconst selectedId = shallowRef<string | number | null>(null);\nconst filteredItems = computed(() => {\n const query = search.value.trim().toLocaleLowerCase();\n if (!query) return props.templates.items;\n return props.templates.items.filter((item) =>\n [item.label, item.description, item.group]\n .filter((value): value is string => Boolean(value))\n .some((value) => value.toLocaleLowerCase().includes(query)),\n );\n});\nconst groups = computed(() => {\n const result = new Map<string, EditorTemplateItem[]>();\n for (const item of filteredItems.value) {\n const group = item.group?.trim() || 'General';\n const items = result.get(group) ?? [];\n items.push(item);\n result.set(group, items);\n }\n return [...result].map(([label, items]) => ({ label, items }));\n});\nconst selected = computed(\n () => props.templates.items.find((item) => item.id === selectedId.value) ?? null,\n);\nconst previewHtml = computed(() =>\n selected.value\n ? sanitizeHtml(selected.value.content, {\n allowedTags: props.config.allowedTags,\n allowedAttributes: props.config.allowedAttributes,\n allowRelativeUrls: props.config.relativeUrls,\n })\n : '',\n);\n\nwatch(\n filteredItems,\n (items) => {\n if (!items.some((item) => item.id === selectedId.value)) {\n selectedId.value = items[0]?.id ?? null;\n }\n },\n { immediate: true },\n);\n\nfunction insert(): void {\n if (selected.value) emit('insert', selected.value);\n}\n</script>\n\n<template>\n <BaseDialog\n title=\"Templates\"\n wide\n :footer-divider=\"false\"\n @close=\"emit('close')\"\n >\n <div class=\"erag-template-dialog\">\n <aside class=\"erag-template-dialog__sidebar\">\n <label class=\"erag-template-dialog__search\">\n <span class=\"erag-template-dialog__search-label\">Search templates</span>\n <input\n v-model=\"search\"\n type=\"search\"\n class=\"erag-template-dialog__search-input\"\n placeholder=\"Search\"\n />\n </label>\n <div class=\"erag-template-dialog__groups\">\n <section\n v-for=\"group in groups\"\n :key=\"group.label\"\n class=\"erag-template-dialog__group\"\n >\n <h3 class=\"erag-template-dialog__group-title\">{{ group.label }}</h3>\n <button\n v-for=\"item in group.items\"\n :key=\"item.id\"\n type=\"button\"\n class=\"erag-template-dialog__item\"\n :class=\"{ 'erag-is-active': item.id === selectedId }\"\n :aria-pressed=\"item.id === selectedId\"\n @click=\"selectedId = item.id\"\n @dblclick=\"emit('insert', item)\"\n >\n <span class=\"erag-template-dialog__item-label\">{{ item.label }}</span>\n <span\n v-if=\"item.description\"\n class=\"erag-template-dialog__item-description\"\n >{{ item.description }}</span\n >\n </button>\n </section>\n <p\n v-if=\"groups.length === 0\"\n class=\"erag-template-dialog__empty\"\n >\n No templates found\n </p>\n </div>\n </aside>\n <section\n class=\"erag-template-dialog__preview\"\n aria-label=\"Template preview\"\n >\n <div\n v-if=\"selected\"\n class=\"erag-template-dialog__preview-content\"\n v-html=\"previewHtml\"\n />\n <p\n v-else\n class=\"erag-template-dialog__empty\"\n >\n Select a template to preview it\n </p>\n </section>\n </div>\n <template #footer>\n <button\n type=\"button\"\n class=\"erag-button\"\n @click=\"emit('close')\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n class=\"erag-button erag-button--primary\"\n :disabled=\"!selected\"\n @click=\"insert\"\n >\n Insert\n </button>\n </template>\n </BaseDialog>\n</template>\n","<script setup lang=\"ts\">\nimport type { WordCountData } from '../../types';\nimport BaseDialog from './BaseDialog.vue';\n\ndefineProps<{ counts: WordCountData }>();\ndefineEmits<{ close: [] }>();\n</script>\n\n<template>\n <BaseDialog\n title=\"Word Count\"\n :footer-divider=\"false\"\n @close=\"$emit('close')\"\n >\n <table class=\"erag-word-count__table\">\n <thead>\n <tr>\n <th class=\"erag-word-count__heading erag-word-count__heading--label\">Count</th>\n <th class=\"erag-word-count__heading\">Document</th>\n <th class=\"erag-word-count__heading\">Selection</th>\n </tr>\n </thead>\n <tbody>\n <tr class=\"erag-word-count__row\">\n <th class=\"erag-word-count__label\">Words</th>\n <td class=\"erag-word-count__value\">{{ counts.document.words }}</td>\n <td class=\"erag-word-count__value\">{{ counts.selection.words }}</td>\n </tr>\n <tr class=\"erag-word-count__row\">\n <th class=\"erag-word-count__label\">Characters (no spaces)</th>\n <td class=\"erag-word-count__value\">\n {{ counts.document.charactersWithoutSpaces }}\n </td>\n <td class=\"erag-word-count__value\">\n {{ counts.selection.charactersWithoutSpaces }}\n </td>\n </tr>\n <tr class=\"erag-word-count__row\">\n <th class=\"erag-word-count__label\">Characters</th>\n <td class=\"erag-word-count__value\">{{ counts.document.characters }}</td>\n <td class=\"erag-word-count__value\">{{ counts.selection.characters }}</td>\n </tr>\n </tbody>\n </table>\n <template #footer>\n <button\n type=\"button\"\n class=\"erag-button erag-button--primary\"\n @click=\"$emit('close')\"\n >\n Close\n </button>\n </template>\n </BaseDialog>\n</template>\n","<script setup lang=\"ts\">\nimport type { WordCountData } from '../../types';\nimport BaseDialog from './BaseDialog.vue';\n\ndefineProps<{ counts: WordCountData }>();\ndefineEmits<{ close: [] }>();\n</script>\n\n<template>\n <BaseDialog\n title=\"Word Count\"\n :footer-divider=\"false\"\n @close=\"$emit('close')\"\n >\n <table class=\"erag-word-count__table\">\n <thead>\n <tr>\n <th class=\"erag-word-count__heading erag-word-count__heading--label\">Count</th>\n <th class=\"erag-word-count__heading\">Document</th>\n <th class=\"erag-word-count__heading\">Selection</th>\n </tr>\n </thead>\n <tbody>\n <tr class=\"erag-word-count__row\">\n <th class=\"erag-word-count__label\">Words</th>\n <td class=\"erag-word-count__value\">{{ counts.document.words }}</td>\n <td class=\"erag-word-count__value\">{{ counts.selection.words }}</td>\n </tr>\n <tr class=\"erag-word-count__row\">\n <th class=\"erag-word-count__label\">Characters (no spaces)</th>\n <td class=\"erag-word-count__value\">\n {{ counts.document.charactersWithoutSpaces }}\n </td>\n <td class=\"erag-word-count__value\">\n {{ counts.selection.charactersWithoutSpaces }}\n </td>\n </tr>\n <tr class=\"erag-word-count__row\">\n <th class=\"erag-word-count__label\">Characters</th>\n <td class=\"erag-word-count__value\">{{ counts.document.characters }}</td>\n <td class=\"erag-word-count__value\">{{ counts.selection.characters }}</td>\n </tr>\n </tbody>\n </table>\n <template #footer>\n <button\n type=\"button\"\n class=\"erag-button erag-button--primary\"\n @click=\"$emit('close')\"\n >\n Close\n </button>\n </template>\n </BaseDialog>\n</template>\n","<script setup lang=\"ts\">\nimport type { EditorDialogsEmits, EditorDialogsProps } from '../types';\nimport ColorDialog from './dialogs/ColorDialog.vue';\nimport EmojiDialog from './dialogs/EmojiDialog.vue';\nimport FindReplaceDialog from './dialogs/FindReplaceDialog.vue';\nimport InfoDialog from './dialogs/InfoDialog.vue';\nimport LinkDialog from './dialogs/LinkDialog.vue';\nimport MediaDialog from './dialogs/MediaDialog.vue';\nimport PreviewDialog from './dialogs/PreviewDialog.vue';\nimport SourceDialog from './dialogs/SourceDialog.vue';\nimport SpecialCharacterDialog from './dialogs/SpecialCharacterDialog.vue';\nimport TableDialog from './dialogs/TableDialog.vue';\nimport TablePropertiesDialog from './dialogs/TablePropertiesDialog.vue';\nimport TemplateDialog from './dialogs/TemplateDialog.vue';\nimport WordCountDialog from './dialogs/WordCountDialog.vue';\n\ndefineProps<EditorDialogsProps>();\ndefineEmits<EditorDialogsEmits>();\n</script>\n\n<template>\n <LinkDialog\n v-if=\"dialog === 'link'\"\n :initial=\"linkInitial\"\n :allow-relative=\"config.relativeUrls\"\n :can-unlink=\"Boolean(linkInitial.url)\"\n @close=\"$emit('close')\"\n @save=\"$emit('saveLink', $event)\"\n @unlink=\"$emit('unlink')\"\n />\n <MediaDialog\n v-if=\"dialog === 'media'\"\n :allow-relative=\"config.relativeUrls\"\n @close=\"$emit('close')\"\n @save=\"$emit('saveMedia', $event)\"\n />\n <TableDialog\n v-if=\"dialog === 'table'\"\n :size=\"config.tableGridSize\"\n @close=\"$emit('close')\"\n @save=\"(rows, columns) => $emit('saveTable', rows, columns)\"\n />\n <SpecialCharacterDialog\n v-if=\"dialog === 'special-character'\"\n @close=\"$emit('close')\"\n @select=\"$emit('selectCharacter', $event)\"\n />\n <EmojiDialog\n v-if=\"dialog === 'emoji'\"\n @close=\"$emit('close')\"\n @select=\"$emit('selectCharacter', $event)\"\n />\n <SourceDialog\n v-if=\"dialog === 'source'\"\n :html=\"html\"\n @close=\"$emit('close')\"\n @save=\"$emit('saveSource', $event)\"\n />\n <PreviewDialog\n v-if=\"dialog === 'preview'\"\n :html=\"previewHtml\"\n :content-style=\"config.contentStyle\"\n @close=\"$emit('close')\"\n />\n <FindReplaceDialog\n v-if=\"dialog === 'find-replace' && root\"\n :root=\"root\"\n @close=\"$emit('close')\"\n @changed=\"$emit('changed')\"\n />\n <InfoDialog\n v-if=\"dialog === 'shortcuts' || dialog === 'about'\"\n :kind=\"dialog\"\n @close=\"$emit('close')\"\n />\n <WordCountDialog\n v-if=\"dialog === 'word-count'\"\n :counts=\"wordCountData\"\n @close=\"$emit('close')\"\n />\n <TablePropertiesDialog\n v-if=\"dialog === 'table-properties'\"\n @close=\"$emit('close')\"\n @save=\"$emit('saveTableProperties', $event)\"\n />\n <TemplateDialog\n v-if=\"dialog === 'templates'\"\n :templates=\"config.templates\"\n :config=\"config\"\n @close=\"$emit('close')\"\n @insert=\"$emit('insertTemplate', $event)\"\n />\n <ColorDialog\n v-if=\"dialogMode\"\n :mode=\"dialogMode\"\n :colors=\"dialogMode === 'forecolor' ? config.textColors : config.backgroundColors\"\n @close=\"$emit('close')\"\n @select=\"$emit('selectColor', $event)\"\n />\n</template>\n","<script setup lang=\"ts\">\nimport type { EditorDialogsEmits, EditorDialogsProps } from '../types';\nimport ColorDialog from './dialogs/ColorDialog.vue';\nimport EmojiDialog from './dialogs/EmojiDialog.vue';\nimport FindReplaceDialog from './dialogs/FindReplaceDialog.vue';\nimport InfoDialog from './dialogs/InfoDialog.vue';\nimport LinkDialog from './dialogs/LinkDialog.vue';\nimport MediaDialog from './dialogs/MediaDialog.vue';\nimport PreviewDialog from './dialogs/PreviewDialog.vue';\nimport SourceDialog from './dialogs/SourceDialog.vue';\nimport SpecialCharacterDialog from './dialogs/SpecialCharacterDialog.vue';\nimport TableDialog from './dialogs/TableDialog.vue';\nimport TablePropertiesDialog from './dialogs/TablePropertiesDialog.vue';\nimport TemplateDialog from './dialogs/TemplateDialog.vue';\nimport WordCountDialog from './dialogs/WordCountDialog.vue';\n\ndefineProps<EditorDialogsProps>();\ndefineEmits<EditorDialogsEmits>();\n</script>\n\n<template>\n <LinkDialog\n v-if=\"dialog === 'link'\"\n :initial=\"linkInitial\"\n :allow-relative=\"config.relativeUrls\"\n :can-unlink=\"Boolean(linkInitial.url)\"\n @close=\"$emit('close')\"\n @save=\"$emit('saveLink', $event)\"\n @unlink=\"$emit('unlink')\"\n />\n <MediaDialog\n v-if=\"dialog === 'media'\"\n :allow-relative=\"config.relativeUrls\"\n @close=\"$emit('close')\"\n @save=\"$emit('saveMedia', $event)\"\n />\n <TableDialog\n v-if=\"dialog === 'table'\"\n :size=\"config.tableGridSize\"\n @close=\"$emit('close')\"\n @save=\"(rows, columns) => $emit('saveTable', rows, columns)\"\n />\n <SpecialCharacterDialog\n v-if=\"dialog === 'special-character'\"\n @close=\"$emit('close')\"\n @select=\"$emit('selectCharacter', $event)\"\n />\n <EmojiDialog\n v-if=\"dialog === 'emoji'\"\n @close=\"$emit('close')\"\n @select=\"$emit('selectCharacter', $event)\"\n />\n <SourceDialog\n v-if=\"dialog === 'source'\"\n :html=\"html\"\n @close=\"$emit('close')\"\n @save=\"$emit('saveSource', $event)\"\n />\n <PreviewDialog\n v-if=\"dialog === 'preview'\"\n :html=\"previewHtml\"\n :content-style=\"config.contentStyle\"\n @close=\"$emit('close')\"\n />\n <FindReplaceDialog\n v-if=\"dialog === 'find-replace' && root\"\n :root=\"root\"\n @close=\"$emit('close')\"\n @changed=\"$emit('changed')\"\n />\n <InfoDialog\n v-if=\"dialog === 'shortcuts' || dialog === 'about'\"\n :kind=\"dialog\"\n @close=\"$emit('close')\"\n />\n <WordCountDialog\n v-if=\"dialog === 'word-count'\"\n :counts=\"wordCountData\"\n @close=\"$emit('close')\"\n />\n <TablePropertiesDialog\n v-if=\"dialog === 'table-properties'\"\n @close=\"$emit('close')\"\n @save=\"$emit('saveTableProperties', $event)\"\n />\n <TemplateDialog\n v-if=\"dialog === 'templates'\"\n :templates=\"config.templates\"\n :config=\"config\"\n @close=\"$emit('close')\"\n @insert=\"$emit('insertTemplate', $event)\"\n />\n <ColorDialog\n v-if=\"dialogMode\"\n :mode=\"dialogMode\"\n :colors=\"dialogMode === 'forecolor' ? config.textColors : config.backgroundColors\"\n @close=\"$emit('close')\"\n @select=\"$emit('selectColor', $event)\"\n />\n</template>\n","import type { MenuDefinition, MenuItemDefinition } from '../types';\n\nconst separator = (id: string): MenuItemDefinition => ({ id, label: '', separator: true });\nconst blocks: MenuItemDefinition[] = [\n 'p',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'pre',\n 'blockquote',\n].map((value) => ({\n id: `block-${value}`,\n label:\n value === 'p'\n ? 'Paragraph'\n : value === 'pre'\n ? 'Preformatted'\n : value === 'blockquote'\n ? 'Blockquote'\n : `Heading ${value.slice(1)}`,\n command: 'formatBlock',\n value,\n}));\nconst align: MenuItemDefinition[] = [\n { id: 'align-left', label: 'Left', command: 'alignleft' },\n { id: 'align-center', label: 'Center', command: 'aligncenter' },\n { id: 'align-right', label: 'Right', command: 'alignright' },\n { id: 'align-justify', label: 'Justify', command: 'alignjustify' },\n];\nconst inline: MenuItemDefinition[] = [\n { id: 'bold', label: 'Bold', command: 'bold', shortcut: 'Ctrl+B' },\n { id: 'italic', label: 'Italic', command: 'italic', shortcut: 'Ctrl+I' },\n { id: 'underline', label: 'Underline', command: 'underline', shortcut: 'Ctrl+U' },\n { id: 'strike', label: 'Strikethrough', command: 'strikethrough' },\n { id: 'sup', label: 'Superscript', command: 'superscript' },\n { id: 'sub', label: 'Subscript', command: 'subscript' },\n { id: 'inline-code', label: 'Inline code', command: 'inlineCode' },\n];\nconst changeCase: MenuItemDefinition[] = [\n { id: 'case-lowercase', label: 'lowercase', command: 'changeCase', value: 'lowercase' },\n { id: 'case-uppercase', label: 'UPPERCASE', command: 'changeCase', value: 'uppercase' },\n { id: 'case-title', label: 'Title Case', command: 'changeCase', value: 'titlecase' },\n];\n\nexport const MENU_DEFINITIONS: MenuDefinition[] = [\n {\n name: 'file',\n label: 'File',\n icon: 'file',\n items: [\n { id: 'new', label: 'New document', command: 'new' },\n { id: 'preview', label: 'Preview', dialog: 'preview', plugin: 'preview' },\n { id: 'print', label: 'Print', command: 'print' },\n ],\n },\n {\n name: 'edit',\n label: 'Edit',\n icon: 'edit',\n items: [\n { id: 'undo', label: 'Undo', command: 'undo', shortcut: 'Ctrl+Z' },\n { id: 'redo', label: 'Redo', command: 'redo', shortcut: 'Ctrl+Y' },\n separator('edit-1'),\n { id: 'cut', label: 'Cut', command: 'cut', shortcut: 'Ctrl+X' },\n { id: 'copy', label: 'Copy', command: 'copy', shortcut: 'Ctrl+C' },\n { id: 'paste', label: 'Paste', command: 'paste', shortcut: 'Ctrl+V' },\n { id: 'paste-text', label: 'Paste as plain text', command: 'pasteText' },\n separator('edit-2'),\n { id: 'select-all', label: 'Select all', command: 'selectall', shortcut: 'Ctrl+A' },\n {\n id: 'find',\n label: 'Find and replace',\n dialog: 'find-replace',\n shortcut: 'Ctrl+F',\n plugin: 'find-replace',\n },\n ],\n },\n {\n name: 'view',\n label: 'View',\n icon: 'view',\n items: [\n { id: 'source', label: 'Source code', dialog: 'source', plugin: 'code' },\n { id: 'view-preview', label: 'Preview', dialog: 'preview', plugin: 'preview' },\n { id: 'fullscreen', label: 'Fullscreen', command: 'fullscreen', plugin: 'fullscreen' },\n ],\n },\n {\n name: 'insert',\n label: 'Insert',\n icon: 'insert',\n items: [\n { id: 'image', label: 'Image', command: 'imageUpload', plugin: 'image' },\n { id: 'link', label: 'Link', dialog: 'link', plugin: 'link' },\n { id: 'media', label: 'Media', dialog: 'media', plugin: 'media' },\n { id: 'table', label: 'Table', dialog: 'table', plugin: 'table' },\n {\n id: 'character',\n label: 'Special character',\n dialog: 'special-character',\n plugin: 'special-character',\n },\n { id: 'emoji', label: 'Emoji', dialog: 'emoji', plugin: 'emoji' },\n { id: 'hr', label: 'Horizontal line', command: 'hr', plugin: 'horizontal-rule' },\n { id: 'anchor', label: 'Anchor', command: 'anchor', plugin: 'anchor' },\n { id: 'date-time', label: 'Date/time', plugin: 'date-time' },\n ],\n },\n {\n name: 'merge-tags',\n label: 'Merge tag',\n icon: 'merge-tag',\n items: [],\n },\n {\n name: 'templates',\n label: 'Templates',\n icon: 'template',\n items: [],\n },\n {\n name: 'format',\n label: 'Format',\n icon: 'format',\n items: [\n ...inline,\n { id: 'change-case', label: 'Change case', children: changeCase },\n separator('format-1'),\n {\n id: 'formats',\n label: 'Formats',\n children: [\n { id: 'format-headings', label: 'Headings', children: blocks.slice(1, 7) },\n { id: 'format-inline', label: 'Inline', children: inline },\n { id: 'format-blocks', label: 'Blocks', children: blocks },\n { id: 'format-align', label: 'Alignment', children: align },\n ],\n },\n { id: 'blocks', label: 'Blocks', children: blocks },\n { id: 'alignment', label: 'Alignment', children: align },\n { id: 'line-height', label: 'Line height', command: 'lineHeightMenu' },\n separator('format-2'),\n { id: 'clear', label: 'Clear formatting', command: 'removeformat' },\n ],\n },\n {\n name: 'tools',\n label: 'Tools',\n icon: 'tools',\n items: [\n { id: 'tools-source', label: 'Source code', dialog: 'source', plugin: 'code' },\n { id: 'words', label: 'Word count', command: 'wordCount' },\n ],\n },\n {\n name: 'table',\n label: 'Table',\n icon: 'table',\n items: [\n { id: 'insert-table', label: 'Insert table', dialog: 'table', plugin: 'table' },\n {\n id: 'table-properties',\n label: 'Table properties',\n dialog: 'table-properties',\n tableOnly: true,\n },\n { id: 'delete-table', label: 'Delete table', command: 'deleteTable', tableOnly: true },\n {\n id: 'cell',\n label: 'Cell',\n children: [\n {\n id: 'cell-properties',\n label: 'Cell properties',\n command: 'cellProperties',\n tableOnly: true,\n },\n {\n id: 'merge-cells',\n label: 'Merge cells',\n command: 'mergeCells',\n tableOnly: true,\n },\n {\n id: 'split-cell',\n label: 'Split cell',\n command: 'splitCell',\n tableOnly: true,\n },\n ],\n },\n {\n id: 'row',\n label: 'Row',\n children: [\n {\n id: 'row-before',\n label: 'Insert row before',\n command: 'rowBefore',\n tableOnly: true,\n },\n {\n id: 'row-after',\n label: 'Insert row after',\n command: 'rowAfter',\n tableOnly: true,\n },\n {\n id: 'delete-row',\n label: 'Delete row',\n command: 'deleteRow',\n tableOnly: true,\n },\n ],\n },\n {\n id: 'column',\n label: 'Column',\n children: [\n {\n id: 'column-before',\n label: 'Insert column before',\n command: 'columnBefore',\n tableOnly: true,\n },\n {\n id: 'column-after',\n label: 'Insert column after',\n command: 'columnAfter',\n tableOnly: true,\n },\n {\n id: 'delete-column',\n label: 'Delete column',\n command: 'deleteColumn',\n tableOnly: true,\n },\n ],\n },\n ],\n },\n {\n name: 'help',\n label: 'Help',\n icon: 'help',\n items: [\n {\n id: 'shortcuts',\n label: 'Keyboard shortcuts',\n dialog: 'shortcuts',\n shortcut: 'Alt+0',\n },\n { id: 'about', label: 'About', dialog: 'about' },\n ],\n },\n];\n","import type { MenuItemDefinition } from '../types';\n\nconst COMMAND_ICONS: Record<string, string> = {\n new: 'file',\n print: 'print',\n undo: 'undo',\n redo: 'redo',\n cut: 'cut',\n copy: 'copy',\n paste: 'paste',\n pasteText: 'paste',\n selectall: 'select-all',\n imageUpload: 'image',\n fullscreen: 'fullscreen',\n hr: 'horizontal-rule',\n anchor: 'anchor',\n dateTime: 'calendar',\n bold: 'bold',\n italic: 'italic',\n underline: 'underline',\n strikethrough: 'strikethrough',\n superscript: 'superscript',\n subscript: 'subscript',\n inlineCode: 'code',\n changeCase: 'case-change',\n formatBlock: 'format',\n lineHeightMenu: 'format',\n lineheight: 'format',\n removeformat: 'clear-format',\n wordCount: 'count',\n insertMergeTag: 'merge-tag',\n deleteTable: 'trash',\n cellProperties: 'table',\n mergeCells: 'table',\n splitCell: 'table',\n rowBefore: 'table',\n rowAfter: 'table',\n deleteRow: 'trash',\n columnBefore: 'table',\n columnAfter: 'table',\n deleteColumn: 'trash',\n alignleft: 'alignleft',\n aligncenter: 'aligncenter',\n alignright: 'alignright',\n alignjustify: 'alignjustify',\n};\n\nconst DIALOG_ICONS: Record<string, string> = {\n source: 'code',\n preview: 'preview',\n 'find-replace': 'search',\n image: 'image',\n link: 'link',\n media: 'media',\n table: 'table',\n 'table-properties': 'table',\n 'special-character': 'special-character',\n emoji: 'emoji',\n shortcuts: 'keyboard',\n about: 'help',\n};\n\nconst CATEGORY_ICONS: Record<string, string> = {\n formats: 'format',\n 'format-headings': 'format',\n 'format-inline': 'format',\n 'format-blocks': 'format',\n 'format-align': 'alignleft',\n blocks: 'format',\n alignment: 'alignleft',\n 'change-case': 'case-change',\n 'date-time': 'calendar',\n 'merge-tag': 'merge-tag',\n cell: 'table',\n row: 'table',\n column: 'table',\n};\n\nexport function resolveMenuItemIcon(item: MenuItemDefinition): string {\n if (item.icon) return item.icon;\n const commandIcon = item.command ? COMMAND_ICONS[item.command] : undefined;\n if (commandIcon) return commandIcon;\n const dialogIcon = item.dialog ? DIALOG_ICONS[item.dialog] : undefined;\n if (dialogIcon) return dialogIcon;\n return CATEGORY_ICONS[item.id] ?? 'menu-item';\n}\n","<script setup lang=\"ts\">\nimport { nextTick, useTemplateRef } from 'vue';\nimport { resolveMenuItemIcon } from '../../config/menuIcons';\nimport type { MenuItemDefinition } from '../../types';\nimport EditorIcon from '../icons/EditorIcon.vue';\n\nconst props = defineProps<{\n items: MenuItemDefinition[];\n disabled: boolean;\n activeCommands: Record<string, boolean>;\n availableCommands: Record<string, boolean>;\n insideTable: boolean;\n level?: number;\n}>();\nconst emit = defineEmits<{ select: [item: MenuItemDefinition]; close: [] }>();\nconst menu = useTemplateRef<HTMLElement>('menu');\n\nfunction isDisabled(item: MenuItemDefinition): boolean {\n const explicitlyUnavailable = Boolean(\n item.command && props.availableCommands[item.command] === false,\n );\n return props.disabled || explicitlyUnavailable || Boolean(item.tableOnly && !props.insideTable);\n}\nfunction isActive(item: MenuItemDefinition): boolean {\n return Boolean(item.command && !isDisabled(item) && props.activeCommands[item.command]);\n}\nfunction select(item: MenuItemDefinition): void {\n if (!item.children && !item.separator && !isDisabled(item)) emit('select', item);\n}\nasync function onKeydown(event: KeyboardEvent): Promise<void> {\n const target = event.target as HTMLElement;\n const buttons = menu.value\n ? [\n ...menu.value.querySelectorAll<HTMLElement>(\n ':scope > .erag-menu__entry > .erag-menu__item:not([aria-disabled=\"true\"])',\n ),\n ]\n : [];\n const index = buttons.indexOf(target);\n if (event.key === 'Escape') {\n emit('close');\n return;\n }\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n const offset = event.key === 'ArrowDown' ? 1 : -1;\n buttons[(index + offset + buttons.length) % buttons.length]?.focus();\n }\n if (event.key === 'Home') {\n event.preventDefault();\n buttons[0]?.focus();\n }\n if (event.key === 'End') {\n event.preventDefault();\n buttons.at(-1)?.focus();\n }\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n target.click();\n }\n await nextTick();\n}\n</script>\n\n<template>\n <div\n ref=\"menu\"\n class=\"erag-menu\"\n :class=\"{ 'erag-menu--nested': (level ?? 0) > 0 }\"\n role=\"menu\"\n @keydown=\"onKeydown\"\n >\n <template\n v-for=\"item in items\"\n :key=\"item.id\"\n >\n <div\n v-if=\"item.separator\"\n class=\"erag-menu__separator\"\n role=\"separator\"\n />\n <div\n v-else\n class=\"erag-menu__entry\"\n >\n <button\n type=\"button\"\n class=\"erag-menu__item\"\n :class=\"{ 'erag-is-active': isActive(item) }\"\n role=\"menuitem\"\n :aria-haspopup=\"Boolean(item.children)\"\n :aria-disabled=\"isDisabled(item)\"\n :tabindex=\"isDisabled(item) ? -1 : 0\"\n @mousedown.prevent\n @click=\"select(item)\"\n >\n <span class=\"erag-menu__check\">{{ isActive(item) ? '✓' : '' }}</span>\n <EditorIcon\n class=\"erag-menu__icon\"\n :name=\"resolveMenuItemIcon(item)\"\n :size=\"16\"\n />\n <span class=\"erag-menu__label\">{{ item.label }}</span>\n <span\n v-if=\"item.shortcut\"\n class=\"erag-menu__shortcut\"\n >{{ item.shortcut }}</span\n >\n <span\n v-if=\"item.children\"\n class=\"erag-menu__arrow\"\n >›</span\n >\n </button>\n <FloatingMenu\n v-if=\"item.children\"\n :items=\"item.children\"\n :disabled=\"disabled\"\n :active-commands=\"activeCommands\"\n :available-commands=\"availableCommands\"\n :inside-table=\"insideTable\"\n :level=\"(level ?? 0) + 1\"\n @select=\"emit('select', $event)\"\n @close=\"emit('close')\"\n />\n </div>\n </template>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { nextTick, useTemplateRef } from 'vue';\nimport { resolveMenuItemIcon } from '../../config/menuIcons';\nimport type { MenuItemDefinition } from '../../types';\nimport EditorIcon from '../icons/EditorIcon.vue';\n\nconst props = defineProps<{\n items: MenuItemDefinition[];\n disabled: boolean;\n activeCommands: Record<string, boolean>;\n availableCommands: Record<string, boolean>;\n insideTable: boolean;\n level?: number;\n}>();\nconst emit = defineEmits<{ select: [item: MenuItemDefinition]; close: [] }>();\nconst menu = useTemplateRef<HTMLElement>('menu');\n\nfunction isDisabled(item: MenuItemDefinition): boolean {\n const explicitlyUnavailable = Boolean(\n item.command && props.availableCommands[item.command] === false,\n );\n return props.disabled || explicitlyUnavailable || Boolean(item.tableOnly && !props.insideTable);\n}\nfunction isActive(item: MenuItemDefinition): boolean {\n return Boolean(item.command && !isDisabled(item) && props.activeCommands[item.command]);\n}\nfunction select(item: MenuItemDefinition): void {\n if (!item.children && !item.separator && !isDisabled(item)) emit('select', item);\n}\nasync function onKeydown(event: KeyboardEvent): Promise<void> {\n const target = event.target as HTMLElement;\n const buttons = menu.value\n ? [\n ...menu.value.querySelectorAll<HTMLElement>(\n ':scope > .erag-menu__entry > .erag-menu__item:not([aria-disabled=\"true\"])',\n ),\n ]\n : [];\n const index = buttons.indexOf(target);\n if (event.key === 'Escape') {\n emit('close');\n return;\n }\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n const offset = event.key === 'ArrowDown' ? 1 : -1;\n buttons[(index + offset + buttons.length) % buttons.length]?.focus();\n }\n if (event.key === 'Home') {\n event.preventDefault();\n buttons[0]?.focus();\n }\n if (event.key === 'End') {\n event.preventDefault();\n buttons.at(-1)?.focus();\n }\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n target.click();\n }\n await nextTick();\n}\n</script>\n\n<template>\n <div\n ref=\"menu\"\n class=\"erag-menu\"\n :class=\"{ 'erag-menu--nested': (level ?? 0) > 0 }\"\n role=\"menu\"\n @keydown=\"onKeydown\"\n >\n <template\n v-for=\"item in items\"\n :key=\"item.id\"\n >\n <div\n v-if=\"item.separator\"\n class=\"erag-menu__separator\"\n role=\"separator\"\n />\n <div\n v-else\n class=\"erag-menu__entry\"\n >\n <button\n type=\"button\"\n class=\"erag-menu__item\"\n :class=\"{ 'erag-is-active': isActive(item) }\"\n role=\"menuitem\"\n :aria-haspopup=\"Boolean(item.children)\"\n :aria-disabled=\"isDisabled(item)\"\n :tabindex=\"isDisabled(item) ? -1 : 0\"\n @mousedown.prevent\n @click=\"select(item)\"\n >\n <span class=\"erag-menu__check\">{{ isActive(item) ? '✓' : '' }}</span>\n <EditorIcon\n class=\"erag-menu__icon\"\n :name=\"resolveMenuItemIcon(item)\"\n :size=\"16\"\n />\n <span class=\"erag-menu__label\">{{ item.label }}</span>\n <span\n v-if=\"item.shortcut\"\n class=\"erag-menu__shortcut\"\n >{{ item.shortcut }}</span\n >\n <span\n v-if=\"item.children\"\n class=\"erag-menu__arrow\"\n >›</span\n >\n </button>\n <FloatingMenu\n v-if=\"item.children\"\n :items=\"item.children\"\n :disabled=\"disabled\"\n :active-commands=\"activeCommands\"\n :available-commands=\"availableCommands\"\n :inside-table=\"insideTable\"\n :level=\"(level ?? 0) + 1\"\n @select=\"emit('select', $event)\"\n @close=\"emit('close')\"\n />\n </div>\n </template>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, nextTick, onBeforeUnmount, onMounted, shallowRef, useTemplateRef } from 'vue';\nimport { MENU_DEFINITIONS } from '../config/menuConfig';\nimport type {\n DateTimeFormatOption,\n EditorMenuName,\n LineHeightOption,\n MenuItemDefinition,\n ResolvedMergeTagConfig,\n ResolvedEditorTemplatesConfig,\n} from '../types';\nimport { formatDateTime, mergeDateTimeFormats } from '../utils/dateTime';\nimport EditorIcon from './icons/EditorIcon.vue';\nimport FloatingMenu from './menus/FloatingMenu.vue';\n\nconst props = defineProps<{\n menus: true | EditorMenuName[];\n plugins: string[];\n disabled: boolean;\n activeCommands: Record<string, boolean>;\n availableCommands: Record<string, boolean>;\n insideTable: boolean;\n lineHeightFormats: LineHeightOption[];\n dateFormats: DateTimeFormatOption[];\n timeFormats: DateTimeFormatOption[];\n mergeTags: ResolvedMergeTagConfig;\n templates: ResolvedEditorTemplatesConfig;\n mergeTagSidebarOpen: boolean;\n templateDialogOpen: boolean;\n}>();\nconst emit = defineEmits<{\n select: [item: MenuItemDefinition];\n opening: [name: EditorMenuName];\n mergeTagToggle: [];\n templatesOpen: [];\n}>();\ndefineSlots<{ end(): unknown }>();\nconst open = shallowRef<EditorMenuName | null>(null);\nconst root = useTemplateRef<HTMLElement>('root');\nconst currentDate = shallowRef(new Date());\nconst definitions = computed(() =>\n MENU_DEFINITIONS.filter(\n (menu) =>\n (props.menus === true || props.menus.includes(menu.name)) &&\n (menu.name !== 'merge-tags' ||\n (props.plugins.includes('merge-tags') &&\n props.mergeTags.enabled &&\n props.mergeTags.items.length > 0)) &&\n (menu.name !== 'templates' ||\n (props.plugins.includes('templates') &&\n props.templates.enabled &&\n props.templates.items.length > 0)),\n ).map((menu) => ({ ...menu, items: resolveItems(menu.items) })),\n);\nfunction resolveItems(items: MenuItemDefinition[]): MenuItemDefinition[] {\n return items\n .filter((item) => !item.plugin || props.plugins.includes(item.plugin))\n .map((item) => {\n let children = item.children;\n if (item.id === 'line-height')\n children = props.lineHeightFormats.map((option) => ({\n id: `line-height-${option.value}`,\n label: option.label,\n command: 'lineheight',\n value: option.value,\n }));\n if (item.id === 'date-time')\n children = mergeDateTimeFormats(props.dateFormats, props.timeFormats).map(\n (option, index) => ({\n id: `date-time-${index}`,\n label: formatDateTime(option, currentDate.value),\n command: 'dateTime',\n value: String(index),\n }),\n );\n return children ? { ...item, children: resolveItems(children) } : item;\n });\n}\nfunction toggle(name: EditorMenuName): void {\n if (props.disabled) return;\n currentDate.value = new Date();\n emit('opening', name);\n if (name === 'merge-tags') {\n open.value = null;\n emit('mergeTagToggle');\n return;\n }\n if (name === 'templates') {\n open.value = null;\n emit('templatesOpen');\n return;\n }\n open.value = open.value === name ? null : name;\n}\nfunction isOpen(name: EditorMenuName): boolean {\n if (name === 'merge-tags') return props.mergeTagSidebarOpen;\n if (name === 'templates') return props.templateDialogOpen;\n return open.value === name;\n}\nasync function select(item: MenuItemDefinition): Promise<void> {\n open.value = null;\n await nextTick();\n emit('select', item);\n}\nfunction outside(event: PointerEvent): void {\n if (!root.value?.contains(event.target as Node)) open.value = null;\n}\nfunction keydown(event: KeyboardEvent): void {\n if (event.key === 'Escape') open.value = null;\n}\nonMounted(() => {\n document.addEventListener('pointerdown', outside);\n document.addEventListener('keydown', keydown);\n});\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', outside);\n document.removeEventListener('keydown', keydown);\n});\n</script>\n\n<template>\n <div\n ref=\"root\"\n class=\"erag-menubar\"\n role=\"menubar\"\n aria-label=\"Editor menu\"\n >\n <div\n v-for=\"menu in definitions\"\n :key=\"menu.name\"\n class=\"erag-menubar__entry\"\n >\n <button\n type=\"button\"\n class=\"erag-menubar__button\"\n :class=\"{ 'erag-is-active': isOpen(menu.name) }\"\n role=\"menuitem\"\n :aria-expanded=\"isOpen(menu.name)\"\n :disabled=\"disabled\"\n @mousedown.prevent\n @click=\"toggle(menu.name)\"\n >\n <EditorIcon\n class=\"erag-menubar__icon\"\n :name=\"menu.icon\"\n :size=\"15\"\n />\n <span class=\"erag-menubar__label\">{{ menu.label }}</span>\n </button>\n <FloatingMenu\n v-if=\"!['merge-tags', 'templates'].includes(menu.name) && open === menu.name\"\n :items=\"menu.items\"\n :disabled=\"disabled\"\n :active-commands=\"activeCommands\"\n :available-commands=\"availableCommands\"\n :inside-table=\"insideTable\"\n @select=\"select\"\n @close=\"open = null\"\n />\n </div>\n <div\n v-if=\"$slots.end\"\n class=\"erag-menubar__end\"\n >\n <slot name=\"end\" />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, nextTick, onBeforeUnmount, onMounted, shallowRef, useTemplateRef } from 'vue';\nimport { MENU_DEFINITIONS } from '../config/menuConfig';\nimport type {\n DateTimeFormatOption,\n EditorMenuName,\n LineHeightOption,\n MenuItemDefinition,\n ResolvedMergeTagConfig,\n ResolvedEditorTemplatesConfig,\n} from '../types';\nimport { formatDateTime, mergeDateTimeFormats } from '../utils/dateTime';\nimport EditorIcon from './icons/EditorIcon.vue';\nimport FloatingMenu from './menus/FloatingMenu.vue';\n\nconst props = defineProps<{\n menus: true | EditorMenuName[];\n plugins: string[];\n disabled: boolean;\n activeCommands: Record<string, boolean>;\n availableCommands: Record<string, boolean>;\n insideTable: boolean;\n lineHeightFormats: LineHeightOption[];\n dateFormats: DateTimeFormatOption[];\n timeFormats: DateTimeFormatOption[];\n mergeTags: ResolvedMergeTagConfig;\n templates: ResolvedEditorTemplatesConfig;\n mergeTagSidebarOpen: boolean;\n templateDialogOpen: boolean;\n}>();\nconst emit = defineEmits<{\n select: [item: MenuItemDefinition];\n opening: [name: EditorMenuName];\n mergeTagToggle: [];\n templatesOpen: [];\n}>();\ndefineSlots<{ end(): unknown }>();\nconst open = shallowRef<EditorMenuName | null>(null);\nconst root = useTemplateRef<HTMLElement>('root');\nconst currentDate = shallowRef(new Date());\nconst definitions = computed(() =>\n MENU_DEFINITIONS.filter(\n (menu) =>\n (props.menus === true || props.menus.includes(menu.name)) &&\n (menu.name !== 'merge-tags' ||\n (props.plugins.includes('merge-tags') &&\n props.mergeTags.enabled &&\n props.mergeTags.items.length > 0)) &&\n (menu.name !== 'templates' ||\n (props.plugins.includes('templates') &&\n props.templates.enabled &&\n props.templates.items.length > 0)),\n ).map((menu) => ({ ...menu, items: resolveItems(menu.items) })),\n);\nfunction resolveItems(items: MenuItemDefinition[]): MenuItemDefinition[] {\n return items\n .filter((item) => !item.plugin || props.plugins.includes(item.plugin))\n .map((item) => {\n let children = item.children;\n if (item.id === 'line-height')\n children = props.lineHeightFormats.map((option) => ({\n id: `line-height-${option.value}`,\n label: option.label,\n command: 'lineheight',\n value: option.value,\n }));\n if (item.id === 'date-time')\n children = mergeDateTimeFormats(props.dateFormats, props.timeFormats).map(\n (option, index) => ({\n id: `date-time-${index}`,\n label: formatDateTime(option, currentDate.value),\n command: 'dateTime',\n value: String(index),\n }),\n );\n return children ? { ...item, children: resolveItems(children) } : item;\n });\n}\nfunction toggle(name: EditorMenuName): void {\n if (props.disabled) return;\n currentDate.value = new Date();\n emit('opening', name);\n if (name === 'merge-tags') {\n open.value = null;\n emit('mergeTagToggle');\n return;\n }\n if (name === 'templates') {\n open.value = null;\n emit('templatesOpen');\n return;\n }\n open.value = open.value === name ? null : name;\n}\nfunction isOpen(name: EditorMenuName): boolean {\n if (name === 'merge-tags') return props.mergeTagSidebarOpen;\n if (name === 'templates') return props.templateDialogOpen;\n return open.value === name;\n}\nasync function select(item: MenuItemDefinition): Promise<void> {\n open.value = null;\n await nextTick();\n emit('select', item);\n}\nfunction outside(event: PointerEvent): void {\n if (!root.value?.contains(event.target as Node)) open.value = null;\n}\nfunction keydown(event: KeyboardEvent): void {\n if (event.key === 'Escape') open.value = null;\n}\nonMounted(() => {\n document.addEventListener('pointerdown', outside);\n document.addEventListener('keydown', keydown);\n});\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', outside);\n document.removeEventListener('keydown', keydown);\n});\n</script>\n\n<template>\n <div\n ref=\"root\"\n class=\"erag-menubar\"\n role=\"menubar\"\n aria-label=\"Editor menu\"\n >\n <div\n v-for=\"menu in definitions\"\n :key=\"menu.name\"\n class=\"erag-menubar__entry\"\n >\n <button\n type=\"button\"\n class=\"erag-menubar__button\"\n :class=\"{ 'erag-is-active': isOpen(menu.name) }\"\n role=\"menuitem\"\n :aria-expanded=\"isOpen(menu.name)\"\n :disabled=\"disabled\"\n @mousedown.prevent\n @click=\"toggle(menu.name)\"\n >\n <EditorIcon\n class=\"erag-menubar__icon\"\n :name=\"menu.icon\"\n :size=\"15\"\n />\n <span class=\"erag-menubar__label\">{{ menu.label }}</span>\n </button>\n <FloatingMenu\n v-if=\"!['merge-tags', 'templates'].includes(menu.name) && open === menu.name\"\n :items=\"menu.items\"\n :disabled=\"disabled\"\n :active-commands=\"activeCommands\"\n :available-commands=\"availableCommands\"\n :inside-table=\"insideTable\"\n @select=\"select\"\n @close=\"open = null\"\n />\n </div>\n <div\n v-if=\"$slots.end\"\n class=\"erag-menubar__end\"\n >\n <slot name=\"end\" />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport type { EditorCounts } from '../types';\ndefineProps<{\n path: string;\n counts: EditorCounts;\n resize: boolean;\n helpText: string;\n disabled: boolean;\n}>();\ndefineEmits<{ resizeStart: [event: PointerEvent] }>();\ndefineSlots<{ start(): unknown; end(): unknown }>();\n</script>\n<template>\n <div class=\"erag-statusbar\">\n <div\n v-if=\"$slots.start\"\n class=\"erag-statusbar__slot\"\n >\n <slot name=\"start\" />\n </div>\n <span class=\"erag-statusbar__path\">{{ path }}</span\n ><span class=\"erag-statusbar__count\">{{ counts.words }} words</span\n ><span class=\"erag-statusbar__count\">{{ counts.characters }} characters</span>\n <span class=\"erag-statusbar__help\">{{ helpText }}</span>\n <div\n v-if=\"$slots.end\"\n class=\"erag-statusbar__slot\"\n >\n <slot name=\"end\" />\n </div>\n <button\n v-if=\"resize\"\n type=\"button\"\n class=\"erag-statusbar__resize\"\n aria-label=\"Resize editor\"\n :disabled=\"disabled\"\n @pointerdown=\"$emit('resizeStart', $event)\"\n >\n <span />\n </button>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport type { EditorCounts } from '../types';\ndefineProps<{\n path: string;\n counts: EditorCounts;\n resize: boolean;\n helpText: string;\n disabled: boolean;\n}>();\ndefineEmits<{ resizeStart: [event: PointerEvent] }>();\ndefineSlots<{ start(): unknown; end(): unknown }>();\n</script>\n<template>\n <div class=\"erag-statusbar\">\n <div\n v-if=\"$slots.start\"\n class=\"erag-statusbar__slot\"\n >\n <slot name=\"start\" />\n </div>\n <span class=\"erag-statusbar__path\">{{ path }}</span\n ><span class=\"erag-statusbar__count\">{{ counts.words }} words</span\n ><span class=\"erag-statusbar__count\">{{ counts.characters }} characters</span>\n <span class=\"erag-statusbar__help\">{{ helpText }}</span>\n <div\n v-if=\"$slots.end\"\n class=\"erag-statusbar__slot\"\n >\n <slot name=\"end\" />\n </div>\n <button\n v-if=\"resize\"\n type=\"button\"\n class=\"erag-statusbar__resize\"\n aria-label=\"Resize editor\"\n :disabled=\"disabled\"\n @pointerdown=\"$emit('resizeStart', $event)\"\n >\n <span />\n </button>\n </div>\n</template>\n","import type { EditorToolbarGroup, EditorToolbarItemName, ToolbarItemDefinition } from '../types';\n\nexport const DEFAULT_TOOLBAR =\n 'undo redo | blocks fontfamily fontsize | bold italic underline strikethrough superscript subscript casechange | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image media table | hr removeformat | code preview fullscreen more';\n\nexport const TOOLBAR_ITEMS: Record<EditorToolbarItemName, ToolbarItemDefinition> = {\n undo: { name: 'undo', label: 'Undo', icon: 'undo', command: 'undo' },\n redo: { name: 'redo', label: 'Redo', icon: 'redo', command: 'redo' },\n blocks: { name: 'blocks', label: 'Blocks', select: 'blocks' },\n fontfamily: {\n name: 'fontfamily',\n label: 'Font family',\n select: 'fontfamily',\n },\n fontsize: {\n name: 'fontsize',\n label: 'Font size',\n select: 'fontsize',\n },\n bold: { name: 'bold', label: 'Bold', icon: 'bold', command: 'bold' },\n italic: {\n name: 'italic',\n label: 'Italic',\n icon: 'italic',\n command: 'italic',\n },\n underline: {\n name: 'underline',\n label: 'Underline',\n icon: 'underline',\n command: 'underline',\n },\n strikethrough: {\n name: 'strikethrough',\n label: 'Strikethrough',\n icon: 'strikethrough',\n command: 'strikethrough',\n },\n superscript: {\n name: 'superscript',\n label: 'Superscript',\n icon: 'superscript',\n command: 'superscript',\n },\n subscript: {\n name: 'subscript',\n label: 'Subscript',\n icon: 'subscript',\n command: 'subscript',\n },\n casechange: {\n name: 'casechange',\n label: 'Change case',\n icon: 'case-change',\n },\n forecolor: {\n name: 'forecolor',\n label: 'Text color',\n icon: 'text-color',\n dialog: 'forecolor',\n },\n backcolor: {\n name: 'backcolor',\n label: 'Background color',\n icon: 'highlight',\n dialog: 'backcolor',\n },\n alignleft: {\n name: 'alignleft',\n label: 'Align left',\n icon: 'align-left',\n command: 'alignleft',\n },\n aligncenter: {\n name: 'aligncenter',\n label: 'Align center',\n icon: 'align-center',\n command: 'aligncenter',\n },\n alignright: {\n name: 'alignright',\n label: 'Align right',\n icon: 'align-right',\n command: 'alignright',\n },\n alignjustify: {\n name: 'alignjustify',\n label: 'Justify',\n icon: 'align-justify',\n command: 'alignjustify',\n },\n bullist: {\n name: 'bullist',\n label: 'Bulleted list',\n icon: 'list',\n command: 'bullist',\n },\n numlist: {\n name: 'numlist',\n label: 'Numbered list',\n icon: 'numbered-list',\n command: 'numlist',\n },\n outdent: {\n name: 'outdent',\n label: 'Decrease indent',\n icon: 'outdent',\n command: 'outdent',\n },\n indent: {\n name: 'indent',\n label: 'Increase indent',\n icon: 'indent',\n command: 'indent',\n },\n link: { name: 'link', label: 'Insert link', icon: 'link', dialog: 'link', plugin: 'link' },\n image: {\n name: 'image',\n label: 'Insert image',\n icon: 'image',\n command: 'imageUpload',\n plugin: 'image',\n },\n media: {\n name: 'media',\n label: 'Insert media',\n icon: 'media',\n dialog: 'media',\n plugin: 'media',\n },\n table: {\n name: 'table',\n label: 'Insert table',\n icon: 'table',\n dialog: 'table',\n plugin: 'table',\n },\n hr: {\n name: 'hr',\n label: 'Horizontal line',\n icon: 'horizontal-rule',\n command: 'hr',\n plugin: 'horizontal-rule',\n },\n removeformat: {\n name: 'removeformat',\n label: 'Clear formatting',\n icon: 'clear-format',\n command: 'removeformat',\n },\n code: { name: 'code', label: 'Source code', icon: 'code', dialog: 'source', plugin: 'code' },\n preview: {\n name: 'preview',\n label: 'Preview',\n icon: 'preview',\n dialog: 'preview',\n plugin: 'preview',\n },\n fullscreen: {\n name: 'fullscreen',\n label: 'Fullscreen',\n icon: 'fullscreen',\n command: 'fullscreen',\n plugin: 'fullscreen',\n },\n more: { name: 'more', label: 'More', icon: 'more' },\n};\n\nexport function parseToolbar(value: boolean | string | EditorToolbarGroup[]): EditorToolbarGroup[] {\n if (value === false) return [];\n if (Array.isArray(value)) return value.map((group) => ({ ...group, items: [...group.items] }));\n const source = value === true ? DEFAULT_TOOLBAR : value;\n return source\n .split('|')\n .map((part, index) => ({\n name: `group-${index}`,\n items: part\n .trim()\n .split(/\\s+/)\n .filter((item): item is EditorToolbarItemName => item in TOOLBAR_ITEMS),\n }))\n .filter((group) => group.items.length > 0);\n}\n","import { nextTick, onBeforeUnmount, onMounted, shallowRef, watch, type Ref } from 'vue';\n\nconst OVERFLOW_BUTTON_WIDTH = 34;\nconst OVERFLOW_GAP = 4;\n\nexport function useToolbarOverflow(\n container: Ref<HTMLElement | null>,\n itemCount: Ref<number>,\n layoutKey: Ref<string>,\n) {\n const visibleCount = shallowRef(itemCount.value);\n const groupWidths: number[] = [];\n let observer: ResizeObserver | null = null;\n\n function horizontalSize(element: HTMLElement | null): number {\n return element?.getBoundingClientRect().width ?? 0;\n }\n\n async function measure(): Promise<void> {\n await nextTick();\n\n const element = container.value;\n if (!element) return;\n\n const renderedGroups = element.querySelectorAll<HTMLElement>(\n '[data-erag-toolbar-group-index]',\n );\n\n renderedGroups.forEach((group) => {\n const index = Number(group.dataset.eragToolbarGroupIndex);\n if (Number.isInteger(index)) {\n groupWidths[index] = group.getBoundingClientRect().width;\n }\n });\n\n if (groupWidths.slice(0, itemCount.value).some((width) => !width)) return;\n\n const styles = window.getComputedStyle(element);\n const padding =\n Number.parseFloat(styles.paddingInlineStart) +\n Number.parseFloat(styles.paddingInlineEnd);\n const startWidth = horizontalSize(\n element.querySelector<HTMLElement>('[data-erag-toolbar-start]'),\n );\n const endWidth = horizontalSize(\n element.querySelector<HTMLElement>('[data-erag-toolbar-end]'),\n );\n const availableWidth = Math.max(0, element.clientWidth - padding - startWidth - endWidth);\n const totalGroupWidth = groupWidths\n .slice(0, itemCount.value)\n .reduce((total, width) => total + width, 0);\n\n if (totalGroupWidth <= availableWidth) {\n visibleCount.value = itemCount.value;\n return;\n }\n\n const availableGroupWidth = Math.max(\n 0,\n availableWidth - OVERFLOW_BUTTON_WIDTH - OVERFLOW_GAP,\n );\n let usedWidth = 0;\n let nextVisibleCount = 0;\n\n for (const width of groupWidths.slice(0, itemCount.value)) {\n if (usedWidth + width > availableGroupWidth) break;\n usedWidth += width;\n nextVisibleCount += 1;\n }\n\n visibleCount.value = nextVisibleCount;\n }\n\n function reset(): void {\n groupWidths.length = 0;\n visibleCount.value = itemCount.value;\n void measure();\n }\n\n watch([itemCount, layoutKey], reset);\n\n onMounted(() => {\n observer = new ResizeObserver(() => void measure());\n if (container.value) observer.observe(container.value);\n void measure();\n });\n\n onBeforeUnmount(() => observer?.disconnect());\n\n return { visibleCount, measure };\n}\n","<script setup lang=\"ts\">\nimport { nextTick, onMounted, shallowRef, useTemplateRef } from 'vue';\nimport type { TextCaseMode } from '../../types';\n\nconst props = defineProps<{ mode: TextCaseMode | null }>();\nconst emit = defineEmits<{\n close: [];\n select: [mode: TextCaseMode];\n}>();\nconst root = useTemplateRef<HTMLElement>('root');\nconst highlightedMode = shallowRef<TextCaseMode | null>(null);\nconst options: { label: string; value: TextCaseMode }[] = [\n { label: 'lowercase', value: 'lowercase' },\n { label: 'UPPERCASE', value: 'uppercase' },\n { label: 'Title Case', value: 'titlecase' },\n];\n\nfunction keydown(event: KeyboardEvent): void {\n if (event.key === 'Escape') {\n event.preventDefault();\n emit('close');\n return;\n }\n if (!['ArrowDown', 'ArrowUp', 'Home', 'End'].includes(event.key)) return;\n event.preventDefault();\n const buttons = [...(root.value?.querySelectorAll<HTMLButtonElement>('button') ?? [])];\n if (!buttons.length) return;\n const current = Math.max(0, buttons.indexOf(document.activeElement as HTMLButtonElement));\n const next =\n event.key === 'Home'\n ? 0\n : event.key === 'End'\n ? buttons.length - 1\n : (current + (event.key === 'ArrowDown' ? 1 : -1) + buttons.length) % buttons.length;\n buttons[next]?.focus();\n}\n\nfunction isHighlighted(mode: TextCaseMode): boolean {\n return (\n highlightedMode.value === mode || (highlightedMode.value === null && props.mode === mode)\n );\n}\n\nfunction restoreFocusedHighlight(): void {\n const focused = root.value?.contains(document.activeElement)\n ? (document.activeElement as HTMLElement).dataset.eragCase\n : undefined;\n highlightedMode.value = (focused as TextCaseMode | undefined) ?? null;\n}\n\nonMounted(async () => {\n await nextTick();\n const selector = props.mode ? `[data-erag-case=\"${props.mode}\"]` : 'button';\n root.value?.querySelector<HTMLButtonElement>(selector)?.focus();\n});\n</script>\n\n<template>\n <div\n ref=\"root\"\n class=\"erag-case-menu\"\n role=\"menu\"\n aria-label=\"Change text case\"\n @keydown=\"keydown\"\n @pointerleave=\"restoreFocusedHighlight\"\n >\n <button\n v-for=\"option in options\"\n :key=\"option.value\"\n type=\"button\"\n class=\"erag-case-menu__item\"\n :class=\"{ 'erag-is-active': isHighlighted(option.value) }\"\n role=\"menuitemradio\"\n :aria-checked=\"mode === option.value\"\n :data-erag-case=\"option.value\"\n @focus=\"highlightedMode = option.value\"\n @pointerenter=\"highlightedMode = option.value\"\n @mousedown.prevent\n @click=\"emit('select', option.value)\"\n >\n <span class=\"erag-case-menu__label\">{{ option.label }}</span>\n <span\n class=\"erag-case-menu__check\"\n aria-hidden=\"true\"\n >{{ mode === option.value ? '✓' : '' }}</span\n >\n </button>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { nextTick, onMounted, shallowRef, useTemplateRef } from 'vue';\nimport type { TextCaseMode } from '../../types';\n\nconst props = defineProps<{ mode: TextCaseMode | null }>();\nconst emit = defineEmits<{\n close: [];\n select: [mode: TextCaseMode];\n}>();\nconst root = useTemplateRef<HTMLElement>('root');\nconst highlightedMode = shallowRef<TextCaseMode | null>(null);\nconst options: { label: string; value: TextCaseMode }[] = [\n { label: 'lowercase', value: 'lowercase' },\n { label: 'UPPERCASE', value: 'uppercase' },\n { label: 'Title Case', value: 'titlecase' },\n];\n\nfunction keydown(event: KeyboardEvent): void {\n if (event.key === 'Escape') {\n event.preventDefault();\n emit('close');\n return;\n }\n if (!['ArrowDown', 'ArrowUp', 'Home', 'End'].includes(event.key)) return;\n event.preventDefault();\n const buttons = [...(root.value?.querySelectorAll<HTMLButtonElement>('button') ?? [])];\n if (!buttons.length) return;\n const current = Math.max(0, buttons.indexOf(document.activeElement as HTMLButtonElement));\n const next =\n event.key === 'Home'\n ? 0\n : event.key === 'End'\n ? buttons.length - 1\n : (current + (event.key === 'ArrowDown' ? 1 : -1) + buttons.length) % buttons.length;\n buttons[next]?.focus();\n}\n\nfunction isHighlighted(mode: TextCaseMode): boolean {\n return (\n highlightedMode.value === mode || (highlightedMode.value === null && props.mode === mode)\n );\n}\n\nfunction restoreFocusedHighlight(): void {\n const focused = root.value?.contains(document.activeElement)\n ? (document.activeElement as HTMLElement).dataset.eragCase\n : undefined;\n highlightedMode.value = (focused as TextCaseMode | undefined) ?? null;\n}\n\nonMounted(async () => {\n await nextTick();\n const selector = props.mode ? `[data-erag-case=\"${props.mode}\"]` : 'button';\n root.value?.querySelector<HTMLButtonElement>(selector)?.focus();\n});\n</script>\n\n<template>\n <div\n ref=\"root\"\n class=\"erag-case-menu\"\n role=\"menu\"\n aria-label=\"Change text case\"\n @keydown=\"keydown\"\n @pointerleave=\"restoreFocusedHighlight\"\n >\n <button\n v-for=\"option in options\"\n :key=\"option.value\"\n type=\"button\"\n class=\"erag-case-menu__item\"\n :class=\"{ 'erag-is-active': isHighlighted(option.value) }\"\n role=\"menuitemradio\"\n :aria-checked=\"mode === option.value\"\n :data-erag-case=\"option.value\"\n @focus=\"highlightedMode = option.value\"\n @pointerenter=\"highlightedMode = option.value\"\n @mousedown.prevent\n @click=\"emit('select', option.value)\"\n >\n <span class=\"erag-case-menu__label\">{{ option.label }}</span>\n <span\n class=\"erag-case-menu__check\"\n aria-hidden=\"true\"\n >{{ mode === option.value ? '✓' : '' }}</span\n >\n </button>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport type { ToolbarItemDefinition } from '../../types';\nimport EditorIcon from '../icons/EditorIcon.vue';\ndefineProps<{\n item: ToolbarItemDefinition;\n active: boolean;\n available: boolean;\n disabled: boolean;\n}>();\ndefineEmits<{ activate: [item: ToolbarItemDefinition, event: MouseEvent] }>();\n</script>\n<template>\n <button\n type=\"button\"\n class=\"erag-toolbar__button\"\n :class=\"{\n 'erag-is-active': active,\n 'erag-is-available': available,\n 'erag-is-disabled': disabled,\n }\"\n :disabled=\"disabled\"\n :aria-label=\"item.label\"\n :title=\"item.label\"\n :aria-pressed=\"active\"\n @mousedown.prevent\n @click=\"$emit('activate', item, $event)\"\n >\n <EditorIcon :name=\"item.icon ?? 'more'\" />\n </button>\n</template>\n","<script setup lang=\"ts\">\nimport type { ToolbarItemDefinition } from '../../types';\nimport EditorIcon from '../icons/EditorIcon.vue';\ndefineProps<{\n item: ToolbarItemDefinition;\n active: boolean;\n available: boolean;\n disabled: boolean;\n}>();\ndefineEmits<{ activate: [item: ToolbarItemDefinition, event: MouseEvent] }>();\n</script>\n<template>\n <button\n type=\"button\"\n class=\"erag-toolbar__button\"\n :class=\"{\n 'erag-is-active': active,\n 'erag-is-available': available,\n 'erag-is-disabled': disabled,\n }\"\n :disabled=\"disabled\"\n :aria-label=\"item.label\"\n :title=\"item.label\"\n :aria-pressed=\"active\"\n @mousedown.prevent\n @click=\"$emit('activate', item, $event)\"\n >\n <EditorIcon :name=\"item.icon ?? 'more'\" />\n </button>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, nextTick, onBeforeUnmount, onMounted, shallowRef, useTemplateRef } from 'vue';\nimport { TOOLBAR_ITEMS, parseToolbar } from '../config/toolbarConfig';\nimport { useToolbarOverflow } from '../composables/useToolbarOverflow';\nimport type {\n EditorToolbarGroup,\n ResolvedEditorInit,\n TextCaseMode,\n ToolbarItemDefinition,\n} from '../types';\nimport ColorPalette from './toolbar/ColorPalette.vue';\nimport CaseChangeMenu from './toolbar/CaseChangeMenu.vue';\nimport ToolbarButton from './toolbar/ToolbarButton.vue';\n\nconst props = defineProps<{\n toolbar: boolean | string | EditorToolbarGroup[];\n config: ResolvedEditorInit;\n activeCommands: Record<string, boolean>;\n availableCommands: Record<string, boolean>;\n disabled: boolean;\n insideTable: boolean;\n}>();\nconst emit = defineEmits<{ command: [id: string, value?: string]; dialog: [name: string] }>();\ndefineSlots<{ start(): unknown; end(): unknown }>();\nconst container = useTemplateRef<HTMLElement>('container');\nconst open = shallowRef<string | null>(null);\nconst selectedCase = shallowRef<TextCaseMode | null>(null);\nconst popoverAnchor = shallowRef<HTMLElement | null>(null);\nconst popoverLeft = shallowRef(8);\nconst popoverStyle = computed(() => ({ left: `${popoverLeft.value}px` }));\nconst groups = computed(() =>\n parseToolbar(props.toolbar)\n .map((group) => ({\n ...group,\n items: group.items.filter((name) => name !== 'more' && available(TOOLBAR_ITEMS[name])),\n }))\n .filter((group) => group.items.length > 0),\n);\nconst count = computed(() => groups.value.length);\nconst layoutKey = computed(() =>\n groups.value.map((group) => `${group.name}:${group.items.join(',')}`).join('|'),\n);\nconst { visibleCount } = useToolbarOverflow(container, count, layoutKey);\nconst visible = computed(() => groups.value.slice(0, visibleCount.value));\nconst overflow = computed(() => groups.value.slice(visibleCount.value));\nfunction available(item: ToolbarItemDefinition): boolean {\n return !item.plugin || props.config.plugins.includes(item.plugin as never);\n}\nfunction positionPopover(): void {\n const toolbar = container.value;\n const anchor = popoverAnchor.value;\n const popover = toolbar?.querySelector<HTMLElement>('.erag-toolbar__popover');\n if (!toolbar || !anchor || !popover) return;\n\n const toolbarRect = toolbar.getBoundingClientRect();\n const anchorRect = anchor.getBoundingClientRect();\n const inset = 8;\n const preferredLeft = anchorRect.left - toolbarRect.left;\n const maximumLeft = Math.max(inset, toolbarRect.width - popover.offsetWidth - inset);\n popoverLeft.value = Math.min(Math.max(preferredLeft, inset), maximumLeft);\n}\nfunction togglePopover(name: string, event: MouseEvent): void {\n const willOpen = open.value !== name;\n open.value = willOpen ? name : null;\n popoverAnchor.value = willOpen ? (event.currentTarget as HTMLElement) : null;\n if (willOpen) void nextTick(positionPopover);\n}\nfunction activate(item: ToolbarItemDefinition, event: MouseEvent): void {\n if (isDisabled(item)) return;\n if (item.name === 'casechange') {\n togglePopover('casechange', event);\n } else if (item.command) emit('command', item.command);\n else if (item.dialog) {\n if (item.dialog === 'forecolor' || item.dialog === 'backcolor')\n togglePopover(item.dialog, event);\n else emit('dialog', item.dialog);\n } else if (item.name === 'more') open.value = open.value === 'more' ? null : 'more';\n}\nfunction chooseCase(mode: TextCaseMode): void {\n selectedCase.value = mode;\n emit('command', 'changeCase', mode);\n open.value = null;\n}\nfunction outside(event: PointerEvent): void {\n if (!container.value?.contains(event.target as Node)) open.value = null;\n}\nfunction isHistoryCommand(item: ToolbarItemDefinition): boolean {\n return item.command === 'undo' || item.command === 'redo';\n}\nfunction isAvailable(item: ToolbarItemDefinition): boolean {\n return Boolean(item.command && props.availableCommands[item.command]);\n}\nfunction isDisabled(item: ToolbarItemDefinition): boolean {\n return props.disabled || (isHistoryCommand(item) && !isAvailable(item));\n}\nfunction isActive(item: ToolbarItemDefinition): boolean {\n if (item.name === 'casechange') return open.value === 'casechange';\n return Boolean(item.command && !isDisabled(item) && props.activeCommands[item.command]);\n}\nfunction selectValue(item: ToolbarItemDefinition, event: Event): void {\n emit(\n 'command',\n item.select === 'blocks' ? 'formatBlock' : (item.select ?? ''),\n (event.target as HTMLSelectElement).value,\n );\n}\nfunction options(item: ToolbarItemDefinition): { label: string; value: string }[] {\n if (item.select === 'blocks') return props.config.blockFormats;\n if (item.select === 'fontfamily') return props.config.fontFamilyFormats;\n return props.config.fontSizeFormats;\n}\nfunction chooseColor(type: string, color: string): void {\n emit('command', type, color || (type === 'forecolor' ? '#000000' : 'transparent'));\n open.value = null;\n}\nonMounted(() => {\n document.addEventListener('pointerdown', outside);\n window.addEventListener('resize', positionPopover);\n});\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', outside);\n window.removeEventListener('resize', positionPopover);\n});\n</script>\n\n<template>\n <div\n ref=\"container\"\n class=\"erag-toolbar\"\n role=\"toolbar\"\n aria-label=\"Text formatting toolbar\"\n >\n <div\n v-if=\"$slots.start\"\n class=\"erag-toolbar__slot\"\n data-erag-toolbar-start\n >\n <slot name=\"start\" />\n </div>\n <div\n v-for=\"(group, index) in visible\"\n :key=\"group.name\"\n class=\"erag-toolbar__group\"\n :data-erag-toolbar-group-index=\"index\"\n >\n <template\n v-for=\"name in group.items\"\n :key=\"name\"\n >\n <select\n v-if=\"TOOLBAR_ITEMS[name].select && available(TOOLBAR_ITEMS[name])\"\n class=\"erag-toolbar__select\"\n :aria-label=\"TOOLBAR_ITEMS[name].label\"\n :disabled=\"isDisabled(TOOLBAR_ITEMS[name])\"\n @mousedown=\"$emit('command', 'saveSelection')\"\n @change=\"selectValue(TOOLBAR_ITEMS[name], $event)\"\n >\n <option value=\"\">{{ TOOLBAR_ITEMS[name].label }}</option>\n <option\n v-for=\"option in options(TOOLBAR_ITEMS[name])\"\n :key=\"option.value\"\n :value=\"option.value\"\n >\n {{ option.label }}\n </option>\n </select>\n <ToolbarButton\n v-else-if=\"available(TOOLBAR_ITEMS[name])\"\n :item=\"TOOLBAR_ITEMS[name]\"\n :active=\"isActive(TOOLBAR_ITEMS[name])\"\n :available=\"isAvailable(TOOLBAR_ITEMS[name])\"\n :disabled=\"isDisabled(TOOLBAR_ITEMS[name])\"\n @activate=\"activate\"\n />\n </template>\n </div>\n <div\n v-if=\"overflow.length\"\n class=\"erag-toolbar__overflow\"\n >\n <ToolbarButton\n :item=\"TOOLBAR_ITEMS.more\"\n :active=\"open === 'more'\"\n :available=\"false\"\n :disabled=\"disabled\"\n @activate=\"activate\"\n />\n <div\n v-if=\"open === 'more'\"\n class=\"erag-toolbar__overflow-menu\"\n role=\"menu\"\n aria-label=\"More formatting options\"\n >\n <div\n v-for=\"group in overflow\"\n :key=\"group.name\"\n class=\"erag-toolbar__overflow-group\"\n >\n <template\n v-for=\"name in group.items\"\n :key=\"name\"\n >\n <select\n v-if=\"TOOLBAR_ITEMS[name].select\"\n class=\"erag-toolbar__select erag-toolbar__select--overflow\"\n :aria-label=\"TOOLBAR_ITEMS[name].label\"\n :disabled=\"isDisabled(TOOLBAR_ITEMS[name])\"\n @mousedown=\"$emit('command', 'saveSelection')\"\n @change=\"selectValue(TOOLBAR_ITEMS[name], $event)\"\n >\n <option value=\"\">{{ TOOLBAR_ITEMS[name].label }}</option>\n <option\n v-for=\"option in options(TOOLBAR_ITEMS[name])\"\n :key=\"option.value\"\n :value=\"option.value\"\n >\n {{ option.label }}\n </option>\n </select>\n <ToolbarButton\n v-else\n :item=\"TOOLBAR_ITEMS[name]\"\n :active=\"isActive(TOOLBAR_ITEMS[name])\"\n :available=\"isAvailable(TOOLBAR_ITEMS[name])\"\n :disabled=\"isDisabled(TOOLBAR_ITEMS[name])\"\n @activate=\"activate\"\n />\n </template>\n </div>\n </div>\n </div>\n <ColorPalette\n v-if=\"open === 'forecolor'\"\n class=\"erag-toolbar__popover\"\n :style=\"popoverStyle\"\n :colors=\"config.textColors\"\n current=\"\"\n label=\"Text color\"\n @select=\"chooseColor('forecolor', $event)\"\n />\n <CaseChangeMenu\n v-if=\"open === 'casechange'\"\n class=\"erag-toolbar__popover\"\n :style=\"popoverStyle\"\n :mode=\"selectedCase\"\n @select=\"chooseCase\"\n @close=\"open = null\"\n />\n <ColorPalette\n v-if=\"open === 'backcolor'\"\n class=\"erag-toolbar__popover\"\n :style=\"popoverStyle\"\n :colors=\"config.backgroundColors\"\n current=\"\"\n label=\"Background color\"\n @select=\"chooseColor('backcolor', $event)\"\n />\n <div\n v-if=\"$slots.end\"\n class=\"erag-toolbar__slot erag-toolbar__slot--end\"\n data-erag-toolbar-end\n >\n <slot name=\"end\" />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, nextTick, onBeforeUnmount, onMounted, shallowRef, useTemplateRef } from 'vue';\nimport { TOOLBAR_ITEMS, parseToolbar } from '../config/toolbarConfig';\nimport { useToolbarOverflow } from '../composables/useToolbarOverflow';\nimport type {\n EditorToolbarGroup,\n ResolvedEditorInit,\n TextCaseMode,\n ToolbarItemDefinition,\n} from '../types';\nimport ColorPalette from './toolbar/ColorPalette.vue';\nimport CaseChangeMenu from './toolbar/CaseChangeMenu.vue';\nimport ToolbarButton from './toolbar/ToolbarButton.vue';\n\nconst props = defineProps<{\n toolbar: boolean | string | EditorToolbarGroup[];\n config: ResolvedEditorInit;\n activeCommands: Record<string, boolean>;\n availableCommands: Record<string, boolean>;\n disabled: boolean;\n insideTable: boolean;\n}>();\nconst emit = defineEmits<{ command: [id: string, value?: string]; dialog: [name: string] }>();\ndefineSlots<{ start(): unknown; end(): unknown }>();\nconst container = useTemplateRef<HTMLElement>('container');\nconst open = shallowRef<string | null>(null);\nconst selectedCase = shallowRef<TextCaseMode | null>(null);\nconst popoverAnchor = shallowRef<HTMLElement | null>(null);\nconst popoverLeft = shallowRef(8);\nconst popoverStyle = computed(() => ({ left: `${popoverLeft.value}px` }));\nconst groups = computed(() =>\n parseToolbar(props.toolbar)\n .map((group) => ({\n ...group,\n items: group.items.filter((name) => name !== 'more' && available(TOOLBAR_ITEMS[name])),\n }))\n .filter((group) => group.items.length > 0),\n);\nconst count = computed(() => groups.value.length);\nconst layoutKey = computed(() =>\n groups.value.map((group) => `${group.name}:${group.items.join(',')}`).join('|'),\n);\nconst { visibleCount } = useToolbarOverflow(container, count, layoutKey);\nconst visible = computed(() => groups.value.slice(0, visibleCount.value));\nconst overflow = computed(() => groups.value.slice(visibleCount.value));\nfunction available(item: ToolbarItemDefinition): boolean {\n return !item.plugin || props.config.plugins.includes(item.plugin as never);\n}\nfunction positionPopover(): void {\n const toolbar = container.value;\n const anchor = popoverAnchor.value;\n const popover = toolbar?.querySelector<HTMLElement>('.erag-toolbar__popover');\n if (!toolbar || !anchor || !popover) return;\n\n const toolbarRect = toolbar.getBoundingClientRect();\n const anchorRect = anchor.getBoundingClientRect();\n const inset = 8;\n const preferredLeft = anchorRect.left - toolbarRect.left;\n const maximumLeft = Math.max(inset, toolbarRect.width - popover.offsetWidth - inset);\n popoverLeft.value = Math.min(Math.max(preferredLeft, inset), maximumLeft);\n}\nfunction togglePopover(name: string, event: MouseEvent): void {\n const willOpen = open.value !== name;\n open.value = willOpen ? name : null;\n popoverAnchor.value = willOpen ? (event.currentTarget as HTMLElement) : null;\n if (willOpen) void nextTick(positionPopover);\n}\nfunction activate(item: ToolbarItemDefinition, event: MouseEvent): void {\n if (isDisabled(item)) return;\n if (item.name === 'casechange') {\n togglePopover('casechange', event);\n } else if (item.command) emit('command', item.command);\n else if (item.dialog) {\n if (item.dialog === 'forecolor' || item.dialog === 'backcolor')\n togglePopover(item.dialog, event);\n else emit('dialog', item.dialog);\n } else if (item.name === 'more') open.value = open.value === 'more' ? null : 'more';\n}\nfunction chooseCase(mode: TextCaseMode): void {\n selectedCase.value = mode;\n emit('command', 'changeCase', mode);\n open.value = null;\n}\nfunction outside(event: PointerEvent): void {\n if (!container.value?.contains(event.target as Node)) open.value = null;\n}\nfunction isHistoryCommand(item: ToolbarItemDefinition): boolean {\n return item.command === 'undo' || item.command === 'redo';\n}\nfunction isAvailable(item: ToolbarItemDefinition): boolean {\n return Boolean(item.command && props.availableCommands[item.command]);\n}\nfunction isDisabled(item: ToolbarItemDefinition): boolean {\n return props.disabled || (isHistoryCommand(item) && !isAvailable(item));\n}\nfunction isActive(item: ToolbarItemDefinition): boolean {\n if (item.name === 'casechange') return open.value === 'casechange';\n return Boolean(item.command && !isDisabled(item) && props.activeCommands[item.command]);\n}\nfunction selectValue(item: ToolbarItemDefinition, event: Event): void {\n emit(\n 'command',\n item.select === 'blocks' ? 'formatBlock' : (item.select ?? ''),\n (event.target as HTMLSelectElement).value,\n );\n}\nfunction options(item: ToolbarItemDefinition): { label: string; value: string }[] {\n if (item.select === 'blocks') return props.config.blockFormats;\n if (item.select === 'fontfamily') return props.config.fontFamilyFormats;\n return props.config.fontSizeFormats;\n}\nfunction chooseColor(type: string, color: string): void {\n emit('command', type, color || (type === 'forecolor' ? '#000000' : 'transparent'));\n open.value = null;\n}\nonMounted(() => {\n document.addEventListener('pointerdown', outside);\n window.addEventListener('resize', positionPopover);\n});\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', outside);\n window.removeEventListener('resize', positionPopover);\n});\n</script>\n\n<template>\n <div\n ref=\"container\"\n class=\"erag-toolbar\"\n role=\"toolbar\"\n aria-label=\"Text formatting toolbar\"\n >\n <div\n v-if=\"$slots.start\"\n class=\"erag-toolbar__slot\"\n data-erag-toolbar-start\n >\n <slot name=\"start\" />\n </div>\n <div\n v-for=\"(group, index) in visible\"\n :key=\"group.name\"\n class=\"erag-toolbar__group\"\n :data-erag-toolbar-group-index=\"index\"\n >\n <template\n v-for=\"name in group.items\"\n :key=\"name\"\n >\n <select\n v-if=\"TOOLBAR_ITEMS[name].select && available(TOOLBAR_ITEMS[name])\"\n class=\"erag-toolbar__select\"\n :aria-label=\"TOOLBAR_ITEMS[name].label\"\n :disabled=\"isDisabled(TOOLBAR_ITEMS[name])\"\n @mousedown=\"$emit('command', 'saveSelection')\"\n @change=\"selectValue(TOOLBAR_ITEMS[name], $event)\"\n >\n <option value=\"\">{{ TOOLBAR_ITEMS[name].label }}</option>\n <option\n v-for=\"option in options(TOOLBAR_ITEMS[name])\"\n :key=\"option.value\"\n :value=\"option.value\"\n >\n {{ option.label }}\n </option>\n </select>\n <ToolbarButton\n v-else-if=\"available(TOOLBAR_ITEMS[name])\"\n :item=\"TOOLBAR_ITEMS[name]\"\n :active=\"isActive(TOOLBAR_ITEMS[name])\"\n :available=\"isAvailable(TOOLBAR_ITEMS[name])\"\n :disabled=\"isDisabled(TOOLBAR_ITEMS[name])\"\n @activate=\"activate\"\n />\n </template>\n </div>\n <div\n v-if=\"overflow.length\"\n class=\"erag-toolbar__overflow\"\n >\n <ToolbarButton\n :item=\"TOOLBAR_ITEMS.more\"\n :active=\"open === 'more'\"\n :available=\"false\"\n :disabled=\"disabled\"\n @activate=\"activate\"\n />\n <div\n v-if=\"open === 'more'\"\n class=\"erag-toolbar__overflow-menu\"\n role=\"menu\"\n aria-label=\"More formatting options\"\n >\n <div\n v-for=\"group in overflow\"\n :key=\"group.name\"\n class=\"erag-toolbar__overflow-group\"\n >\n <template\n v-for=\"name in group.items\"\n :key=\"name\"\n >\n <select\n v-if=\"TOOLBAR_ITEMS[name].select\"\n class=\"erag-toolbar__select erag-toolbar__select--overflow\"\n :aria-label=\"TOOLBAR_ITEMS[name].label\"\n :disabled=\"isDisabled(TOOLBAR_ITEMS[name])\"\n @mousedown=\"$emit('command', 'saveSelection')\"\n @change=\"selectValue(TOOLBAR_ITEMS[name], $event)\"\n >\n <option value=\"\">{{ TOOLBAR_ITEMS[name].label }}</option>\n <option\n v-for=\"option in options(TOOLBAR_ITEMS[name])\"\n :key=\"option.value\"\n :value=\"option.value\"\n >\n {{ option.label }}\n </option>\n </select>\n <ToolbarButton\n v-else\n :item=\"TOOLBAR_ITEMS[name]\"\n :active=\"isActive(TOOLBAR_ITEMS[name])\"\n :available=\"isAvailable(TOOLBAR_ITEMS[name])\"\n :disabled=\"isDisabled(TOOLBAR_ITEMS[name])\"\n @activate=\"activate\"\n />\n </template>\n </div>\n </div>\n </div>\n <ColorPalette\n v-if=\"open === 'forecolor'\"\n class=\"erag-toolbar__popover\"\n :style=\"popoverStyle\"\n :colors=\"config.textColors\"\n current=\"\"\n label=\"Text color\"\n @select=\"chooseColor('forecolor', $event)\"\n />\n <CaseChangeMenu\n v-if=\"open === 'casechange'\"\n class=\"erag-toolbar__popover\"\n :style=\"popoverStyle\"\n :mode=\"selectedCase\"\n @select=\"chooseCase\"\n @close=\"open = null\"\n />\n <ColorPalette\n v-if=\"open === 'backcolor'\"\n class=\"erag-toolbar__popover\"\n :style=\"popoverStyle\"\n :colors=\"config.backgroundColors\"\n current=\"\"\n label=\"Background color\"\n @select=\"chooseColor('backcolor', $event)\"\n />\n <div\n v-if=\"$slots.end\"\n class=\"erag-toolbar__slot erag-toolbar__slot--end\"\n data-erag-toolbar-end\n >\n <slot name=\"end\" />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, shallowRef, watch } from 'vue';\nimport type { MentionItem } from '../../types';\n\nconst props = defineProps<{\n item: MentionItem;\n active: boolean;\n optionId: string;\n}>();\nconst emit = defineEmits<{ select: []; activate: [] }>();\ndefineSlots<{ default(props: { item: MentionItem; active: boolean }): unknown }>();\nconst avatarVisible = shallowRef(Boolean(props.item.avatar));\nconst initials = computed(() =>\n props.item.label\n .split(/\\s+/u)\n .slice(0, 2)\n .map((part) => part.charAt(0).toLocaleUpperCase())\n .join(''),\n);\n\nwatch(\n () => props.item.avatar,\n (avatar) => {\n avatarVisible.value = Boolean(avatar);\n },\n);\n</script>\n\n<template>\n <button\n :id=\"optionId\"\n type=\"button\"\n class=\"erag-mention-dropdown__item\"\n :class=\"{ 'erag-is-active': active }\"\n role=\"option\"\n :aria-selected=\"active\"\n tabindex=\"-1\"\n @pointerenter=\"emit('activate')\"\n @pointerdown.prevent=\"emit('select')\"\n >\n <slot\n :item=\"item\"\n :active=\"active\"\n >\n <img\n v-if=\"item.avatar && avatarVisible\"\n class=\"erag-mention-dropdown__avatar\"\n :src=\"item.avatar\"\n alt=\"\"\n @error=\"avatarVisible = false\"\n />\n <span\n v-else\n class=\"erag-mention-dropdown__avatar-fallback\"\n aria-hidden=\"true\"\n >\n {{ initials }}\n </span>\n <span class=\"erag-mention-dropdown__content\">\n <span class=\"erag-mention-dropdown__label\">{{ item.label }}</span>\n <span\n v-if=\"item.description\"\n class=\"erag-mention-dropdown__description\"\n >\n {{ item.description }}\n </span>\n </span>\n </slot>\n </button>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, shallowRef, watch } from 'vue';\nimport type { MentionItem } from '../../types';\n\nconst props = defineProps<{\n item: MentionItem;\n active: boolean;\n optionId: string;\n}>();\nconst emit = defineEmits<{ select: []; activate: [] }>();\ndefineSlots<{ default(props: { item: MentionItem; active: boolean }): unknown }>();\nconst avatarVisible = shallowRef(Boolean(props.item.avatar));\nconst initials = computed(() =>\n props.item.label\n .split(/\\s+/u)\n .slice(0, 2)\n .map((part) => part.charAt(0).toLocaleUpperCase())\n .join(''),\n);\n\nwatch(\n () => props.item.avatar,\n (avatar) => {\n avatarVisible.value = Boolean(avatar);\n },\n);\n</script>\n\n<template>\n <button\n :id=\"optionId\"\n type=\"button\"\n class=\"erag-mention-dropdown__item\"\n :class=\"{ 'erag-is-active': active }\"\n role=\"option\"\n :aria-selected=\"active\"\n tabindex=\"-1\"\n @pointerenter=\"emit('activate')\"\n @pointerdown.prevent=\"emit('select')\"\n >\n <slot\n :item=\"item\"\n :active=\"active\"\n >\n <img\n v-if=\"item.avatar && avatarVisible\"\n class=\"erag-mention-dropdown__avatar\"\n :src=\"item.avatar\"\n alt=\"\"\n @error=\"avatarVisible = false\"\n />\n <span\n v-else\n class=\"erag-mention-dropdown__avatar-fallback\"\n aria-hidden=\"true\"\n >\n {{ initials }}\n </span>\n <span class=\"erag-mention-dropdown__content\">\n <span class=\"erag-mention-dropdown__label\">{{ item.label }}</span>\n <span\n v-if=\"item.description\"\n class=\"erag-mention-dropdown__description\"\n >\n {{ item.description }}\n </span>\n </span>\n </slot>\n </button>\n</template>\n","<script setup lang=\"ts\">\nimport {\n computed,\n nextTick,\n onMounted,\n useId,\n useTemplateRef,\n watch,\n type CSSProperties,\n} from 'vue';\nimport type { MentionDropdownState, MentionItem } from '../../types';\nimport MentionResultItem from './MentionItem.vue';\n\nconst props = defineProps<{\n items: MentionItem[];\n activeIndex: number;\n state: MentionDropdownState;\n query: string;\n positionStyle: CSSProperties;\n}>();\nconst emit = defineEmits<{\n select: [item: MentionItem];\n activate: [index: number];\n retry: [];\n ready: [element: HTMLElement];\n}>();\ndefineSlots<{\n item(props: { item: MentionItem; active: boolean }): unknown;\n loading(props: { query: string }): unknown;\n empty(props: { query: string }): unknown;\n error(props: { query: string; retry: () => void }): unknown;\n}>();\nconst root = useTemplateRef<HTMLElement>('root');\nconst instanceId = useId().replaceAll(':', '');\nconst activeOptionId = computed(() =>\n props.state === 'results' && props.items[props.activeIndex]\n ? optionId(props.activeIndex)\n : undefined,\n);\nconst announcement = computed(() => {\n if (props.state === 'loading') return 'Loading mentions';\n if (props.state === 'error') return 'Unable to load mentions';\n if (props.state === 'empty') return 'No mentions found';\n return `${props.items.length} mention results available`;\n});\n\nfunction optionId(index: number): string {\n return `erag-mention-option-${instanceId}-${index}`;\n}\n\nfunction retry(): void {\n emit('retry');\n}\n\nwatch(\n () => props.activeIndex,\n async () => {\n await nextTick();\n const id = activeOptionId.value;\n if (id) document.getElementById(id)?.scrollIntoView({ block: 'nearest' });\n },\n);\n\nonMounted(() => {\n if (root.value) emit('ready', root.value);\n});\n</script>\n\n<template>\n <div\n ref=\"root\"\n class=\"erag-mention-dropdown\"\n :class=\"{\n 'erag-is-loading': state === 'loading',\n 'erag-is-empty': state === 'empty',\n 'erag-has-error': state === 'error',\n }\"\n :style=\"positionStyle\"\n role=\"listbox\"\n aria-label=\"Mention suggestions\"\n :aria-activedescendant=\"activeOptionId\"\n >\n <div\n class=\"erag-mention-dropdown__status\"\n aria-live=\"polite\"\n aria-atomic=\"true\"\n >\n {{ announcement }}\n </div>\n <div\n v-if=\"state === 'loading'\"\n class=\"erag-mention-dropdown__loading\"\n >\n <slot\n name=\"loading\"\n :query=\"query\"\n >\n Loading mentions…\n </slot>\n </div>\n <div\n v-else-if=\"state === 'error'\"\n class=\"erag-mention-dropdown__error\"\n >\n <slot\n name=\"error\"\n :query=\"query\"\n :retry=\"retry\"\n >\n <span>Unable to load mentions</span>\n <button\n type=\"button\"\n class=\"erag-mention-dropdown__retry\"\n @pointerdown.prevent=\"retry\"\n >\n Retry\n </button>\n </slot>\n </div>\n <div\n v-else-if=\"state === 'empty'\"\n class=\"erag-mention-dropdown__empty\"\n >\n <slot\n name=\"empty\"\n :query=\"query\"\n >\n No mentions found\n </slot>\n </div>\n <div\n v-else\n class=\"erag-mention-dropdown__list\"\n >\n <MentionResultItem\n v-for=\"(item, index) in items\"\n :key=\"item.id\"\n :item=\"item\"\n :active=\"index === activeIndex\"\n :option-id=\"optionId(index)\"\n @activate=\"emit('activate', index)\"\n @select=\"emit('select', item)\"\n >\n <template\n v-if=\"$slots.item\"\n #default=\"slotProps\"\n >\n <slot\n name=\"item\"\n v-bind=\"slotProps\"\n />\n </template>\n </MentionResultItem>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport {\n computed,\n nextTick,\n onMounted,\n useId,\n useTemplateRef,\n watch,\n type CSSProperties,\n} from 'vue';\nimport type { MentionDropdownState, MentionItem } from '../../types';\nimport MentionResultItem from './MentionItem.vue';\n\nconst props = defineProps<{\n items: MentionItem[];\n activeIndex: number;\n state: MentionDropdownState;\n query: string;\n positionStyle: CSSProperties;\n}>();\nconst emit = defineEmits<{\n select: [item: MentionItem];\n activate: [index: number];\n retry: [];\n ready: [element: HTMLElement];\n}>();\ndefineSlots<{\n item(props: { item: MentionItem; active: boolean }): unknown;\n loading(props: { query: string }): unknown;\n empty(props: { query: string }): unknown;\n error(props: { query: string; retry: () => void }): unknown;\n}>();\nconst root = useTemplateRef<HTMLElement>('root');\nconst instanceId = useId().replaceAll(':', '');\nconst activeOptionId = computed(() =>\n props.state === 'results' && props.items[props.activeIndex]\n ? optionId(props.activeIndex)\n : undefined,\n);\nconst announcement = computed(() => {\n if (props.state === 'loading') return 'Loading mentions';\n if (props.state === 'error') return 'Unable to load mentions';\n if (props.state === 'empty') return 'No mentions found';\n return `${props.items.length} mention results available`;\n});\n\nfunction optionId(index: number): string {\n return `erag-mention-option-${instanceId}-${index}`;\n}\n\nfunction retry(): void {\n emit('retry');\n}\n\nwatch(\n () => props.activeIndex,\n async () => {\n await nextTick();\n const id = activeOptionId.value;\n if (id) document.getElementById(id)?.scrollIntoView({ block: 'nearest' });\n },\n);\n\nonMounted(() => {\n if (root.value) emit('ready', root.value);\n});\n</script>\n\n<template>\n <div\n ref=\"root\"\n class=\"erag-mention-dropdown\"\n :class=\"{\n 'erag-is-loading': state === 'loading',\n 'erag-is-empty': state === 'empty',\n 'erag-has-error': state === 'error',\n }\"\n :style=\"positionStyle\"\n role=\"listbox\"\n aria-label=\"Mention suggestions\"\n :aria-activedescendant=\"activeOptionId\"\n >\n <div\n class=\"erag-mention-dropdown__status\"\n aria-live=\"polite\"\n aria-atomic=\"true\"\n >\n {{ announcement }}\n </div>\n <div\n v-if=\"state === 'loading'\"\n class=\"erag-mention-dropdown__loading\"\n >\n <slot\n name=\"loading\"\n :query=\"query\"\n >\n Loading mentions…\n </slot>\n </div>\n <div\n v-else-if=\"state === 'error'\"\n class=\"erag-mention-dropdown__error\"\n >\n <slot\n name=\"error\"\n :query=\"query\"\n :retry=\"retry\"\n >\n <span>Unable to load mentions</span>\n <button\n type=\"button\"\n class=\"erag-mention-dropdown__retry\"\n @pointerdown.prevent=\"retry\"\n >\n Retry\n </button>\n </slot>\n </div>\n <div\n v-else-if=\"state === 'empty'\"\n class=\"erag-mention-dropdown__empty\"\n >\n <slot\n name=\"empty\"\n :query=\"query\"\n >\n No mentions found\n </slot>\n </div>\n <div\n v-else\n class=\"erag-mention-dropdown__list\"\n >\n <MentionResultItem\n v-for=\"(item, index) in items\"\n :key=\"item.id\"\n :item=\"item\"\n :active=\"index === activeIndex\"\n :option-id=\"optionId(index)\"\n @activate=\"emit('activate', index)\"\n @select=\"emit('select', item)\"\n >\n <template\n v-if=\"$slots.item\"\n #default=\"slotProps\"\n >\n <slot\n name=\"item\"\n v-bind=\"slotProps\"\n />\n </template>\n </MentionResultItem>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, onMounted, shallowRef, useTemplateRef, watch, type CSSProperties } from 'vue';\nimport type { MentionItem } from '../../types';\n\nconst props = defineProps<{\n item: MentionItem;\n positionStyle: CSSProperties;\n}>();\nconst emit = defineEmits<{ ready: [element: HTMLElement] }>();\nconst root = useTemplateRef<HTMLElement>('root');\nconst avatarVisible = shallowRef(Boolean(props.item.avatar));\nconst initials = computed(() =>\n props.item.label\n .split(/\\s+/u)\n .slice(0, 2)\n .map((part) => part.charAt(0).toLocaleUpperCase())\n .join(''),\n);\n\nwatch(\n () => props.item.avatar,\n (avatar) => {\n avatarVisible.value = Boolean(avatar);\n },\n);\n\nonMounted(() => {\n if (root.value) emit('ready', root.value);\n});\n</script>\n\n<template>\n <div\n ref=\"root\"\n class=\"erag-mention-hover-card\"\n :style=\"positionStyle\"\n role=\"tooltip\"\n >\n <img\n v-if=\"item.avatar && avatarVisible\"\n class=\"erag-mention-hover-card__avatar\"\n :src=\"item.avatar\"\n alt=\"\"\n @error=\"avatarVisible = false\"\n />\n <span\n v-else\n class=\"erag-mention-hover-card__avatar-fallback\"\n aria-hidden=\"true\"\n >\n {{ initials }}\n </span>\n <span class=\"erag-mention-hover-card__content\">\n <span class=\"erag-mention-hover-card__label\">{{ item.label }}</span>\n <span\n v-if=\"item.description\"\n class=\"erag-mention-hover-card__description\"\n >\n {{ item.description }}\n </span>\n <span\n v-if=\"item.value\"\n class=\"erag-mention-hover-card__value\"\n >\n {{ item.value }}\n </span>\n </span>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, onMounted, shallowRef, useTemplateRef, watch, type CSSProperties } from 'vue';\nimport type { MentionItem } from '../../types';\n\nconst props = defineProps<{\n item: MentionItem;\n positionStyle: CSSProperties;\n}>();\nconst emit = defineEmits<{ ready: [element: HTMLElement] }>();\nconst root = useTemplateRef<HTMLElement>('root');\nconst avatarVisible = shallowRef(Boolean(props.item.avatar));\nconst initials = computed(() =>\n props.item.label\n .split(/\\s+/u)\n .slice(0, 2)\n .map((part) => part.charAt(0).toLocaleUpperCase())\n .join(''),\n);\n\nwatch(\n () => props.item.avatar,\n (avatar) => {\n avatarVisible.value = Boolean(avatar);\n },\n);\n\nonMounted(() => {\n if (root.value) emit('ready', root.value);\n});\n</script>\n\n<template>\n <div\n ref=\"root\"\n class=\"erag-mention-hover-card\"\n :style=\"positionStyle\"\n role=\"tooltip\"\n >\n <img\n v-if=\"item.avatar && avatarVisible\"\n class=\"erag-mention-hover-card__avatar\"\n :src=\"item.avatar\"\n alt=\"\"\n @error=\"avatarVisible = false\"\n />\n <span\n v-else\n class=\"erag-mention-hover-card__avatar-fallback\"\n aria-hidden=\"true\"\n >\n {{ initials }}\n </span>\n <span class=\"erag-mention-hover-card__content\">\n <span class=\"erag-mention-hover-card__label\">{{ item.label }}</span>\n <span\n v-if=\"item.description\"\n class=\"erag-mention-hover-card__description\"\n >\n {{ item.description }}\n </span>\n <span\n v-if=\"item.value\"\n class=\"erag-mention-hover-card__value\"\n >\n {{ item.value }}\n </span>\n </span>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, onMounted, useId, useTemplateRef, type CSSProperties } from 'vue';\nimport type { MergeTagItem } from '../../types';\nimport { formatMergeTagValue } from '../../utils/mergeTag';\n\nconst props = defineProps<{\n items: MergeTagItem[];\n activeIndex: number;\n query: string;\n positionStyle: CSSProperties;\n}>();\nconst emit = defineEmits<{\n select: [item: MergeTagItem];\n activate: [index: number];\n ready: [element: HTMLElement];\n}>();\nconst root = useTemplateRef<HTMLElement>('root');\nconst instanceId = useId().replaceAll(':', '');\nconst activeId = computed(() =>\n props.items[props.activeIndex]\n ? `erag-merge-tag-option-${instanceId}-${props.activeIndex}`\n : undefined,\n);\nconst sections = computed(() => {\n const groupedItems = new Map<string, { item: MergeTagItem; index: number }[]>();\n props.items.forEach((item, index) => {\n const group = item.group?.trim() ?? '';\n const entries = groupedItems.get(group) ?? [];\n entries.push({ item, index });\n groupedItems.set(group, entries);\n });\n return [...groupedItems].map(([label, entries]) => ({ label, entries }));\n});\n\nonMounted(() => {\n if (root.value) emit('ready', root.value);\n});\n</script>\n\n<template>\n <div\n ref=\"root\"\n class=\"erag-merge-tag-dropdown\"\n :style=\"positionStyle\"\n role=\"listbox\"\n aria-label=\"Merge tag suggestions\"\n :aria-activedescendant=\"activeId\"\n >\n <div\n class=\"erag-merge-tag-dropdown__status\"\n aria-live=\"polite\"\n >\n {{ items.length }} merge tag suggestions for {{ query }}\n </div>\n <div\n v-if=\"items.length\"\n class=\"erag-merge-tag-dropdown__list\"\n >\n <div\n v-for=\"section in sections\"\n :key=\"section.label || 'ungrouped'\"\n class=\"erag-merge-tag-dropdown__section\"\n role=\"group\"\n :aria-label=\"section.label || 'Merge tags'\"\n >\n <span\n v-if=\"section.label\"\n class=\"erag-merge-tag-dropdown__section-title\"\n >{{ section.label }}</span\n >\n <button\n v-for=\"entry in section.entries\"\n :id=\"`erag-merge-tag-option-${instanceId}-${entry.index}`\"\n :key=\"`${entry.item.value}-${entry.index}`\"\n type=\"button\"\n class=\"erag-merge-tag-dropdown__item\"\n :class=\"{ 'erag-is-active': entry.index === activeIndex }\"\n role=\"option\"\n :aria-selected=\"entry.index === activeIndex\"\n tabindex=\"-1\"\n @pointerenter=\"emit('activate', entry.index)\"\n @pointerdown.prevent=\"emit('select', entry.item)\"\n >\n <span class=\"erag-merge-tag-dropdown__label\">\n {{ formatMergeTagValue(entry.item.value) }}\n </span>\n </button>\n </div>\n </div>\n <div\n v-else\n class=\"erag-merge-tag-dropdown__empty\"\n role=\"status\"\n >\n No merge tags found\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, onMounted, useId, useTemplateRef, type CSSProperties } from 'vue';\nimport type { MergeTagItem } from '../../types';\nimport { formatMergeTagValue } from '../../utils/mergeTag';\n\nconst props = defineProps<{\n items: MergeTagItem[];\n activeIndex: number;\n query: string;\n positionStyle: CSSProperties;\n}>();\nconst emit = defineEmits<{\n select: [item: MergeTagItem];\n activate: [index: number];\n ready: [element: HTMLElement];\n}>();\nconst root = useTemplateRef<HTMLElement>('root');\nconst instanceId = useId().replaceAll(':', '');\nconst activeId = computed(() =>\n props.items[props.activeIndex]\n ? `erag-merge-tag-option-${instanceId}-${props.activeIndex}`\n : undefined,\n);\nconst sections = computed(() => {\n const groupedItems = new Map<string, { item: MergeTagItem; index: number }[]>();\n props.items.forEach((item, index) => {\n const group = item.group?.trim() ?? '';\n const entries = groupedItems.get(group) ?? [];\n entries.push({ item, index });\n groupedItems.set(group, entries);\n });\n return [...groupedItems].map(([label, entries]) => ({ label, entries }));\n});\n\nonMounted(() => {\n if (root.value) emit('ready', root.value);\n});\n</script>\n\n<template>\n <div\n ref=\"root\"\n class=\"erag-merge-tag-dropdown\"\n :style=\"positionStyle\"\n role=\"listbox\"\n aria-label=\"Merge tag suggestions\"\n :aria-activedescendant=\"activeId\"\n >\n <div\n class=\"erag-merge-tag-dropdown__status\"\n aria-live=\"polite\"\n >\n {{ items.length }} merge tag suggestions for {{ query }}\n </div>\n <div\n v-if=\"items.length\"\n class=\"erag-merge-tag-dropdown__list\"\n >\n <div\n v-for=\"section in sections\"\n :key=\"section.label || 'ungrouped'\"\n class=\"erag-merge-tag-dropdown__section\"\n role=\"group\"\n :aria-label=\"section.label || 'Merge tags'\"\n >\n <span\n v-if=\"section.label\"\n class=\"erag-merge-tag-dropdown__section-title\"\n >{{ section.label }}</span\n >\n <button\n v-for=\"entry in section.entries\"\n :id=\"`erag-merge-tag-option-${instanceId}-${entry.index}`\"\n :key=\"`${entry.item.value}-${entry.index}`\"\n type=\"button\"\n class=\"erag-merge-tag-dropdown__item\"\n :class=\"{ 'erag-is-active': entry.index === activeIndex }\"\n role=\"option\"\n :aria-selected=\"entry.index === activeIndex\"\n tabindex=\"-1\"\n @pointerenter=\"emit('activate', entry.index)\"\n @pointerdown.prevent=\"emit('select', entry.item)\"\n >\n <span class=\"erag-merge-tag-dropdown__label\">\n {{ formatMergeTagValue(entry.item.value) }}\n </span>\n </button>\n </div>\n </div>\n <div\n v-else\n class=\"erag-merge-tag-dropdown__empty\"\n role=\"status\"\n >\n No merge tags found\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, onMounted } from 'vue';\nimport type { MergeTagItem } from '../../types';\nimport { formatMergeTagValue } from '../../utils/mergeTag';\nimport EditorIcon from '../icons/EditorIcon.vue';\n\nconst props = defineProps<{\n id: string;\n items: MergeTagItem[];\n disabled: boolean;\n}>();\nconst emit = defineEmits<{\n close: [];\n select: [item: MergeTagItem];\n}>();\nconst groups = computed(() => {\n const groupedItems = new Map<string, MergeTagItem[]>();\n for (const item of props.items) {\n const group = item.group?.trim() ?? '';\n const items = groupedItems.get(group) ?? [];\n items.push(item);\n groupedItems.set(group, items);\n }\n return [...groupedItems].map(([label, items]) => ({ label, items }));\n});\n\nfunction keydown(event: KeyboardEvent): void {\n if (event.key === 'Escape') emit('close');\n}\n\nonMounted(() => document.addEventListener('keydown', keydown));\nonBeforeUnmount(() => document.removeEventListener('keydown', keydown));\n</script>\n\n<template>\n <aside\n :id=\"id\"\n class=\"erag-merge-tag-sidebar\"\n aria-label=\"Merge tags\"\n >\n <header class=\"erag-merge-tag-sidebar__header\">\n <span class=\"erag-merge-tag-sidebar__title\">Merge tag</span>\n <button\n type=\"button\"\n class=\"erag-merge-tag-sidebar__close\"\n aria-label=\"Close merge tags\"\n @mousedown.prevent\n @click=\"emit('close')\"\n >\n <EditorIcon\n name=\"close\"\n :size=\"18\"\n />\n </button>\n </header>\n <div class=\"erag-merge-tag-sidebar__body\">\n <section\n v-for=\"group in groups\"\n :key=\"group.label\"\n class=\"erag-merge-tag-sidebar__group\"\n >\n <h3\n v-if=\"group.label\"\n class=\"erag-merge-tag-sidebar__group-title\"\n >\n {{ group.label }}\n </h3>\n <div class=\"erag-merge-tag-sidebar__list\">\n <button\n v-for=\"item in group.items\"\n :key=\"item.value\"\n type=\"button\"\n class=\"erag-merge-tag-sidebar__item\"\n :disabled=\"disabled\"\n @mousedown.prevent\n @click=\"emit('select', item)\"\n >\n <span class=\"erag-merge-tag-sidebar__item-value\">\n {{ formatMergeTagValue(item.value) }}\n </span>\n </button>\n </div>\n </section>\n <p\n v-if=\"groups.length === 0\"\n class=\"erag-merge-tag-sidebar__empty\"\n >\n No merge tags configured\n </p>\n </div>\n </aside>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, onMounted } from 'vue';\nimport type { MergeTagItem } from '../../types';\nimport { formatMergeTagValue } from '../../utils/mergeTag';\nimport EditorIcon from '../icons/EditorIcon.vue';\n\nconst props = defineProps<{\n id: string;\n items: MergeTagItem[];\n disabled: boolean;\n}>();\nconst emit = defineEmits<{\n close: [];\n select: [item: MergeTagItem];\n}>();\nconst groups = computed(() => {\n const groupedItems = new Map<string, MergeTagItem[]>();\n for (const item of props.items) {\n const group = item.group?.trim() ?? '';\n const items = groupedItems.get(group) ?? [];\n items.push(item);\n groupedItems.set(group, items);\n }\n return [...groupedItems].map(([label, items]) => ({ label, items }));\n});\n\nfunction keydown(event: KeyboardEvent): void {\n if (event.key === 'Escape') emit('close');\n}\n\nonMounted(() => document.addEventListener('keydown', keydown));\nonBeforeUnmount(() => document.removeEventListener('keydown', keydown));\n</script>\n\n<template>\n <aside\n :id=\"id\"\n class=\"erag-merge-tag-sidebar\"\n aria-label=\"Merge tags\"\n >\n <header class=\"erag-merge-tag-sidebar__header\">\n <span class=\"erag-merge-tag-sidebar__title\">Merge tag</span>\n <button\n type=\"button\"\n class=\"erag-merge-tag-sidebar__close\"\n aria-label=\"Close merge tags\"\n @mousedown.prevent\n @click=\"emit('close')\"\n >\n <EditorIcon\n name=\"close\"\n :size=\"18\"\n />\n </button>\n </header>\n <div class=\"erag-merge-tag-sidebar__body\">\n <section\n v-for=\"group in groups\"\n :key=\"group.label\"\n class=\"erag-merge-tag-sidebar__group\"\n >\n <h3\n v-if=\"group.label\"\n class=\"erag-merge-tag-sidebar__group-title\"\n >\n {{ group.label }}\n </h3>\n <div class=\"erag-merge-tag-sidebar__list\">\n <button\n v-for=\"item in group.items\"\n :key=\"item.value\"\n type=\"button\"\n class=\"erag-merge-tag-sidebar__item\"\n :disabled=\"disabled\"\n @mousedown.prevent\n @click=\"emit('select', item)\"\n >\n <span class=\"erag-merge-tag-sidebar__item-value\">\n {{ formatMergeTagValue(item.value) }}\n </span>\n </button>\n </div>\n </section>\n <p\n v-if=\"groups.length === 0\"\n class=\"erag-merge-tag-sidebar__empty\"\n >\n No merge tags configured\n </p>\n </div>\n </aside>\n</template>\n","import type { ImageResizeHandle } from '../types';\n\nexport const IMAGE_RESIZE_HANDLES: readonly ImageResizeHandle[] = [\n 'north-west',\n 'north-east',\n 'south-west',\n 'south-east',\n];\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { IMAGE_RESIZE_HANDLES } from '../../constants/imageResize';\nimport type { ImageResizeBox, ImageResizeHandle } from '../../types';\nimport EditorIcon from '../icons/EditorIcon.vue';\n\nconst props = defineProps<{\n box: ImageResizeBox;\n deleting: boolean;\n deleteError: string;\n deleteFromServer: boolean;\n}>();\nconst emit = defineEmits<{\n resizeStart: [event: PointerEvent, handle: ImageResizeHandle];\n delete: [];\n}>();\nconst overlayStyle = computed(() => ({\n top: `${props.box.top}px`,\n left: `${props.box.left}px`,\n width: `${props.box.width}px`,\n height: `${props.box.height}px`,\n}));\nconst deleteLabel = computed(\n () =>\n props.deleteError ||\n (props.deleteFromServer ? 'Delete from server' : 'Delete image from editor'),\n);\n</script>\n\n<template>\n <div\n class=\"erag-image-resize\"\n :style=\"overlayStyle\"\n >\n <button\n v-for=\"handle in IMAGE_RESIZE_HANDLES\"\n :key=\"handle\"\n type=\"button\"\n class=\"erag-image-resize__handle\"\n :class=\"`erag-image-resize__handle--${handle}`\"\n tabindex=\"-1\"\n :aria-label=\"`Resize image from ${handle.replace('-', ' ')}`\"\n @pointerdown=\"emit('resizeStart', $event, handle)\"\n />\n <button\n type=\"button\"\n class=\"erag-image-resize__delete\"\n :class=\"{ 'erag-is-loading': deleting, 'erag-has-error': deleteError }\"\n :disabled=\"deleting\"\n :aria-label=\"deleteLabel\"\n :aria-busy=\"deleting\"\n :data-erag-tooltip=\"deleteLabel\"\n @pointerdown.prevent.stop\n @click.stop=\"emit('delete')\"\n >\n <EditorIcon\n name=\"trash\"\n :size=\"17\"\n />\n </button>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { IMAGE_RESIZE_HANDLES } from '../../constants/imageResize';\nimport type { ImageResizeBox, ImageResizeHandle } from '../../types';\nimport EditorIcon from '../icons/EditorIcon.vue';\n\nconst props = defineProps<{\n box: ImageResizeBox;\n deleting: boolean;\n deleteError: string;\n deleteFromServer: boolean;\n}>();\nconst emit = defineEmits<{\n resizeStart: [event: PointerEvent, handle: ImageResizeHandle];\n delete: [];\n}>();\nconst overlayStyle = computed(() => ({\n top: `${props.box.top}px`,\n left: `${props.box.left}px`,\n width: `${props.box.width}px`,\n height: `${props.box.height}px`,\n}));\nconst deleteLabel = computed(\n () =>\n props.deleteError ||\n (props.deleteFromServer ? 'Delete from server' : 'Delete image from editor'),\n);\n</script>\n\n<template>\n <div\n class=\"erag-image-resize\"\n :style=\"overlayStyle\"\n >\n <button\n v-for=\"handle in IMAGE_RESIZE_HANDLES\"\n :key=\"handle\"\n type=\"button\"\n class=\"erag-image-resize__handle\"\n :class=\"`erag-image-resize__handle--${handle}`\"\n tabindex=\"-1\"\n :aria-label=\"`Resize image from ${handle.replace('-', ' ')}`\"\n @pointerdown=\"emit('resizeStart', $event, handle)\"\n />\n <button\n type=\"button\"\n class=\"erag-image-resize__delete\"\n :class=\"{ 'erag-is-loading': deleting, 'erag-has-error': deleteError }\"\n :disabled=\"deleting\"\n :aria-label=\"deleteLabel\"\n :aria-busy=\"deleting\"\n :data-erag-tooltip=\"deleteLabel\"\n @pointerdown.prevent.stop\n @click.stop=\"emit('delete')\"\n >\n <EditorIcon\n name=\"trash\"\n :size=\"17\"\n />\n </button>\n </div>\n</template>\n","import { nextTick, onBeforeUnmount, onMounted, shallowRef, watch, type Ref } from 'vue';\n\nconst VIEWPORT_PADDING = 8;\nconst FLOATING_GAP = 6;\n\nexport function useFloatingPosition(\n trigger: Ref<HTMLElement | null>,\n panel: Ref<HTMLElement | null>,\n boundary?: Ref<HTMLElement | null>,\n) {\n const style = shallowRef<Record<string, string>>({\n position: 'fixed',\n left: '-9999px',\n top: '-9999px',\n });\n let frame = 0;\n let resizeObserver: ResizeObserver | null = null;\n let activeTrigger: HTMLElement | null = null;\n let placeAbove: boolean | null = null;\n const boundaryRef = boundary ?? shallowRef<HTMLElement | null>(null);\n\n async function update(): Promise<void> {\n await nextTick();\n if (!trigger.value || !panel.value) return;\n if (activeTrigger !== trigger.value) {\n activeTrigger = trigger.value;\n placeAbove = null;\n }\n const a = trigger.value.getBoundingClientRect();\n const p = panel.value.getBoundingClientRect();\n const bounds = boundaryRef.value?.getBoundingClientRect();\n const triggerOutsideBoundary =\n bounds &&\n (a.bottom <= bounds.top ||\n a.top >= bounds.bottom ||\n a.right <= bounds.left ||\n a.left >= bounds.right);\n if (triggerOutsideBoundary) {\n style.value = {\n position: 'fixed',\n left: '-9999px',\n top: '-9999px',\n visibility: 'hidden',\n pointerEvents: 'none',\n };\n return;\n }\n const minLeft = Math.max(\n VIEWPORT_PADDING,\n bounds ? bounds.left + VIEWPORT_PADDING : VIEWPORT_PADDING,\n );\n const maxRight = Math.min(\n window.innerWidth - VIEWPORT_PADDING,\n bounds ? bounds.right - VIEWPORT_PADDING : window.innerWidth - VIEWPORT_PADDING,\n );\n const minTop = Math.max(\n VIEWPORT_PADDING,\n bounds ? bounds.top + VIEWPORT_PADDING : VIEWPORT_PADDING,\n );\n const maxBottom = Math.min(\n window.innerHeight - VIEWPORT_PADDING,\n bounds ? bounds.bottom - VIEWPORT_PADDING : window.innerHeight - VIEWPORT_PADDING,\n );\n const maxLeft = Math.max(minLeft, maxRight - p.width);\n const left = Math.max(minLeft, Math.min(a.left, maxLeft));\n const below = a.bottom + FLOATING_GAP;\n const above = a.top - p.height - FLOATING_GAP;\n if (placeAbove === null) {\n const spaceBelow = maxBottom - a.bottom - FLOATING_GAP;\n const spaceAbove = a.top - minTop - FLOATING_GAP;\n placeAbove = spaceBelow < p.height && spaceAbove > spaceBelow;\n }\n const preferredTop = placeAbove ? above : below;\n const maxTop = Math.max(minTop, maxBottom - p.height);\n const top = Math.max(minTop, Math.min(preferredTop, maxTop));\n style.value = {\n position: 'fixed',\n left: `${left}px`,\n top: `${top}px`,\n };\n }\n\n function scheduleUpdate(): void {\n cancelAnimationFrame(frame);\n frame = requestAnimationFrame(() => void update());\n }\n\n watch(\n [trigger, panel, boundaryRef],\n () => {\n if (!trigger.value) {\n activeTrigger = null;\n placeAbove = null;\n }\n resizeObserver?.disconnect();\n resizeObserver = null;\n if (trigger.value && panel.value && typeof ResizeObserver !== 'undefined') {\n resizeObserver = new ResizeObserver(scheduleUpdate);\n resizeObserver.observe(trigger.value);\n resizeObserver.observe(panel.value);\n if (boundaryRef.value) {\n resizeObserver.observe(boundaryRef.value);\n }\n }\n scheduleUpdate();\n },\n { flush: 'post' },\n );\n onMounted(() => {\n window.addEventListener('resize', scheduleUpdate);\n window.addEventListener('scroll', scheduleUpdate, true);\n scheduleUpdate();\n });\n onBeforeUnmount(() => {\n cancelAnimationFrame(frame);\n resizeObserver?.disconnect();\n window.removeEventListener('resize', scheduleUpdate);\n window.removeEventListener('scroll', scheduleUpdate, true);\n });\n\n return { style, update: scheduleUpdate };\n}\n","<script setup lang=\"ts\">\nimport { computed, nextTick, shallowRef, useId, useTemplateRef, watch } from 'vue';\nimport EditorIcon from '../icons/EditorIcon.vue';\n\nconst props = defineProps<{\n acceptedFormats: string[];\n filePicker: boolean;\n urlInput: boolean;\n loading: boolean;\n progress: number;\n error: string;\n}>();\nconst emit = defineEmits<{\n file: [file: File];\n insertUrl: [url: string];\n close: [];\n}>();\nconst fileInput = useTemplateRef<HTMLInputElement>('fileInput');\nconst urlField = useTemplateRef<HTMLInputElement>('urlField');\nconst urlInputId = useId();\nconst url = shallowRef('');\nconst mode = shallowRef<'actions' | 'url'>('actions');\nconst isDragging = shallowRef(false);\nconst accept = computed(() => props.acceptedFormats.join(','));\n\nfunction chooseFile(): void {\n if (props.filePicker && !props.loading) fileInput.value?.click();\n}\n\nfunction selectFile(file: File | undefined): void {\n if (!file || props.loading) return;\n emit('file', file);\n if (fileInput.value) fileInput.value.value = '';\n}\n\nfunction drop(event: DragEvent): void {\n isDragging.value = false;\n if (props.filePicker) selectFile(event.dataTransfer?.files[0]);\n}\n\nfunction submitUrl(): void {\n if (url.value.trim() && !props.loading) emit('insertUrl', url.value);\n}\n\nwatch(mode, (value) => {\n if (value === 'url') void nextTick(() => urlField.value?.focus());\n});\n</script>\n\n<template>\n <span\n class=\"erag-inline-image-upload\"\n :class=\"{\n 'erag-is-dragging': isDragging,\n 'erag-is-loading': loading,\n 'erag-has-error': error,\n }\"\n role=\"group\"\n aria-label=\"Insert image\"\n @keydown.esc.prevent=\"emit('close')\"\n @dragenter.prevent=\"isDragging = true\"\n @dragover.prevent\n @dragleave.prevent=\"isDragging = false\"\n @drop.prevent=\"drop\"\n >\n <input\n ref=\"fileInput\"\n class=\"erag-inline-image-upload__file\"\n type=\"file\"\n :accept=\"accept\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n @change=\"selectFile(($event.target as HTMLInputElement).files?.[0])\"\n />\n <button\n v-if=\"mode === 'actions'\"\n class=\"erag-inline-image-upload__dropzone\"\n type=\"button\"\n :disabled=\"loading || !filePicker\"\n @click=\"chooseFile\"\n >\n <span class=\"erag-inline-image-upload__illustration\">\n <EditorIcon\n name=\"image\"\n :size=\"34\"\n />\n </span>\n <span class=\"erag-inline-image-upload__title\">\n {{ loading ? 'Uploading image…' : 'Drop files here' }}\n </span>\n <span\n v-if=\"loading\"\n class=\"erag-inline-image-upload__progress-label\"\n >\n {{ Math.round(progress) }}%\n </span>\n </button>\n <form\n v-else\n class=\"erag-inline-image-upload__url-form\"\n @submit.prevent=\"submitUrl\"\n >\n <label\n class=\"erag-inline-image-upload__url-label\"\n :for=\"urlInputId\"\n >Image URL</label\n >\n <span class=\"erag-inline-image-upload__url-row\">\n <input\n :id=\"urlInputId\"\n ref=\"urlField\"\n v-model=\"url\"\n class=\"erag-inline-image-upload__url-input\"\n type=\"text\"\n inputmode=\"url\"\n autocomplete=\"url\"\n placeholder=\"https://example.com/image.jpg\"\n />\n <button\n class=\"erag-inline-image-upload__insert\"\n type=\"submit\"\n :disabled=\"loading || !url.trim()\"\n >\n Insert\n </button>\n </span>\n </form>\n <progress\n v-if=\"loading\"\n class=\"erag-inline-image-upload__progress\"\n max=\"100\"\n :value=\"progress > 0 ? progress : undefined\"\n >\n {{ progress }}%\n </progress>\n <span\n v-if=\"error\"\n class=\"erag-inline-image-upload__error\"\n role=\"alert\"\n >\n {{ error }}\n </span>\n <span class=\"erag-inline-image-upload__actions\">\n <button\n v-if=\"filePicker\"\n class=\"erag-inline-image-upload__action\"\n type=\"button\"\n title=\"Upload from device\"\n aria-label=\"Upload from device\"\n :disabled=\"loading\"\n @click=\"chooseFile\"\n >\n <EditorIcon\n name=\"upload\"\n :size=\"18\"\n />\n </button>\n <button\n v-if=\"urlInput\"\n class=\"erag-inline-image-upload__action\"\n :class=\"{ 'erag-is-active': mode === 'url' }\"\n type=\"button\"\n title=\"Upload from URL\"\n aria-label=\"Upload from URL\"\n :disabled=\"loading\"\n @click=\"mode = mode === 'url' ? 'actions' : 'url'\"\n >\n <EditorIcon\n name=\"link\"\n :size=\"18\"\n />\n </button>\n <button\n class=\"erag-inline-image-upload__action erag-inline-image-upload__action--close\"\n type=\"button\"\n title=\"Cancel image upload\"\n aria-label=\"Cancel image upload\"\n @click=\"emit('close')\"\n >\n <EditorIcon\n name=\"close\"\n :size=\"17\"\n />\n </button>\n </span>\n </span>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, nextTick, shallowRef, useId, useTemplateRef, watch } from 'vue';\nimport EditorIcon from '../icons/EditorIcon.vue';\n\nconst props = defineProps<{\n acceptedFormats: string[];\n filePicker: boolean;\n urlInput: boolean;\n loading: boolean;\n progress: number;\n error: string;\n}>();\nconst emit = defineEmits<{\n file: [file: File];\n insertUrl: [url: string];\n close: [];\n}>();\nconst fileInput = useTemplateRef<HTMLInputElement>('fileInput');\nconst urlField = useTemplateRef<HTMLInputElement>('urlField');\nconst urlInputId = useId();\nconst url = shallowRef('');\nconst mode = shallowRef<'actions' | 'url'>('actions');\nconst isDragging = shallowRef(false);\nconst accept = computed(() => props.acceptedFormats.join(','));\n\nfunction chooseFile(): void {\n if (props.filePicker && !props.loading) fileInput.value?.click();\n}\n\nfunction selectFile(file: File | undefined): void {\n if (!file || props.loading) return;\n emit('file', file);\n if (fileInput.value) fileInput.value.value = '';\n}\n\nfunction drop(event: DragEvent): void {\n isDragging.value = false;\n if (props.filePicker) selectFile(event.dataTransfer?.files[0]);\n}\n\nfunction submitUrl(): void {\n if (url.value.trim() && !props.loading) emit('insertUrl', url.value);\n}\n\nwatch(mode, (value) => {\n if (value === 'url') void nextTick(() => urlField.value?.focus());\n});\n</script>\n\n<template>\n <span\n class=\"erag-inline-image-upload\"\n :class=\"{\n 'erag-is-dragging': isDragging,\n 'erag-is-loading': loading,\n 'erag-has-error': error,\n }\"\n role=\"group\"\n aria-label=\"Insert image\"\n @keydown.esc.prevent=\"emit('close')\"\n @dragenter.prevent=\"isDragging = true\"\n @dragover.prevent\n @dragleave.prevent=\"isDragging = false\"\n @drop.prevent=\"drop\"\n >\n <input\n ref=\"fileInput\"\n class=\"erag-inline-image-upload__file\"\n type=\"file\"\n :accept=\"accept\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n @change=\"selectFile(($event.target as HTMLInputElement).files?.[0])\"\n />\n <button\n v-if=\"mode === 'actions'\"\n class=\"erag-inline-image-upload__dropzone\"\n type=\"button\"\n :disabled=\"loading || !filePicker\"\n @click=\"chooseFile\"\n >\n <span class=\"erag-inline-image-upload__illustration\">\n <EditorIcon\n name=\"image\"\n :size=\"34\"\n />\n </span>\n <span class=\"erag-inline-image-upload__title\">\n {{ loading ? 'Uploading image…' : 'Drop files here' }}\n </span>\n <span\n v-if=\"loading\"\n class=\"erag-inline-image-upload__progress-label\"\n >\n {{ Math.round(progress) }}%\n </span>\n </button>\n <form\n v-else\n class=\"erag-inline-image-upload__url-form\"\n @submit.prevent=\"submitUrl\"\n >\n <label\n class=\"erag-inline-image-upload__url-label\"\n :for=\"urlInputId\"\n >Image URL</label\n >\n <span class=\"erag-inline-image-upload__url-row\">\n <input\n :id=\"urlInputId\"\n ref=\"urlField\"\n v-model=\"url\"\n class=\"erag-inline-image-upload__url-input\"\n type=\"text\"\n inputmode=\"url\"\n autocomplete=\"url\"\n placeholder=\"https://example.com/image.jpg\"\n />\n <button\n class=\"erag-inline-image-upload__insert\"\n type=\"submit\"\n :disabled=\"loading || !url.trim()\"\n >\n Insert\n </button>\n </span>\n </form>\n <progress\n v-if=\"loading\"\n class=\"erag-inline-image-upload__progress\"\n max=\"100\"\n :value=\"progress > 0 ? progress : undefined\"\n >\n {{ progress }}%\n </progress>\n <span\n v-if=\"error\"\n class=\"erag-inline-image-upload__error\"\n role=\"alert\"\n >\n {{ error }}\n </span>\n <span class=\"erag-inline-image-upload__actions\">\n <button\n v-if=\"filePicker\"\n class=\"erag-inline-image-upload__action\"\n type=\"button\"\n title=\"Upload from device\"\n aria-label=\"Upload from device\"\n :disabled=\"loading\"\n @click=\"chooseFile\"\n >\n <EditorIcon\n name=\"upload\"\n :size=\"18\"\n />\n </button>\n <button\n v-if=\"urlInput\"\n class=\"erag-inline-image-upload__action\"\n :class=\"{ 'erag-is-active': mode === 'url' }\"\n type=\"button\"\n title=\"Upload from URL\"\n aria-label=\"Upload from URL\"\n :disabled=\"loading\"\n @click=\"mode = mode === 'url' ? 'actions' : 'url'\"\n >\n <EditorIcon\n name=\"link\"\n :size=\"18\"\n />\n </button>\n <button\n class=\"erag-inline-image-upload__action erag-inline-image-upload__action--close\"\n type=\"button\"\n title=\"Cancel image upload\"\n aria-label=\"Cancel image upload\"\n @click=\"emit('close')\"\n >\n <EditorIcon\n name=\"close\"\n :size=\"17\"\n />\n </button>\n </span>\n </span>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, toRef, useTemplateRef } from 'vue';\nimport { useFloatingPosition } from '../../composables/useFloatingPosition';\nimport type { ResolvedEditorInit, UploadState } from '../../types';\nimport InlineImageUpload from './InlineImageUpload.vue';\n\nconst props = defineProps<{\n target: HTMLElement | null;\n config: ResolvedEditorInit;\n state: UploadState;\n error: string;\n}>();\ndefineEmits<{\n file: [file: File];\n insertUrl: [url: string];\n close: [];\n}>();\nconst panel = useTemplateRef<HTMLElement>('panel');\nconst target = toRef(props, 'target');\nconst boundary = computed<HTMLElement | null>(\n () => props.target?.closest<HTMLElement>('.erag-editor__content-wrap') ?? null,\n);\nconst { style } = useFloatingPosition(target, panel, boundary);\n</script>\n\n<template>\n <span\n v-if=\"target\"\n ref=\"panel\"\n class=\"erag-inline-image-upload-portal\"\n :style=\"style\"\n >\n <InlineImageUpload\n :accepted-formats=\"config.acceptedFormats\"\n :file-picker=\"config.imageFilePicker\"\n :url-input=\"config.imageUrlInput\"\n :loading=\"state.loading\"\n :progress=\"state.progress\"\n :error=\"error\"\n @file=\"$emit('file', $event)\"\n @insert-url=\"$emit('insertUrl', $event)\"\n @close=\"$emit('close')\"\n />\n </span>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, toRef, useTemplateRef } from 'vue';\nimport { useFloatingPosition } from '../../composables/useFloatingPosition';\nimport type { ResolvedEditorInit, UploadState } from '../../types';\nimport InlineImageUpload from './InlineImageUpload.vue';\n\nconst props = defineProps<{\n target: HTMLElement | null;\n config: ResolvedEditorInit;\n state: UploadState;\n error: string;\n}>();\ndefineEmits<{\n file: [file: File];\n insertUrl: [url: string];\n close: [];\n}>();\nconst panel = useTemplateRef<HTMLElement>('panel');\nconst target = toRef(props, 'target');\nconst boundary = computed<HTMLElement | null>(\n () => props.target?.closest<HTMLElement>('.erag-editor__content-wrap') ?? null,\n);\nconst { style } = useFloatingPosition(target, panel, boundary);\n</script>\n\n<template>\n <span\n v-if=\"target\"\n ref=\"panel\"\n class=\"erag-inline-image-upload-portal\"\n :style=\"style\"\n >\n <InlineImageUpload\n :accepted-formats=\"config.acceptedFormats\"\n :file-picker=\"config.imageFilePicker\"\n :url-input=\"config.imageUrlInput\"\n :loading=\"state.loading\"\n :progress=\"state.progress\"\n :error=\"error\"\n @file=\"$emit('file', $event)\"\n @insert-url=\"$emit('insertUrl', $event)\"\n @close=\"$emit('close')\"\n />\n </span>\n</template>\n","<script setup lang=\"ts\">\nimport {\n computed,\n nextTick,\n onBeforeUnmount,\n onMounted,\n shallowRef,\n useTemplateRef,\n watch,\n} from 'vue';\nimport { executeAsyncEditorCommand, executeEditorCommand } from '../commands/commandRegistry';\nimport { applyTableProperties, navigateTableCell } from '../commands/tableCommands';\nimport { insertImage, insertLink, insertMedia, insertTable } from '../commands/insertCommands';\nimport { KEYBOARD_SHORTCUTS } from '../constants/keyboardShortcuts';\nimport { useEditor } from '../composables/useEditor';\nimport { useEditorConfig } from '../composables/useEditorConfig';\nimport { useEditorHistory } from '../composables/useEditorHistory';\nimport { useEditorResize } from '../composables/useEditorResize';\nimport { useEditorSelection } from '../composables/useEditorSelection';\nimport { useEditorUpload } from '../composables/useEditorUpload';\nimport { useFullscreen } from '../composables/useFullscreen';\nimport { useImageResize } from '../composables/useImageResize';\nimport { useInlineImageUpload } from '../composables/useInlineImageUpload';\nimport { useLinkInitial } from '../composables/useLinkInitial';\nimport { useMentions } from '../composables/useMentions';\nimport { useMergeTags } from '../composables/useMergeTags';\nimport { useMergeTagSidebar } from '../composables/useMergeTagSidebar';\nimport { useWordCount } from '../composables/useWordCount';\nimport type {\n EditorDialogName,\n EditorEmits,\n EditorInstance,\n EditorSlots,\n EditorTemplateItem,\n EditorProps,\n LinkValue,\n MediaValue,\n MenuItemDefinition,\n} from '../types';\nimport { formatDateTime, mergeDateTimeFormats } from '../utils/dateTime';\nimport { escapeHtml, insertAtSelection } from '../utils/html';\nimport { cssUnit } from '../utils/units';\nimport EditorContent from './EditorContent.vue';\nimport EditorDialogs from './EditorDialogs.vue';\nimport EditorMenuBar from './EditorMenuBar.vue';\nimport EditorStatusBar from './EditorStatusBar.vue';\nimport EditorToolbar from './EditorToolbar.vue';\nimport MentionDropdown from './mentions/MentionDropdown.vue';\nimport MentionHoverCard from './mentions/MentionHoverCard.vue';\nimport MergeTagDropdown from './merge-tags/MergeTagDropdown.vue';\nimport MergeTagSidebar from './merge-tags/MergeTagSidebar.vue';\nimport ImageResizeOverlay from './images/ImageResizeOverlay.vue';\nimport InlineImageUploadPortal from './images/InlineImageUploadPortal.vue';\n\ndefineOptions({ inheritAttrs: false });\nconst props = withDefaults(defineProps<EditorProps>(), {\n modelValue: '',\n disabled: false,\n readonly: false,\n ariaLabel: 'Rich text editor',\n});\nconst emit = defineEmits<EditorEmits>();\ndefineSlots<EditorSlots>();\nconst config = useEditorConfig(() => props.init);\nconst editor = useEditor(config, props.modelValue);\nconst history = useEditorHistory(editor.root);\nconst selection = useEditorSelection(editor.root);\nconst shell = useTemplateRef<HTMLElement>('shell');\nconst contentWrap = useTemplateRef<HTMLElement>('contentWrap');\nconst dialog = shallowRef<EditorDialogName | null>(null);\nconst dialogMode = shallowRef<'forecolor' | 'backcolor' | null>(null);\nconst lastCommitted = shallowRef(props.modelValue);\nconst lastPublished = shallowRef(props.modelValue);\nconst { toggle: toggleFullscreen } = useFullscreen(shell);\nconst { upload: uploadImage, cancel: cancelImageUpload } = useEditorUpload(config);\nconst locked = computed(() => props.disabled || props.readonly || config.value.readonly);\nconst inlineImageUpload = useInlineImageUpload(editor.root, config, locked, syncInput);\nconst editorResize = useEditorResize(shell, config, locked, (height) => emit('resize', { height }));\nconst imageResizeLocked = computed(() => locked.value || !config.value.imageResize);\nconst imageResize = useImageResize(\n editor.root,\n contentWrap,\n imageResizeLocked,\n syncInput,\n (image) => emit('image-remove', image),\n);\nconst menubar = computed(() => config.value.menubar);\nconst toolbar = computed(() => config.value.toolbar);\nconst statusbar = computed(() => config.value.statusbar);\nconst mentionConfig = computed(() => config.value.mentions);\nconst mergeTagConfig = computed(() => config.value.mergeTags);\nconst mentions = useMentions(\n { root: editor.root, config: mentionConfig, locked },\n {\n search: (event) => emit('mention-search', event),\n select: (event) => emit('mention-select', event),\n remove: (event) => emit('mention-remove', event),\n change: () => syncInput(),\n },\n);\nconst mergeTags = useMergeTags(\n { root: editor.root, config: mergeTagConfig, locked },\n {\n select: (event) => emit('merge-tag-select', event),\n remove: (event) => emit('merge-tag-remove', event),\n change: () => syncInput(),\n },\n);\nconst mergeTagSidebar = useMergeTagSidebar(\n { config: mergeTagConfig, disabled: computed(() => props.disabled), locked },\n {\n restoreSelection: selection.restore,\n saveSelection: selection.save,\n insert: mergeTags.insert,\n },\n);\nconst availableCommands = computed<Record<string, boolean>>(() => ({\n undo: history.canUndo.value,\n redo: history.canRedo.value,\n}));\nconst activeCommands = computed<Record<string, boolean>>(() => ({\n ...selection.state.value.commands,\n ...(imageResize.box.value ? imageResize.activeCommands.value : {}),\n}));\nconst wordCountData = useWordCount(editor.root, selection.savedRange);\nconst shellStyle = computed(() => ({\n width: cssUnit(config.value.width),\n minHeight: cssUnit(config.value.minHeight),\n maxHeight: cssUnit(config.value.maxHeight),\n '--erag-editor-height': cssUnit(editorResize.currentHeight.value ?? config.value.height),\n}));\nconst { initial: linkInitial, getSelectedAnchor } = useLinkInitial(\n editor.root,\n selection.savedRange,\n);\n\nwatch(\n () => props.modelValue,\n (value) => {\n lastPublished.value = value;\n if (value !== editor.sync()) {\n inlineImageUpload.discard();\n editor.setHtml(value, true);\n history.reset();\n }\n },\n);\nwatch(\n config,\n (value) => {\n if (editor.root.value) {\n editor.root.value.setAttribute('dir', value.direction);\n editor.updateCounts();\n }\n editorResize.reset();\n },\n { deep: true },\n);\n\nfunction ready(root: HTMLElement): void {\n editor.connect(root);\n selection.update();\n history.update();\n emit('ready', root);\n if (config.value.autofocus && !locked.value) nextTick(() => root.focus());\n}\nfunction syncInput(event?: InputEvent): void {\n const value = editor.sync();\n if (value !== lastPublished.value) {\n lastPublished.value = value;\n emit('update:modelValue', value);\n }\n if (event) emit('input', event);\n selection.update();\n history.update();\n imageResize.refresh();\n}\nfunction handleInput(event: InputEvent): void {\n syncInput(event);\n mentions.handleInput();\n mergeTags.handleInput();\n}\nfunction restoreAndRun(id: string, value?: string): void {\n if (locked.value || !editor.root.value) return;\n if (id === 'saveSelection') {\n selection.save();\n return;\n }\n if (imageResize.executeCommand(id)) return;\n selection.restore();\n if (id === 'imageUpload') {\n void inlineImageUpload.open();\n return;\n }\n if (inlineImageUpload.isOpen.value) {\n void inlineImageUpload.close().then(() => restoreAndRun(id, value));\n return;\n }\n if (id === 'insertMergeTag') {\n const item = config.value.mergeTags.items.find((entry) => entry.value === value);\n if (item) mergeTags.insert(item);\n return;\n }\n if (id === 'fullscreen') {\n void toggleFullscreen();\n return;\n }\n if (id === 'new') {\n setHtml('');\n history.reset();\n return;\n }\n if (id === 'dateTime') {\n const formats = mergeDateTimeFormats(config.value.dateFormats, config.value.timeFormats);\n const format = formats[Number.parseInt(value ?? '0', 10)];\n if (format) insertText(formatDateTime(format, new Date()));\n return;\n }\n if (id === 'wordCount') {\n dialog.value = 'word-count';\n return;\n }\n if (['cut', 'copy', 'paste', 'pasteText'].includes(id)) {\n void executeAsyncEditorCommand(editor.root.value, id).then(() => syncInput());\n return;\n }\n if (executeEditorCommand(editor.root.value, id, value)) syncInput();\n}\nfunction openDialog(name: string): void {\n if (locked.value && !['preview', 'source', 'shortcuts', 'about'].includes(name)) return;\n if (inlineImageUpload.isOpen.value) {\n void inlineImageUpload.close().then(() => openDialog(name));\n return;\n }\n selection.save();\n if (name === 'forecolor' || name === 'backcolor') {\n dialogMode.value = name;\n return;\n }\n dialog.value = name as EditorDialogName;\n}\nfunction handleMenu(item: MenuItemDefinition): void {\n if (item.dialog) openDialog(item.dialog);\n else if (item.command) restoreAndRun(item.command, item.value);\n}\nfunction closeDialog(): void {\n dialog.value = null;\n dialogMode.value = null;\n nextTick(() => selection.restore());\n}\nfunction saveLink(value: LinkValue): void {\n if (!editor.root.value) return;\n selection.restore();\n const anchor = getSelectedAnchor();\n if (anchor) {\n anchor.href = value.url;\n anchor.textContent = value.text || value.url;\n anchor.title = value.title;\n if (value.target === '_blank') {\n anchor.target = '_blank';\n anchor.rel = 'noopener noreferrer';\n } else {\n anchor.removeAttribute('target');\n anchor.removeAttribute('rel');\n }\n } else insertLink(editor.root.value, value, config.value.relativeUrls);\n syncInput();\n closeDialog();\n}\nfunction unlink(): void {\n selection.restore();\n document.execCommand('unlink', false);\n syncInput();\n closeDialog();\n}\nfunction saveMedia(value: MediaValue): void {\n if (editor.root.value) {\n selection.restore();\n insertMedia(editor.root.value, value, config.value.relativeUrls);\n syncInput();\n }\n closeDialog();\n}\nfunction saveTable(rows: number, columns: number): void {\n if (editor.root.value) {\n selection.restore();\n insertTable(editor.root.value, rows, columns);\n syncInput();\n }\n closeDialog();\n}\nfunction saveSource(value: string): void {\n editor.setHtml(editor.clean(value), false);\n syncInput();\n closeDialog();\n}\nfunction saveTableProperties(values: Record<string, string>): void {\n if (editor.root.value) {\n selection.restore();\n applyTableProperties(editor.root.value, values);\n syncInput();\n }\n closeDialog();\n}\nfunction insertCharacter(value: string): void {\n insertText(value);\n closeDialog();\n}\nfunction insertTemplate(item: EditorTemplateItem): void {\n if (!editor.root.value || locked.value) return;\n selection.restore();\n insertAtSelection(editor.root.value, editor.clean(item.content));\n syncInput();\n emit('template-insert', { item: { ...item } });\n closeDialog();\n}\nfunction applyDialogColor(color: string): void {\n if (dialogMode.value)\n restoreAndRun(\n dialogMode.value,\n color || (dialogMode.value === 'forecolor' ? '#000000' : 'transparent'),\n );\n closeDialog();\n}\nfunction commandShortcut(event: KeyboardEvent): boolean {\n const prefix = event.metaKey || event.ctrlKey ? 'mod+' : '';\n const shift = event.shiftKey ? 'shift+' : '';\n const key = `${prefix}${shift}${event.key.toLowerCase()}`;\n const command = KEYBOARD_SHORTCUTS[key];\n if (!command) return false;\n event.preventDefault();\n command.includes('-') ? openDialog(command) : restoreAndRun(command);\n return true;\n}\nfunction handleKeydown(event: KeyboardEvent): void {\n emit('keydown', event);\n if (\n locked.value ||\n mentions.handleKeydown(event) ||\n mergeTags.handleKeydown(event) ||\n mentions.handleRemoval(event) ||\n mergeTags.handleRemoval(event)\n )\n return;\n if (commandShortcut(event)) return;\n if (event.altKey && event.key === '0') {\n event.preventDefault();\n openDialog('shortcuts');\n }\n if (\n event.key === 'Tab' &&\n editor.root.value &&\n navigateTableCell(editor.root.value, event.shiftKey)\n )\n event.preventDefault();\n}\nasync function handlePaste(event: ClipboardEvent): Promise<void> {\n emit('paste', event);\n if (locked.value || !editor.root.value) {\n event.preventDefault();\n return;\n }\n const image = [...(event.clipboardData?.files ?? [])].find((file) =>\n file.type.startsWith('image/'),\n );\n if (image && config.value.pasteImages && config.value.automaticUploads) {\n event.preventDefault();\n selection.save();\n try {\n const url = await uploadImage(image);\n selection.restore();\n insertImage(\n editor.root.value,\n { src: url, alt: image.name, width: '', height: '' },\n config.value.relativeUrls,\n );\n syncInput();\n mentions.handleInput();\n mergeTags.handleInput();\n } catch {\n return;\n } finally {\n cancelImageUpload();\n }\n return;\n }\n const html = event.clipboardData?.getData('text/html');\n const text = event.clipboardData?.getData('text/plain') ?? '';\n event.preventDefault();\n selection.restore();\n insertAtSelection(\n editor.root.value,\n html ? editor.clean(html) : escapeHtml(text).replaceAll('\\n', '<br>'),\n );\n syncInput();\n mentions.handleInput();\n mergeTags.handleInput();\n}\nfunction selectionChanged(): void {\n selection.update();\n mentions.handleSelectionChange();\n mergeTags.handleSelectionChange();\n const current = window.getSelection();\n if (current) emit('selection-change', current);\n}\nfunction handleBlur(event: FocusEvent): void {\n emit('blur', event);\n const value = editor.sync();\n if (value !== lastCommitted.value) {\n lastCommitted.value = value;\n emit('change', value);\n }\n}\nfunction handleEditorClick(event: MouseEvent): void {\n imageResize.selectFromEvent(event);\n emit('click', event);\n}\nfunction focus(): void {\n editor.root.value?.focus();\n}\nfunction blur(): void {\n editor.root.value?.blur();\n}\nfunction getHtml(): string {\n return editor.sync();\n}\nfunction setHtml(value: string): void {\n inlineImageUpload.discard();\n editor.setHtml(value, false);\n syncInput();\n}\nfunction getText(): string {\n return editor.getText();\n}\nfunction clear(): void {\n setHtml('');\n}\nfunction insertHtml(value: string): void {\n if (!editor.root.value || locked.value) return;\n selection.restore();\n insertAtSelection(editor.root.value, editor.clean(value));\n syncInput();\n}\nfunction insertText(value: string): void {\n insertHtml(escapeHtml(value));\n}\nfunction selectAll(): void {\n focus();\n document.execCommand('selectAll', false);\n selection.update();\n}\nfunction undo(): void {\n restoreAndRun('undo');\n}\nfunction redo(): void {\n restoreAndRun('redo');\n}\nfunction openSourceCode(): void {\n openDialog('source');\n}\nfunction openPreview(): void {\n openDialog('preview');\n}\ndefineExpose<EditorInstance>({\n focus,\n blur,\n getHtml,\n setHtml,\n getText,\n clear,\n insertHtml,\n insertText,\n selectAll,\n undo,\n redo,\n openSourceCode,\n openPreview,\n getRootElement: () => editor.root.value,\n});\nonMounted(() => document.addEventListener('selectionchange', selectionChanged));\nonBeforeUnmount(() => document.removeEventListener('selectionchange', selectionChanged));\n</script>\n\n<template>\n <div\n ref=\"shell\"\n class=\"erag-editor\"\n :class=\"{\n 'erag-is-disabled': props.disabled,\n 'erag-is-readonly': locked && !props.disabled,\n }\"\n :style=\"shellStyle\"\n >\n <input\n v-if=\"name\"\n type=\"hidden\"\n :name=\"name\"\n :value=\"editor.html.value\"\n />\n <EditorMenuBar\n v-if=\"menubar\"\n :menus=\"menubar === true ? true : menubar\"\n :plugins=\"config.plugins\"\n :disabled=\"props.disabled\"\n :active-commands=\"activeCommands\"\n :available-commands=\"availableCommands\"\n :inside-table=\"selection.state.value.insideTable\"\n :line-height-formats=\"config.lineHeightFormats\"\n :date-formats=\"config.dateFormats\"\n :time-formats=\"config.timeFormats\"\n :merge-tags=\"config.mergeTags\"\n :templates=\"config.templates\"\n :merge-tag-sidebar-open=\"mergeTagSidebar.isOpen.value\"\n :template-dialog-open=\"dialog === 'templates'\"\n @opening=\"mergeTagSidebar.handleMenubarOpening\"\n @merge-tag-toggle=\"mergeTagSidebar.toggle\"\n @templates-open=\"openDialog('templates')\"\n @select=\"handleMenu\"\n ><template\n v-if=\"$slots['menubar-end']\"\n #end\n ><slot name=\"menubar-end\" /></template\n ></EditorMenuBar>\n <EditorToolbar\n v-if=\"toolbar\"\n :toolbar=\"toolbar\"\n :config=\"config\"\n :disabled=\"props.disabled\"\n :active-commands=\"activeCommands\"\n :available-commands=\"availableCommands\"\n :inside-table=\"selection.state.value.insideTable\"\n @command=\"restoreAndRun\"\n @dialog=\"openDialog\"\n ><template\n v-if=\"$slots['toolbar-start']\"\n #start\n ><slot name=\"toolbar-start\" /></template\n ><template\n v-if=\"$slots['toolbar-end']\"\n #end\n ><slot name=\"toolbar-end\" /></template\n ></EditorToolbar>\n <div\n ref=\"contentWrap\"\n class=\"erag-editor__content-wrap\"\n >\n <EditorContent\n :id=\"props.id\"\n :html=\"editor.html.value\"\n :disabled=\"props.disabled\"\n :readonly=\"locked\"\n :placeholder=\"config.placeholder\"\n :spellcheck=\"config.spellcheck\"\n :direction=\"config.direction\"\n :content-class=\"config.contentClass\"\n :content-style=\"config.contentStyle\"\n :label=\"props.ariaLabel\"\n @ready=\"ready\"\n @click=\"handleEditorClick\"\n @focus=\"emit('focus', $event)\"\n @blur=\"handleBlur\"\n @input=\"handleInput\"\n @keydown=\"handleKeydown\"\n @paste=\"handlePaste\"\n @selectionchange=\"selectionChanged\"\n />\n <ImageResizeOverlay\n v-if=\"imageResize.box.value\"\n :box=\"imageResize.box.value\"\n :deleting=\"imageResize.deleting.value\"\n :delete-error=\"imageResize.deleteError.value\"\n :delete-from-server=\"Boolean(config.imagesDeleteHandler)\"\n @resize-start=\"imageResize.resizeStart\"\n @delete=\"imageResize.deleteSelected(config.imagesDeleteHandler)\"\n />\n <div\n v-if=\"editor.empty.value && !inlineImageUpload.isOpen.value && $slots.empty\"\n class=\"erag-editor__empty\"\n >\n <slot name=\"empty\" />\n </div>\n <MergeTagSidebar\n v-if=\"mergeTagSidebar.isOpen.value\"\n :id=\"mergeTagSidebar.id\"\n :items=\"config.mergeTags.items\"\n :disabled=\"locked\"\n @close=\"mergeTagSidebar.close\"\n @select=\"mergeTagSidebar.select\"\n />\n </div>\n <InlineImageUploadPortal\n :target=\"inlineImageUpload.target.value\"\n :config=\"config\"\n :state=\"inlineImageUpload.state\"\n :error=\"inlineImageUpload.message.value\"\n @file=\"inlineImageUpload.uploadFile\"\n @insert-url=\"inlineImageUpload.insertUrl\"\n @close=\"inlineImageUpload.close\"\n />\n <EditorStatusBar\n v-if=\"statusbar\"\n :path=\"selection.state.value.path\"\n :counts=\"editor.counts.value\"\n :resize=\"config.resize\"\n :help-text=\"config.helpShortcutText\"\n :disabled=\"props.disabled\"\n @resize-start=\"editorResize.start\"\n ><template\n v-if=\"$slots['statusbar-start']\"\n #start\n ><slot name=\"statusbar-start\" /></template\n ><template\n v-if=\"$slots['statusbar-end']\"\n #end\n ><slot name=\"statusbar-end\" /></template\n ></EditorStatusBar>\n <MentionDropdown\n v-if=\"mentions.isOpen.value\"\n :items=\"mentions.items.value\"\n :active-index=\"mentions.activeIndex.value\"\n :state=\"mentions.state.value\"\n :query=\"mentions.query.value\"\n :position-style=\"mentions.positionStyle.value\"\n @activate=\"mentions.setActiveIndex\"\n @select=\"mentions.select\"\n @retry=\"mentions.retry\"\n @ready=\"mentions.setDropdownElement\"\n >\n <template\n v-if=\"$slots['mention-item']\"\n #item=\"slotProps\"\n >\n <slot\n name=\"mention-item\"\n v-bind=\"slotProps\"\n />\n </template>\n <template\n v-if=\"$slots['mention-loading']\"\n #loading=\"slotProps\"\n >\n <slot\n name=\"mention-loading\"\n v-bind=\"slotProps\"\n />\n </template>\n <template\n v-if=\"$slots['mention-empty']\"\n #empty=\"slotProps\"\n >\n <slot\n name=\"mention-empty\"\n v-bind=\"slotProps\"\n />\n </template>\n <template\n v-if=\"$slots['mention-error']\"\n #error=\"slotProps\"\n >\n <slot\n name=\"mention-error\"\n v-bind=\"slotProps\"\n />\n </template>\n </MentionDropdown>\n <MergeTagDropdown\n v-if=\"mergeTags.isOpen.value\"\n :items=\"mergeTags.items.value\"\n :active-index=\"mergeTags.activeIndex.value\"\n :query=\"mergeTags.query.value\"\n :position-style=\"mergeTags.positionStyle.value\"\n @activate=\"mergeTags.setActiveIndex\"\n @select=\"mergeTags.select\"\n @ready=\"mergeTags.setDropdownElement\"\n />\n <MentionHoverCard\n v-if=\"mentions.hoverItem.value\"\n :item=\"mentions.hoverItem.value\"\n :position-style=\"mentions.hoverPositionStyle.value\"\n @ready=\"mentions.setHoverCardElement\"\n />\n </div>\n <EditorDialogs\n :dialog=\"dialog\"\n :dialog-mode=\"dialogMode\"\n :config=\"config\"\n :link-initial=\"linkInitial\"\n :html=\"editor.html.value\"\n :preview-html=\"editor.clean(editor.html.value)\"\n :root=\"editor.root.value\"\n :word-count-data=\"wordCountData\"\n @close=\"closeDialog\"\n @save-link=\"saveLink\"\n @unlink=\"unlink\"\n @save-media=\"saveMedia\"\n @save-table=\"saveTable\"\n @select-character=\"insertCharacter\"\n @save-source=\"saveSource\"\n @changed=\"syncInput\"\n @save-table-properties=\"saveTableProperties\"\n @select-color=\"applyDialogColor\"\n @insert-template=\"insertTemplate\"\n />\n</template>\n","<script setup lang=\"ts\">\nimport {\n computed,\n nextTick,\n onBeforeUnmount,\n onMounted,\n shallowRef,\n useTemplateRef,\n watch,\n} from 'vue';\nimport { executeAsyncEditorCommand, executeEditorCommand } from '../commands/commandRegistry';\nimport { applyTableProperties, navigateTableCell } from '../commands/tableCommands';\nimport { insertImage, insertLink, insertMedia, insertTable } from '../commands/insertCommands';\nimport { KEYBOARD_SHORTCUTS } from '../constants/keyboardShortcuts';\nimport { useEditor } from '../composables/useEditor';\nimport { useEditorConfig } from '../composables/useEditorConfig';\nimport { useEditorHistory } from '../composables/useEditorHistory';\nimport { useEditorResize } from '../composables/useEditorResize';\nimport { useEditorSelection } from '../composables/useEditorSelection';\nimport { useEditorUpload } from '../composables/useEditorUpload';\nimport { useFullscreen } from '../composables/useFullscreen';\nimport { useImageResize } from '../composables/useImageResize';\nimport { useInlineImageUpload } from '../composables/useInlineImageUpload';\nimport { useLinkInitial } from '../composables/useLinkInitial';\nimport { useMentions } from '../composables/useMentions';\nimport { useMergeTags } from '../composables/useMergeTags';\nimport { useMergeTagSidebar } from '../composables/useMergeTagSidebar';\nimport { useWordCount } from '../composables/useWordCount';\nimport type {\n EditorDialogName,\n EditorEmits,\n EditorInstance,\n EditorSlots,\n EditorTemplateItem,\n EditorProps,\n LinkValue,\n MediaValue,\n MenuItemDefinition,\n} from '../types';\nimport { formatDateTime, mergeDateTimeFormats } from '../utils/dateTime';\nimport { escapeHtml, insertAtSelection } from '../utils/html';\nimport { cssUnit } from '../utils/units';\nimport EditorContent from './EditorContent.vue';\nimport EditorDialogs from './EditorDialogs.vue';\nimport EditorMenuBar from './EditorMenuBar.vue';\nimport EditorStatusBar from './EditorStatusBar.vue';\nimport EditorToolbar from './EditorToolbar.vue';\nimport MentionDropdown from './mentions/MentionDropdown.vue';\nimport MentionHoverCard from './mentions/MentionHoverCard.vue';\nimport MergeTagDropdown from './merge-tags/MergeTagDropdown.vue';\nimport MergeTagSidebar from './merge-tags/MergeTagSidebar.vue';\nimport ImageResizeOverlay from './images/ImageResizeOverlay.vue';\nimport InlineImageUploadPortal from './images/InlineImageUploadPortal.vue';\n\ndefineOptions({ inheritAttrs: false });\nconst props = withDefaults(defineProps<EditorProps>(), {\n modelValue: '',\n disabled: false,\n readonly: false,\n ariaLabel: 'Rich text editor',\n});\nconst emit = defineEmits<EditorEmits>();\ndefineSlots<EditorSlots>();\nconst config = useEditorConfig(() => props.init);\nconst editor = useEditor(config, props.modelValue);\nconst history = useEditorHistory(editor.root);\nconst selection = useEditorSelection(editor.root);\nconst shell = useTemplateRef<HTMLElement>('shell');\nconst contentWrap = useTemplateRef<HTMLElement>('contentWrap');\nconst dialog = shallowRef<EditorDialogName | null>(null);\nconst dialogMode = shallowRef<'forecolor' | 'backcolor' | null>(null);\nconst lastCommitted = shallowRef(props.modelValue);\nconst lastPublished = shallowRef(props.modelValue);\nconst { toggle: toggleFullscreen } = useFullscreen(shell);\nconst { upload: uploadImage, cancel: cancelImageUpload } = useEditorUpload(config);\nconst locked = computed(() => props.disabled || props.readonly || config.value.readonly);\nconst inlineImageUpload = useInlineImageUpload(editor.root, config, locked, syncInput);\nconst editorResize = useEditorResize(shell, config, locked, (height) => emit('resize', { height }));\nconst imageResizeLocked = computed(() => locked.value || !config.value.imageResize);\nconst imageResize = useImageResize(\n editor.root,\n contentWrap,\n imageResizeLocked,\n syncInput,\n (image) => emit('image-remove', image),\n);\nconst menubar = computed(() => config.value.menubar);\nconst toolbar = computed(() => config.value.toolbar);\nconst statusbar = computed(() => config.value.statusbar);\nconst mentionConfig = computed(() => config.value.mentions);\nconst mergeTagConfig = computed(() => config.value.mergeTags);\nconst mentions = useMentions(\n { root: editor.root, config: mentionConfig, locked },\n {\n search: (event) => emit('mention-search', event),\n select: (event) => emit('mention-select', event),\n remove: (event) => emit('mention-remove', event),\n change: () => syncInput(),\n },\n);\nconst mergeTags = useMergeTags(\n { root: editor.root, config: mergeTagConfig, locked },\n {\n select: (event) => emit('merge-tag-select', event),\n remove: (event) => emit('merge-tag-remove', event),\n change: () => syncInput(),\n },\n);\nconst mergeTagSidebar = useMergeTagSidebar(\n { config: mergeTagConfig, disabled: computed(() => props.disabled), locked },\n {\n restoreSelection: selection.restore,\n saveSelection: selection.save,\n insert: mergeTags.insert,\n },\n);\nconst availableCommands = computed<Record<string, boolean>>(() => ({\n undo: history.canUndo.value,\n redo: history.canRedo.value,\n}));\nconst activeCommands = computed<Record<string, boolean>>(() => ({\n ...selection.state.value.commands,\n ...(imageResize.box.value ? imageResize.activeCommands.value : {}),\n}));\nconst wordCountData = useWordCount(editor.root, selection.savedRange);\nconst shellStyle = computed(() => ({\n width: cssUnit(config.value.width),\n minHeight: cssUnit(config.value.minHeight),\n maxHeight: cssUnit(config.value.maxHeight),\n '--erag-editor-height': cssUnit(editorResize.currentHeight.value ?? config.value.height),\n}));\nconst { initial: linkInitial, getSelectedAnchor } = useLinkInitial(\n editor.root,\n selection.savedRange,\n);\n\nwatch(\n () => props.modelValue,\n (value) => {\n lastPublished.value = value;\n if (value !== editor.sync()) {\n inlineImageUpload.discard();\n editor.setHtml(value, true);\n history.reset();\n }\n },\n);\nwatch(\n config,\n (value) => {\n if (editor.root.value) {\n editor.root.value.setAttribute('dir', value.direction);\n editor.updateCounts();\n }\n editorResize.reset();\n },\n { deep: true },\n);\n\nfunction ready(root: HTMLElement): void {\n editor.connect(root);\n selection.update();\n history.update();\n emit('ready', root);\n if (config.value.autofocus && !locked.value) nextTick(() => root.focus());\n}\nfunction syncInput(event?: InputEvent): void {\n const value = editor.sync();\n if (value !== lastPublished.value) {\n lastPublished.value = value;\n emit('update:modelValue', value);\n }\n if (event) emit('input', event);\n selection.update();\n history.update();\n imageResize.refresh();\n}\nfunction handleInput(event: InputEvent): void {\n syncInput(event);\n mentions.handleInput();\n mergeTags.handleInput();\n}\nfunction restoreAndRun(id: string, value?: string): void {\n if (locked.value || !editor.root.value) return;\n if (id === 'saveSelection') {\n selection.save();\n return;\n }\n if (imageResize.executeCommand(id)) return;\n selection.restore();\n if (id === 'imageUpload') {\n void inlineImageUpload.open();\n return;\n }\n if (inlineImageUpload.isOpen.value) {\n void inlineImageUpload.close().then(() => restoreAndRun(id, value));\n return;\n }\n if (id === 'insertMergeTag') {\n const item = config.value.mergeTags.items.find((entry) => entry.value === value);\n if (item) mergeTags.insert(item);\n return;\n }\n if (id === 'fullscreen') {\n void toggleFullscreen();\n return;\n }\n if (id === 'new') {\n setHtml('');\n history.reset();\n return;\n }\n if (id === 'dateTime') {\n const formats = mergeDateTimeFormats(config.value.dateFormats, config.value.timeFormats);\n const format = formats[Number.parseInt(value ?? '0', 10)];\n if (format) insertText(formatDateTime(format, new Date()));\n return;\n }\n if (id === 'wordCount') {\n dialog.value = 'word-count';\n return;\n }\n if (['cut', 'copy', 'paste', 'pasteText'].includes(id)) {\n void executeAsyncEditorCommand(editor.root.value, id).then(() => syncInput());\n return;\n }\n if (executeEditorCommand(editor.root.value, id, value)) syncInput();\n}\nfunction openDialog(name: string): void {\n if (locked.value && !['preview', 'source', 'shortcuts', 'about'].includes(name)) return;\n if (inlineImageUpload.isOpen.value) {\n void inlineImageUpload.close().then(() => openDialog(name));\n return;\n }\n selection.save();\n if (name === 'forecolor' || name === 'backcolor') {\n dialogMode.value = name;\n return;\n }\n dialog.value = name as EditorDialogName;\n}\nfunction handleMenu(item: MenuItemDefinition): void {\n if (item.dialog) openDialog(item.dialog);\n else if (item.command) restoreAndRun(item.command, item.value);\n}\nfunction closeDialog(): void {\n dialog.value = null;\n dialogMode.value = null;\n nextTick(() => selection.restore());\n}\nfunction saveLink(value: LinkValue): void {\n if (!editor.root.value) return;\n selection.restore();\n const anchor = getSelectedAnchor();\n if (anchor) {\n anchor.href = value.url;\n anchor.textContent = value.text || value.url;\n anchor.title = value.title;\n if (value.target === '_blank') {\n anchor.target = '_blank';\n anchor.rel = 'noopener noreferrer';\n } else {\n anchor.removeAttribute('target');\n anchor.removeAttribute('rel');\n }\n } else insertLink(editor.root.value, value, config.value.relativeUrls);\n syncInput();\n closeDialog();\n}\nfunction unlink(): void {\n selection.restore();\n document.execCommand('unlink', false);\n syncInput();\n closeDialog();\n}\nfunction saveMedia(value: MediaValue): void {\n if (editor.root.value) {\n selection.restore();\n insertMedia(editor.root.value, value, config.value.relativeUrls);\n syncInput();\n }\n closeDialog();\n}\nfunction saveTable(rows: number, columns: number): void {\n if (editor.root.value) {\n selection.restore();\n insertTable(editor.root.value, rows, columns);\n syncInput();\n }\n closeDialog();\n}\nfunction saveSource(value: string): void {\n editor.setHtml(editor.clean(value), false);\n syncInput();\n closeDialog();\n}\nfunction saveTableProperties(values: Record<string, string>): void {\n if (editor.root.value) {\n selection.restore();\n applyTableProperties(editor.root.value, values);\n syncInput();\n }\n closeDialog();\n}\nfunction insertCharacter(value: string): void {\n insertText(value);\n closeDialog();\n}\nfunction insertTemplate(item: EditorTemplateItem): void {\n if (!editor.root.value || locked.value) return;\n selection.restore();\n insertAtSelection(editor.root.value, editor.clean(item.content));\n syncInput();\n emit('template-insert', { item: { ...item } });\n closeDialog();\n}\nfunction applyDialogColor(color: string): void {\n if (dialogMode.value)\n restoreAndRun(\n dialogMode.value,\n color || (dialogMode.value === 'forecolor' ? '#000000' : 'transparent'),\n );\n closeDialog();\n}\nfunction commandShortcut(event: KeyboardEvent): boolean {\n const prefix = event.metaKey || event.ctrlKey ? 'mod+' : '';\n const shift = event.shiftKey ? 'shift+' : '';\n const key = `${prefix}${shift}${event.key.toLowerCase()}`;\n const command = KEYBOARD_SHORTCUTS[key];\n if (!command) return false;\n event.preventDefault();\n command.includes('-') ? openDialog(command) : restoreAndRun(command);\n return true;\n}\nfunction handleKeydown(event: KeyboardEvent): void {\n emit('keydown', event);\n if (\n locked.value ||\n mentions.handleKeydown(event) ||\n mergeTags.handleKeydown(event) ||\n mentions.handleRemoval(event) ||\n mergeTags.handleRemoval(event)\n )\n return;\n if (commandShortcut(event)) return;\n if (event.altKey && event.key === '0') {\n event.preventDefault();\n openDialog('shortcuts');\n }\n if (\n event.key === 'Tab' &&\n editor.root.value &&\n navigateTableCell(editor.root.value, event.shiftKey)\n )\n event.preventDefault();\n}\nasync function handlePaste(event: ClipboardEvent): Promise<void> {\n emit('paste', event);\n if (locked.value || !editor.root.value) {\n event.preventDefault();\n return;\n }\n const image = [...(event.clipboardData?.files ?? [])].find((file) =>\n file.type.startsWith('image/'),\n );\n if (image && config.value.pasteImages && config.value.automaticUploads) {\n event.preventDefault();\n selection.save();\n try {\n const url = await uploadImage(image);\n selection.restore();\n insertImage(\n editor.root.value,\n { src: url, alt: image.name, width: '', height: '' },\n config.value.relativeUrls,\n );\n syncInput();\n mentions.handleInput();\n mergeTags.handleInput();\n } catch {\n return;\n } finally {\n cancelImageUpload();\n }\n return;\n }\n const html = event.clipboardData?.getData('text/html');\n const text = event.clipboardData?.getData('text/plain') ?? '';\n event.preventDefault();\n selection.restore();\n insertAtSelection(\n editor.root.value,\n html ? editor.clean(html) : escapeHtml(text).replaceAll('\\n', '<br>'),\n );\n syncInput();\n mentions.handleInput();\n mergeTags.handleInput();\n}\nfunction selectionChanged(): void {\n selection.update();\n mentions.handleSelectionChange();\n mergeTags.handleSelectionChange();\n const current = window.getSelection();\n if (current) emit('selection-change', current);\n}\nfunction handleBlur(event: FocusEvent): void {\n emit('blur', event);\n const value = editor.sync();\n if (value !== lastCommitted.value) {\n lastCommitted.value = value;\n emit('change', value);\n }\n}\nfunction handleEditorClick(event: MouseEvent): void {\n imageResize.selectFromEvent(event);\n emit('click', event);\n}\nfunction focus(): void {\n editor.root.value?.focus();\n}\nfunction blur(): void {\n editor.root.value?.blur();\n}\nfunction getHtml(): string {\n return editor.sync();\n}\nfunction setHtml(value: string): void {\n inlineImageUpload.discard();\n editor.setHtml(value, false);\n syncInput();\n}\nfunction getText(): string {\n return editor.getText();\n}\nfunction clear(): void {\n setHtml('');\n}\nfunction insertHtml(value: string): void {\n if (!editor.root.value || locked.value) return;\n selection.restore();\n insertAtSelection(editor.root.value, editor.clean(value));\n syncInput();\n}\nfunction insertText(value: string): void {\n insertHtml(escapeHtml(value));\n}\nfunction selectAll(): void {\n focus();\n document.execCommand('selectAll', false);\n selection.update();\n}\nfunction undo(): void {\n restoreAndRun('undo');\n}\nfunction redo(): void {\n restoreAndRun('redo');\n}\nfunction openSourceCode(): void {\n openDialog('source');\n}\nfunction openPreview(): void {\n openDialog('preview');\n}\ndefineExpose<EditorInstance>({\n focus,\n blur,\n getHtml,\n setHtml,\n getText,\n clear,\n insertHtml,\n insertText,\n selectAll,\n undo,\n redo,\n openSourceCode,\n openPreview,\n getRootElement: () => editor.root.value,\n});\nonMounted(() => document.addEventListener('selectionchange', selectionChanged));\nonBeforeUnmount(() => document.removeEventListener('selectionchange', selectionChanged));\n</script>\n\n<template>\n <div\n ref=\"shell\"\n class=\"erag-editor\"\n :class=\"{\n 'erag-is-disabled': props.disabled,\n 'erag-is-readonly': locked && !props.disabled,\n }\"\n :style=\"shellStyle\"\n >\n <input\n v-if=\"name\"\n type=\"hidden\"\n :name=\"name\"\n :value=\"editor.html.value\"\n />\n <EditorMenuBar\n v-if=\"menubar\"\n :menus=\"menubar === true ? true : menubar\"\n :plugins=\"config.plugins\"\n :disabled=\"props.disabled\"\n :active-commands=\"activeCommands\"\n :available-commands=\"availableCommands\"\n :inside-table=\"selection.state.value.insideTable\"\n :line-height-formats=\"config.lineHeightFormats\"\n :date-formats=\"config.dateFormats\"\n :time-formats=\"config.timeFormats\"\n :merge-tags=\"config.mergeTags\"\n :templates=\"config.templates\"\n :merge-tag-sidebar-open=\"mergeTagSidebar.isOpen.value\"\n :template-dialog-open=\"dialog === 'templates'\"\n @opening=\"mergeTagSidebar.handleMenubarOpening\"\n @merge-tag-toggle=\"mergeTagSidebar.toggle\"\n @templates-open=\"openDialog('templates')\"\n @select=\"handleMenu\"\n ><template\n v-if=\"$slots['menubar-end']\"\n #end\n ><slot name=\"menubar-end\" /></template\n ></EditorMenuBar>\n <EditorToolbar\n v-if=\"toolbar\"\n :toolbar=\"toolbar\"\n :config=\"config\"\n :disabled=\"props.disabled\"\n :active-commands=\"activeCommands\"\n :available-commands=\"availableCommands\"\n :inside-table=\"selection.state.value.insideTable\"\n @command=\"restoreAndRun\"\n @dialog=\"openDialog\"\n ><template\n v-if=\"$slots['toolbar-start']\"\n #start\n ><slot name=\"toolbar-start\" /></template\n ><template\n v-if=\"$slots['toolbar-end']\"\n #end\n ><slot name=\"toolbar-end\" /></template\n ></EditorToolbar>\n <div\n ref=\"contentWrap\"\n class=\"erag-editor__content-wrap\"\n >\n <EditorContent\n :id=\"props.id\"\n :html=\"editor.html.value\"\n :disabled=\"props.disabled\"\n :readonly=\"locked\"\n :placeholder=\"config.placeholder\"\n :spellcheck=\"config.spellcheck\"\n :direction=\"config.direction\"\n :content-class=\"config.contentClass\"\n :content-style=\"config.contentStyle\"\n :label=\"props.ariaLabel\"\n @ready=\"ready\"\n @click=\"handleEditorClick\"\n @focus=\"emit('focus', $event)\"\n @blur=\"handleBlur\"\n @input=\"handleInput\"\n @keydown=\"handleKeydown\"\n @paste=\"handlePaste\"\n @selectionchange=\"selectionChanged\"\n />\n <ImageResizeOverlay\n v-if=\"imageResize.box.value\"\n :box=\"imageResize.box.value\"\n :deleting=\"imageResize.deleting.value\"\n :delete-error=\"imageResize.deleteError.value\"\n :delete-from-server=\"Boolean(config.imagesDeleteHandler)\"\n @resize-start=\"imageResize.resizeStart\"\n @delete=\"imageResize.deleteSelected(config.imagesDeleteHandler)\"\n />\n <div\n v-if=\"editor.empty.value && !inlineImageUpload.isOpen.value && $slots.empty\"\n class=\"erag-editor__empty\"\n >\n <slot name=\"empty\" />\n </div>\n <MergeTagSidebar\n v-if=\"mergeTagSidebar.isOpen.value\"\n :id=\"mergeTagSidebar.id\"\n :items=\"config.mergeTags.items\"\n :disabled=\"locked\"\n @close=\"mergeTagSidebar.close\"\n @select=\"mergeTagSidebar.select\"\n />\n </div>\n <InlineImageUploadPortal\n :target=\"inlineImageUpload.target.value\"\n :config=\"config\"\n :state=\"inlineImageUpload.state\"\n :error=\"inlineImageUpload.message.value\"\n @file=\"inlineImageUpload.uploadFile\"\n @insert-url=\"inlineImageUpload.insertUrl\"\n @close=\"inlineImageUpload.close\"\n />\n <EditorStatusBar\n v-if=\"statusbar\"\n :path=\"selection.state.value.path\"\n :counts=\"editor.counts.value\"\n :resize=\"config.resize\"\n :help-text=\"config.helpShortcutText\"\n :disabled=\"props.disabled\"\n @resize-start=\"editorResize.start\"\n ><template\n v-if=\"$slots['statusbar-start']\"\n #start\n ><slot name=\"statusbar-start\" /></template\n ><template\n v-if=\"$slots['statusbar-end']\"\n #end\n ><slot name=\"statusbar-end\" /></template\n ></EditorStatusBar>\n <MentionDropdown\n v-if=\"mentions.isOpen.value\"\n :items=\"mentions.items.value\"\n :active-index=\"mentions.activeIndex.value\"\n :state=\"mentions.state.value\"\n :query=\"mentions.query.value\"\n :position-style=\"mentions.positionStyle.value\"\n @activate=\"mentions.setActiveIndex\"\n @select=\"mentions.select\"\n @retry=\"mentions.retry\"\n @ready=\"mentions.setDropdownElement\"\n >\n <template\n v-if=\"$slots['mention-item']\"\n #item=\"slotProps\"\n >\n <slot\n name=\"mention-item\"\n v-bind=\"slotProps\"\n />\n </template>\n <template\n v-if=\"$slots['mention-loading']\"\n #loading=\"slotProps\"\n >\n <slot\n name=\"mention-loading\"\n v-bind=\"slotProps\"\n />\n </template>\n <template\n v-if=\"$slots['mention-empty']\"\n #empty=\"slotProps\"\n >\n <slot\n name=\"mention-empty\"\n v-bind=\"slotProps\"\n />\n </template>\n <template\n v-if=\"$slots['mention-error']\"\n #error=\"slotProps\"\n >\n <slot\n name=\"mention-error\"\n v-bind=\"slotProps\"\n />\n </template>\n </MentionDropdown>\n <MergeTagDropdown\n v-if=\"mergeTags.isOpen.value\"\n :items=\"mergeTags.items.value\"\n :active-index=\"mergeTags.activeIndex.value\"\n :query=\"mergeTags.query.value\"\n :position-style=\"mergeTags.positionStyle.value\"\n @activate=\"mergeTags.setActiveIndex\"\n @select=\"mergeTags.select\"\n @ready=\"mergeTags.setDropdownElement\"\n />\n <MentionHoverCard\n v-if=\"mentions.hoverItem.value\"\n :item=\"mentions.hoverItem.value\"\n :position-style=\"mentions.hoverPositionStyle.value\"\n @ready=\"mentions.setHoverCardElement\"\n />\n </div>\n <EditorDialogs\n :dialog=\"dialog\"\n :dialog-mode=\"dialogMode\"\n :config=\"config\"\n :link-initial=\"linkInitial\"\n :html=\"editor.html.value\"\n :preview-html=\"editor.clean(editor.html.value)\"\n :root=\"editor.root.value\"\n :word-count-data=\"wordCountData\"\n @close=\"closeDialog\"\n @save-link=\"saveLink\"\n @unlink=\"unlink\"\n @save-media=\"saveMedia\"\n @save-table=\"saveTable\"\n @select-character=\"insertCharacter\"\n @save-source=\"saveSource\"\n @changed=\"syncInput\"\n @save-table-properties=\"saveTableProperties\"\n @select-color=\"applyDialogColor\"\n @insert-template=\"insertTemplate\"\n />\n</template>\n"],"mappings":"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"}
|